summaryrefslogtreecommitdiff
path: root/network
diff options
context:
space:
mode:
authorAaron M. Ucko <ucko@debian.org>2005-03-23 15:50:17 +0000
committerAaron M. Ucko <ucko@debian.org>2005-03-23 15:50:17 +0000
commit5d9c18cdc6c0e622f123be548f6f7b8ba827d3ac (patch)
tree2b219ac945a1f81c6a6ffc09fa0db76191716644 /network
[svn-inject] Installing original source of ncbi-tools6 (6.0.2)
Diffstat (limited to 'network')
-rw-r--r--network/apple/README14
-rw-r--r--network/blast2/client/blast18.asn380
-rw-r--r--network/blast2/client/blast18p.h73
-rw-r--r--network/blast2/client/blast2.c1206
-rw-r--r--network/blast2/client/blast2.h209
-rw-r--r--network/blast2/client/blastasn.c1084
-rw-r--r--network/blast2/client/blastasn.h78
-rw-r--r--network/blast2/client/blastcl2.c572
-rw-r--r--network/blast2/client/blastcli.c1292
-rw-r--r--network/blast2/client/blstout2.c1823
-rw-r--r--network/blast2/client/netblap2.c2813
-rw-r--r--network/blast2/client/netblap2.h298
-rw-r--r--network/blast2/client/objblst2.c5857
-rw-r--r--network/blast2/client/objblst2.h696
-rw-r--r--network/blast3/client/blastcl3.c507
-rw-r--r--network/blast3/client/blastpat.h78
-rw-r--r--network/blast3/client/blstspc.asn245
-rw-r--r--network/blast3/client/netblap3.c2010
-rw-r--r--network/blast3/client/netblap3.h183
-rw-r--r--network/blast3/client/objblst3.c3524
-rw-r--r--network/blast3/client/objblst3.h421
-rw-r--r--network/encrypt/README141
-rw-r--r--network/entrez/client/netentr.asn369
-rw-r--r--network/entrez/client/netentr.c2754
-rw-r--r--network/entrez/client/netentr.h234
-rw-r--r--network/entrez/client/netlib.c880
-rw-r--r--network/entrez/client/netlib.h153
-rw-r--r--network/entrez/client/netpriv.h72
-rw-r--r--network/entrez/client/objneten.c5253
-rw-r--r--network/entrez/client/objneten.h646
-rw-r--r--network/id1arch/accid1.c312
-rw-r--r--network/id1arch/accid1.h61
-rw-r--r--network/id1arch/id1.asn77
-rw-r--r--network/id1arch/id1.h116
-rw-r--r--network/id1arch/id1arch.c680
-rw-r--r--network/id1arch/id1arch.h80
-rw-r--r--network/id1arch/id1gen.c1000
-rw-r--r--network/id1arch/id1gen.h130
-rw-r--r--network/id1arch/id1map.h6
-rw-r--r--network/id1arch/idfetch.c506
-rw-r--r--network/medarch/client/mapmla.h92
-rw-r--r--network/medarch/client/mdrcherr.h35
-rw-r--r--network/medarch/client/medarch.c2194
-rw-r--r--network/medarch/client/medarch.h247
-rw-r--r--network/medarch/client/medarch.msg13
-rw-r--r--network/medarch/client/medutil.c1095
-rw-r--r--network/medarch/client/medutil.h129
-rw-r--r--network/medarch/client/mla.asn121
-rw-r--r--network/medarch/client/objmla.c1023
-rw-r--r--network/medarch/client/objmla.h147
-rw-r--r--network/medarch/client/sybmed.c275
-rw-r--r--network/medarch/server/bulkgetmed.h77
-rw-r--r--network/medarch/server/charset.h132
-rw-r--r--network/medarch/server/cmdline.c630
-rw-r--r--network/medarch/server/cmdline.h32
-rw-r--r--network/medarch/server/config.h65
-rw-r--r--network/medarch/server/error.h86
-rw-r--r--network/medarch/server/get_medline.h21
-rw-r--r--network/medarch/server/getmedart.c848
-rw-r--r--network/medarch/server/getmedart.h119
-rw-r--r--network/medarch/server/ma_global.c65
-rw-r--r--network/medarch/server/ma_global.h101
-rw-r--r--network/medarch/server/ma_intfc.c405
-rw-r--r--network/medarch/server/ma_intfc.h50
-rw-r--r--network/medarch/server/makeserver.old87
-rw-r--r--network/medarch/server/makesybmla.unx108
-rw-r--r--network/medarch/server/mapmedarch.h24
-rw-r--r--network/medarch/server/mappings.h25
-rw-r--r--network/medarch/server/medart2asn.c1117
-rw-r--r--network/medarch/server/medart2asn.h0
-rw-r--r--network/medarch/server/medfield.h78
-rw-r--r--network/medarch/server/medretrieve.c783
-rw-r--r--network/medarch/server/medschema.h104
-rw-r--r--network/medarch/server/medserv.inp19
-rw-r--r--network/medarch/server/medsmain.c252
-rw-r--r--network/medarch/server/message.c396
-rw-r--r--network/medarch/server/message.h47
-rw-r--r--network/medarch/server/mfmt_medasn.c233
-rw-r--r--network/medarch/server/mfmt_simple.h42
-rw-r--r--network/medarch/server/outmedart.c110
-rw-r--r--network/medarch/server/outmedart.h22
-rw-r--r--network/medarch/server/password.c319
-rw-r--r--network/medarch/server/password.h50
-rw-r--r--network/medarch/server/patchtoiso.c182
-rw-r--r--network/medarch/server/patchtoiso.h137
-rw-r--r--network/medarch/server/sqlstring.c368
-rw-r--r--network/medarch/server/sqlstring.h48
-rw-r--r--network/medarch/server/sybase.h27
-rw-r--r--network/medarch/server/sybbind.c249
-rw-r--r--network/medarch/server/sybbind.h46
-rw-r--r--network/medarch/server/sybintfc.c461
-rw-r--r--network/medarch/server/sybintfc.h70
-rw-r--r--network/medarch/server/voutf.c259
-rw-r--r--network/medarch/server/voutf.h45
-rw-r--r--network/medarch/server/xalloc.c491
-rw-r--r--network/medarch/server/xalloc.h77
-rw-r--r--network/ncsasock/a_ftp.h106
-rw-r--r--network/ncsasock/a_inet.h51
-rw-r--r--network/ncsasock/a_namesr.h252
-rw-r--r--network/ncsasock/a_telnet.h218
-rw-r--r--network/ncsasock/a_tftp.h74
-rw-r--r--network/ncsasock/dprintf.c49
-rw-r--r--network/ncsasock/ma_types.h65
-rw-r--r--network/ncsasock/macsockd.h68
-rw-r--r--network/ncsasock/netdb.c712
-rw-r--r--network/ncsasock/netdb.h94
-rw-r--r--network/ncsasock/neterrno.h192
-rw-r--r--network/ncsasock/neti_in.h162
-rw-r--r--network/ncsasock/neti_tcp.h84
-rw-r--r--network/ncsasock/rexec.c242
-rw-r--r--network/ncsasock/rexec.h53
-rw-r--r--network/ncsasock/s_compat.h162
-rw-r--r--network/ncsasock/s_fcntl.h112
-rw-r--r--network/ncsasock/s_file.h95
-rw-r--r--network/ncsasock/s_ioctl.h218
-rw-r--r--network/ncsasock/s_param.h41
-rw-r--r--network/ncsasock/s_socket.h238
-rw-r--r--network/ncsasock/s_time.h88
-rw-r--r--network/ncsasock/s_timeb.h31
-rw-r--r--network/ncsasock/s_ttych.h50
-rw-r--r--network/ncsasock/s_ttydev.h54
-rw-r--r--network/ncsasock/s_types.h117
-rw-r--r--network/ncsasock/s_uio.h70
-rw-r--r--network/ncsasock/s_unistd.h79
-rw-r--r--network/ncsasock/sock_ext.h159
-rw-r--r--network/ncsasock/sock_int.h153
-rw-r--r--network/ncsasock/sock_std.c565
-rw-r--r--network/ncsasock/sock_str.h178
-rw-r--r--network/ncsasock/sock_tcp.c1035
-rw-r--r--network/ncsasock/sock_udp.c436
-rw-r--r--network/ncsasock/sock_utl.c442
-rw-r--r--network/ncsasock/socket.c1710
-rw-r--r--network/ncsasock/syslog.c114
-rw-r--r--network/ncsasock/syslog.h83
-rw-r--r--network/ncsasock/tcpglue.c557
-rw-r--r--network/ncsasock/unixlib.c640
-rw-r--r--network/netmanag/README9
-rw-r--r--network/nsclilib/lbapi.c240
-rw-r--r--network/nsclilib/lbapi.h120
-rw-r--r--network/nsclilib/ncbibuf.c299
-rw-r--r--network/nsclilib/ncbibuf.h115
-rw-r--r--network/nsclilib/ncbicli.c570
-rw-r--r--network/nsclilib/ncbicli.h138
-rw-r--r--network/nsclilib/ncbinet.h188
-rw-r--r--network/nsclilib/ncbisock.c1491
-rw-r--r--network/nsclilib/ncbisock.h288
-rw-r--r--network/nsclilib/ncbiurl.c499
-rw-r--r--network/nsclilib/ncbiurl.h100
-rw-r--r--network/nsclilib/ni_debug.c222
-rw-r--r--network/nsclilib/ni_defin.h388
-rw-r--r--network/nsclilib/ni_disp.c3838
-rw-r--r--network/nsclilib/ni_encr.c1005
-rw-r--r--network/nsclilib/ni_encr.h102
-rw-r--r--network/nsclilib/ni_encrs.c104
-rw-r--r--network/nsclilib/ni_error.c193
-rw-r--r--network/nsclilib/ni_error.h243
-rw-r--r--network/nsclilib/ni_lib.c3823
-rw-r--r--network/nsclilib/ni_lib.h78
-rw-r--r--network/nsclilib/ni_lib_.c334
-rw-r--r--network/nsclilib/ni_lib_.h178
-rw-r--r--network/nsclilib/ni_list.c494
-rw-r--r--network/nsclilib/ni_list.h98
-rw-r--r--network/nsclilib/ni_macdv.c418
-rw-r--r--network/nsclilib/ni_msg.asn232
-rw-r--r--network/nsclilib/ni_msg.c4587
-rw-r--r--network/nsclilib/ni_msg.h399
-rw-r--r--network/nsclilib/ni_net.h214
-rw-r--r--network/nsclilib/ni_types.h287
-rw-r--r--network/nsclilib/ni_www.c526
-rw-r--r--network/nsclilib/readme142
-rw-r--r--network/nsdemocl/Makefile23
-rw-r--r--network/nsdemocl/catalogc.c464
-rw-r--r--network/nsdemocl/echo.asn53
-rw-r--r--network/nsdemocl/encrutil.c277
-rw-r--r--network/nsdemocl/vclient.c696
-rw-r--r--network/pcnfs/README21
-rw-r--r--network/socks/socks.cstc.4.2.pre1.tar.Zbin0 -> 427552 bytes
-rw-r--r--network/socks/socks.cstc.4.2/CHANGES118
-rw-r--r--network/socks/socks.cstc.4.2/COPYRIGHTS50
-rw-r--r--network/socks/socks.cstc.4.2/How_to_SOCKSify35
-rw-r--r--network/socks/socks.cstc.4.2/Makefile311
-rw-r--r--network/socks/socks.cstc.4.2/README.1st249
-rw-r--r--network/socks/socks.cstc.4.2/README.4.0292
-rw-r--r--network/socks/socks.cstc.4.2/README.4.1332
-rw-r--r--network/socks/socks.cstc.4.2/README.4.2249
-rw-r--r--network/socks/socks.cstc.4.2/README.DK49
-rw-r--r--network/socks/socks.cstc.4.2/What_SOCKS_expects48
-rw-r--r--network/socks/socks.cstc.4.2/What_are_the_risks70
-rw-r--r--network/socks/socks.cstc.4.2/bsdinstall27
-rw-r--r--network/socks/socks.cstc.4.2/doc/Makefile25
-rw-r--r--network/socks/socks.cstc.4.2/doc/rfinger.11
-rw-r--r--network/socks/socks.cstc.4.2/doc/rftp.11
-rw-r--r--network/socks/socks.cstc.4.2/doc/rtelnet.11
-rw-r--r--network/socks/socks.cstc.4.2/doc/rwhois.11
-rw-r--r--network/socks/socks.cstc.4.2/doc/sockd.8136
-rw-r--r--network/socks/socks.cstc.4.2/doc/sockd.conf.5195
-rw-r--r--network/socks/socks.cstc.4.2/doc/sockd.route.579
-rw-r--r--network/socks/socks.cstc.4.2/doc/socks.conf.5142
-rw-r--r--network/socks/socks.cstc.4.2/doc/socks_clients.197
-rw-r--r--network/socks/socks.cstc.4.2/doc/test_sockd_conf.8200
-rw-r--r--network/socks/socks.cstc.4.2/include/bstring.h5
-rw-r--r--network/socks/socks.cstc.4.2/include/ptx-2.1.h32
-rw-r--r--network/socks/socks.cstc.4.2/include/socks.h162
-rw-r--r--network/socks/socks.cstc.4.2/lib/Makefile113
-rw-r--r--network/socks/socks.cstc.4.2/lib/Rconnect.c867
-rw-r--r--network/socks/socks.cstc.4.2/lib/Rrcmd.c254
-rw-r--r--network/socks/socks.cstc.4.2/lib/SendGetDst.c102
-rw-r--r--network/socks/socks.cstc.4.2/lib/check_cconf.c258
-rw-r--r--network/socks/socks.cstc.4.2/lib/check_user.c175
-rw-r--r--network/socks/socks.cstc.4.2/lib/getpass.c128
-rw-r--r--network/socks/socks.cstc.4.2/lib/percent_x.c110
-rw-r--r--network/socks/socks.cstc.4.2/lib/porttoserv.c20
-rw-r--r--network/socks/socks.cstc.4.2/lib/saddrtoname.c19
-rw-r--r--network/socks/socks.cstc.4.2/lib/shell_cmd.c112
-rw-r--r--network/socks/socks.cstc.4.2/libident/Makefile93
-rw-r--r--network/socks/socks.cstc.4.2/libident/README16
-rw-r--r--network/socks/socks.cstc.4.2/libident/id_close.c25
-rw-r--r--network/socks/socks.cstc.4.2/libident/id_open.c162
-rw-r--r--network/socks/socks.cstc.4.2/libident/id_parse.c236
-rw-r--r--network/socks/socks.cstc.4.2/libident/id_query.c62
-rw-r--r--network/socks/socks.cstc.4.2/libident/ident-tester.c171
-rw-r--r--network/socks/socks.cstc.4.2/libident/ident.3276
-rw-r--r--network/socks/socks.cstc.4.2/libident/ident.c139
-rw-r--r--network/socks/socks.cstc.4.2/libident/ident.h88
-rw-r--r--network/socks/socks.cstc.4.2/libident/lookup-tester.c57
-rw-r--r--network/socks/socks.cstc.4.2/make.out121
-rw-r--r--network/socks/socks.cstc.4.2/rfinger/Makefile97
-rw-r--r--network/socks/socks.cstc.4.2/rfinger/finger.c145
-rw-r--r--network/socks/socks.cstc.4.2/sockd/Makefile105
-rw-r--r--network/socks/socks.cstc.4.2/sockd/flip_cfmasks.c167
-rw-r--r--network/socks/socks.cstc.4.2/sockd/sockd.c1182
-rw-r--r--network/socks/socks.cstc.4.2/sockd/sockd.conf.sample5
-rwxr-xr-xnetwork/socks/socks.cstc.4.2/sockd/test.csh154
-rw-r--r--network/suggest/client/suggapi.c414
-rw-r--r--network/suggest/client/suggapi.h71
-rw-r--r--network/suggest/client/suggcli.c87
-rw-r--r--network/suggest/client/suggen.c1005
-rw-r--r--network/suggest/client/suggen.h174
-rw-r--r--network/suggest/client/suggest.asn67
-rw-r--r--network/suggest/client/sugprefx.h2
-rw-r--r--network/suggest/server/suggsrv.c430
-rw-r--r--network/suggest/stdalone/suggalon.c559
-rw-r--r--network/taxon1/client/fscproc.c731
-rw-r--r--network/taxon1/client/objtaxc0.c1470
-rw-r--r--network/taxon1/client/objtaxc0.h213
-rw-r--r--network/taxon1/client/tax0.c616
-rw-r--r--network/taxon1/client/tax0.h79
-rw-r--r--network/taxon1/common/asntax1.h172
-rw-r--r--network/taxon1/common/checkid.c157
-rw-r--r--network/taxon1/common/objtax1.c1451
-rw-r--r--network/taxon1/common/objtax1.h173
-rw-r--r--network/taxon1/common/tax1map.h16
-rw-r--r--network/taxon1/common/taxinc.h153
-rw-r--r--network/taxon1/common/taxon1.asn85
-rw-r--r--network/taxon1/common/taxuerr.h9
-rw-r--r--network/taxon1/common/taxutil.c739
-rw-r--r--network/taxon1/common/taxutil.h43
-rw-r--r--network/taxon1/common/taxutil.msg5
-rw-r--r--network/taxon1/server/Makefile54
-rw-r--r--network/taxon1/server/taxprocs.c1066
-rw-r--r--network/taxon1/server/taxsmain.c320
-rw-r--r--network/taxon1/stdalone/division.c169
-rw-r--r--network/taxon1/stdalone/fs1proc.c1416
-rw-r--r--network/taxon1/stdalone/fsutils.c211
-rw-r--r--network/taxon1/stdalone/fsutils.h44
-rw-r--r--network/taxon1/stdalone/gc.c173
-rw-r--r--network/taxon1/stdalone/nmclass.c151
-rw-r--r--network/taxon1/stdalone/objtax0.c1464
-rw-r--r--network/taxon1/stdalone/objtax0.h204
-rw-r--r--network/taxon1/stdalone/rank.c151
-rw-r--r--network/taxon1/stdalone/rex_util.c89
-rw-r--r--network/taxon1/stdalone/rex_util.h21
-rw-r--r--network/taxon1/stdalone/tax1proc.c159
-rw-r--r--network/taxon1/stdalone/tax_cmmn.h232
-rw-r--r--network/taxon1/stdalone/taxctl.c349
-rw-r--r--network/taxon1/stdalone/taxinc.h130
-rw-r--r--network/taxon1/stdalone/taxname.c734
-rw-r--r--network/taxon1/stdalone/taxobj.h61
-rw-r--r--network/taxon1/stdalone/taxtree.c395
-rw-r--r--network/taxon1/taxon2/parttree.c297
-rw-r--r--network/taxon1/taxon2/taxcs.c534
-rw-r--r--network/taxon1/taxon2/taxext.h88
-rw-r--r--network/taxon1/taxon2/tc2proc.c1644
-rw-r--r--network/taxon1/taxon2/txcdproc.c1244
-rw-r--r--network/taxon1/taxon2/txclient.h178
-rw-r--r--network/taxon1/taxon2/txcommon.h225
-rw-r--r--network/taxon1/taxon2/txcproc.c2499
-rw-r--r--network/vibnet/docsum.c4354
-rw-r--r--network/vibnet/entrez.h191
-rw-r--r--network/vibnet/netcnfg.c452
-rw-r--r--network/vibnet/netcnfg.h73
-rw-r--r--network/vibnet/trmlst.c3562
-rw-r--r--network/winsock/README6
-rw-r--r--network/winsock/winsock.h853
-rw-r--r--network/winsock/winsock.libbin0 -> 4096 bytes
295 files changed, 125536 insertions, 0 deletions
diff --git a/network/apple/README b/network/apple/README
new file mode 100644
index 00000000..3da81ec3
--- /dev/null
+++ b/network/apple/README
@@ -0,0 +1,14 @@
+In order to use the NCBI-modified NCSA socket library, and NCBI network
+services on a Macintosh, it is necessary to obtain the following files
+from the MacTCP developer disk, and place them within this "apple"
+directory.
+
+dnr.c
+AddressXlation.h
+GetMyIPAddr.h
+MacTCPCommonTypes.h
+TCPPB.h
+UDPPB.h
+
+These files are copyrighted by Apple, so it is not possible for NCBI
+to distribute them in its software tree.
diff --git a/network/blast2/client/blast18.asn b/network/blast2/client/blast18.asn
new file mode 100644
index 00000000..54d833a1
--- /dev/null
+++ b/network/blast2/client/blast18.asn
@@ -0,0 +1,380 @@
+--$Revision: 6.0 $
+--DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT
+--********************************************************************
+--
+-- BLAST Interface, 1.8
+-- revised April 1995 by Tom Madden and Jim Ostell
+--
+-- original author:
+-- Warren Gish
+-- September 1993
+-- For a good look, set tabstops every 4 columns
+--
+--
+--
+--********************************************************************
+--DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT-DRAFT
+
+NCBI-BLAST-1 DEFINITIONS ::=
+BEGIN
+
+EXPORTS
+ BLAST0-Preface,
+ BLAST0-Job-desc,
+ BLAST0-Job-progress,
+ BLAST0-Sequence,
+ BLAST0-KA-Blk,
+ BLAST0-Db-Desc,
+ BLAST0-Result,
+ BLAST0-Matrix,
+ BLAST0-Warning,
+ BLAST0-Status,
+ BLAST0-Outblk;
+
+IMPORTS
+ Seq-align-set, Score-set FROM NCBI-Seqalign;
+
+BLAST0-Request ::= CHOICE { -- list of possible client messages to the server
+ hello VisibleString, -- a client-selectable session name for themselves
+ motd NULL, -- request messages-of-the-day
+ prog-info NULL, -- request a list of programs available on this server
+ usage-info VisibleString, -- gets a BLAST0-Preface that includes
+ -- the valid options (prog-usage) for this program.
+ db-info NULL, -- request a list of databases
+ matrix-info NULL, -- request a sequence of BLAST0-Matrix, without
+ -- the actual scores.
+ matrix-get VisibleString, -- get one BLAST0-Matrix, with scores.
+ search BLAST0-Search,
+ goodbye NULL -- hang-up
+ }
+
+BLAST0-Search ::= SEQUENCE {
+ program VisibleString,
+ database VisibleString,
+ query BLAST0-Sequence,
+ options SEQUENCE OF VisibleString OPTIONAL,
+ -- BLAST command line options, see the BLAST manunal pages
+ -- for a list of these.
+ --
+ -- listed below are BOOLEANS that determine the number and type of
+ -- elements returned in the BLAST0-Response.
+ --
+ return-matrix BOOLEAN DEFAULT TRUE,
+ -- should the matrix used be sent? Only needed if an alignment
+ -- showing positive/negative interactions between aligned residues
+ -- will be presented.
+ return-query BOOLEAN DEFAULT TRUE,
+ -- if TRUE, the original query is returned in BLAST0-Response.query .
+ return-BLAST0result BOOLEAN DEFAULT TRUE,
+ -- if TRUE, a BLAST0-Result is sent back in BLAST0-Response.result;
+ -- if not true, a Seq-align-set is returned in BLAST0-Response.seqalign
+ -- (see comment in the BLAST0-Response definition concerning the
+ -- type of Seq-align returned).
+ return-query-seq-in-seg BOOLEAN DEFAULT TRUE,
+ -- if TRUE, part of the query sequence, useful for an alignment,
+ -- is returned in the BLAST0-Sequence that is referenced by
+ -- BLAST0-HSP.segs.
+ return-db-seq-in-seg BOOLEAN DEFAULT TRUE
+ -- if TRUE, part of the database sequence, useful for an alignment,
+ -- is returned in the BLAST0-Sequence that is referenced by
+ -- BLAST0-HSP.segs.
+ }
+
+BLAST0-Response ::= CHOICE { -- list of possible server messages to client
+ hello VisibleString, -- server version and session identification data
+ motd VisibleString, -- the message of the day, new lines are
+ -- indicated by tildes ("~")
+ prog-info SEQUENCE OF BLAST0-Preface, -- list of programs
+ usage-info BLAST0-Preface, -- includes valid options for program
+ db-info SEQUENCE OF BLAST0-Db-Desc, -- response to BLAST0-Request.db-info
+ matrix-info SEQUENCE OF BLAST0-Matrix, -- does not include scores
+ ack BLAST0-Ack, -- final response to search
+ goodbye BLAST0-Ack, -- server-initiated close of connection
+
+ -- For the blast service, the application programs that perform the search
+ -- are independent entities from the server daemon itself that may
+ -- abort/crash for any one of a variety of reasons.
+ -- Response to a Search request thus consists of a procession of choices
+ -- of the following discrete messages, from "queued" through "status",
+ -- with each one (except "queued") generated by the application program;
+ -- the complete response to a Search request is finally indicated
+ -- when the client receives an "ack" generated by the blast network
+ -- service daemon. If the "ack" is received without a previous "status",
+ -- the client should assume that a severe problem occurred
+ -- in the application program and any output that was received
+ -- should be considered dubious in quality.
+ -- See BLAST0-Outblk for a description of how these discrete messages
+ -- can be bundled together for archival purposes.
+ queued BLAST0-Queued, -- series of these when a search has been queued
+ preface BLAST0-Preface, -- description of program used for search,
+ query BLAST0-Sequence, -- the original query sequence
+ dbdesc BLAST0-Db-Desc, -- description of database used for search,
+ matrix SEQUENCE OF BLAST0-Matrix, -- the scoring scheme(s) used
+ kablk SEQUENCE OF BLAST0-KA-Blk, -- Karlin-Altschul statistics data block
+ job-start BLAST0-Job-desc,
+ job-progress BLAST0-Job-progress,
+ job-done BLAST0-Job-progress,
+ score-defs SEQUENCE OF BLAST0-Score-Info,
+ -- The score-defs assign integer numbers to each of the different
+ -- score definitions that are used as part of the BLAST0-Result
+ -- or the Seq-align.
+ result BLAST0-Result,
+ seqalign Seq-align-set,
+ -- Either a BLAST0-Result (result) or a Seq-align-set (seqalign)
+ -- is returned. The behavior is determined by the BOOLEAN
+ -- BLAST0-search.return-BLAST0result. If a seqalign is
+ -- returned, then the Seq-align is of type dense-diag if the
+ -- query and subject sequence have the same length (i.e., if
+ -- both are nucleotide or protein as in blastn, blastp, and blastx);
+ -- a set of Seq-align of type Std-seg is returned if the query and
+ -- subject have different lengths, as in blastx or tblastn.
+ parms SEQUENCE OF VisibleString, -- BLAST parameters of search
+ stats SEQUENCE OF VisibleString, -- accumulated search statistics
+ warning BLAST0-Warning, -- see enum in .h files of blast function lib
+ status BLAST0-Status -- see enum in .h files of blast function lib
+ }
+
+BLAST0-Job-desc ::= SEQUENCE {
+ jid ENUMERATED { -- job identifier
+ not-set (0),
+ neighborhood (1), -- generating blast neighborhood
+ search (2), -- database search
+ threecomps (3) -- blast3 comparisons to find three-way alignments
+ },
+ desc VisibleString, -- short description of job
+ size INTEGER -- no. of units of work in job (0 if unknown)
+ }
+
+BLAST0-Job-progress ::= SEQUENCE { -- doubles as an "I'm alive" message
+ done INTEGER, -- no. of units of work completed thusfar
+ positives INTEGER -- no. of successful jobs (e.g., no. of seqs matched)
+ }
+
+BLAST0-Preface ::= SEQUENCE {
+ program VisibleString, -- name of server program
+ desc VisibleString, -- concise description of program
+ version VisibleString OPTIONAL, -- version number of server program
+ dev-date VisibleString OPTIONAL, -- development date of server program
+ bld-date VisibleString OPTIONAL, -- build date of server program
+ cit SEQUENCE OF VisibleString OPTIONAL, -- journal or other citations
+ notice SEQUENCE OF VisibleString OPTIONAL, -- cautionaries about program
+ prog-usage SEQUENCE OF VisibleString OPTIONAL, -- information
+ -- about valid options for this program
+ susage BLAST0-Seq-usage, -- how subject database sequences are used
+ qusage BLAST0-Seq-usage -- how query sequences are used
+ }
+
+BLAST0-KA-Blk ::= SEQUENCE { -- Karlin-Altschul statistics parameter block
+ matid INTEGER, -- Matrix identifier (0, 1, 2, 3,...)
+
+-- "frames" is the reading frame in each sequence {-3, -2, -1, 0, +1, +2, +3}.
+-- There are as many frames listed as the value of n-way above.
+-- For the typical BLAST search, there will be just two; for BLAST3 there
+-- will be three.
+-- A reading frame of 0 might be specified in a variety of cases:
+-- if the original sequence is protein (e.g., the query with BLASTP);
+-- if the original sequence is nucleic acid and this KA-Blk is to be
+-- applied uniformly to all reading frames (as in the database with TBLASTN).
+-- Untranslated nucleotide sequences may have frames of +1 or -1.
+ frames SEQUENCE OF INTEGER, -- query 1st, subject 2nd (see n-way, though)
+
+ -- Lambda, K, and H are computed under a variety of assumptions
+ -- (residue composition, scoring system). Values < 0 are reported
+ -- when the computation failed or when the user did not provide a value.
+ -- (for a description of lambda, k and h see Karlin and Altschul,
+ -- Proc. Natl. Acad. Sci. USA, 87:2264-68 (1990)).
+ lambda REAL,
+ k REAL,
+ h REAL
+ }
+
+
+BLAST0-Db-Desc ::= SEQUENCE {
+ name VisibleString,
+ type BLAST0-Alphatype,
+ def VisibleString OPTIONAL, -- full definition
+ rel-date VisibleString OPTIONAL, -- date of release from the curator
+ bld-date VisibleString OPTIONAL, -- date of build (brought on-line)
+ count INTEGER OPTIONAL, -- no. of sequences in database
+ totlen INTEGER OPTIONAL, -- total no. of letters or residues in database
+ maxlen INTEGER OPTIONAL -- max. no. of letters or residues in any one seq
+ }
+
+BLAST0-Result ::= SEQUENCE {
+ hist BLAST0-Histogram OPTIONAL,
+ count INTEGER,
+ -- no. of hitlists (e.g., the no. of db sequences matched)
+ hitlists SEQUENCE OF BLAST0-HitList
+ -- each subject sequence has it's own BLAST0-HitList
+ }
+
+-- Used to produce Histogram in the traditional BLAST output (with H=1).
+BLAST0-Histogram ::= SEQUENCE {
+ expect REAL,
+ observed INTEGER,
+ base INTEGER,
+ nbars INTEGER,
+ bar SEQUENCE OF BLAST0-Histogram-bar
+ }
+
+BLAST0-Histogram-bar ::= SEQUENCE {
+ x REAL,
+ -- theoret. E value, before the search, 1st column in Histogram
+ n INTEGER
+ -- real. E value, after the search, 2nd column in Histogram
+ -- The 3rd histogram column is found by subtracting the value
+ -- in the 2nd column from the value in the 2nd column for the
+ -- next row.
+ }
+
+-- BLAST0-HitList is a list of the HSPs involving a set of sequences.
+BLAST0-HitList ::= SEQUENCE {
+ count INTEGER, -- no. of hsps contained in this BLAST0-HitList
+ -- also the number of hits on a single database sequence.
+ kablk SEQUENCE OF BLAST0-KA-Blk OPTIONAL,
+ -- one for each scoring system
+ hsps SEQUENCE OF BLAST0-HSP,
+ seqs SEQUENCE OF BLAST0-Sequence
+ }
+
+-- BLAST0-HSP (High-scoring Segment Pair) is the fundamental unit of BLAST output
+BLAST0-HSP ::= SEQUENCE {
+ matid INTEGER, -- scoring matrix identifier
+ -- the score reported below contain an Object-id that references
+ -- different types of scores (e.g., p-value, BLAST "score")
+ -- by an integer. The structure BLAST0-Score-Info, returned as
+ -- part of the BLAST0-Response, provides the mapping between
+ -- this integer and the type of score.
+ scores Score-set, -- this is the equivalent of SEQUENCE OF Score
+ len INTEGER, -- length of each segment (in the alignment alphabet)
+ segs SEQUENCE OF BLAST0-Segment
+ }
+
+BLAST0-Segment ::= SEQUENCE {
+ loc BLAST0-Seq-interval,
+ str BLAST0-Seq-data OPTIONAL,
+ str-raw BLAST0-Seq-data OPTIONAL -- str prior to translation
+ }
+
+BLAST0-Sequence ::= SEQUENCE {
+ desc SEQUENCE OF BLAST0-Seq-desc,
+ length INTEGER, -- length of complete sequence (untranslated)
+ gcode INTEGER OPTIONAL, -- genetic code
+ seq BLAST0-Seq-data OPTIONAL
+ }
+
+BLAST0-Seq-desc ::= SEQUENCE {
+ id BLAST0-Seq-id,
+ defline VisibleString OPTIONAL
+ }
+
+BLAST0-Seq-id ::= SET OF CHOICE {
+ giid INTEGER, -- zero if no giid is available
+ textid VisibleString -- other ids, in "long FASTA" syntax
+ }
+
+BLAST0-Seq-data ::= CHOICE {
+ ncbistdaa OCTET STRING, -- standard amino acid alphabet (NCBIstdaa)
+ ncbi2na OCTET STRING, -- standard nucleic acid alphabet (NCBI2na)
+ ncbi4na OCTET STRING -- alternate nucleic acid alphabet (NCBI4na)
+ }
+
+BLAST0-Seq-interval ::= SEQUENCE {
+ strand ENUMERATED {
+ plus (1), -- interval is on the plus strand
+ minus (2), -- interval is on the complementary, minus strand
+ both (3), -- "from" and "to" are specified relative to plus strand
+ plus-rf (5), -- restricted to reading frame implied by "from"
+ minus-rf (6) -- restricted to reading frame implied by "from"
+ } OPTIONAL, -- only specified when nt. or translated nt. is involved.
+-- Restricted means the interval applies only to the implied reading frame.
+-- When needed, the reading frame is found by computing "from" modulo 3 + 1.
+ from INTEGER, -- zero-based offset
+ to INTEGER -- zero-based offset
+ }
+
+-- A particular scoring scheme is referenced in the BLAST0-Result and
+-- the Seq-align-set only by an integer. BLAST0-Score-Info provides a
+-- mapping between the integer ("sid") and the name and/or
+-- definition of a scoring scheme.
+BLAST0-Score-Info ::= SEQUENCE {
+ sid INTEGER,
+ tag VisibleString, -- short name
+ desc VisibleString OPTIONAL -- longer description
+ }
+
+BLAST0-Alphatype ::= ENUMERATED {
+ not-set (0),
+ amino-acid (1),
+ nucleic-acid (2),
+ other (255)
+ }
+
+BLAST0-Seq-usage ::= SEQUENCE {
+ raw BLAST0-Alphatype, -- the input sequence type
+ cooked BLAST0-Alphatype -- the sequence type actually searched
+ }
+
+BLAST0-Alpha-ID ::= ENUMERATED {
+ ncbi4na (4), -- 4 bit nucleotide code
+ ncbistdaa (11) -- consecutive codes for standard amino acids, 0-25
+ }
+
+BLAST0-Matrix ::= SEQUENCE { -- substitution scoring matrix
+ matid INTEGER,
+ name VisibleString, -- name for this scoring system
+ comments SEQUENCE OF VisibleString OPTIONAL,
+ qalpha BLAST0-Alpha-ID, -- query alphabet
+ salpha BLAST0-Alpha-ID, -- subject/database alphabet
+ scores CHOICE { -- length of sequence = sizeof(qalpha) X sizeof(salpha)
+ scaled-ints SEQUENCE { -- scaled integer scores
+ scale REAL, -- multiply ints by scale, 0 means unscaled
+ ints SEQUENCE OF INTEGER -- presented in qalpha-major order
+ -- NOTE! undefined scores are indicated by the special
+ -- value -2147483648 (INT4_MIN) before scaling
+ },
+ reals SEQUENCE OF REAL -- presented in qalpha-major order
+ -- NOTE! undefined scores are indicated by the special value -1.e32
+ } OPTIONAL -- omit scores when just associating matid with matrix name
+ }
+
+-- BLAST0-Status is a general message for acknowledgments, warnings, and errors
+BLAST0-Status ::= SEQUENCE {
+ code INTEGER, -- program exit status, warning message identifier, etc.
+ -- code 0 means no error
+ reason VisibleString OPTIONAL -- description of non-zero code
+ }
+
+BLAST0-Warning ::= BLAST0-Status
+
+BLAST0-Queued ::= SEQUENCE { -- doubles as "I'm alive" message
+ name VisibleString, -- name of this queue
+ length INTEGER -- no. of requests ahead of this one in the queue
+ }
+
+BLAST0-Ack ::= SEQUENCE { -- acknowledgment
+ code INTEGER,
+ reason VisibleString OPTIONAL
+ }
+
+-- BLAST0-Outblk is a model of complete blast application program output
+-- as it might be archived for future reference; however during an actual search
+-- the choices are produced as separate, distinct BLAST0-Responses.
+BLAST0-Outblk ::= SET OF CHOICE {
+ preface BLAST0-Preface,
+ query BLAST0-Sequence,
+ dbdesc BLAST0-Db-Desc,
+ matrix SEQUENCE OF BLAST0-Matrix, -- the scoring scheme(s) used (optional)
+ kablk SEQUENCE OF BLAST0-KA-Blk, -- Karlin-Altschul data block
+ job-start BLAST0-Job-desc,
+ job-progress BLAST0-Job-progress,
+ job-done BLAST0-Job-progress,
+ result BLAST0-Result,
+ parms SEQUENCE OF VisibleString, -- parameters of search
+ stats SEQUENCE OF VisibleString, -- accumulated search statistics
+ warning BLAST0-Warning,
+ status BLAST0-Status
+ }
+
+
+END
diff --git a/network/blast2/client/blast18p.h b/network/blast2/client/blast18p.h
new file mode 100644
index 00000000..f3ed2b8b
--- /dev/null
+++ b/network/blast2/client/blast18p.h
@@ -0,0 +1,73 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: blast18p.h
+*
+* Author: Jonathan Epstein
+*
+* Version Creation Date: 06/16/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Header file to patch around constructs which the "ASNCODE" generator
+* is unable to deal with; this file is specific to the BLAST 1.8 ASN.1
+* specification.
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: blast18p.h,v $
+* Revision 6.0 1997/08/25 18:33:51 madden
+* Revision changed to 6.0
+*
+* Revision 5.0 1996/05/28 14:09:11 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:55:34 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.2 1995/06/21 17:18:11 epstein
+ * use Seq-align set instead of SET OF Seq-align (hack-around via SpecialSeqAlignSetAsn{Read,Write})
+ *
+ * Revision 1.1 95/06/16 11:26:14 epstein
+ * Initial revision
+ *
+*/
+
+#include <objalign.h>
+
+#define NLM_EXTERN_LOADS { SeqAlignAsnLoad(); }
+
+#define struct_Score score
+
+#define SeqAlignSetAsnWrite SpecialSeqAlignSetAsnWrite
+#define SeqAlignSetAsnRead SpecialSeqAlignSetAsnRead
diff --git a/network/blast2/client/blast2.c b/network/blast2/client/blast2.c
new file mode 100644
index 00000000..e183101c
--- /dev/null
+++ b/network/blast2/client/blast2.c
@@ -0,0 +1,1206 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: blast2.c
+*
+* Author: Tom Madden
+*
+* Version Creation Date: 10/26/95
+*
+* $Revision: 6.1 $
+*
+* File Description:
+* Functions to format parts of the traditional BLAST output.
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: blast2.c,v $
+* Revision 6.1 1997/11/28 18:21:57 madden
+* fprintf fixes
+*
+* Revision 6.0 1997/08/25 18:33:53 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1996/12/13 18:10:58 madden
+* Added TraditionalBlastReportAddResult.
+*
+ * Revision 5.1 1996/11/27 14:01:16 madden
+ * Replaced strlen by Nlm_StringLen.
+ *
+ * Revision 5.0 1996/05/28 14:09:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 1.12 1996/05/22 18:04:17 madden
+ * Fixed formatting of Query ID if only gi is present.
+ *
+ * Revision 1.11 1996/03/25 17:30:33 shavirin
+ * Changes due to new function TraditionalBlastOutputHTML(),
+ * that produce HTML output from the BLAST server
+ *
+ * Revision 1.10 1996/03/11 22:02:09 madden
+ * Added function BLAST0SeqData2Bioseq.
+ *
+ * Revision 1.9 1995/11/22 22:43:08 madden
+ * Added return value for PrintTraditionalBlastPreface.
+ *
+ * Revision 1.8 1995/11/07 17:56:51 madden
+ * Added PrintTraditionalBlastPreface and BlastPrintCheckBufferStatus.
+ *
+ * Revision 1.7 1995/11/03 16:02:43 madden
+ * Added BlastPrintNewLine, renames BlastPrintInit to BlastPrintStructInit.
+ *
+ * Revision 1.6 1995/11/02 23:14:49 madden
+ * Fixed bugs with BlastPrintTabToColumn.
+ *
+ * Revision 1.5 1995/11/02 21:46:44 madden
+ * Added functions BlastPrintDoubleAdd and BlastPrintIntegerAdd.
+ *
+ * Revision 1.4 1995/11/02 21:12:25 madden
+ * Added "BlastPrint" functions to print out lines.
+ *
+ * Revision 1.3 1995/11/01 15:40:18 madden
+ * Addition of TraditionalBlastReportSetUp and TraditionalBlastReportCleanUp.
+ *
+ * Revision 1.2 1995/10/27 21:17:10 madden
+ * Added TraditionalHistBlastOutput.
+ *
+ * Revision 1.1 1995/10/26 17:06:44 madden
+ * Initial revision
+ *
+*
+*/
+
+#include <ncbi.h>
+#include <objseq.h>
+#include <objsset.h>
+#include <sequtil.h>
+#include <seqport.h>
+#define NLM_GENERATED_CODE_PROTO
+#include <blast2.h>
+#include <objblst2.h>
+
+
+/*
+ This function is used, by TraditionalBlastReportSetUp, to find
+ a node specified by the Uint1 v.
+*/
+
+static Pointer find(BLAST0ResponsePtr p, Uint1 v)
+{
+ BLAST0ResponsePtr b;
+
+ for (b = p; b != NULL && b->choice != v; b = b->next)
+ ;
+
+ return (b == NULL) ? NULL : b->data.ptrvalue;
+}
+
+/*
+ Adds the BLAST0ResultPtr result, BLAST0ResponsePtr blresp
+ to a BlastReportStructPtr that has already been allocated
+ and (possibly) used to print out the BLAST header before
+ the full results were available.
+
+ The BlastReportStructPtr should be allocated with the
+ function TraditionalBlastReportSetUp first.
+*/
+
+Boolean LIBCALL
+TraditionalBlastReportAddResult(BlastReportStructPtr blrp, BLAST0ResultPtr result, BLAST0ResponsePtr blresp)
+
+{
+ if (blrp == NULL)
+ return FALSE;
+
+ blrp->result = result;
+ blrp->blresp = blresp;
+
+ return TRUE;
+}
+
+/*****************************************************************************
+*
+* Allocates and fills in the BlastReportStruct. This function should
+* be called before any of the other "traditional" formatter functions
+* are called.
+****************************************************************************/
+BlastReportStructPtr
+TraditionalBlastReportSetUp(BLAST0ResultPtr result, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp, Int4 type)
+
+{
+ Boolean get_gi=FALSE;
+ BlastReportStructPtr blrp;
+ BLAST0SequencePtr query;
+ CharPtr string;
+ Int4 offset, num_deflines, num_of_aligns;
+ ValNodePtr parms;
+
+ if ((blrp=MemNew(sizeof(BlastReportStruct))) == NULL)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0,
+ "Couldn't allocate memory in SetUpForTraditionalBlastReport");
+ return NULL;
+ }
+
+ blrp->result = result;
+ blrp->blresp = blresp;
+ blrp->program = StringSave(program);
+ blrp->bpsp = BlastPrintStructInit(BLAST2_LINE_LENGTH, fp);
+
+/* Set is_prot if alignments done with proteins (regardless of query type) */
+ if (StringCmp(program, "blastn") != 0)
+ blrp->is_prot = TRUE;
+ else
+ blrp->is_prot = FALSE;
+
+ if ((query = find(blresp, BLAST0Response_query)) != NULL)
+ blrp->query_length = query->length;
+ else
+ blrp->query_length = 0;
+
+ offset = 0;
+ num_deflines = 500;
+ num_of_aligns = 250;
+ if ((parms = find(blresp, BLAST0Response_parms)) != NULL)
+ {
+ while (parms != NULL)
+ {
+ string = parms->data.ptrvalue;
+ if (StringNCmp(string, "-qoffset", 8) == 0)
+ sscanf(string+9, "%ld", &offset);
+ else if (StringNCmp(string, "V=", 2) == 0)
+ sscanf(string+2, "%ld", &num_deflines);
+ else if (StringNCmp(string, "B=", 2) == 0)
+ sscanf(string+2, "%ld", &num_of_aligns);
+ else if (StringNCmp(string, "-gi", 3) == 0)
+ get_gi=TRUE;
+ parms = parms->next;
+ }
+ }
+
+ blrp->qoffset = offset;
+ blrp->num_of_defline = num_deflines;
+ blrp->num_of_align = num_of_aligns;
+ blrp->get_gi = get_gi;
+ blrp->type = type; /* TEXT_OUTPUT or HTML_OUTPUT */
+
+ return blrp;
+}
+
+/**************************************************************************
+*
+* Deallocate the BlastReportStructPtr and all allocated memory
+* within it.
+************************************************************************/
+
+BlastReportStructPtr
+TraditionalBlastReportCleanUp(BlastReportStructPtr blrp)
+
+{
+ if (blrp == NULL)
+ return NULL;
+
+ blrp->program = MemFree(blrp->program);
+ blrp->bpsp = BlastPrintStructClose(blrp->bpsp);
+
+ blrp = MemFree(blrp);
+
+ return blrp;
+}
+
+/***************************************************************************
+*
+*
+* Format the "preface" of the BLAST output. This includes the
+* program, version, compile date:
+*
+*BLASTN 1.4.7MP [16-Oct-94] [Build 16:01:48 Dec 16 1994]
+*
+*Reference: Altschul, Stephen F., Warren Gish, Webb Miller, Eugene W. Myers,
+*and David J. Lipman (1990). Basic local alignment search tool. J. Mol. Biol.
+*215:403-10.
+*
+*Notice: this program and its default parameter settings are optimized to find
+*nearly identical sequences rapidly. To identify weak similarities encoded in
+*nucleic acid, use BLASTX, TBLASTN or TBLASTX.
+*
+**************************************************************************/
+
+Boolean LIBCALL
+PrintTraditionalBlastPreface(BlastReportStructPtr blrp)
+{
+ BlastPrintStructurePtr bpsp;
+ BLAST0ResponsePtr blresp;
+ BLAST0PrefacePtr preface;
+ Char temp[BLAST2_LINE_LENGTH];
+ CharPtr string;
+ ValNodePtr node;
+
+ if (blrp == NULL)
+ return FALSE;
+
+ blresp = blrp->blresp;
+ bpsp = blrp->bpsp;
+
+ preface = find(blresp, BLAST0Response_preface);
+
+ if (preface == NULL)
+ return FALSE;
+
+ BlastPrintStart(bpsp, 0, 0);
+ if(blrp->type == HTML_OUTPUT)
+ sprintf(temp, "<PRE><b>%s %s [%s]", preface->program, preface->version, preface->dev_date);
+ else /* blrp->type == TEXT_OUTPUT */
+ sprintf(temp, "%s %s [%s]", preface->program, preface->version, preface->dev_date);
+
+ BlastPrintStringAdd(bpsp, temp);
+
+ if (preface->bld_date != NULL)
+ {
+ if(blrp->type == HTML_OUTPUT)
+ sprintf(temp, " [Build %s]</b>", preface->bld_date);
+ else /* blrp->type == TEXT_OUTPUT */
+ sprintf(temp, " [Build %s]", preface->bld_date);
+
+ BlastPrintStringAdd(bpsp, temp);
+ }
+ BlastPrintNewLine(bpsp);
+ BlastPrintNewLine(bpsp);
+
+ for (node = preface->cit; node != NULL; node = node->next)
+ {
+ string = (CharPtr) node->data.ptrvalue;
+ if (node == preface->cit)
+ {
+ if(blrp->type == HTML_OUTPUT)
+ BlastPrintStringAdd(bpsp, "<b>Reference:</b> ");
+ else /* blrp->type == TEXT_OUTPUT */
+ BlastPrintStringAdd(bpsp, "Reference: ");
+ }
+ BlastPrintStringAdd(bpsp, string);
+ BlastPrintNewLine(bpsp);
+ }
+
+ for (node = preface->notice; node != NULL; node = node->next)
+ {
+ BlastPrintNewLine(bpsp);
+ string = (CharPtr) node->data.ptrvalue;
+ if(blrp->type == HTML_OUTPUT)
+ BlastPrintStringAdd(bpsp, "<b>Notice:</b> ");
+ else /* blrp->type == TEXT_OUTPUT */
+ BlastPrintStringAdd(bpsp, "Notice: ");
+
+ BlastPrintStringAdd(bpsp, string);
+ }
+ BlastPrintEnd(bpsp);
+
+ return TRUE;
+}
+
+/*************************************************************************
+*
+* This function acknowledges the BLAST request. The information
+* comes in the BLAST0SequencePtr, which is then formatted as something
+* of the form:
+*
+* Query= 195747|Mitochondrion Rupicapra rupi
+* (646 letters)
+*
+* The query length is returned.
+*
+* This code was orignally part of TraditionalHeadBlastOutput in
+* blstout1.c and is still called in TraditionalHeadBlastOutput.
+*
+* "strands" tells how which strands are being translated (set by
+* "-top" and "-bottom").
+* "offset" reports the offset of the search (set by "-qoffset" option).
+*
+*
+*************************************************************************/
+
+#define BLASTCOM_BUFFER_SIZE 50
+
+Int4 LIBCALL
+acknowledge_blast_request(CharPtr program, BLAST0SequencePtr query, Int2 strands, Int4 offset, FILE *fp, Int4 type)
+
+{
+
+ Char buf[BLASTCOM_BUFFER_SIZE];
+ CharPtr string;
+ Int4 query_length=0;
+ ValNodePtr node;
+
+ if(type == HTML_OUTPUT)
+ fprintf(fp, "<b>\nQuery=</b> ");
+ else /* type == TEXT_OUTPUT */
+ fprintf(fp, "\nQuery= ");
+ if (query != NULL && query->desc != NULL)
+ {
+ node = query->desc->id;
+ while (node)
+ {
+ if (node->choice == BLAST0SeqId_giid)
+ {
+ if (node->next)
+ sprintf(buf, "gi|%ld|", (long) node->data.intvalue);
+ else
+ sprintf(buf, "gi|%ld", (long) node->data.intvalue);
+ string = &buf[0];
+ }
+ else if (node->choice == BLAST0SeqId_textid)
+ {
+ string = node->data.ptrvalue;
+ if (strncmp(string, "lcl|", 4) == 0)
+ {
+ StringNCpy(buf, string+4, BLASTCOM_BUFFER_SIZE);
+ string = &buf[0];
+ }
+ }
+ fprintf(fp, "%s", string);
+ node = node->next;
+ }
+ if((string=query->desc->defline) != NULL && *string != NULLB)
+ blast2_wrap(fp, " ", string, Nlm_StringLen(string), 79, 8);
+ else
+ fprintf(fp, "\n");
+ }
+ else
+ {
+ fprintf(fp, "Unknown\n");
+ }
+
+ if (query)
+ {
+ query_length = query->length;
+ fprintf(fp, " (%s letters",
+ Nlm_Ultostr(query->length, 1));
+ }
+
+ if (offset > 0)
+ fprintf(fp, ", %s offset", Ltostr(offset,1));
+
+ fprintf(fp, ")\n");
+
+ if (StringCmp(program, "blastx") == 0 ||
+ StringCmp(program, "tblastx") == 0)
+ {
+ fprintf(fp, "\n Translating ");
+ switch (strands) {
+ case 0:
+ break;
+ case 1:
+ fprintf(fp, "top strand of query sequence in 3 reading frames\n");
+ break;
+ case 2:
+ fprintf(fp, "bottom strand of query sequence in 3 reading frames\n");
+ break;
+ case 3:
+ fprintf(fp, "both strands of query sequence in all 6 reading frames\n");
+ break;
+ default:
+ break;
+ }
+ }
+
+ return query_length;
+}
+
+/*************************************************************************
+*
+* Produces an NCBI SeqId from a BLAST0 SeqId.
+*
+**************************************************************************/
+
+static SeqIdPtr
+BLAST0_ID2NCBI_ID(ValNodePtr vnp)
+
+{
+ ValNodePtr seqid=NULL, text_seqid;
+
+ while (vnp)
+ {
+ if (vnp->choice == BLAST0SeqId_giid)
+ {
+ ValNodeAddInt(&seqid, SEQID_GI, vnp->data.intvalue);
+ }
+ else if (vnp->choice == BLAST0SeqId_textid)
+ {
+ text_seqid = SeqIdParse(vnp->data.ptrvalue);
+ ValNodeLink(&seqid, text_seqid);
+ }
+ }
+ return seqid;
+}
+
+/***************************************************************************
+*
+* Produces a BioseqPtr from the data in BLAST0SequencePtr.
+*
+****************************************************************************/
+
+BioseqPtr LIBCALL
+BLAST0Sequence2Bioseq(BLAST0SequencePtr sequence)
+
+{
+
+ BioseqPtr bsp;
+
+ bsp = BioseqNew();
+ if (bsp == NULL)
+ return NULL;
+
+ BLAST0SeqData2Bioseq(bsp, sequence->seq, sequence->length);
+ bsp->id = BLAST0_ID2NCBI_ID(sequence->desc->id);
+ if (sequence->desc && sequence->desc->defline)
+ ValNodeCopyStr(&(bsp->descr), Seq_descr_title, sequence->desc->defline);
+
+ return bsp;
+}
+
+
+/************************************************************************
+*
+* Transfers the sequence data from the BLAST0SequencePtr sequence
+* (in the ValNodePtr str) to the BioseqPtr bsp. Note that the
+* BioseqPtr is not allocated here.
+*
+************************************************************************/
+
+Int2 LIBCALL
+BLAST0SeqData2Bioseq(BioseqPtr bsp, ValNodePtr sequence, Int4 length)
+
+{
+ if (bsp == NULL || sequence == NULL)
+ return 1;
+
+ bsp->length = length;
+ switch (sequence->choice)
+ {
+ case BLAST0SeqData_ncbistdaa:
+ bsp->seq_data_type = Seq_code_ncbistdaa;
+ bsp->mol = Seq_mol_aa;
+ break;
+ case BLAST0SeqData_ncbi4na:
+ bsp->seq_data_type = Seq_code_ncbi4na;
+ bsp->mol = Seq_mol_na;
+ break;
+ default:
+ return 1;
+ }
+ bsp->seq_data = sequence->data.ptrvalue;
+ bsp->repr = Seq_repr_raw;
+
+ return 0;
+}
+
+
+/*************************************************************************
+*
+* Print out the strings stored in the ValNodePtr stack. "title"
+* is printed first.
+*************************************************************************/
+
+Int2 LIBCALL
+BlastPrintValNodeStack(ValNodePtr stack, CharPtr title, FILE *fp)
+
+{
+ Boolean new;
+ CharPtr string;
+ ValNodePtr vnp;
+
+ if (fp == NULL || stack == NULL)
+ return 0;
+
+ if (stack != NULL)
+ {
+ if (title != NULL)
+ fprintf(fp, "\n%s:\n", title);
+ new = TRUE;
+ for (vnp=stack; vnp != NULL; vnp = vnp->next)
+ {
+ string = vnp->data.ptrvalue;
+ if (*string == NULLB)
+ {
+ fprintf(fp, "\n");
+ new = TRUE;
+ }
+ else
+ {
+ if (new)
+ fprintf(fp, " ");
+ fprintf(fp, "%s", string);
+ new = FALSE;
+ }
+ }
+ }
+ return 0;
+}
+
+
+static void
+doindent(FILE *fp, int ncols)
+{
+ while (ncols-- > 0)
+ fputc(' ', fp);
+}
+
+/*************************************************************
+* *
+* Warren Gish's utilities needed for producing BLAST output *
+* *
+ *************************************************************/
+
+/* blast2_wrap -- wordwrap lines of output */
+
+void
+blast2_wrap(FILE *fp, /* the output stream */
+ CharPtr title, /* title string */
+ CharPtr s, /* pointer to null-terminated string for output */
+ int slen, /* strlen(s), or -1 */
+ int linelen, /* max. length of output line before each '\n' */
+ int indent /* no. of columns to indent any continuation lines */
+ )
+{
+ register char *savep, *savep2;
+ register char *cp, ch;
+ int outlen, len, olinelen;
+ int titlelen;
+ Boolean once = TRUE;
+
+ if (title != NULL) {
+ cp = title;
+ len = 0;
+ while ((ch = *cp++) != NULLB) {
+ fputc(ch, fp);
+ if (ch == '\n')
+ len = cp - title;
+ }
+ titlelen = (cp - title) - len - 1;
+ }
+ else
+ titlelen = 0;
+
+ if (slen < 0)
+ slen = Nlm_StringLen(s);
+
+ if (indent >= linelen) {
+ indent = MIN(1 + titlelen, linelen-5);
+ indent = MAX(indent, 0);
+ }
+ olinelen = linelen;
+ linelen -= titlelen;
+ for (cp = s; cp < s + slen;) {
+ /* Skip leading white space */
+ for (;; ++cp) {
+ if ((ch = *cp) == NULLB)
+ return;
+ if (!IS_WHITESP(ch))
+ break;
+ }
+
+ outlen = cp - s;
+ if (slen - outlen <= linelen) {
+ /* Remainder is short enough to fit on one line */
+ if (!once)
+ doindent(fp, indent);
+ fprintf(fp, "%s\n", cp);
+ break;
+ }
+ else {
+ savep2 = cp + linelen;
+ ch = *savep2;
+ if (IS_WHITESP(ch)) {
+Phase2:
+ for (savep = savep2; savep >= cp; --savep)
+ if (!IS_WHITESP(*savep)) {
+ ++savep;
+ break;
+ }
+ }
+ else {
+ for (savep = savep2; savep >= cp; --savep)
+ if (IS_WHITESP(*savep)) {
+ savep2 = savep;
+ goto Phase2;
+ }
+ /* a _very_ long word here! */
+ savep = savep2;
+ }
+ }
+ if (!once)
+ doindent(fp, indent);
+ once = FALSE;
+ while (cp < savep)
+ fputc(*cp++, fp);
+ putc('\n', fp);
+ cp = savep2;
+ linelen = olinelen - indent;
+ }
+
+}
+
+/*
+ This function is used by TraditionalHistBlastOutput
+ (below).
+*/
+static CharPtr
+print_double(CharPtr pCh, double dX, int iWidth, int iPrecision)
+{
+ double dY;
+ int i;
+
+ dY = log(dX * 1.000000001) / NCBIMATH_LN10;
+ i = dY;
+ dY = Nlm_Powi(10., i - iPrecision + 1);
+ dX = Nlm_Nint(dX / dY) * dY;
+ dY = Nlm_Powi(10., iPrecision - 1) - 1.e-7;
+ if (dX >= dY)
+ sprintf(pCh, "%*.0lf", iWidth, dX);
+ else
+ sprintf(pCh, "%*.*lf", iWidth, iPrecision - i - 1, dX);
+
+ return pCh;
+}
+
+#define PAGE_W 80
+#define EXPECT_W 6
+#define EXPECT_PRCSN 3
+#define SEPARATOR_SYMBOL '|'
+#define DRAWING_SYMBOL '='
+#define SMALLDRAWING_SYMBOL ':'
+/**************************************************************************
+ * The function formats histgram data and is part of the "traditional"
+ * BLAST output.
+ *
+ *
+ **************************************************************************/
+Boolean LIBCALL
+TraditionalHistBlastOutput(BlastReportStructPtr blrp)
+{
+ BLAST0HistogramPtr pHist;
+ BLAST0ResultPtr result;
+ Int4 nBars; /* Number of histogram bars */
+ Int4 i;
+ Int4 nMaxObserved;
+ Int4 nMaxHist;
+ Int4 nHistValue;
+ Int2 nObsWidth; /* Width (in symbols) of field wich represents observed value */
+ Int2 nHistWidth;/* Width (in symbols) of field wich represents histogram value */
+ Int2 nCols; /* Width of space (in symbols) where histogram is painted */
+ Int2 nPerCol; /* Number of sequences per unit */
+ Int2 nUnits; /* Number units needed to represent histogram bar */
+ Int2 j;
+ FloatLo fDelta;
+ Char aCh[20];
+ Boolean bNeedCheck = TRUE;
+ BLAST0HistogramBarPtr pBar;
+ FILE *fp;
+
+
+ if (blrp == NULL)
+ return FALSE;
+
+ fp = blrp->bpsp->fp;
+ result = blrp->result;
+ pHist = result->hist;
+
+ if (pHist == NULL)
+ return TRUE;
+
+
+ putc('\n', fp);
+ putc('\n', fp);
+ fprintf(fp, " Observed Numbers of Database Sequences Satisfying\n");
+ fprintf(fp, " Various EXPECTation Thresholds (E parameter values)\n");
+ putc('\n', fp);
+
+ nBars = pHist->nbars;
+
+ /* Find out max observed and histogram data values
+ */
+ for (i = 0, nMaxObserved = 0, nMaxHist = 0, pBar = pHist->bar;
+ i < nBars; i++) {
+ nMaxObserved = MAX(nMaxObserved, pBar->n);
+
+ if (i == nBars - 1) /* the last one */
+ nMaxHist = MAX(nMaxHist, pBar->n - pHist->base);
+ else
+ nMaxHist = MAX(nMaxHist, pBar->n - pBar->next->n);
+
+ pBar = pBar->next;
+ }
+
+ nObsWidth = Nlm_Ulwidth(nMaxObserved, 0);
+ nObsWidth = MAX(nObsWidth, 2);
+ nHistWidth = Nlm_Ulwidth(nMaxHist, 0);
+ nHistWidth = MAX(nHistWidth, 2);
+
+/* Gets the number of hits per "=" */
+ nCols = PAGE_W - (EXPECT_W+1 + nObsWidth+1 + nHistWidth+1 + 2);
+ fDelta = (float)nMaxHist / (float)nCols;
+ nPerCol = ceil(fDelta);
+ nPerCol = MAX(nPerCol, 1);
+
+ fprintf(fp, " Histogram units: %c %d Sequence%s",
+ DRAWING_SYMBOL, nPerCol, (nPerCol == 1 ? "" : "s"));
+
+ if (fDelta > 1.0)
+ fprintf(fp, " %c less than %d sequences\n", SMALLDRAWING_SYMBOL, nPerCol);
+ else
+ putc('\n', fp);
+
+ putc('\n', fp);
+ fprintf(fp, " EXPECTation Threshold\n");
+ fprintf(fp, " (E parameter)\n");
+ fprintf(fp, " |\n");
+ fprintf(fp, " V Observed Counts-->\n");
+
+/* If there were no hits, exit. */
+ if (nMaxHist == 0)
+ {
+ fprintf(fp, "\n\n*** histogram slots are all empty ***\n\n");
+ return TRUE;
+ }
+
+ /* Draw the histogram
+ */
+ for (i = 0, pBar = pHist->bar; i < nBars; i++)
+ {
+ if ( bNeedCheck && (pBar->x <= pHist->expect + 1e-6)) {
+ /* This line must appear only once
+ */
+ fprintf(fp,
+ " >>>>>>>>>>>>>>>>>>>>> Expect = %#0.3lg, Observed = %lu <<<<<<<<<<<<<<<<<\n",
+ pHist->expect, pHist->observed);
+ bNeedCheck = FALSE;
+ }
+
+ nHistValue = (i < nBars - 1) ? (pBar->n - pBar->next->n) : (pBar->n - pHist->base);
+ fprintf(fp, " %s %*lu %*lu %c", print_double(aCh, pBar->x, 6, 3),
+ nObsWidth, pBar->n, nHistWidth, nHistValue, SEPARATOR_SYMBOL);
+
+ /* Draw long line ("=")
+ nHistValue is the number of hits observed, nPerCol is the number of
+ hits that each symbol represents.
+ */
+ nUnits = (Int2) (nHistValue/nPerCol);
+ for (j = 0; j < nUnits; j++)
+ putc(DRAWING_SYMBOL, fp);
+
+ /* Draw tiny line if nothing was drawn above (":").
+ */
+ if (j == 0 && nHistValue > 0 && nPerCol > 1)
+ putc(SMALLDRAWING_SYMBOL, fp);
+
+ putc('\n', fp);
+
+ pBar = pBar->next;
+ }
+
+ return TRUE;
+}
+
+/************************************************************************
+
+ The following functions are used to print the output to a file:
+
+ BlastPrintStructInit: call once at beginning of program, performs
+ initialization.
+ BlastPrintStart: call when a newline should be started or the
+ initial or continuation line indentation changes.
+ BlastPrintAddString: Adds String to the print "buffer".
+ BlastPrintAddChar: Adds a Char to the print "buffer".
+ BlastPrintEnd: finishes section, newline inserted.
+ BlastPrintStructClose: call once at end of program, does deallocation.
+
+*************************************************************************/
+
+/*
+ Call this function ONCE. If failure, NULL is returned,
+ otherwise the BlastPrintStructurePtr is returned.
+*/
+
+BlastPrintStructurePtr
+BlastPrintStructInit(Int2 line_length, FILE *fp)
+
+{
+ BlastPrintStructurePtr bpsp;
+ CharPtr buffer;
+
+ bpsp = (BlastPrintStructurePtr) MemNew(sizeof(BlastPrintStructure));
+
+ if (bpsp == NULL)
+ {
+ return NULL;
+ }
+/* Make the buffer 2 longer for safety */
+ buffer = (CharPtr) MemNew((line_length+2)*sizeof(Char));
+ if (buffer == NULL)
+ {
+ bpsp = MemFree(bpsp);
+ return NULL;
+ }
+
+ bpsp->fp = fp;
+ bpsp->buffer = buffer;
+ bpsp->line_length = line_length;
+ bpsp->position = 0;
+
+ return bpsp;
+}
+
+
+/*
+ Call at the start of every "paragraph". TRUE is returned on
+ success, otherwise FALSE.
+*/
+Boolean
+BlastPrintStart(BlastPrintStructurePtr bpsp, Int2 init_indent, Int2 cont_indent)
+
+{
+ if (bpsp == NULL)
+ return FALSE;
+
+ bpsp->init_indent = init_indent;
+ bpsp->cont_indent = cont_indent;
+ bpsp->position = 0; /* set position of buffer to zero. */
+ bpsp->first_line = TRUE;
+ bpsp->buffer[0] = NULLB;
+
+ return TRUE;
+}
+
+/*
+ Adds a string to the buffer; if buffer is full, print buffer,
+ add line return, and reset position to zero.
+
+ The total number of characters printed is returned.
+*/
+
+Int2
+BlastPrintStringAdd(BlastPrintStructurePtr bpsp, CharPtr string)
+
+{
+ CharPtr buffer;
+ Int2 indent, line_length, num_of_chars=0, position;
+
+ if (bpsp == NULL)
+ return 0;
+
+ buffer = bpsp->buffer;
+ position = bpsp->position;
+ buffer += position;
+ line_length = bpsp->line_length;
+
+/* if position is zero we're starting a new line. */
+ if (position == 0)
+ {
+ if (bpsp->first_line == TRUE)
+ {
+ indent = bpsp->init_indent;
+ bpsp->first_line = FALSE;
+ }
+ else
+ {
+ indent = bpsp->cont_indent;
+ }
+
+ while (indent > 0)
+ {
+ *buffer = ' ';
+ buffer++;
+ position++;
+ }
+ }
+
+ while (*string != NULLB)
+ {
+ *buffer = *string;
+ string++;
+ buffer++;
+ position++;
+ if (position >= line_length && *string != NULLB)
+ {
+ bpsp->position = position;
+ num_of_chars += BlastPrintCheckBufferStatus(bpsp, *(string));
+ if (*string == ' ')
+ string++;
+ num_of_chars += BlastPrintStringAdd(bpsp, string);
+ break;
+ }
+ }
+
+
+/* If num_of_chars is non-zero, then position was set. */
+ if (num_of_chars == 0)
+ {
+ bpsp->position = position;
+ return position;
+ }
+ else
+ {
+ return num_of_chars;
+ }
+}
+
+#define NUM_TO_BACKTRACK 10 /* How far to look for whitespace. */
+Int2
+BlastPrintCheckBufferStatus (BlastPrintStructurePtr bpsp, Char next_char)
+
+{
+ Boolean found_whitespace=FALSE;
+ CharPtr buffer, ptr;
+ Char temp[NUM_TO_BACKTRACK];
+ Int2 index, num_of_chars=0;
+
+ if (next_char != NULLB && next_char != ' ')
+ {
+ buffer = bpsp->buffer;
+
+ buffer += bpsp->position;
+
+ /* Look for a whitespace to break on. */
+ for (index=0; index<NUM_TO_BACKTRACK; index++)
+ {
+ if (*buffer == ' ')
+ {
+ found_whitespace=TRUE;
+ break;
+ }
+ buffer--;
+ }
+
+ if (found_whitespace == TRUE)
+ {
+ *buffer = NULLB;
+ buffer++;
+ bpsp->position -= index;
+
+ ptr = &temp[0];
+ while (index > 0)
+ {
+ *ptr = *buffer;
+ ptr++; buffer++;
+ index--;
+ }
+ *ptr = NULLB;
+ }
+ num_of_chars = bpsp->position;
+ BlastPrintFlush(bpsp);
+ buffer = bpsp->buffer;
+ ptr = temp;
+ index=0;
+ while (*ptr != NULLB)
+ {
+ *buffer = *ptr;
+ buffer++; ptr++;
+ index++;
+ }
+ bpsp->position = index;
+ }
+ else
+ {
+ num_of_chars = bpsp->position;
+ BlastPrintFlush(bpsp);
+ }
+
+ return num_of_chars;
+
+}
+
+Int2
+BlastPrintDoubleAdd(BlastPrintStructurePtr bpsp, CharPtr format, double number)
+
+{
+ Char temp[BLAST2_LINE_LENGTH];
+
+ sprintf(temp, format, (double) number);
+ number = BlastPrintStringAdd(bpsp, temp);
+ return number;
+}
+
+Int2
+BlastPrintIntegerAdd(BlastPrintStructurePtr bpsp, CharPtr format, Int4 number)
+
+{
+ Char temp[BLAST2_LINE_LENGTH];
+
+ sprintf(temp, format, (long) number);
+ number = BlastPrintStringAdd(bpsp, temp);
+ return number;
+}
+
+
+Int2
+BlastPrintCharAdd(BlastPrintStructurePtr bpsp, Char character)
+
+{
+ CharPtr buffer;
+ Int2 indent, line_length, num_of_chars=0, position;
+
+ if (bpsp == NULL)
+ return 0;
+
+ buffer = bpsp->buffer;
+ position = bpsp->position;
+ buffer += position;
+ line_length = bpsp->line_length;
+
+/* if position is zero we're starting a new line. */
+ if (position == 0)
+ {
+ if (bpsp->first_line == TRUE)
+ {
+ indent = bpsp->init_indent;
+ bpsp->first_line = FALSE;
+ }
+ else
+ {
+ indent = bpsp->cont_indent;
+ }
+
+ while (indent > 0)
+ {
+ *buffer = ' ';
+ buffer++;
+ position++;
+ }
+ }
+
+ if (position > line_length)
+ {
+ bpsp->position = position;
+ BlastPrintFlush(bpsp);
+ position = bpsp->position;
+ buffer = bpsp->buffer;
+ }
+
+ position++;
+ bpsp->position = position;
+ *buffer = character;
+
+ return 1;
+}
+
+/*
+ Tab to column given by column. If column is less than position
+ a negative number is returned, otherwise the number of blank
+ spaces added is returned.
+
+*/
+Int2
+BlastPrintTabToColumn(BlastPrintStructurePtr bpsp, Int2 column)
+
+{
+ CharPtr buffer;
+ Int2 diff, position;
+
+ if (bpsp == NULL)
+ return -1;
+
+ column -= 1; /* Change column so it's zero offset, like position. */
+
+ if (column > bpsp->line_length)
+ return -1;
+
+ position = bpsp->position;
+ diff = column - position;
+ if (diff <= 0)
+ return diff;
+
+ buffer = bpsp->buffer;
+ buffer += position;
+
+ while (diff > 0)
+ {
+ *buffer = ' ';
+ buffer++;
+ diff--;
+ }
+
+ diff = column - position;
+ bpsp->position = column;
+
+ return diff;
+}
+
+/*
+ Starts a new-line.
+*/
+void
+BlastPrintNewLine(BlastPrintStructurePtr bpsp)
+
+{
+ BlastPrintFlush(bpsp);
+ bpsp->position = 0;
+ bpsp->buffer[0] = NULLB;
+}
+
+
+/*
+ Ends printing.
+*/
+void
+BlastPrintEnd(BlastPrintStructurePtr bpsp)
+
+{
+ BlastPrintFlush(bpsp);
+ bpsp->position = 0;
+ bpsp->buffer[0] = NULLB;
+}
+
+/*
+ Prints the buffer to the File*.
+ This funciton could also store the buffer in a
+ ByteStorePtr for later use.
+*/
+void
+BlastPrintFlush(BlastPrintStructurePtr bpsp)
+
+{
+ bpsp->buffer[bpsp->position] = NULLB;
+ fprintf(bpsp->fp, "%s\n", bpsp->buffer);
+ bpsp->position = 0;
+}
+
+/*
+ Deallocates the CharPtr buffer and the BlastPrintStructurePtr.
+ This function does NOT close the file for FILE* fp!
+*/
+BlastPrintStructurePtr
+BlastPrintStructClose(BlastPrintStructurePtr bpsp)
+
+{
+ bpsp->buffer = MemFree(bpsp->buffer);
+ bpsp = MemFree(bpsp);
+ return bpsp;
+}
diff --git a/network/blast2/client/blast2.h b/network/blast2/client/blast2.h
new file mode 100644
index 00000000..f3ebdde4
--- /dev/null
+++ b/network/blast2/client/blast2.h
@@ -0,0 +1,209 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: blast2.h
+*
+* Author: Tom Madden
+*
+* Version Creation Date: 10/26/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Functions that format traditional BLAST output.
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: blast2.h,v $
+* Revision 6.0 1997/08/25 18:33:55 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/05/14 14:19:15 shavirin
+* Added define for absolute links
+*
+ * Revision 5.1 1996/12/13 18:10:58 madden
+ * Added TraditionalBlastReportAddResult.
+ *
+ * Revision 5.0 1996/05/28 14:09:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 1.11 1996/03/25 17:28:26 shavirin
+ * Changes due to new function TraditionalBlastOutputHTML(),
+ * that produce HTML output from the BLAST server
+ *
+ * Revision 1.10 1996/03/22 17:28:49 madden
+ * Moved formatting prototypes from netblap2.h
+ *
+ * Revision 1.9 1996/03/12 19:10:32 madden
+ * Added prototype fro BLAST0Sequence2Bioseq.
+ *
+ * Revision 1.8 1996/03/11 22:02:09 madden
+ * Added function BLAST0SeqData2Bioseq.
+ *
+ * Revision 1.7 1995/11/07 17:55:47 madden
+ * Added prototypes for PrintTraditionalBlastPreface and BlastPrintCheckBufferStatus.
+ *
+ * Revision 1.6 1995/11/03 16:02:43 madden
+ * Added BlastPrintNewLine, renames BlastPrintInit to BlastPrintStructInit.
+ *
+ * Revision 1.5 1995/11/02 21:46:44 madden
+ * Added functions BlastPrintDoubleAdd and BlastPrintIntegerAdd.
+ *
+ * Revision 1.4 1995/11/02 21:12:25 madden
+ * Added prototypes for "BlastPrint" functions and typedef for blast_print_struct.
+ *
+ * Revision 1.3 1995/11/01 15:40:18 madden
+ * Addition of TraditionalBlastReportSetUp and TraditionalBlastReportCleanUp.
+ *
+ * Revision 1.2 1995/10/27 21:17:10 madden
+ * Added prototype for TraditionalHistBlastOutput and struct blast_report_struct.
+ *
+ * Revision 1.1 1995/10/26 17:06:44 madden
+ * Initial revision
+ *
+ *
+*/
+#ifndef _BLAST2_
+#define _BLAST2_
+
+#include <ncbi.h>
+#include <objblst2.h>
+#include <objseq.h>
+#define BLAST2_LINE_LENGTH 79
+
+#define TEXT_OUTPUT 0
+#define HTML_OUTPUT 1
+#define ABSOLUTE_LINKS 2
+
+/*
+The following structure contains all the info for the "BlastPrint"
+functions (e.g., BlastPrintStructInit, BlastPrintStart etc.)
+*/
+
+typedef struct blast_print_struct {
+ CharPtr buffer; /* contains line to be printed. */
+ FILE *fp; /* File to print to */
+ Int2 init_indent, /* Indentation of first line */
+ cont_indent, /* indentation of continuation lines. */
+ line_length, /* size of allocated buffer (above) */
+ position; /* position in buffer. */
+ Boolean first_line; /* TRUE if first call after BlastStartPrint. */
+} BlastPrintStructure, PNTR BlastPrintStructurePtr;
+
+BlastPrintStructurePtr BlastPrintStructInit PROTO((Int2 line_length, FILE *fp));
+
+Boolean BlastPrintStart PROTO((BlastPrintStructurePtr bpsp, Int2 init_indent, Int2 cont_indent));
+
+Int2 BlastPrintStringAdd PROTO((BlastPrintStructurePtr bpsp, CharPtr string));
+
+Int2 BlastPrintCharAdd PROTO((BlastPrintStructurePtr bpsp, Char character));
+
+Int2 BlastPrintDoubleAdd PROTO((BlastPrintStructurePtr bpsp, CharPtr format, double number));
+
+Int2 BlastPrintIntegerAdd PROTO((BlastPrintStructurePtr bpsp, CharPtr format, Int4 number));
+
+Int2 BlastPrintCheckBufferStatus PROTO((BlastPrintStructurePtr bpsp, Char next_char));
+void BlastPrintNewLine PROTO((BlastPrintStructurePtr bpsp));
+
+Int2 BlastPrintTabToColumn PROTO((BlastPrintStructurePtr bpsp, Int2 column));
+
+void BlastPrintEnd PROTO((BlastPrintStructurePtr bpsp));
+
+void BlastPrintFlush PROTO((BlastPrintStructurePtr bpsp));
+
+BlastPrintStructurePtr BlastPrintStructClose PROTO((BlastPrintStructurePtr bpsp));
+
+typedef struct blast_report_struct {
+ BLAST0ResultPtr result; /* contains histogram & hitlist */
+ BLAST0ResponsePtr blresp;/* contains preface, matrix, etc. */
+ Int4 query_length, /* number of residues/basepairs in query. */
+ qoffset, /* offset for command-line option "-qoffset" */
+ num_of_defline, /* number of (one-line) descriptions to show*/
+ num_of_align; /* number of alignments to show*/
+ CharPtr program; /* name of the program (e.g., blastn) */
+ Boolean is_prot, /* TRUE if the protein alignments are shown */
+ get_gi; /* TRUE if gi's are shown in FASTA id */
+ Int4 type; /* TEXT_OUTPUT or HTML_OUTPUT */
+ BlastPrintStructurePtr bpsp; /* Printing info in this structure. */
+ Int2Ptr window; /* Array to save actual window sizes for
+ Stephen A's development of BLAST. */
+ Int2Ptr right_dropoff_sizes;
+ Int2Ptr left_dropoff_sizes;
+} BlastReportStruct, PNTR BlastReportStructPtr;
+
+Boolean LIBCALL TraditionalBlastReportAddResult PROTO((BlastReportStructPtr blrp, BLAST0ResultPtr result, BLAST0ResponsePtr blresp));
+
+BlastReportStructPtr TraditionalBlastReportSetUp PROTO((BLAST0ResultPtr result, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp, Int4 type));
+
+BlastReportStructPtr TraditionalBlastReportCleanUp PROTO((BlastReportStructPtr));
+
+Boolean LIBCALL TraditionalHistBlastOutput PROTO((BlastReportStructPtr blrp));
+
+Boolean LIBCALL PrintTraditionalBlastPreface PROTO((BlastReportStructPtr blrp));
+
+Int4 LIBCALL acknowledge_blast_request PROTO((CharPtr program, BLAST0SequencePtr query, Int2 strands, Int4 offset, FILE *fp, Int4 type));
+
+Int2 LIBCALL BlastPrintValNodeStack PROTO((ValNodePtr stack, CharPtr title, FILE *fp));
+
+void blast2_wrap PROTO((FILE *fp, CharPtr title, CharPtr s, int slen, int linelen, int indent));
+
+BioseqPtr LIBCALL BLAST0Sequence2Bioseq PROTO((BLAST0SequencePtr sequence));
+
+Int2 LIBCALL BLAST0SeqData2Bioseq PROTO((BioseqPtr bsp, ValNodePtr sequence, Int4 length));
+
+/* This function produces the traditional BLAST output. */
+Boolean LIBCALL TraditionalBlastOutput PROTO((BLAST0ResultPtr hdp, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp));
+
+/* This function produces the traditional BLAST output in HTML format */
+Boolean LIBCALL TraditionalBlastOutputHTML PROTO((BLAST0ResultPtr hdp, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp));
+
+/* This function produces the BLAST output in short HTML format */
+Boolean LIBCALL TraditionalBlastOutputHTML2 PROTO((BLAST0ResultPtr hdp, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp));
+
+/* These functions produce parts of the traditional output and are used
+by TraditionalBlastOutput */
+
+Boolean LIBCALL TraditionalHeadBlastOutput PROTO((BlastReportStructPtr blrp));
+
+Boolean LIBCALL TraditionalHistBlastOutput PROTO((BlastReportStructPtr blrp));
+
+void LIBCALL TraditionalBlastWarning PROTO((BlastReportStructPtr blrp));
+
+
+Boolean LIBCALL TraditionalTopBlastOutput PROTO((BlastReportStructPtr blrp));
+
+Boolean LIBCALL TraditionalBottomBlastOutput PROTO((BlastReportStructPtr blrp));
+
+Boolean LIBCALL TraditionalTailBlastOutput PROTO((BlastReportStructPtr blrp));
+
+
+#endif /* _BLAST2_ */
diff --git a/network/blast2/client/blastasn.c b/network/blast2/client/blastasn.c
new file mode 100644
index 00000000..a5daccaf
--- /dev/null
+++ b/network/blast2/client/blastasn.c
@@ -0,0 +1,1084 @@
+/**************************************************************************
+* *
+* COPYRIGHT NOTICE *
+* *
+* This software/database is categorized as "United States Government *
+* Work" under the terms of the United States Copyright Act. It was *
+* produced as part of the author's official duties as a Government *
+* employee and thus can not be copyrighted. This software/database is *
+* freely available to the public for use without a copyright notice. *
+* Restrictions can not be placed on its present or future use. *
+* *
+* Although all reasonable efforts have been taken to ensure the accuracy *
+* and reliability of the software and data, the National Library of *
+* Medicine (NLM) and the U.S. Government do not and can not warrant the *
+* performance or results that may be obtained by using this software, *
+* data, or derivative works thereof. The NLM and the U.S. Government *
+* disclaim any and all warranties, expressed or implied, as to the *
+* performance, merchantability or fitness for any particular purpose or *
+* use. *
+* *
+* In any work or product derived from this material, proper attribution *
+* of the author(s) as the source of the software or data would be *
+* appreciated. *
+* *
+**************************************************************************/
+/*****************************************************************************
+
+File name: blastasn.c
+
+Author: Tom Madden
+
+Contents: Functions to produce BLAST ASN.1 (specification 1.8) from data
+ produced by BLAST.
+
+Detailed Contents:
+
+ - Functions that produce a SeqAlign from BLAST structures.
+
+ - Functions that produce a BLAST0Result from BLAST structures.
+
+******************************************************************************/
+
+/* $Log: blastasn.c,v $
+/* Revision 6.3 1998/04/15 20:13:00 madden
+/* MakeBLAST0Result is non-NULL if results are NULL
+/*
+ * Revision 6.2 1998/03/26 14:15:47 madden
+ * Added second (NULL) argument to GetScoreSetFromBlastResultHsp
+ *
+ * Revision 6.1 1997/12/12 16:41:26 madden
+ * charPtr to Uint1Ptr in GetBLAST0SeqData
+ *
+ * Revision 6.0 1997/08/25 18:33:57 madden
+ * Revision changed to 6.0
+ *
+ * Revision 1.28 1997/07/07 13:58:35 madden
+ * switched order of gi and textid
+ *
+ * Revision 1.27 1997/02/11 01:32:26 kans
+ * cast second parameter of GetBLAST0Segment to CharPtr (for CodeWarrior)
+ *
+ * Revision 1.26 1997/01/15 13:35:06 madden
+ * Changes for nucl. alphabets.
+ *
+ * Revision 1.25 1997/01/13 17:55:44 madden
+ * Replaced tabs by spaces.
+ *
+ * Revision 1.24 1997/01/13 17:16:22 madden
+ * Save ncbi4na matrix for blastn.
+ *
+ * Revision 1.23 1997/01/03 20:30:55 madden
+ * Fixed formatting of results.
+ *
+ * Revision 1.22 1997/01/03 14:51:00 madden
+ * Fixed memory leak.
+ *
+ * Revision 1.21 1996/12/23 14:13:01 madden
+ * Changed gap stats printed out.
+ *
+ * Revision 1.20 1996/12/17 21:36:55 madden
+ * Changes to allow deflines for inidividual entries to be retrieved.
+ *
+ * Revision 1.19 1996/12/17 19:41:20 madden
+ * Added gapped stats.
+ *
+ * Revision 1.18 1996/11/27 16:42:19 madden
+ * Produced DbDesc from Readdb information.
+ *
+ * Revision 1.17 1996/11/14 16:22:52 madden
+ * Fixed problem in input to GetTranslation/
+ *
+ * Revision 1.16 1996/11/13 22:37:28 madden
+ * Added call to readdb_get_bioseq for tblast[nx].
+ *
+ * Revision 1.15 1996/11/08 21:50:48 madden
+ * *** empty log message ***
+ *
+ * Revision 1.14 1996/11/07 22:34:16 madden
+ * Replaced call to readdb_get_partial_unpacked_sequence with call
+ * to readdb_get_bioseq.
+ *
+ * Revision 1.13 1996/11/06 22:12:09 madden
+ * Changed call to BlastTranslateUnambiguousSequence.
+ *
+ * Revision 1.12 1996/10/03 13:33:47 madden
+ * Changed kbp to kbp[0].
+ *
+ * Revision 1.11 1996/09/30 21:57:30 madden
+ * Replaced ncbi2na alphabet, for query, with blastna alphabet.
+ *
+ * Revision 1.10 1996/09/25 20:02:43 madden
+ * Added "stats" Boolean if stats were collected.
+ *
+ * Revision 1.9 1996/09/25 14:18:47 madden
+ * Removed discontiguous references.
+ *
+ * Revision 1.8 1996/09/24 18:41:34 madden
+ * Fixed conversion to ncbi4na for blastn.
+ *
+ * Revision 1.7 1996/09/23 17:36:48 madden
+ * Changed CharPtr's to Uint1Ptr's.
+ *
+ * Revision 1.6 1996/09/17 15:29:25 madden
+ * Use readdb_get_partial_unpacked_sequence function to fetch sequences
+ * for blastn.
+ *
+ * Revision 1.5 1996/09/17 14:29:43 madden
+ * Changes for blastn formatting.
+ *
+ * Revision 1.4 1996/08/27 21:52:40 madden
+ * Added tblastx.
+ *
+ * Revision 1.3 1996/08/22 21:35:30 madden
+ * Corrections to calculation of offsets on negative frames.
+ *
+ * Revision 1.2 1996/08/14 17:20:40 madden
+ * Subject sequence now translated for tblastn.
+ *
+ * Revision 1.1 1996/08/07 14:07:13 madden
+ * Initial revision
+ *
+ * Revision 1.2 1996/08/06 15:23:58 madden
+ * Changes in FillInStdSegInfo to produce seqalign for blastx.
+ *
+ * Revision 1.1 1996/08/05 19:47:16 madden
+ * Initial revision
+ *
+ * Revision 1.34 1996/08/05 17:26:56 madden
+ * Added check for query and subject frame to FillInStdSegInfo.
+ *
+ * Revision 1.33 1996/07/25 20:45:20 madden
+ * Change to calling convention of readdb_get_sequence; protected
+ * against some NULL pointers.
+ *
+ * Revision 1.32 1996/07/25 12:55:57 madden
+ * readdb_get_sequence call changed to allow for systems w/o mmap.
+ *
+ * Revision 1.31 1996/07/24 13:16:28 madden
+ * Removed defunct functions asn_coord0 and asn_coord1.
+ *
+ * Revision 1.30 1996/07/24 12:01:28 madden
+ * Changes for blastx
+ *
+ * Revision 1.29 1996/07/18 13:36:48 madden
+ * Addition of the BLASTContextStructPtr.
+ *
+ * Revision 1.28 1996/07/12 16:32:37 madden
+ * Added function GetTheSeqAlignID, fixed errors.
+ *
+ * Revision 1.27 1996/07/11 16:03:58 madden
+ * Corrected production of SeqAlign.
+ *
+ * Revision 1.26 1996/06/26 15:54:25 madden
+ * Dropoff scores for both passes printed out.
+ *
+ * Revision 1.25 1996/06/20 16:15:57 madden
+ * Replaced int's with Int4's.
+ *
+ * Revision 1.24 1996/06/20 14:11:24 madden
+ * Removed unused parameters in FillInDenseDiagInfo and FillInStdSegInfo.
+ *
+ * Revision 1.23 1996/06/19 14:19:53 madden
+ * Allowed SeqId to be added for a sequence comparison.
+ *
+ * Revision 1.22 1996/06/18 16:05:23 madden
+ * fixed problem with length of SeqAlign.
+ *
+ * Revision 1.21 1996/06/17 21:06:45 madden
+ * Added function to produce SeqAlign from a hitlist.
+ *
+ * Revision 1.20 1996/06/07 13:05:36 madden
+ * contiguous/discontiguous printed as parameter.
+ *
+ * Revision 1.19 1996/06/06 17:55:00 madden
+ * Cutoff for second pass now printed.
+ *
+ * Revision 1.18 1996/06/04 15:33:31 madden
+ * Changed GetParameterStack for different programs.
+ *
+ * Revision 1.17 1996/05/28 14:14:14 madden
+ * GetParameterStack changed to include statistics info.
+ *
+ * Revision 1.16 1996/05/22 20:19:50 madden
+ * Changed location used in GetBLAST0Segment to correct one.
+ *
+ * Revision 1.15 1996/05/16 19:50:15 madden
+ * Added documentation block.
+ *
+ * Revision 1.14 1996/05/01 14:58:51 madden
+ * Functions to convert BlastResult structures to BLAST0 structs.
+ *
+ * Revision 1.13 1996/04/24 12:52:41 madden
+ * *** empty log message ***
+ *
+ * Revision 1.12 1996/04/22 21:40:31 madden
+ * *** empty log message ***
+ *
+ * Revision 1.11 1996/04/03 19:15:02 madden
+ * removed DuplicateBLAST0SeqDesc.
+ *
+ * Revision 1.10 1996/03/29 21:27:06 madden
+ * Added functions to produce a BLAST0Result from a SeqAlignPtr.
+ *
+ * Revision 1.9 1996/03/29 14:08:54 madden
+ * GetSeqAlignForSparseHitList added.
+ *
+ * Revision 1.8 1996/01/23 16:31:31 madden
+ * changes to print out parameters.
+ *
+ * Revision 1.7 1996/01/17 23:18:15 madden
+ * Added GetParameterStack function.
+ *
+ * Revision 1.6 1996/01/08 23:23:22 madden
+ * *** empty log message ***
+ *
+ * Revision 1.5 1996/01/06 18:57:19 madden
+ * Changed hsp->n to hsp->num to agree with current defs.
+ *
+ * Revision 1.4 1995/12/30 19:21:24 madden
+ * Added GetBLAST0KABlk.
+ *
+ * Revision 1.3 1995/12/26 23:03:48 madden
+ * moved GetBLAST0Matrix here.
+ *
+ * Revision 1.2 1995/12/19 22:31:39 madden
+ * *** empty log message ***
+ *
+ * Revision 1.1 1995/12/08 15:48:23 madden
+ * Initial revision
+ *
+ * */
+
+/* VAR_ARGS is used by PrintToValNode. */
+#ifdef VAR_ARGS
+#include <varargs.h>
+#else
+#include <stdarg.h>
+#endif
+
+#include <blastpri.h>
+#include <blastasn.h>
+#include <seqport.h>
+
+
+#define BLASTASN_BUF_SIZE 128
+
+static BLAST0SegmentPtr GetBLAST0Segment PROTO((BlastSearchBlkPtr search, Uint1Ptr sequence, Int4 total_length, Int4 from, Int4 length, Boolean get_seq, Int2 frame, Uint1 alphabet));
+
+static ValNodePtr GetBLAST0SeqData PROTO((BlastSearchBlkPtr search, Uint1Ptr sequence, Int4 offset, Int4 length, Uint1 alphabet));
+
+static BLAST0HitListPtr GetBLAST0HitList PROTO((BlastSearchBlkPtr search, Int4 count, Boolean get_query_seq, Boolean get_db_seq));
+
+static BLAST0SequencePtr GetBLAST0Sequence PROTO((BlastSearchBlkPtr search, Int4 sequence_number, Boolean get_seq));
+
+/* These are used by BLAST to print to a ValNodePtr. */
+static void PrintToValNode VPROTO((ValNodePtr PNTR stk, char *format, ...));
+static void PrintNewLineToValNode PROTO((ValNodePtr PNTR stp));
+
+/*
+ This function assembles a BLAST0DbDescPtr from the information
+ in the ReadDBFILEPtr.
+*/
+BLAST0DbDescPtr LIBCALL
+MakeBLAST0DbDesc(ReadDBFILEPtr rdfp)
+
+{
+ BLAST0DbDescPtr dbdesc;
+
+ dbdesc = BLAST0DbDescNew();
+ if (dbdesc != NULL)
+ {
+ dbdesc->name = StringSave(readdb_get_filename(rdfp));
+ if (readdb_is_prot(rdfp) == TRUE)
+ dbdesc->type = 1;
+ else
+ dbdesc->type = 2;
+ dbdesc->def = StringSave(readdb_get_title(rdfp));
+ dbdesc->rel_date = NULL; /* Not used or supported. */
+ dbdesc->bld_date = StringSave(readdb_get_date(rdfp));
+ dbdesc->count = readdb_get_num_entries(rdfp);
+ dbdesc->totlen = readdb_get_dblen(rdfp);
+ dbdesc->maxlen = readdb_get_maxlen(rdfp);
+ }
+
+ return dbdesc;
+}
+
+/*************************************************************************
+*
+* This function assembles all the components of the BLAST0Result
+* structure. The result is then passed back to a calling program
+* or made into ASN.1.
+***************************************************************************/
+
+BLAST0ResultPtr LIBCALL
+MakeBLAST0Result(BlastSearchBlkPtr search, Boolean get_query_seq, Boolean get_db_seq)
+{
+ BLAST0ResultPtr brp;
+ BLAST0HitListPtr bhlp;
+ BLASTResultsStructPtr result_struct=NULL;
+ Int4 count, total;
+
+
+ if ((brp = (BLAST0ResultPtr) MemNew(sizeof(BLAST0Result))) == NULL)
+ return NULL;
+
+ if (search)
+ {
+ result_struct = search->result_struct;
+ brp->count = result_struct->hitlist_count;
+ }
+ total = brp->count;
+
+ if (total > 0 && search)
+ {
+ bhlp = GetBLAST0HitList(search, 0, get_query_seq, get_db_seq);
+ brp->hitlists = bhlp;
+ for (count=1; count<total; count++)
+ {
+ bhlp->next = GetBLAST0HitList(search, count, get_query_seq, get_db_seq);
+ bhlp = bhlp->next;
+ }
+ }
+ else
+ {
+ brp->hitlists = NULL;
+ }
+
+ return brp;
+}
+
+static BLAST0HitListPtr
+GetBLAST0HitList(BlastSearchBlkPtr search, Int4 count, Boolean get_query_seq, Boolean get_db_seq)
+
+{
+ BioseqPtr bsp;
+ BLAST0HitListPtr bhlp;
+ BLASTResultHitlistPtr result_hitlist;
+ BLASTResultHspPtr hsp;
+ BLAST0HSPPtr blhsp, blhsp_tmp;
+ Int4 index, hspcnt, length, hsp_length, prot_length;
+ Int4 start, stop;
+ SeqPortPtr spp;
+ Uint1Ptr buffer_start, buffer, sequence, prot_seq;
+ Uint1 alphabet;
+
+ if ((bhlp = (BLAST0HitListPtr) MemNew(sizeof(BLAST0HitList))) == NULL)
+ return NULL;
+
+ result_hitlist = search->result_struct->results[count];
+ hspcnt = result_hitlist->hspcnt;
+ buffer_start=NULL;
+
+ prot_seq = NULL;
+ sequence = NULL;
+ blhsp=NULL;
+ bsp = readdb_get_bioseq(search->rdfp, result_hitlist->subject_id);
+
+ for (index=0; index<hspcnt; index++)
+ {
+ hsp = &(result_hitlist->hsp_array[index]);
+ blhsp_tmp = (BLAST0HSPPtr) MemNew(sizeof(BLAST0HSP));
+ blhsp_tmp->scores = GetScoreSetFromBlastResultHsp(hsp, NULL);
+ blhsp_tmp->len = hsp->query_length;
+ blhsp_tmp->segs = GetBLAST0Segment(search, search->context[hsp->context].query->sequence+hsp->query_offset, search->context[hsp->context].query->original_length, hsp->query_offset, hsp->query_length, get_query_seq, hsp->query_frame, search->sbp->alphabet_code);
+ alphabet = search->sbp->alphabet_code;
+ if (get_db_seq)
+ {
+ if (StringCmp("blastn", search->prog_name) == 0)
+ {
+ length = readdb_get_sequence_length(search->rdfp, result_hitlist->subject_id);
+ spp = SeqPortNew(bsp, hsp->subject_offset, hsp->subject_offset + hsp->subject_length - 1, Seq_strand_plus, Seq_code_ncbi4na);
+ hsp_length = hsp->subject_length;
+ buffer_start = buffer = MemNew(hsp_length*sizeof(Uint1));
+ while (hsp_length > 0)
+ {
+ *buffer = SeqPortGetResidue(spp);
+ buffer++;
+ hsp_length--;
+ }
+ spp = SeqPortFree(spp);
+
+ sequence = buffer_start;
+ /* readdb_get_partial_unpacked_sequence returns ncbi4na here. */
+ alphabet = Seq_code_ncbi4na;
+ }
+ else
+ {
+ if (StringCmp("tblastn", search->prog_name) == 0 || StringCmp("tblastx", search->prog_name) == 0)
+ {
+ length = bsp->length;
+ if (hsp->subject_frame > 0)
+ {
+ start = CODON_LENGTH*(hsp->subject_offset) + ABS(hsp->subject_frame) - 1;
+ stop = start + CODON_LENGTH*(hsp->subject_length) - 1;
+ spp = SeqPortNew(bsp, start, stop, Seq_strand_plus, Seq_code_ncbi4na);
+ }
+ else
+ {
+ start = bsp->length - CODON_LENGTH*(hsp->subject_offset + hsp->subject_length) + hsp->subject_frame + 1;
+ stop = bsp->length - CODON_LENGTH*(hsp->subject_offset) + hsp->subject_frame;
+ spp = SeqPortNew(bsp, start, stop, Seq_strand_minus, Seq_code_ncbi4na);
+ }
+ hsp_length = CODON_LENGTH*hsp->subject_length;
+ buffer_start = buffer = MemNew(hsp_length*sizeof(Uint1));
+ while (hsp_length > 0)
+ {
+ *buffer = SeqPortGetResidue(spp);
+ buffer++;
+ hsp_length--;
+ }
+ spp = SeqPortFree(spp);
+ hsp_length = CODON_LENGTH*hsp->subject_length;
+ prot_seq = GetTranslation(buffer_start, hsp_length, 1, &prot_length, search->db_genetic_code);
+
+ /* The translated sequence starts with a (sentinel) NULLB */
+ sequence = prot_seq+1;
+ }
+ else
+ {
+ length = readdb_get_sequence(search->rdfp, result_hitlist->subject_id, &sequence);
+ sequence += hsp->subject_offset;
+ }
+ }
+ }
+ else
+ {
+ length = readdb_get_sequence_length(search->rdfp, result_hitlist->subject_id);
+ }
+ blhsp_tmp->segs->next =
+ GetBLAST0Segment(search, sequence, length, hsp->subject_offset, hsp->subject_length, get_db_seq, hsp->subject_frame, alphabet);
+ if (blhsp)
+ {
+ blhsp->next = blhsp_tmp;
+ blhsp = blhsp->next;
+ }
+ else
+ {
+ bhlp->hsps = blhsp_tmp;
+ blhsp = blhsp_tmp;
+ }
+ if (buffer_start)
+ buffer_start = MemFree(buffer_start);
+ if (prot_seq)
+ prot_seq = MemFree(prot_seq);
+ }
+
+ bsp = BioseqFree(bsp);
+
+ bhlp->seqs = GetBLAST0Sequence(search, result_hitlist->subject_id, FALSE);
+
+ return bhlp;
+}
+
+static BLAST0SequencePtr
+GetBLAST0Sequence (BlastSearchBlkPtr search, Int4 sequence_number, Boolean get_seq)
+
+{
+ BLAST0SeqDescPtr desc;
+ BLAST0SequencePtr blsp;
+ Boolean not_done;
+ Char textid[100];
+ CharPtr definition=NULL;
+ Uint1Ptr sequence;
+ Int4 length, gi;
+ Uint4 index;
+ SeqIdPtr sip=NULL;
+ ValNodePtr new_id, vnp;
+
+
+ if ((blsp = (BLAST0SequencePtr) MemNew(sizeof(BLAST0Sequence))) == NULL)
+ return NULL;
+
+ desc = blsp->desc = BLAST0SeqDescNew();
+ not_done = TRUE;
+ index = 0;
+ while (not_done == TRUE)
+ {
+ not_done = readdb_get_header(search->rdfp, sequence_number, &index, &sip, &definition);
+
+ new_id = NULL;
+/* Only save an id as a textid if it's not a gi! */
+ textid[0] = NULLB;
+ if ((vnp = sip) != NULL)
+ {
+ while (vnp)
+ {
+ if (vnp->choice == SEQID_GI)
+ {
+ gi = vnp->data.intvalue;
+ ValNodeAddInt(&new_id, BLAST0SeqId_giid, gi);
+ break;
+ }
+ vnp = vnp->next;
+ }
+
+ vnp = sip;
+ while (vnp)
+ {
+ if (vnp->choice != SEQID_GI)
+ {
+ SeqIdPrint(vnp, textid, PRINTID_FASTA_LONG);
+ ValNodeCopyStr(&new_id, BLAST0SeqId_textid, textid);
+ break;
+ }
+ vnp = vnp->next;
+ }
+ }
+ sip = SeqIdSetFree(sip);
+ desc->defline = definition;
+ desc->id = new_id;
+ if (not_done == TRUE)
+ {
+ desc->next = BLAST0SeqDescNew();
+ desc = desc->next;
+ }
+ }
+
+
+ /* This needs to be set up for other codes. */
+ blsp->gcode = 1; /* "1" is the default code for the toolbox. */
+
+ /* seq BLAST0-Seq-data OPTIONAL */
+ if (get_seq)
+ {
+ sequence=NULL;
+ length = readdb_get_sequence(search->rdfp, sequence_number, &sequence);
+ blsp->seq = GetBLAST0SeqData(search, sequence, 0, length, search->sbp->alphabet_code);
+ }
+ else
+ {
+ length = readdb_get_sequence_length(search->rdfp, sequence_number);
+ }
+ blsp->length = length;
+
+ return blsp;
+}
+
+static BLAST0SegmentPtr
+GetBLAST0Segment (BlastSearchBlkPtr search, Uint1Ptr sequence, Int4 total_length, Int4 from, Int4 length, Boolean get_seq, Int2 frame, Uint1 alphabet_code)
+
+{
+ BLAST0SegmentPtr blsp;
+ BLAST0SeqIntervalPtr b0sip;
+ Uint2 strand;
+
+
+ if ((blsp = (BLAST0SegmentPtr) MemNew(sizeof(BLAST0Segment))) == NULL)
+ return NULL;
+
+ if ((b0sip = (BLAST0SeqIntervalPtr) MemNew(sizeof(BLAST0SeqInterval))) == NULL)
+ return NULL;
+
+ strand = 0;
+ if (frame > 0)
+ strand = BLAST0_Seq_interval_strand_plus;
+ else if (frame < 0)
+ strand = BLAST0_Seq_interval_strand_minus;
+
+ b0sip->strand = strand;
+ if (alphabet_code == Seq_code_ncbistdaa)
+ {
+ if (frame == 0)
+ { /* blastp */
+ b0sip->from = from;
+ b0sip->to = from + length - 1;
+ }
+ else if (frame > 0)
+ { /* blastx, tblast[nx] */
+ b0sip->from = CODON_LENGTH*from + frame - 1;
+ b0sip->to = CODON_LENGTH*(from+length) + frame;
+ }
+ else
+ { /* This may seem counterintuitive, but formatter views it this way. */
+ /* blastx, tblast[nx] */
+ b0sip->from = total_length - CODON_LENGTH*(from+length) + frame + 1;
+ b0sip->to = total_length - CODON_LENGTH*(from) + frame;
+ }
+ }
+ else
+ { /* blastn. */
+ if (frame > 0)
+ {
+ b0sip->from = from;
+ b0sip->to = from + length - 1;
+ }
+ else
+ {
+ b0sip->to = total_length - from - 1;
+ b0sip->from = total_length - from - length - 2;
+ }
+ }
+
+ blsp->loc = b0sip;
+
+ /* str BLAST0-Seq-data OPTIONAL */
+ if (get_seq)
+ {
+ /* Save sequence starting with "from" for a distance of "length",
+ where "length" is the length of the HSP. */
+ blsp->str = GetBLAST0SeqData(search, sequence, from, length, alphabet_code);
+ }
+
+ return blsp;
+}
+
+static ValNodePtr
+GetBLAST0SeqData(BlastSearchBlkPtr search, Uint1Ptr sequence, Int4 offset, Int4 length, Uint1 alphabet_code)
+{
+ ByteStorePtr byte_sp=NULL;
+ ValNodePtr vnp=NULL;
+ Int4 index, enc_index, enclen, remainder;
+ Uint1Ptr buffer;
+ Uint1 byte;
+
+ if (alphabet_code == Seq_code_ncbistdaa)
+ {
+ byte_sp = BSNew(length);
+ BSWrite(byte_sp, sequence, length);
+ ValNodeAddPointer(&vnp, BLAST0SeqData_ncbistdaa, byte_sp);
+
+ }
+ else if (alphabet_code == Seq_code_ncbi4na)
+ {
+ enclen = length/2;
+ byte_sp = BSNew(enclen + length%2);
+ buffer = MemNew((enclen+1)*sizeof(Char));
+ enc_index=0;
+ for (index=0; index<2*enclen; index += 2)
+ {
+ byte = sequence[index];
+ byte <<= 4;
+ byte += sequence[index+1];
+ buffer[enc_index] = byte;
+ enc_index++;
+ }
+
+ remainder = length%2;
+ if (remainder > 0)
+ {
+ byte = sequence[index];
+ byte <<= 4;
+ buffer[enc_index] = byte;
+ }
+ BSWrite(byte_sp, buffer, enclen+length%2);
+ ValNodeAddPointer(&vnp, BLAST0SeqData_ncbi4na, byte_sp);
+ buffer = MemFree(buffer);
+ }
+ else
+ { /* Convert blastna to ncbi4na and save. */
+ enclen = length/2;
+ byte_sp = BSNew(enclen + length%2);
+ buffer = MemNew((enclen+1)*sizeof(Char));
+ enc_index=0;
+ for (index=0; index<2*enclen; index += 2)
+ {
+ byte = blastna_to_ncbi4na[sequence[index]];
+ byte <<= 4;
+ byte += blastna_to_ncbi4na[sequence[index+1]];
+ buffer[enc_index] = byte;
+ enc_index++;
+ }
+
+ remainder = length%2;
+ if (remainder > 0)
+ {
+ byte = blastna_to_ncbi4na[sequence[index]];
+ byte <<= 4;
+ buffer[enc_index] = byte;
+ }
+
+ BSWrite(byte_sp, buffer, enclen+length%2);
+ ValNodeAddPointer(&vnp, BLAST0SeqData_ncbi4na, byte_sp);
+ buffer = MemFree(buffer);
+ }
+
+ return vnp;
+}
+
+/**************************************************************************
+*
+* Translates the information in the BLAST_ScoreBlkPtr into the
+* BLAST0MatrixPtr. If there is a problem (e.g., the BLAST0MatrixPtr
+* cannot be allocated), NULL is returned.
+* The Boolean fullreport specifies whether comments and scores
+* should be reported.
+*
+**************************************************************************/
+
+BLAST0MatrixPtr LIBCALL
+GetBLAST0Matrix(BLAST_ScoreBlkPtr sbp, Boolean fullreport)
+{
+ BLAST0MatrixPtr b0mp;
+ BLAST_Score score;
+ Scores_scaled_intsPtr sco;
+ SeqCodeTablePtr sctp;
+ Int4 index1, index2, ncbi4na_index1, ncbi4na_index2, total, start_at;
+ Uint1 alphabet_code;
+ ValNodePtr vnp, vnp1;
+
+ if (sbp == NULL)
+ return NULL;
+
+ if ((b0mp = (BLAST0MatrixPtr) MemNew(sizeof(BLAST0Matrix))) == NULL)
+ return NULL;
+
+ alphabet_code=sbp->alphabet_code;
+
+ b0mp->matid = sbp->matid;
+ if (sbp->name)
+ b0mp->name = StringSave(sbp->name);
+ else
+ b0mp->name = StringSave("unknown matrix");
+
+ if (fullreport && sbp->comments != NULL)
+ {
+ vnp = NULL;
+ for (vnp1 = sbp->comments; vnp1 != NULL; vnp1 = vnp1->next)
+ ValNodeCopyStr(&vnp, 0, vnp1->data.ptrvalue);
+ b0mp->comments = vnp;
+ }
+
+/* Does this need to be fixed for blastn? */
+ if (alphabet_code != BLASTNA_SEQ_CODE)
+ {
+ b0mp->qalpha = alphabet_code;
+ b0mp->salpha = alphabet_code;
+ }
+ else
+ {
+ b0mp->qalpha = Seq_code_ncbi4na;
+ b0mp->salpha = Seq_code_ncbi4na;
+ }
+
+ if (fullreport)
+ { /* If a full report is requested, add the scores */
+ if (alphabet_code != BLASTNA_SEQ_CODE)
+ {
+ sctp = SeqCodeTableFindObj(alphabet_code);
+ start_at = sctp->start_at;
+ total = sctp->start_at + sctp->num;
+ }
+ else
+ {
+ start_at = 0;
+ total = sbp->mat_dim1;
+ }
+
+ vnp=NULL;
+ if (alphabet_code == BLASTNA_SEQ_CODE)
+ {
+ for (index1=start_at; index1<total; index1++)
+ {
+ for (index2 = start_at; index2<total; index2++)
+ {
+ ncbi4na_index1 = blastna_to_ncbi4na[index1];
+ ncbi4na_index2 = blastna_to_ncbi4na[index2];
+ score = sbp->matrix[ncbi4na_index1][ncbi4na_index2];
+ if (score < BLAST_SCORE_1MIN)
+ score = INT4_MIN;
+ ValNodeAddInt(&vnp, 0, score);
+ }
+ }
+ }
+ else
+ {
+ for (index1=start_at; index1<total; index1++)
+ {
+ for (index2 = start_at; index2<total; index2++)
+ {
+ score = sbp->matrix[index1][index2];
+ if (score < BLAST_SCORE_1MIN)
+ score = INT4_MIN;
+ ValNodeAddInt(&vnp, 0, score);
+ }
+ }
+ }
+ sco = (Scores_scaled_intsPtr) MemNew(sizeof(Scores_scaled_ints));
+ sco->ints = vnp;
+ vnp1=NULL;
+ ValNodeAddPointer(&vnp1, Scores_scores_Scores_ScaledInts,sco);
+ b0mp->Scores_scores = vnp1;
+ }
+
+ return b0mp;
+}
+
+/*
+ Function to produce the BLAST0KABlkPtr from information
+ in the BLAST_ScoreBlkPtr. Note that most of this
+ information (everything except the matid) is in the
+ BLAST_KarlinBlkPtr.
+*/
+
+BLAST0KABlkPtr LIBCALL
+GetBLAST0KABlk(BLAST_ScoreBlkPtr sbp)
+
+{
+ BLAST0KABlkPtr b0kbp;
+ BLAST_KarlinBlkPtr kbp;
+ ValNodePtr vnp=NULL;
+
+
+ if (sbp == NULL || sbp->kbp == NULL)
+ return NULL;
+
+ kbp = sbp->kbp[0];
+
+ b0kbp = (BLAST0KABlkPtr) MemNew(sizeof(BLAST0KABlk));
+
+ if (b0kbp != NULL)
+ {
+ b0kbp->matid = sbp->matid;
+ ValNodeAddInt(&vnp, 0, kbp->q_frame);
+ ValNodeAddInt(&vnp, 0, kbp->s_frame);
+ b0kbp->frames = vnp;
+ b0kbp->lambda = kbp->Lambda;
+ b0kbp->k = kbp->K;
+ b0kbp->h = kbp->H;
+ }
+
+ return b0kbp;
+}
+
+/*
+ this function prints out the (Karlin) parameters to
+ the ValNodePtr stp.
+
+ If the Boolean "old" is TRUE, print out stats for one-pass (old)
+ method.
+
+*/
+ValNodePtr LIBCALL
+GetParameterStack(BlastSearchBlkPtr search, ValNodePtr stp, Boolean old, Boolean stats)
+
+{
+ BLAST_ParameterBlkPtr pbp;
+ BLAST_ScoreBlkPtr sbp;
+ BLAST_KarlinBlkPtr kbp;
+ BLAST0DbDescPtr dbdesc;
+
+ if (search == NULL || search->pbp == NULL || search->sbp == NULL || search->sbp->kbp == NULL)
+ return NULL;
+
+ sbp = search->sbp;
+ kbp = sbp->kbp[0];
+ pbp = search->pbp;
+
+
+ PrintNewLineToValNode(&stp);
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp, "Lambda K H");
+ PrintNewLineToValNode(&stp);
+
+ if (kbp->Lambda > 0.)
+ PrintToValNode(&stp, "%#8.3lg ", kbp->Lambda);
+ else
+ PrintToValNode(&stp, " NA ");
+ if (kbp->K > 0.)
+ PrintToValNode(&stp, "%#7.3lg ", kbp->K);
+ else
+ PrintToValNode(&stp, " NA ");
+ if (kbp->H > 0.)
+ PrintToValNode(&stp, "%#7.3lg", kbp->H);
+ else
+ PrintToValNode(&stp, " NA ");
+
+
+ if (pbp->gapped_calculation)
+ {
+ PrintNewLineToValNode(&stp);
+
+ PrintToValNode(&stp, "Gapped");
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp, "Lambda K H");
+ PrintNewLineToValNode(&stp);
+ kbp = sbp->kbp_gap[0];
+
+ if (kbp->Lambda > 0.)
+ PrintToValNode(&stp, "%#8.3lg ", kbp->Lambda);
+ else
+ PrintToValNode(&stp, " NA ");
+ if (kbp->K > 0.)
+ PrintToValNode(&stp, "%#7.3lg ", kbp->K);
+ else
+ PrintToValNode(&stp, " NA ");
+ if (kbp->H > 0.)
+ PrintToValNode(&stp, "%#7.3lg", kbp->H);
+ else
+ PrintToValNode(&stp, " NA ");
+
+ PrintNewLineToValNode(&stp);
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp, "OpenGap ExtendGap GapX trigger gapping");
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp, "%ld %ld %ld %3.1f",
+ (long) pbp->gap_open, (long) pbp->gap_extend, (long) pbp->gap_x_dropoff, pbp->gap_trigger);
+ }
+
+ PrintNewLineToValNode(&stp);
+ PrintNewLineToValNode(&stp);
+
+ if (pbp->two_pass_method == FALSE)
+ {
+ PrintToValNode(&stp, "E S T X");
+ }
+ else
+ {
+ PrintToValNode(&stp, "Cutoff to enter 2nd pass: >= %ld (%4.1f bits)", pbp->cutoff_s_first, pbp->number_of_bits);
+ PrintNewLineToValNode(&stp);
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp, "E S T1 T2 X1 X2 W Gap");
+ }
+
+ PrintNewLineToValNode(&stp);
+
+ if (pbp->two_pass_method == FALSE)
+ {
+ PrintToValNode(&stp, "%3.1f %ld %ld %ld",
+ pbp->cutoff_e, (long) pbp->cutoff_s, (long) pbp->threshold_second, (long) ABS(pbp->X));
+ }
+ else
+ {
+ PrintToValNode(&stp, "%3.1f %ld %ld %ld %ld %ld %ld %ld",
+ pbp->cutoff_e, (long) pbp->cutoff_s, (long) pbp->threshold_first, (long) pbp->threshold_second, (long) pbp->dropoff_1st_pass, (long) pbp->dropoff_2nd_pass, pbp->window_size, pbp->gap_size);
+ }
+
+ PrintNewLineToValNode(&stp);
+ PrintNewLineToValNode(&stp);
+
+ dbdesc = MakeBLAST0DbDesc(search->rdfp);
+ if (dbdesc)
+ {
+ PrintToValNode(&stp, "Database: %s", dbdesc->def);
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp, " Posted date: %s", dbdesc->bld_date);
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp, "# of letters in database: %s", Ultostr(dbdesc->totlen,1));
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp, "# of sequences in database: %s", Ultostr(dbdesc->count,1));
+ PrintNewLineToValNode(&stp);
+ }
+ dbdesc = BLAST0DbDescFree(dbdesc);
+
+ PrintNewLineToValNode(&stp);
+
+ if (stats)
+ {
+ if (pbp->two_pass_method == FALSE)
+ {
+ PrintToValNode(&stp,
+ "Number of Hits to DB: %ld", search->second_pass_hits);
+ PrintNewLineToValNode(&stp);
+
+ PrintToValNode(&stp,
+ "Number of Sequences: %ld", readdb_get_num_entries(search->rdfp));
+ PrintNewLineToValNode(&stp);
+
+ PrintToValNode(&stp,
+ "Number of extensions: %ld", search->second_pass_extends);
+ PrintNewLineToValNode(&stp);
+
+ PrintToValNode(&stp,
+ "Number of successful extensions: %ld", search->second_pass_good_extends);
+ }
+ else
+ {
+ PrintNewLineToValNode(&stp);
+ PrintNewLineToValNode(&stp);
+
+ PrintToValNode(&stp,
+ "Number of Hits to DB: 1st pass: %ld, 2nd pass: %ld",
+ search->first_pass_hits, search->second_pass_hits);
+ PrintNewLineToValNode(&stp);
+
+ PrintToValNode(&stp,
+ "Number of Sequences: 1st pass: %ld, 2nd pass: %ld",
+ readdb_get_num_entries(search->rdfp), search->second_pass_trys);
+ PrintNewLineToValNode(&stp);
+
+ PrintToValNode(&stp,
+ "Number of extensions: 1st pass: %ld, 2nd pass: %ld",
+ search->first_pass_extends, search->second_pass_extends);
+ PrintNewLineToValNode(&stp);
+
+ PrintToValNode(&stp,
+ "Number of successful extensions: 1st pass: %ld, 2nd pass: %ld",
+ search->first_pass_good_extends, search->second_pass_good_extends);
+ }
+
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp,
+ "Number of sequences better than %ld: %ld", (long) pbp->cutoff_e, (long) search->number_of_seqs_better_E);
+
+ PrintNewLineToValNode(&stp);
+ PrintNewLineToValNode(&stp);
+
+ if (pbp->gapped_calculation)
+ {
+ PrintToValNode(&stp,
+ "Number of HSP's better than %ld without gapping: %ld", (long) pbp->cutoff_e, (long) search->prelim_gap_no_contest);
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp,
+ "Number of HSP's successfully gapped in prelim test: %ld", (long) search->prelim_gap_passed);
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp,
+ "Number of HSP's that attempted gapping in prelim test: %ld", (long) search->prelim_gap_attempts);
+ PrintNewLineToValNode(&stp);
+ PrintToValNode(&stp,
+ "Number of HSP's gapped (non-prelim): %ld", (long) search->real_gap_number_of_hsps);
+ PrintNewLineToValNode(&stp);
+
+
+ }
+ }
+
+ return stp;
+}
+/*
+ PrintToValNode and PrintNewLineToValNode (originally from
+ Warren Gish) are used to print strings to a ValNodePtr.
+ These are AsnWritten and decoded by the client.
+
+*/
+
+static void
+#ifdef VAR_ARGS
+PrintToValNode(stk, format, va_alist)
+ ValNodePtr PNTR stk;
+ char *format;
+ va_dcl
+#else
+PrintToValNode(ValNodePtr PNTR stk, char * format, ...)
+#endif
+{
+ va_list args;
+ char buf[4096];
+
+ if (stk == NULL)
+ return;
+
+#ifdef VAR_ARGS
+ va_start(args);
+#else
+ va_start(args, format);
+#endif
+ vsprintf(buf, format, args);
+ va_end(args);
+
+ ValNodeCopyStr(stk, 0, buf);
+}
+
+/*
+ This function prints a NULLB to the ValNodePtr. This
+ indicates to the formatting programs (BlastPrintValNodeStack
+ in blast2) that a new-line should be inserted.
+*/
+static void
+PrintNewLineToValNode(ValNodePtr PNTR stp)
+{
+ if (stp == NULL)
+ return;
+ ValNodeCopyStr(stp, 0, "");
+}
diff --git a/network/blast2/client/blastasn.h b/network/blast2/client/blastasn.h
new file mode 100644
index 00000000..6c7aa820
--- /dev/null
+++ b/network/blast2/client/blastasn.h
@@ -0,0 +1,78 @@
+/* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================*/
+/*****************************************************************************
+
+File name: blastasn.h
+
+Author: Tom Madden
+
+Contents: prototypes for functions that produce blast18 ASN.1 from
+ BLAST structures.
+
+******************************************************************************/
+
+/* $Revision: 6.0 $ */
+/* $Log: blastasn.h,v $
+/* Revision 6.0 1997/08/25 18:34:00 madden
+/* Revision changed to 6.0
+/*
+ * Revision 1.3 1996/11/27 18:04:28 madden
+ * Added prototype for MakeBLAST0DbDesc
+ *
+ * Revision 1.2 1996/09/25 20:03:06 madden
+ * Added prototype for GetParameterStack.
+ *
+ * Revision 1.1 1996/08/07 14:07:13 madden
+ * Initial revision
+ *
+ * */
+#ifndef __BLASTASN__
+#define __BLASTASN__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <blast.h>
+#include <blastkar.h>
+#define NLM_GENERATED_CODE_PROTO /* Needed to get Scores_scaled_intsPtr*/
+#include <blast18p.h> /* Patch for score-set */
+#include <objblst2.h>
+
+
+BLAST0ResultPtr LIBCALL MakeBLAST0Result PROTO((BlastSearchBlkPtr search, Boolean get_query_seq, Boolean get_db_seq));
+
+BLAST0MatrixPtr LIBCALL GetBLAST0Matrix PROTO((BLAST_ScoreBlkPtr sbp, Boolean fullreport));
+
+BLAST0KABlkPtr LIBCALL GetBLAST0KABlk PROTO((BLAST_ScoreBlkPtr sbp));
+
+ValNodePtr LIBCALL GetParameterStack PROTO((BlastSearchBlkPtr search, ValNodePtr stp, Boolean old, Boolean stats));
+
+/* Produce a BLAST0DbDesc from the ReadDBFILEPtr. */
+BLAST0DbDescPtr LIBCALL MakeBLAST0DbDesc PROTO((ReadDBFILEPtr rdfp));
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !__BLASTASN__ */
diff --git a/network/blast2/client/blastcl2.c b/network/blast2/client/blastcl2.c
new file mode 100644
index 00000000..ad4a7535
--- /dev/null
+++ b/network/blast2/client/blastcl2.c
@@ -0,0 +1,572 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: blastcl2.c
+*
+* Author: Roman L. Tatusov, Jonathan Epstein, Tom Madden
+*
+* Version Creation Date: 06/16/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Simulates "traditional" BLAST output
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: blastcl2.c,v $
+* Revision 6.0 1997/08/25 18:34:02 madden
+* Revision changed to 6.0
+*
+* Revision 5.3 1996/07/26 13:09:52 madden
+* Added option to adjust level of dust filtering.
+*
+ * Revision 5.2 1996/06/12 18:06:18 madden
+ * Added filtering (dust or seg) as an option ("-f").
+ *
+ * Revision 5.1 1996/06/04 12:19:37 madden
+ * Removed define for MAX_SEQ_LEN.
+ *
+ * Revision 5.0 1996/05/28 14:09:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.9 1996/05/22 12:52:10 madden
+ * Removed unused variable "ptr".
+ *
+ * Revision 4.8 1996/05/06 13:15:34 madden
+ * Added "PRE" messages around Motd for HTML format.
+ *
+ * Revision 4.7 1996/05/03 21:54:45 madden
+ * Added options to produce HTML format and suppress motd.
+ *
+ * Revision 4.6 1996/04/04 22:43:07 madden
+ * Added "queue" progress monitor.
+ *
+ * Revision 4.5 1996/02/24 19:02:54 madden
+ * Removed second (superfluous) "main" function that did not use GetArgs.
+ *
+ * Revision 4.4 1995/10/24 15:57:56 madden
+ * removed PrintTemplate stuff, cleaned up.
+ *
+ * Revision 4.3 1995/09/01 16:46:01 madden
+ * Change to callback procedure so submissions can be cancelled.
+ *
+ * Revision 4.2 1995/08/15 13:06:12 madden
+ * Removed unused SeqAnnotPtr (sap) from function blast.
+ *
+ * Revision 4.1 1995/08/03 21:21:10 madden
+ * replaced fprintf to stderr with ErrPostEx.
+ *
+ * Revision 4.0 1995/07/26 13:55:34 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.6 1995/07/25 15:02:28 madden
+ * Error messages returned from server printed out.
+ *
+ * Revision 1.5 1995/07/24 17:34:02 madden
+ * Changed HitData to BLAST0Result
+ *
+ * Revision 1.4 1995/07/12 17:45:25 madden
+ * Call BlastBioseq with new argument to perform masking.
+ *
+ * Revision 1.3 1995/06/23 22:14:00 madden
+ * sixth argument in BlastBioseq call is now zero, rather than NULL.
+ *
+ * Revision 1.2 1995/06/22 17:08:16 madden
+ * Added "output" argument to call to BlastBioseq.
+ *
+ * Revision 1.1 1995/06/16 11:26:33 epstein
+ * Initial revision
+ *
+ * Revision 1.16 95/05/17 17:59:18 epstein
+ * add RCS log revision history
+ *
+*/
+#define BLASTCLI_BUF_SIZE 255
+#include <sequtil.h>
+#include <prtutil.h>
+#include <tofasta.h>
+#include <netblap2.h>
+#include <dust.h>
+
+
+/* find the last nucleotide bioseq in the bioseqset */
+static void FindNuc(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
+{
+ BioseqPtr PNTR bp;
+ BioseqPtr local_bsp;
+
+ bp = (BioseqPtr PNTR) data;
+ if (IS_Bioseq(sep))
+ {
+ local_bsp = (BioseqPtr) sep->data.ptrvalue;
+ if (ISA_na(local_bsp->mol))
+ *bp = local_bsp;
+ }
+}
+
+/* find the last protein bioseq in the bioseqset */
+static void FindProt(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
+{
+ BioseqPtr PNTR bp;
+ BioseqPtr local_bsp;
+
+ bp = (BioseqPtr PNTR) data;
+ if (IS_Bioseq(sep))
+ {
+ local_bsp = (BioseqPtr) sep->data.ptrvalue;
+ if (ISA_aa(local_bsp->mol))
+ *bp = local_bsp;
+ }
+}
+/*
+ Montior hook to print to stderr for UNIX clients.
+*/
+
+static int LIBCALLBACK UNIXMontiorHook(Nlm_MonitorPtr mon, MonCode code)
+
+{
+ switch (code)
+ {
+#ifdef OS_UNIX
+ case MonCode_Create :
+ fprintf(stderr, "%s\n", (Nlm_CharPtr) mon->strTitle);
+ break;
+ case MonCode_StrValue :
+ fprintf(stderr, "%s\n", (Nlm_CharPtr) mon->strValue);
+ break;
+#endif
+ default :
+ break;
+ }
+ return 0;
+
+}
+
+/********************************************************************
+*
+* Add a string ("option" to the buffer). "length" gives the
+* total length of the buffer. If option can be added then
+* TRUE is returned, otherwise FALSE is returned.
+********************************************************************/
+
+static Boolean
+AddOptionToBuffer(CharPtr buffer, CharPtr option, Int2 length)
+
+{
+ CharPtr ptr=buffer;
+ Int2 count=0;
+
+ if (option == NULL)
+ return TRUE;
+
+ while(*ptr != NULLB)
+ {
+ ptr++;
+ count++;
+ }
+
+ if ((count+StringLen(option)) >= length)
+ return FALSE;
+ else
+ {
+ while (*option !=NULLB)
+ {
+ *ptr=*option;
+ ptr++;
+ option++;
+ }
+ *ptr=' ';
+ ptr++;
+ *ptr=NULLB;
+ }
+ return TRUE;
+}
+
+/*
+ Callback to show progress in Queue, NOT in actual calculation
+ of results.
+*/
+
+static Boolean LIBCALLBACK
+callback (BLAST0ResponsePtr brp, Boolean PNTR cancel)
+{
+ static MonitorPtr mon = NULL;
+ Boolean retval;
+ BLAST0QueuedPtr queue;
+ Char buffer[40];
+
+ if (brp->choice == BLAST0Response_queued)
+ {
+#ifdef OS_UNIX
+ Nlm_SetMonitorHook(UNIXMontiorHook);
+#endif
+ if((queue=brp->data.ptrvalue) == NULL)
+ return FALSE;
+
+ if (mon == NULL)
+ {
+ sprintf(buffer, "Waiting for %ld jobs to finish", queue->length);
+ mon=Nlm_MonitorStrNew (buffer, 40);
+ }
+ else
+ {
+ retval = Nlm_MonitorStrValue (mon, "still waiting");
+ if (retval == FALSE)
+ { /* If cancelled, then shutdown monitor */
+ *cancel = TRUE;
+ mon = MonitorFree(mon);
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ else
+ {
+ if (mon != NULL)
+ mon = MonitorFree(mon);
+
+ }
+ return FALSE;
+}
+
+static void
+PrintMotd(BLAST0ResponsePtr blastResponse, FILE *fp, Boolean html_format)
+
+{
+ Char buffer[100];
+ CharPtr string, ptr;
+
+ if (blastResponse->choice != BLAST0Response_motd)
+ return;
+
+ string = blastResponse->data.ptrvalue;
+ if (string == NULL)
+ return;
+
+ buffer[0] = NULLB;
+ ptr = buffer;
+
+ if (html_format)
+ {
+ fprintf(fp, "<PRE>\n");
+ }
+
+ while (*string != NULLB)
+ {
+ if (*string == '~')
+ {
+ *ptr = NULLB;
+ fprintf(fp, "%s\n", buffer);
+ buffer[0] = NULLB;
+ ptr = buffer;
+ string++;
+ if (*string == NULLB)
+ break;
+ }
+ else
+ {
+ *ptr=*string;
+ ptr++; string++;
+ }
+ }
+ *ptr = NULLB;
+ fprintf(fp, "%s\n", buffer);
+
+ if (html_format)
+ {
+ fprintf(fp, "</PRE>\n");
+ }
+
+ fflush(fp);
+}
+
+/***********************************************************************
+* This function gets the Message-Of-The-Day, submits a request
+* using BlastBioseq, formats the output, and reports any error
+* messages.
+***********************************************************************/
+static Int2 blast(BioseqPtr bsp, CharPtr blast_program, CharPtr blast_database, CharPtr cmd_options, Boolean HTML_option, Boolean print_motd, SeqLocPtr dust_slp, FILE *outfp)
+
+{
+ BLAST0PrefacePtr preface;
+ BLAST0RequestPtr blreqp;
+ BLAST0ResponsePtr brp, brp1, blastResponse;
+ BLAST0ResultPtr result;
+ BLAST0StatusPtr status;
+ ValNodePtr vnp;
+
+ if (bsp == NULL) {
+ ErrPostEx(SEV_FATAL, 0, 0, "Couldn't read sequences");
+ return (5);
+ }
+#ifdef MAX_SEQ_LEN
+ if (bsp != NULL && bsp->length > MAX_SEQ_LEN) {
+ ErrPostEx(SEV_FATAL, 0, 0, "Cannot process sequences > %d base pairs (this sequence is %d bp long)", MAX_SEQ_LEN, bsp->length);
+ return (4);
+ }
+#endif
+
+/* Get the MOTD from the server. */
+ if (print_motd)
+ {
+ blreqp = ValNodeNew(NULL);
+ blreqp->choice = BLAST0Request_motd;
+ blreqp->data.ptrvalue = StringSave(blast_program);
+ blastResponse = SubmitInfoRequest(blreqp);
+ blreqp->data.ptrvalue = MemFree(blreqp->data.ptrvalue);
+ blreqp = BLAST0RequestFree(blreqp);
+ if (blastResponse == NULL)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "BLAST connection to server failed");
+ return (3);
+ }
+ PrintMotd(blastResponse, outfp, HTML_option);
+ blastResponse = BLAST0ResponseFree(blastResponse);
+ }
+ brp = NULL;
+ result = BlastBioseq(bsp, blast_program, blast_database, cmd_options, &brp, dust_slp, 0, callback);
+ if (result != NULL)
+ {
+#ifdef DEBUG
+ AsnIoPtr aip;
+
+ aip = AsnIoOpen("blastout.asn", "w");
+ BLAST0ResultAsnWrite(result, aip, NULL);
+ AsnIoClose(aip);
+#endif /* DEBUG */
+ if (outfp != NULL)
+ {
+ if (HTML_option)
+ {
+ TraditionalBlastOutputHTML(result, brp, blast_program, outfp);
+ }
+ else
+ {
+ TraditionalBlastOutput(result, brp, blast_program, outfp);
+ }
+ result = BLAST0ResultFree(result);
+ while (brp)
+ {
+ brp1 = brp;
+ brp = brp->next;
+ brp1->next = NULL;
+ BLAST0ResponseFree(brp1);
+ }
+ }
+ else
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "FileOpen failed");
+ return (3);
+ }
+ }
+ else if ((CheckIfBlastJobCancelled()) == TRUE)
+ {
+ return (7);
+ }
+ else
+ {
+ if (brp)
+ {
+ if (brp->choice == BLAST0Response_status)
+ {
+ blreqp = ValNodeNew(NULL);
+ blreqp->choice = BLAST0Response_usage_info;
+ blreqp->data.ptrvalue = StringSave(blast_program);
+ blastResponse = SubmitInfoRequest(blreqp);
+ blreqp = BLAST0RequestFree(blreqp);
+ preface = blastResponse->data.ptrvalue;
+ vnp = preface->prog_usage;
+ print_usage(stderr, vnp);
+ status = brp->data.ptrvalue;
+ ErrPostEx(SEV_FATAL, 0, 0,
+ "%s\nEXIT CODE %ld", status->reason, status->code);
+ }
+ else
+ {
+ brp1 = brp->next;
+ while (brp1)
+ {
+ if (brp1->choice == BLAST0Response_status)
+ {
+ status = brp1->data.ptrvalue;
+ ErrPostEx(SEV_FATAL, 0, 0,
+ "%s\nEXIT CODE %ld", status->reason, status->code);
+ }
+ brp1 = brp1->next;
+ }
+ }
+ }
+ else
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "BLAST search failed");
+ return (3);
+ }
+ }
+
+ return 0;
+}
+
+#define NUMARG 9
+
+static Args myargs [NUMARG] = {
+ { "Program Name (blastn,blastp,blastx,tblastn,tblastx)", "", NULL, NULL, FALSE, 'p', ARG_STRING, 0.0, 0, NULL},
+ { "Database", "nr", NULL, NULL, FALSE, 'd', ARG_STRING, 0.0, 0, NULL},
+ { "Query File", "stdin", NULL, NULL, FALSE, 'i', ARG_FILE_IN, 0.0, 0, NULL},
+ { "Output File", "stdout", NULL, NULL, FALSE, 'o', ARG_FILE_OUT, 0.0, 0, NULL},
+ { "HTML format", "F", NULL, NULL, FALSE, 'h', ARG_BOOLEAN, 0.0, 0, NULL},
+ { "print MOTD", "T", NULL, NULL, FALSE, 'm', ARG_BOOLEAN, 0.0, 0, NULL},
+ { "filter query sequence (nucleotides with dust, proteins with seg)", "F", NULL, NULL, FALSE, 'f', ARG_BOOLEAN, 0.0, 0, NULL},
+ { "level of dust filtering", "-1", NULL, NULL, FALSE, 'l', ARG_INT, 0.0, 0, NULL},
+ { "BLAST options (enclosed in double quotes, separated by spaces)", NULL, NULL, NULL, TRUE, 'b', ARG_STRING, 0.0, 0, NULL}
+};
+
+/*********************************************************************
+* "main" function to call blast for the client.
+*
+* This function checks the command-line arguments, opens the
+* connection to the server, processes all the entries in
+* the FASTA file (obtained using FastaToSeqEntry), and
+* closes the connection.
+*********************************************************************/
+Int2 Main (void)
+
+{
+ CharPtr blast_program;
+ CharPtr blast_database;
+ CharPtr blast_inputfile;
+ CharPtr blast_outputfile;
+ CharPtr blast_params;
+ Char buffer[BLASTCLI_BUF_SIZE+1];
+ Boolean isprot = FALSE;
+ BioseqPtr bsp;
+ Int2 num_of_queries, retval;
+ SeqEntryPtr sep;
+ SeqLocPtr dust_slp=NULL;
+ FILE *fp, *outfp;
+
+ if (! GetArgs ("blastcli", NUMARG, myargs))
+ {
+ exit(1);
+ }
+
+ blast_program = myargs [0].strvalue;
+
+ if (blast_program == NULL)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0,
+ "blast: No name for BLAST program specified:\n");
+ return (2);
+ }
+
+ if (StringCmp(blast_program, "blastp") == 0 ) {
+ isprot = TRUE;
+ } else if (StringCmp(blast_program, "blastx") == 0) {
+ isprot = FALSE;
+ } else if (StringCmp(blast_program, "blastn") == 0) {
+ isprot = FALSE;
+ } else if (StringCmp(blast_program, "tblastn") == 0) {
+ isprot = TRUE;
+ } else if (StringCmp(blast_program, "tblastx") == 0) {
+ isprot = FALSE;
+ } else {
+ ErrPostEx(SEV_FATAL, 0, 0, "blast: Bad name for BLAST program: \"%s\"\n", blast_program);
+ exit(1);
+ }
+ blast_database = myargs [1].strvalue;
+ blast_inputfile = myargs [2].strvalue;
+ blast_outputfile = myargs [3].strvalue;
+
+ if ((fp = FileOpen(blast_inputfile, "r")) == NULL)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "blast: Unable to open input file %s\n", blast_inputfile);
+ return (1);
+ }
+ outfp = FileOpen (blast_outputfile, "w");
+
+ if (! BlastInit("blastcl2", FALSE)) {
+ ErrPostEx(SEV_FATAL, 0, 0, "Unable to initialize BLAST service");
+ return (1);
+ }
+
+ buffer[0] = NULLB;
+ AddOptionToBuffer(buffer, myargs[8].strvalue, BLASTCLI_BUF_SIZE);
+ if (myargs[6].intvalue)
+ {
+ if (StringCmp("blastn", blast_program) != 0)
+ AddOptionToBuffer(buffer, "-filter seg", BLASTCLI_BUF_SIZE);
+ }
+ if (buffer[0] != NULLB)
+ {
+ blast_params = StringSave(buffer);
+ }
+ else
+ {
+ blast_params = NULL;
+ }
+
+ num_of_queries=0;
+ retval=0;
+ while ((sep = FastaToSeqEntry(fp, !isprot)) != NULL)
+ {
+ bsp = NULL;
+ SeqEntryExplore(sep, &bsp, isprot? FindProt : FindNuc);
+ if (bsp == NULL)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "Unable to obtain bioseq\n");
+ retval = 2;
+ break;
+ }
+
+ if (myargs[6].intvalue)
+ {
+ if (StringCmp("blastn", blast_program) == 0)
+ dust_slp = BioseqDust(bsp, 0, -1, myargs[7].intvalue, -1, -1, -1);
+ }
+
+ /* Put a space between the reports. */
+ if (num_of_queries != 0)
+ fprintf(outfp, "\n");
+ retval = blast(bsp, blast_program, blast_database, blast_params, myargs [4].intvalue, myargs [5].intvalue, dust_slp, outfp);
+ if (retval != 0)
+ break;
+
+ if (dust_slp)
+ dust_slp = SeqLocSetFree(dust_slp);
+
+ num_of_queries++;
+ }
+ FileClose(fp);
+ FileClose (outfp);
+ BlastFini();
+ return retval;
+}
diff --git a/network/blast2/client/blastcli.c b/network/blast2/client/blastcli.c
new file mode 100644
index 00000000..aa00ac1f
--- /dev/null
+++ b/network/blast2/client/blastcli.c
@@ -0,0 +1,1292 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: blastcli.c
+*
+* Author: Tom Madden
+*
+* Version Creation Date: 08/22/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Simulates "traditional" BLAST output
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: blastcli.c,v $
+* Revision 6.0 1997/08/25 18:34:05 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1997/04/11 15:18:38 madden
+* Removed static function callbackWithMon, used Blast2callbackWithMon instead.
+*
+ * Revision 5.0 1996/05/28 14:09:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 1.39 1996/04/25 16:51:56 kans
+ * added file and edit menus to main window
+ *
+ * Revision 1.38 1996/04/23 21:26:41 madden
+ * Added version number, hello message; cleaned out unused variable.
+ *
+ * Revision 1.37 1996/04/18 13:04:17 madden
+ * Moved sequence input window into main window.
+ *
+ * Revision 1.36 1996/04/17 14:37:41 madden
+ * Replaced many calls to "TraditionalBlast..." functions with call to
+ * TraditionalBlastOutput. Replaced Histogram check-box with Show GI
+ * checkbox.
+ *
+ * Revision 1.35 1996/04/17 13:59:07 madden
+ * Added "Dismiss" and "Clear" buttons to sequence input window.
+ *
+ * Revision 1.34 1996/04/16 20:56:14 madden
+ * Sequence can now be entered from a window.
+ *
+ * Revision 1.33 1996/04/16 19:16:51 madden
+ * Removed old functions used only with command-line interface.
+ *
+ * Revision 1.32 1996/04/16 19:10:04 madden
+ * Bioseq now found in PerformBlastSearch rather than Calculate.
+ *
+ * Revision 1.31 1996/04/12 19:21:27 madden
+ * Added "queue" monitor that shows when job is waiting to start.
+ *
+ * Revision 1.30 1996/03/25 17:34:09 shavirin
+ * Changes due to new function TraditionalBlastOutputHTML(),
+ * that produce HTML output from the BLAST server
+ *
+ * Revision 1.29 1996/03/19 21:24:27 madden
+ * Removed opening of non-existent file under windows.
+ *
+ * Revision 1.28 1996/03/18 19:23:25 madden
+ * Removed suggested output file for DOS and windows.
+ *
+ * Revision 1.27 1996/03/15 17:00:14 madden
+ * Popup menu added for database list.
+ *
+ * Revision 1.26 1996/02/23 22:39:10 kans
+ * removed extraneous fileclose, moved fileremove
+ *
+ * Revision 1.25 1995/12/15 15:03:21 epstein
+ * add small-screen support
+ *
+ * Revision 1.24 1995/10/18 21:33:34 madden
+ * Added check that blastResponse is not NULL before dereferencing it.
+ *
+ * Revision 1.23 1995/10/17 15:04:18 madden
+ * Changes to accommodate CheckIfBlastJobCancelled.
+ *
+ * Revision 1.22 1995/10/16 21:43:28 madden
+ * Changes to support command-line version of blastcli.
+ *
+ * Revision 1.21 1995/09/06 12:47:30 madden
+ * Added message to help facility.
+ *
+ * Revision 1.20 1995/09/05 18:09:46 madden
+ * missing BlastFini added in.
+ *
+ * Revision 1.19 1995/09/05 18:06:56 madden
+ * Removed commented out callback function.
+ *
+ * Revision 1.18 1995/09/05 18:05:56 madden
+ * BlastInits moved to avoid a problem.
+ *
+ * Revision 1.17 1995/09/05 17:20:38 madden
+ * FileClose called before DisplayFile.
+ *
+ * Revision 1.16 1995/09/05 15:21:32 madden
+ * Changed BLASTCLI_SMALL_BUF_SIZE to PATH_MAX on TmpNam call.
+ *
+ * Revision 1.15 1995/09/01 22:07:02 madden
+ * converted some variable to "static" if they are only referenced in this file.
+ *
+ * Revision 1.14 1995/09/01 22:00:25 madden
+ * Input file now read in with GetInputFileName.
+ *
+ * Revision 1.13 1995/09/01 16:43:11 madden
+ * Changes to allow cancellation of jobs.
+ *
+ * Revision 1.12 1995/09/01 15:05:41 madden
+ * enable "dismiss" button when another window is open.
+ *
+ * Revision 1.11 1995/09/01 13:36:40 madden
+ * Default output file now named after input file.
+ *
+ * Revision 1.10 1995/08/31 22:02:30 madden
+ * Added a second Main function that uses GetArgs.
+ *
+ * Revision 1.9 1995/08/31 20:53:23 madden
+ * WIN_DUMB added as an ifndef.
+ *
+ * Revision 1.8 1995/08/31 15:02:27 madden
+ * Moved num_of_descrp, num_of_align, num_of_expected to global variables.
+ *
+ * Revision 1.7 1995/08/31 14:21:33 madden
+ * Added (number) extension to output file name.
+ *
+ * Revision 1.6 1995/08/31 12:04:41 madden
+ * Changed from desktop GetArgs to customized Vibrant interface.
+ *
+ * Revision 1.5 1995/08/29 21:51:04 madden
+ * removed unused variables that were lint complaints.
+ *
+ * Revision 1.4 1995/08/29 13:39:30 madden
+ * Request no matrix or sequence data if alignments will not be shown.
+ *
+ * Revision 1.3 1995/08/28 21:24:46 madden
+ * corrected index on myargs for call to AddOptionToBuffer.
+ *
+ * Revision 1.2 1995/08/28 17:34:18 madden
+ * replaced custom functions with call to GetOutputFileName.
+ *
+ * Revision 1.1 1995/08/25 22:35:04 madden
+ * Initial revision
+ * */
+
+#include <ncbi.h>
+#include <sequtil.h>
+#include <prtutil.h>
+#include <tofasta.h>
+#include <netblap2.h>
+#include <dust.h>
+#include <vibrant.h>
+#include <document.h>
+#include <blast2.h>
+
+/* If WIN_DUMB is defined, don't use vibrant. */
+#ifndef WIN_DUMB
+#define BLASTCLI_WITH_VIBRANT
+#endif
+
+#define X_VIEW 750
+#define Y_VIEW 500
+
+#define BLASTCLI_SMALL_BUF_SIZE 25
+#define BLASTCLI_BUF_SIZE 100
+
+static DoC document;
+static Nlm_WindoW results_window=NULL;
+static Nlm_TexT input_text=NULL, sequence=NULL;
+static ButtoN options_button, dismiss_button, submit_button, help_button;
+
+CharPtr blast_output=NULL, new_blast_output=NULL, blast_program=NULL;
+
+/* The following (global) variables are used as input for the BLAST
+programs. The large number of variables is to accomodate a command-line
+GetArgs interface and a customized vibrant interface. */
+static Boolean complex_filter, /* Mask low-complexity (dust on blastn, others seg). */
+ get_gi; /* Should gi's be displayed? */
+
+/* The vibrant version stores the info in these buffers (e.g., expect_buffer),
+the information is then read into the Int4 below (e.g., num_of_expected). */
+static Char
+ expect_buffer[BLASTCLI_SMALL_BUF_SIZE],
+ descrp_buffer[BLASTCLI_SMALL_BUF_SIZE],
+ align_buffer[BLASTCLI_SMALL_BUF_SIZE],
+ expert_options[BLASTCLI_BUF_SIZE],
+ score_buffer[BLASTCLI_SMALL_BUF_SIZE],
+ score2_buffer[BLASTCLI_SMALL_BUF_SIZE],
+ blast_inputfile[PATH_MAX],
+ blast_database[BLASTCLI_SMALL_BUF_SIZE];
+
+static Int4 score, score2, num_of_descrp, num_of_align, num_of_expected;
+
+/* contains list of databases, filled in GetListOfDatabases */
+static ValNodePtr database_vnp=NULL;
+
+static void PrintMotd PROTO((BLAST0ResponsePtr blastResponse, FILE *fp));
+
+static void PrintBlastOptions PROTO((FILE *fp, BLAST0ResponsePtr brp));
+
+static Int2 PerformBlastSearch PROTO((BioseqPtr bsp));
+
+static Boolean AddOptionToBuffer PROTO((CharPtr buffer, CharPtr option, Int2 length));
+
+static void PresentReportPanel PROTO((FILE *outfp));
+
+
+/*
+ Clears the window users paste sequence into.
+*/
+static void ClearSeqInputWindow (ButtoN b)
+{
+ SetTitle(sequence, "");
+
+}
+
+
+static void HideResultsWindow (IteM i)
+{
+ if (results_window)
+ Hide(results_window);
+/* These were disabled in PresentReportPanel */
+ Enable(help_button);
+ Enable(options_button);
+ Enable(submit_button);
+/* Select this to keep the dismiss button from becoming the default. */
+ Select(input_text);
+}
+
+static void ButtonQuitProc (ButtoN b)
+{
+ QuitProgram();
+}
+
+static void ItemQuitProc (IteM i)
+{
+ QuitProgram();
+}
+
+/*
+ A function to check that the database and the blast program
+ are compatible.
+
+ CharPtr program: name of program, e.g., blastn, blastp, etc.
+ CharPtr database: database name, e.g., "nr", "est", etc.
+ ValNodePtr vnp: ValNodePtr containing list of DB's (created in
+ function GetListOfDatabases).
+*/
+
+static Boolean
+VerifyProgramDbCompatibility(CharPtr program, CharPtr database, ValNodePtr dblist)
+
+{
+ Uint2 type=0;
+
+ if (program == NULL || *program == NULLB || database == NULL
+ || *database == NULLB)
+ return FALSE;
+
+ for (dblist; dblist; dblist=dblist->next)
+ {
+ if (StringICmp(dblist->data.ptrvalue, database) == 0)
+ {
+ type = dblist->choice;
+ break;
+ }
+ }
+
+ if (type == 0) /* Not found or not set. */
+ return FALSE;
+
+/* Check for compatability. */
+ if ((type == BLAST0_Alphatype_nucleic_acid
+ && StringICmp("blastn", blast_program) != 0
+ && StringICmp("tblastn", blast_program) != 0
+ && StringICmp("tblastx", blast_program) != 0)
+ || (type == BLAST0_Alphatype_amino_acid
+ && StringICmp("blastp", blast_program) != 0
+ && StringICmp("blastx", blast_program) != 0))
+ {
+ ErrPostEx(SEV_WARNING, 0, 0, "Incorrect Database type for %s search", blast_program);
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+/* find the last nucleotide bioseq in the bioseqset */
+static void FindNuc(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
+{
+ BioseqPtr PNTR bp;
+ BioseqPtr local_bsp;
+
+ bp = (BioseqPtr PNTR) data;
+ if (IS_Bioseq(sep))
+ {
+ local_bsp = (BioseqPtr) sep->data.ptrvalue;
+ if (ISA_na(local_bsp->mol))
+ *bp = local_bsp;
+ }
+}
+
+/* find the last protein bioseq in the bioseqset */
+static void FindProt(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
+{
+ BioseqPtr PNTR bp;
+ BioseqPtr local_bsp;
+
+ bp = (BioseqPtr PNTR) data;
+ if (IS_Bioseq(sep))
+ {
+ local_bsp = (BioseqPtr) sep->data.ptrvalue;
+ if (ISA_aa(local_bsp->mol))
+ *bp = local_bsp;
+ }
+}
+
+static void Calculate (ButtoN b)
+{
+ Int2 retval;
+ BioseqPtr bsp;
+ Boolean isprot;
+ CharPtr input_sequence, last_char;
+ SeqEntryPtr sep;
+ FILE *infp;
+
+
+ if (blast_program == NULL || *blast_program == NULLB)
+ {
+ ErrPostEx(SEV_WARNING, 0, 0,
+ "BLAST program name required for search");
+ return;
+ }
+
+ if (StringCmp(blast_program, "blastp") == 0 ) {
+ isprot = TRUE;
+ } else if (StringCmp(blast_program, "blastx") == 0) {
+ isprot = FALSE;
+ } else if (StringCmp(blast_program, "blastn") == 0) {
+ isprot = FALSE;
+ } else if (StringCmp(blast_program, "tblastn") == 0) {
+ isprot = TRUE;
+ } else if (StringCmp(blast_program, "tblastx") == 0) {
+ isprot = FALSE;
+ } else {
+ ErrPostEx(SEV_WARNING, 0, 0, "blast: Bad name for BLAST program: \"%s\"\n", blast_program);
+ return;
+ }
+
+ if (blast_inputfile[0] != NULLB)
+ {
+ if ((infp = FileOpen(blast_inputfile, "r")) == NULL)
+ {
+ ErrPostEx(SEV_WARNING, 0, 0, "blast: Unable to open input file %s\n", blast_inputfile);
+ return ;
+ }
+
+ sep = FastaToSeqEntry(infp, !isprot);
+ FileClose(infp);
+ }
+ else if ((input_sequence=SaveStringFromText(sequence)) != NULL)
+ {
+ last_char = NULL;
+ sep = FastaToSeqBuff(input_sequence, &last_char, !isprot);
+ input_sequence = MemFree(input_sequence);
+ }
+ else
+ {
+ ErrPostEx(SEV_WARNING, 0, 0, "No input file or sequence specified\n");
+ return;
+ }
+
+
+ bsp = NULL;
+ SeqEntryExplore(sep, &bsp, isprot? FindProt : FindNuc);
+ if (bsp == NULL)
+ {
+ ErrPostEx(SEV_WARNING, 0, 0, "Unable to obtain sequence\n");
+ return;
+ }
+
+
+ if (blast_database == NULLB || *blast_database == NULLB)
+ {
+ ErrPostEx(SEV_WARNING, 0, 0, "Database name required");
+ return;
+ }
+
+ if (VerifyProgramDbCompatibility(blast_program, blast_database, database_vnp) == FALSE)
+ return;
+
+ input_sequence = SaveStringFromText(sequence);
+
+ WatchCursor();
+/* These must be disabled to prevent conflicts. */
+ Disable(help_button);
+ Disable(options_button);
+ Disable(submit_button);
+/* Select this to keep the dismiss button from becoming the default. */
+ Select(input_text);
+
+ sscanf(descrp_buffer, "%ld", &num_of_descrp);
+ sscanf(align_buffer, "%ld", &num_of_align);
+ sscanf(expect_buffer, "%ld", &num_of_expected);
+ score=0;
+ if (score_buffer[0] != NULLB && StringCmp(score_buffer, "default") != 0)
+ sscanf(score_buffer, "%ld", &score);
+ score2=0;
+ if (score2_buffer[0] != NULLB &&
+ StringCmp(score2_buffer, "default") != 0)
+ sscanf(score2_buffer, "%ld", &score2);
+ retval = PerformBlastSearch(bsp);
+
+ if (retval != 0)
+ { /* Panel never displayed */
+ Enable(help_button);
+ Enable(options_button);
+ Enable(submit_button);
+/* Select this to keep the dismiss button from becoming the default. */
+ Select(input_text);
+ }
+
+ ArrowCursor();
+
+ if (sep)
+ sep = SeqEntryFree(sep);
+
+ return;
+}
+
+static void GetOptionHelp (ButtoN b)
+{
+ FILE *outfp;
+
+ if (blast_program == NULL || *blast_program == NULLB)
+ {
+ ErrPostEx(SEV_WARNING, 0, 0,
+ "BLAST program name required for option list");
+ return;
+ }
+
+ blast_output = MemNew(PATH_MAX*sizeof(Char));
+ blast_output = TmpNam(blast_output);
+
+ outfp = FileOpen (blast_output, "w");
+ PrintBlastOptions(outfp, NULL);
+ FileRemove(blast_output);
+ blast_output = MemFree(blast_output);
+
+ return;
+}
+
+
+static void GetBlastHelp (ButtoN b)
+{
+
+ FILE *outfp;
+
+ blast_output = MemNew(PATH_MAX*sizeof(Char));
+ blast_output = TmpNam(blast_output);
+
+ outfp = FileOpen (blast_output, "w");
+ fprintf(outfp, "This help facility briefly describes the BLAST client interface. To obtain more BLAST documentation\n");
+ fprintf(outfp, "send a message consisting of just the word ``help'' (without quotes) to blast@ncbi.nlm.nih.gov\n\n");
+ fprintf(outfp, "BLAST Help\n\n");
+ fprintf(outfp, "Input FASTA file: file containing query sequence.\n\n");
+ fprintf(outfp, "BLAST program: select one from the popup menu, choices are:\n");
+ fprintf(outfp, " blastn: compares nt query with nt database.\n");
+ fprintf(outfp, " blastp: compares aa query with aa database.\n");
+ fprintf(outfp, " blastx: compares translated nt query with aa database.\n");
+ fprintf(outfp, " tblastn: compares aa query with translated nt database.\n");
+ fprintf(outfp, " tblastx: compares translated nt query with translated nt database.\n");
+ fprintf(outfp, " (tblastx is only available for smaller databases such as dBEST or dbSTS)\n\n");
+ fprintf(outfp, "Database: the default is non-redundant, or nr.\n\n");
+ fprintf(outfp, "Number of one-line descriptions: number of high-scoring database sequences to be summarized.\n\n");
+ fprintf(outfp, "Number of alignments: number of high-scoring database-query alignments to be shown.\n\n");
+ fprintf(outfp, "Expectation number: number of matches expected by chance alone.\n\n");
+ fprintf(outfp, "Minimum Score to report a database sequence:\n");
+ fprintf(outfp, " the default value is calculated from the Expectation number (above) and the database.\n\n");
+ fprintf(outfp, "Minimum Score to report an HSP:\n");
+ fprintf(outfp, " a database sequence may have multiple High-Scoring Sequence Pairs (HSP). This option\n");
+ fprintf(outfp, " sets a minimum score for each HSP, the default value depends on the program and database.\n\n");
+ fprintf(outfp, "Show GI's: if checked, GI's are reported\n\n");
+ fprintf(outfp, "Low-complexity filtering: for blastn dust is used, other programs use seg.\n\n");
+ fprintf(outfp, "Other (expert) BLAST options may be entered.\n\n");
+ fprintf(outfp, "A list of valid BLAST options may be requested from the server.\n\n");
+
+/* These must be disabled to prevent conflicts. */
+ Disable(help_button);
+ Disable(options_button);
+ Disable(submit_button);
+/* Select this to keep the dismiss button from becoming the default. */
+ Select(input_text);
+
+ if (new_blast_output)
+ new_blast_output = MemFree(new_blast_output);
+ new_blast_output = StringSave("blhelp");
+
+ PresentReportPanel(outfp);
+ FileRemove(blast_output);
+
+ blast_output = MemFree(blast_output);
+
+ return;
+}
+
+
+static void SaveAsProc (IteM i)
+{
+ Char buffer[PATH_MAX];
+ FILE *fp;
+
+ if(GetOutputFileName(buffer, PATH_MAX, new_blast_output))
+ {
+ if (buffer[0] != NULLB)
+ {
+ fp = FileOpen(buffer, "w");
+ SaveDocument(document, fp);
+ FileClose(fp);
+ HideResultsWindow(i);
+ }
+ }
+}
+
+static void
+GetProgramType(PopuP p)
+
+{
+ Int2 program_number;
+
+ if (blast_program != NULL)
+ blast_program = MemFree(blast_program);
+
+ program_number = GetValue (p);
+ if (program_number == 1)
+ blast_program = StringSave("blastn");
+ else if (program_number == 2)
+ blast_program = StringSave("blastp");
+ else if (program_number == 3)
+ blast_program = StringSave("blastx");
+ else if (program_number == 4)
+ blast_program = StringSave("tblastn");
+ else if (program_number == 5)
+ blast_program = StringSave("tblastx");
+ return;
+}
+
+/*
+ A Callback to get the database name selected by the user.
+*/
+static void
+GetDatabaseName(PopuP list)
+
+{
+ Int2 database_number, index;
+ ValNodePtr vnp;
+
+ database_number = GetValue (list);
+
+ for (vnp=database_vnp, index=0; vnp; vnp=vnp->next)
+ {
+ index++;
+ if (index == database_number)
+ break;
+ }
+ VerifyProgramDbCompatibility(blast_program, vnp->data.ptrvalue, database_vnp);
+
+ /* Set the string blast_database to the new db as the popup list
+ shows the new db as THE database. */
+ StringNCpy(blast_database, vnp->data.ptrvalue, BLASTCLI_SMALL_BUF_SIZE);
+ return;
+}
+
+/*
+ Gets the list of databases that apply to a give program.
+ May be called multiple times if the program used changes.
+
+ Two different databases with the same name (e.g., nr for
+ proteins and nucleic acids) are merged. The two "types"
+ (BLAST0_Alphatype_nucleic_acid and BLAST0_Alphatype_amino_acid)
+ are added together to show that the database applies to
+ both molecules.
+
+*/
+static void
+GetListOfDatabases (BLAST0ResponsePtr blresp)
+
+{
+ BLAST0DbDescPtr dbdesc, dbdesc1, last;
+ Uint2 type;
+
+ if (database_vnp)
+ database_vnp = ValNodeFreeData(database_vnp);
+
+ /* Collect list of database names. */
+ for (dbdesc=blresp->data.ptrvalue; dbdesc; dbdesc=dbdesc->next)
+ {
+ type = dbdesc->type;
+ /* Check for redundant names (e.g., "nr"). */
+ last = dbdesc;
+ dbdesc1 = dbdesc->next;
+ while (dbdesc1)
+ {
+ if (StringICmp(dbdesc->name, dbdesc1->name) == 0)
+ {
+ if (dbdesc1->type != type)
+ type += dbdesc1->type;
+ last->next = dbdesc1->next;
+ dbdesc1->next = NULL;
+ dbdesc1 = BLAST0DbDescFree(dbdesc1);
+ dbdesc1 = last->next;
+ }
+ else
+ {
+ last = dbdesc1;
+ dbdesc1 = dbdesc1->next;
+ }
+
+ }
+ ValNodeCopyStr(&database_vnp, type, dbdesc->name);
+ }
+}
+
+static void FileInActnProc (TexT text)
+
+{
+ GetTitle (text, blast_inputfile, PATH_MAX);
+ return;
+}
+
+static void GetInputFile (ButtoN b)
+{
+ Char buffer[PATH_MAX];
+
+ buffer[0] = NULLB;
+ if(GetInputFileName(buffer, PATH_MAX, "*", "TEXT"))
+ {
+
+ if (buffer[0] != NULLB)
+ {
+ StringNCpy(blast_inputfile, buffer, PATH_MAX);
+ SetTitle (input_text, blast_inputfile);
+ }
+ }
+ return;
+}
+
+static void ExpertOptionActnProc (TexT text)
+
+{
+ GetTitle (text, expert_options, BLASTCLI_BUF_SIZE);
+ return;
+}
+
+static void num_of_descrpActnProc (TexT text)
+
+{
+ GetTitle (text, descrp_buffer, BLASTCLI_SMALL_BUF_SIZE);
+ return;
+}
+
+static void num_of_alignActnProc (TexT text)
+
+{
+ GetTitle (text, align_buffer, BLASTCLI_SMALL_BUF_SIZE);
+ return;
+}
+
+static void num_of_expectActnProc (TexT text)
+
+{
+ GetTitle (text, expect_buffer, BLASTCLI_SMALL_BUF_SIZE);
+ return;
+}
+
+static void ScoreActnProc (TexT text)
+
+{
+ GetTitle (text, score_buffer, BLASTCLI_SMALL_BUF_SIZE);
+ return;
+}
+
+static void Score2ActnProc (TexT text)
+
+{
+ GetTitle (text, score2_buffer, BLASTCLI_SMALL_BUF_SIZE);
+ return;
+}
+
+static void GetGi(ButtoN b)
+
+{
+ get_gi = GetStatus(b);
+ return;
+}
+
+static void SaveFilter(ButtoN b)
+
+{
+ complex_filter = GetStatus(b);
+ return;
+}
+
+
+/* The Boolean PNTR "cancel" is here only for PROTOTYPE "consistency" */
+static Boolean LIBCALLBACK
+callback (BLAST0ResponsePtr brp, Boolean PNTR cancel)
+{
+ return FALSE;
+}
+
+/*********************************************************************
+* "main" function to call blast for the client.
+* This function sets up the customized vibrant interface
+* for BLAST. The actual call to BlastBioseq is with
+* PerformBlastSearch.
+*********************************************************************/
+
+Int2 Main (void)
+
+{
+ BLAST0RequestPtr blreqp;
+ BLAST0ResponsePtr blresp;
+ Char buffer[40];
+ CharPtr blastcli_version_number="2.00";
+ WindoW wdialog;
+ MenU menu;
+ GrouP checkbox_group, decision_group, scroll_group,
+ dialog_group=NULL, input_group=NULL, scroll_decision_group;
+ PopuP popd, db_popd;
+ ButtoN input_button, get_gi_button, complex_filter_button;
+ ValNodePtr vnp;
+
+
+ /* BlastInit needed for request of db-list. */
+ if (! BlastInit("blastcli", FALSE))
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "Unable to initialize BLAST service");
+ return (3);
+ }
+
+ sprintf(buffer, "BLAST Search %s", blastcli_version_number);
+ wdialog = FixedWindow (-20, -60, -10, -10, buffer, NULL);
+
+ menu = PulldownMenu (wdialog, "File");
+ CommandItem (menu, "Quit", ItemQuitProc);
+ menu = PulldownMenu (wdialog, "Edit");
+ CommandItem(menu, "Cut", StdCutTextProc);
+ CommandItem(menu, "Copy", StdCopyTextProc);
+ CommandItem(menu, "Paste", StdPasteTextProc);
+ CommandItem(menu, "Clear", StdDeleteTextProc);
+
+ input_group = HiddenGroup (wdialog, 3, 0, NULL);
+
+ StaticPrompt (input_group, "FASTA file input:", 0, dialogTextHeight, systemFont, '1');
+
+ input_button = PushButton (input_group, "File", GetInputFile);
+
+ input_text = DialogText (input_group, blast_inputfile, 20, FileInActnProc);
+
+ scroll_group = HiddenGroup (wdialog, 1, 0, NULL);
+
+ StaticPrompt (scroll_group, "Or cut and paste FASTA query into sequence window:", 0,
+ dialogTextHeight, systemFont, '1');
+ blast_inputfile[0] = NULLB;
+
+ sequence = ScrollText (scroll_group, 33, 6, programFont, TRUE, NULL);
+
+ scroll_decision_group = HiddenGroup(scroll_group, 4, 0, NULL);
+
+ PushButton (scroll_decision_group, "Clear sequence window", ClearSeqInputWindow);
+
+ Break(wdialog);
+
+ dialog_group = HiddenGroup (wdialog, 2, 100, NULL);
+
+ StaticPrompt (dialog_group, "BLAST program", 0, popupMenuHeight, systemFont, '1');
+ popd = PopupList (dialog_group, TRUE, GetProgramType);
+ PopupItem (popd, "blastn");
+ PopupItem (popd, "blastp");
+ PopupItem (popd, "blastx");
+ PopupItem (popd, "tblastn");
+ PopupItem (popd, "tblastx");
+/* Set the popup to blastn to start. */
+ SetValue(popd, 1);
+ if (blast_program != NULL)
+ blast_program = MemFree(blast_program);
+ blast_program = StringSave("blastn");
+
+
+/* Use the same ValNode for two requests. */
+/* Send Hello to server. */
+ blreqp = ValNodeNew(NULL);
+ blreqp->choice = BLAST0Request_hello;
+ blreqp->data.ptrvalue = buffer;
+ blresp = SubmitInfoRequest(blreqp);
+ blresp = BLAST0ResponseFree(blresp);
+ blreqp->data.ptrvalue = NULL;
+/* Get the list of valid databases. */
+ blreqp->choice = BLAST0Request_db_info;
+ blresp = SubmitInfoRequest(blreqp);
+ GetListOfDatabases(blresp);
+ blreqp = BLAST0RequestFree(blreqp);
+ blresp = BLAST0ResponseFree(blresp);
+
+
+ StaticPrompt (dialog_group, "Database", 0, popupMenuHeight, systemFont, '1');
+ db_popd = PopupList (dialog_group, TRUE, GetDatabaseName);
+ for (vnp=database_vnp; vnp; vnp=vnp->next)
+ {
+ PopupItem (db_popd, (CharPtr) vnp->data.ptrvalue);
+ }
+/*Set the popup to the first database (nr?) */
+ SetValue(db_popd, 1);
+ StringNCpy(blast_database, database_vnp->data.ptrvalue, BLASTCLI_SMALL_BUF_SIZE);
+
+ StaticPrompt (dialog_group, "Number of one-line descriptions to be reported (V)", 0, dialogTextHeight, systemFont, '1');
+ StringNCpy(descrp_buffer, "250", BLASTCLI_SMALL_BUF_SIZE);
+ DialogText (dialog_group, descrp_buffer, 5, num_of_descrpActnProc);
+
+ StaticPrompt (dialog_group, "Number of alignments to be reported (B)", 0, dialogTextHeight, systemFont, '1');
+ StringNCpy(align_buffer, "250", BLASTCLI_SMALL_BUF_SIZE);
+ DialogText (dialog_group, align_buffer, 5, num_of_alignActnProc);
+
+ StaticPrompt (dialog_group, "Expectation number (E)", 0, dialogTextHeight, systemFont, '1');
+ StringNCpy(expect_buffer, "10", BLASTCLI_SMALL_BUF_SIZE);
+ DialogText (dialog_group, expect_buffer, 5, num_of_expectActnProc);
+
+ StaticPrompt (dialog_group, "Minimum Score to report a database sequence (S)", 0, dialogTextHeight, systemFont, '1');
+ StringNCpy(score_buffer, "default", BLASTCLI_SMALL_BUF_SIZE);
+ DialogText (dialog_group, score_buffer, 5, ScoreActnProc);
+
+ StaticPrompt (dialog_group, "Minimum Score to report an HSP (S2)", 0, dialogTextHeight, systemFont, '1');
+ StringNCpy(score2_buffer, "default", BLASTCLI_SMALL_BUF_SIZE);
+ DialogText (dialog_group, score2_buffer, 5, Score2ActnProc);
+
+ checkbox_group = HiddenGroup(dialog_group, 4, 0, NULL);
+ get_gi_button = CheckBox(checkbox_group, "Show GI's", GetGi);
+ SetStatus(get_gi_button, FALSE);
+ complex_filter_button = CheckBox(checkbox_group, "Low-complexity filtering", SaveFilter);
+ SetStatus(complex_filter_button, TRUE);
+
+/* Set these in case their CheckBoxes are never touched. */
+ complex_filter=TRUE;
+ get_gi=FALSE;
+
+ Break(dialog_group);
+ StaticPrompt (dialog_group, "Other BLAST Options", 0, dialogTextHeight, systemFont, '1');
+ DialogText (dialog_group, expert_options, 5, ExpertOptionActnProc);
+ options_button = PushButton (dialog_group, "Option List", GetOptionHelp);
+ Break(dialog_group);
+
+
+ Break(dialog_group);
+ decision_group = HiddenGroup(dialog_group, 4, 0, NULL);
+ submit_button = DefaultButton (decision_group, "Submit", Calculate );
+ dismiss_button = PushButton (decision_group, "Dismiss", ButtonQuitProc);
+ help_button = PushButton (decision_group, "Help", GetBlastHelp);
+
+
+ Show (wdialog);
+ ProcessEvents();
+ BlastFini();
+
+ return 0;
+}
+
+
+#define BLASTCLI_FILE_NAME_SIZE 8 /* choose this size for DOS */
+static Int2
+PerformBlastSearch (BioseqPtr bsp)
+
+{
+ BLAST0RequestPtr blreqp;
+ BLAST0StatusPtr status;
+ CharPtr filename, ptr, ptr1;
+ Char buf_tmp[BLASTCLI_SMALL_BUF_SIZE+1], buffer[BLASTCLI_BUF_SIZE];
+ BLAST0ResponsePtr brp, brp1, blastResponse;
+ BLAST0ResultPtr result;
+ Int2 index;
+ static Int2 file_index=0;
+ SeqLocPtr dust_slp=NULL;
+ FILE *outfp;
+ Uint4 output=0;
+
+/* Get the MOTD from the server. */
+ blreqp = ValNodeNew(NULL);
+ blreqp->choice = BLAST0Request_motd;
+ blreqp->data.ptrvalue = StringSave(blast_program);
+ blastResponse = SubmitInfoRequest(blreqp);
+ if (blastResponse == NULL)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "BLAST connection to server failed");
+ return (3);
+ }
+ blast_output = MemNew(PATH_MAX*sizeof(Char));
+ blast_output = TmpNam(blast_output);
+/* Extract the filename from the entire path. */
+ filename = FileNameFind(blast_inputfile);
+ StringNCpy(buf_tmp, filename, BLASTCLI_FILE_NAME_SIZE);
+ index = StringLen(filename);
+/* Both of these must be done to assure no garbage in string. */
+ buf_tmp[index] = NULLB;
+ buf_tmp[BLASTCLI_FILE_NAME_SIZE] = NULLB;
+ ptr = buffer;
+ for (index=0;
+ index<BLASTCLI_FILE_NAME_SIZE, buf_tmp[index] != NULLB;
+ index++)
+ {
+ *ptr = buf_tmp[index];
+ ptr++;
+ }
+
+ *ptr = '.';
+ ptr++;
+ file_index++; /* incremented every time this function is called. */
+ ptr1 = Nlm_Ltostr((long) file_index, 1);
+ while (*ptr1 != NULLB)
+ {
+ *ptr = *ptr1;
+ ptr++; ptr1++;
+ }
+
+ *ptr = NULLB;
+ if (StringCmp(buffer, filename) == 0)
+ {
+ *ptr = 'X';
+ ptr++;
+ }
+ *ptr = NULLB;
+
+/* IF WIN_MSWIN is set, then DO NOT suggest an output file, as it will probably
+collide with the input file because of the 8+3 naming convention of DOS. */
+#ifdef WIN_MSWIN
+ new_blast_output = NULL;
+#else
+/* There is no input filename if the sequence is entered through a window. */
+ if (filename != NULL && filename[0] != NULLB)
+ {
+ new_blast_output = StringSave(buffer);
+ }
+ else
+ {
+ new_blast_output = NULL;
+
+ }
+#endif
+
+ outfp = FileOpen (blast_output, "w");
+ PrintMotd(blastResponse, outfp);
+
+/* Compose the "options" line. */
+
+ buffer[0]=NULLB;
+ /* "V" and "B" options that limit the number of deflines and alignment*/
+ sprintf(buf_tmp, "V=%ld B=%ld", (long) num_of_descrp, (long) num_of_align);
+ AddOptionToBuffer(buffer, buf_tmp, BLASTCLI_BUF_SIZE);
+ /* E (expected number of hits). */
+ if (num_of_expected)
+ {
+ sprintf(buf_tmp, "E=%ld", (long) num_of_expected);
+ AddOptionToBuffer(buffer, buf_tmp, BLASTCLI_BUF_SIZE);
+ }
+
+ /* S (minimum score to report a db sequence) */
+ if (score)
+ {
+ sprintf(buf_tmp, "S=%ld", (long) score);
+ AddOptionToBuffer(buffer, buf_tmp, BLASTCLI_BUF_SIZE);
+ }
+
+ /* S2 (minimum score to report an HSP) */
+ if (score2)
+ {
+ sprintf(buf_tmp, "S2=%ld", (long) score2);
+ AddOptionToBuffer(buffer, buf_tmp, BLASTCLI_BUF_SIZE);
+ }
+
+ /* SHould GI's be shown? */
+ if (get_gi)
+ AddOptionToBuffer(buffer, "-gi", BLASTCLI_BUF_SIZE);
+
+ /* Low comlexity filtering? */
+ dust_slp=NULL;
+ if (complex_filter)
+ {
+ if (StringCmp("blastn", blast_program) != 0)
+ AddOptionToBuffer(buffer, "-filter seg", BLASTCLI_BUF_SIZE);
+ else
+ dust_slp = BioseqDust(bsp, 0, -1, -1, -1, -1, -1);
+ }
+
+ /* Other (expert) BLAST options. */
+ if (expert_options != NULL && *expert_options != NULLB)
+ AddOptionToBuffer(buffer, expert_options, BLASTCLI_BUF_SIZE);
+
+/* If no alignments are requested, then the matrix and sequence data is not
+needed. */
+ if (num_of_align == 0)
+ {
+ output = BLAST_SERVER_OMIT_MATRIX;
+ output += BLAST_SERVER_OMIT_QUERY_SEQ_IN_SEG;
+ output += BLAST_SERVER_OMIT_DB_SEQ_IN_SEG;
+ ptr=expert_options;
+ /* Only a very crude test is done for "V" as an option.*/
+ if (ptr != NULL)
+ {
+ while (*ptr != NULLB)
+ {
+ if (*ptr == 'V' || *ptr == 'v')
+ {
+ if (*(ptr+1) == '=')
+ {
+ output=0;
+ break;
+ }
+ }
+ ptr++;
+ }
+ }
+ }
+
+/* Submit the request. */
+ brp = NULL;
+
+ result = BlastBioseq(bsp, blast_program, blast_database, buffer, &brp, dust_slp, output, Blast2callbackWithMon);
+
+ if (result != NULL)
+ {
+#ifdef DEBUG
+ AsnIoPtr aip;
+
+ aip = AsnIoOpen("blastout.asn", "w");
+ BLAST0ResultAsnWrite(result, aip, NULL);
+ AsnIoClose(aip);
+#endif /* DEBUG */
+ if (outfp != NULL)
+ {
+ TraditionalBlastOutput(result, brp, blast_program, outfp);
+
+ BLAST0ResultFree(result);
+
+ while (brp)
+ {
+ brp1 = brp;
+ brp = brp->next;
+ brp1->next = NULL;
+ BLAST0ResponseFree(brp1);
+ }
+ }
+ else
+ {
+ ErrPostEx(SEV_WARNING, 0, 0, "FileOpen failed");
+ return (3);
+ }
+ }
+ else if ((CheckIfBlastJobCancelled()) == TRUE)
+ {
+ return (7); /*non-zero return value enables buttons */
+ }
+ else
+ {
+ if (brp)
+ {
+ if (brp->choice == BLAST0Response_status)
+ {
+ PrintBlastOptions(outfp, brp);
+ return (5);
+ }
+ else
+ {
+ brp1 = brp->next;
+ while (brp1)
+ {
+ if (brp1->choice == BLAST0Response_status)
+ {
+ status = brp1->data.ptrvalue;
+ ErrPostEx(SEV_WARNING, 0, 0,
+ "%s\nEXIT CODE %ld", status->reason, status->code);
+ }
+ brp1 = brp1->next;
+ }
+ return (6);
+ }
+ }
+
+ else
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "BLAST search failed");
+ return (3);
+ }
+ }
+ if (dust_slp)
+ dust_slp = SeqLocSetFree(dust_slp);
+
+
+ PresentReportPanel(outfp);
+/* Don't remove the output file if command-line version is compiled. */
+#ifdef BLASTCLI_WITH_VIBRANT
+ FileRemove(blast_output);
+#endif
+
+ return 0;
+}
+
+static void
+PrintBlastOptions(FILE *fp, BLAST0ResponsePtr brp)
+{
+ BLAST0RequestPtr blreqp;
+ BLAST0ResponsePtr blastResponse;
+ BLAST0PrefacePtr preface;
+ BLAST0StatusPtr status=NULL;
+ ValNodePtr vnp;
+
+ blreqp = ValNodeNew(NULL);
+ blreqp->choice = BLAST0Request_usage_info;
+ blreqp->data.ptrvalue = StringSave(blast_program);
+ blastResponse = SubmitInfoRequest(blreqp);
+ preface = blastResponse->data.ptrvalue;
+ vnp = preface->prog_usage;
+
+ if (brp != NULL)
+ {
+ status = brp->data.ptrvalue;
+#ifdef BLASTCLI_WITH_VIBRANT
+ if (fp != NULL)
+ fprintf(fp, "%s\nEXIT CODE %ld\n\n", status->reason, status->code);
+#endif
+ }
+
+ if (fp != NULL)
+ print_usage(fp, vnp);
+
+#ifdef BLASTCLI_WITH_VIBRANT
+/* These must be disabled to prevent conflicts. */
+ Disable(help_button);
+ Disable(options_button);
+ Disable(submit_button);
+/* Select this to keep the dismiss button from becoming the default. */
+ Select(input_text);
+
+ if (new_blast_output)
+ new_blast_output = MemFree(new_blast_output);
+ new_blast_output = StringSave("blopt");
+
+ PresentReportPanel(fp);
+#else
+ if (status != NULL)
+ ErrPostEx(SEV_WARNING, 0, 0, "%s\nEXIT CODE %ld\n Valid options have been written to the file %s", status->reason, status->code, blast_output);
+#endif
+ blreqp = ValNodeFreeData(blreqp);
+}
+
+/********************************************************************
+*
+* Add a string ("option" to the buffer). "length" gives the
+* total length of the buffer. If option can be added then
+* TRUE is returned, otherwise FALSE is returned.
+********************************************************************/
+
+static Boolean
+AddOptionToBuffer(CharPtr buffer, CharPtr option, Int2 length)
+
+{
+ CharPtr ptr=buffer;
+ Int2 count=0;
+
+ while(*ptr != NULLB)
+ {
+ ptr++;
+ count++;
+ }
+
+ if ((count+StringLen(option)) >= length)
+ return FALSE;
+ else
+ {
+ while (*option !=NULLB)
+ {
+ *ptr=*option;
+ ptr++;
+ option++;
+ }
+ *ptr=' ';
+ ptr++;
+ *ptr=NULLB;
+ }
+ return TRUE;
+}
+
+static void
+PrintMotd(BLAST0ResponsePtr blastResponse, FILE *fp)
+
+{
+ Char buffer[100];
+ CharPtr string, ptr;
+
+ if (blastResponse->choice != BLAST0Response_motd)
+ return;
+
+ string = blastResponse->data.ptrvalue;
+ if (string == NULL)
+ return;
+
+ buffer[0] = NULLB;
+ ptr = buffer;
+ while (*string != NULLB)
+ {
+ if (*string == '~')
+ {
+ *ptr = NULLB;
+ fprintf(fp, "%s\n", buffer);
+ buffer[0] = NULLB;
+ ptr = buffer;
+ string++;
+ if (*string == NULLB)
+ break;
+ }
+ else
+ {
+ *ptr=*string;
+ ptr++; string++;
+ }
+ }
+ *ptr = NULLB;
+ fprintf(fp, "%s\n", buffer);
+
+ fflush(fp);
+}
+
+static void
+PresentReportPanel(FILE *outfp)
+
+{
+ MenU menu;
+ Int2 doc_x;
+ Int2 doc_y;
+
+#ifdef BLASTCLI_WITH_VIBRANT
+ WatchCursor();
+ if (results_window == NULL)
+ {
+ results_window = FixedWindow(-50, -33, -10, -10, "blastcli", NULL);
+ menu = PulldownMenu (results_window, "File");
+ CommandItem(menu, "Save As", SaveAsProc);
+ CommandItem(menu, "Quit", HideResultsWindow);
+ doc_x = MIN(X_VIEW, (screenRect.right - 50));
+ doc_y = MIN(Y_VIEW, (screenRect.bottom - 50));
+ document = DocumentPanel (results_window, doc_x, doc_y);
+ }
+ FileClose (outfp);
+ DisplayFile (document, blast_output, programFont);
+ ArrowCursor();
+ Show (results_window);
+/* blast_output was created by TmpNam() */
+#else
+ FileClose (outfp);
+#endif
+}
+
diff --git a/network/blast2/client/blstout2.c b/network/blast2/client/blstout2.c
new file mode 100644
index 00000000..5919d3be
--- /dev/null
+++ b/network/blast2/client/blstout2.c
@@ -0,0 +1,1823 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: blstout2.c
+*
+* Author: Roman L. Tatusov, Warren Gish, Jonathan Epstein, Tom Madden, Yuri Sadykov
+*
+* Version Creation Date: 06/16/95
+*
+* $Revision: 6.1 $
+*
+* File Description:
+* Creating BLAST report
+* Warren Gish's utilities needed for producing BLAST output
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: blstout2.c,v $
+* Revision 6.1 1997/11/28 18:21:59 madden
+* fprintf fixes
+*
+* Revision 6.0 1997/08/25 18:34:08 madden
+* Revision changed to 6.0
+*
+* Revision 5.4 1997/07/02 17:58:50 madden
+* Corrected pointer dereferenced to find gi
+*
+* Revision 5.3 1997/05/13 01:10:09 shavirin
+* Added ability to print absolute and relative URLs on BLAST output
+*
+ * Revision 5.2 1996/11/27 14:01:16 madden
+ * Replaced strlen by Nlm_StringLen.
+ *
+ * Revision 5.1 1996/06/06 21:08:57 madden
+ * Removed unused variable.
+ *
+ * Revision 5.0 1996/05/28 14:09:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.43 1996/05/28 13:02:21 madden
+ * Changed max ID length (BLASTCLI_ID_MAX) from 30 to 35.
+ *
+ * Revision 4.42 1996/05/28 12:35:02 madden
+ * Changed maximum ID length (BLASTCLI_ID_MAX) from 25 to 30.
+ *
+ * Revision 4.41 1996/05/27 14:10:41 madden
+ * Added function ResidueSymbolTranslate that protects against
+ * invalid residues.
+ *
+ * Revision 4.40 1996/05/22 15:29:43 vakatov
+ * Modified "sort_letters()" function prototype to suit the MSVC++ compiler
+ *
+ * Revision 4.39 1996/05/17 22:02:09 madden
+ * Optimized lookup of Residue for a given Symbol.
+ *
+ * Revision 4.38 1996/04/16 14:31:32 shavirin
+ * Fixed reference problem in Mosaic for HTML output
+ *
+ * Revision 4.36 1996/04/12 15:40:23 madden
+ * Changed "%d" to "%ld" in two places.
+ *
+ * Revision 4.35 1996/03/31 03:15:59 shavirin
+ * Added HTML output in function TraditionalBlastOutputHTML()
+ *
+ * Revision 4.32 1996/03/22 17:29:52 madden
+ * Removed include of netblap2.h
+ *
+ * Revision 4.31 1996/03/11 22:02:09 madden
+ * portnew now calls BLAST0SeqData2Bioseq
+ *
+ * Revision 4.30 1995/12/04 20:22:34 madden
+ * fixed bug when "-gi" option is used.
+ *
+ * Revision 4.29 1995/11/28 17:11:10 madden
+ * Checked for defline before dereferencing, replaced strlen with StringLen.
+ *
+ * Revision 4.28 1995/11/07 17:56:27 madden
+ * removed PrintTraditionalBlastPreface.
+ *
+ * Revision 4.27 1995/11/06 15:38:02 madden
+ * Fixed "strand" for blastn.
+ *
+ * Revision 4.26 1995/11/03 18:36:56 madden
+ * Fixed formatting of deflines.
+ *
+ * Revision 4.25 1995/11/03 16:03:40 madden
+ * Replaced some fprintf calls in TradtionalTopBlas.. with BlastPrint...
+ *
+ * Revision 4.24 1995/11/02 23:15:18 madden
+ * Used BlastPrintTabToColumn.
+ *
+ * Revision 4.23 1995/11/02 21:48:45 madden
+ * Used BlastPrintIntegerAdd and BlastPrintDoubleAdd.
+ *
+ * Revision 4.22 1995/11/02 21:13:37 madden
+ * Converted to using BlastPrint functions in some parts.
+ *
+ * Revision 4.21 1995/11/02 14:24:19 madden
+ * Changed format_an_id to calculate real number of digits for a gi ID
+ * rather than just using nine.
+ *
+ * Revision 4.20 1995/11/01 15:40:56 madden
+ * removed TraditionalBlastReportSetUp and TraditionalBlastReportCleanUp.
+ *
+ * Revision 4.19 1995/10/27 21:16:31 madden
+ * Removed TraditionalHistBlastOutput (moved to blast2.c).
+ *
+ * Revision 4.18 1995/10/26 17:10:01 madden
+ * moved wrap, PrintBlastPreface, acknowledge_blast_request, and
+ * BlastPrintValNodeStack to blast2.c.
+ *
+ * Revision 4.17 1995/09/05 20:50:01 madden
+ * Check that definition is not just a NULLB.
+ *
+ * Revision 4.16 1995/09/05 20:03:48 madden
+ * Newline added if only id was present.
+ *
+ * Revision 4.15 1995/08/29 21:51:04 madden
+ * removed unused variables that were lint complaints.
+ *
+ * Revision 4.14 1995/08/29 21:28:12 madden
+ * Histogram corrected to agree with stand-alone histogram.
+ *
+ * Revision 4.13 1995/08/29 18:26:36 madden
+ * Sequence ID now printed out even if FASTA definition not found.
+ *
+ * Revision 4.12 1995/08/28 17:33:49 madden
+ * replaced write to stderr with call to ErrPostEx.
+ *
+ * Revision 4.11 1995/08/24 17:23:01 madden
+ * Added support for printing gi's in the FASTA id line.
+ *
+ * Revision 4.10 1995/08/23 22:14:33 madden
+ * removed "qoffset" in the alignment functions.
+ *
+ * Revision 4.9 1995/08/23 13:32:55 madden
+ * Added support for BLAST "V" and "B" options.
+ *
+ * Revision 4.8 1995/08/04 15:06:41 madden
+ * Added function BlastPrintValNodeStack.
+ *
+ * Revision 4.7 1995/08/04 12:44:04 kans
+ * changed return NULL to return FALSE
+ *
+ * Revision 4.6 1995/08/03 13:17:39 madden
+ * Added check to PrintBlastPreface that the BLAST0PrefacePtr is not NULL.
+ *
+ * Revision 4.5 1995/08/02 16:26:24 madden
+ * fixed lint nits (unused variable, functions that could be static).
+ *
+ * Revision 4.4 1995/08/02 16:18:41 madden
+ * Added new preface and acknowledgment functions, enabled the "-qoffset"
+ * option.
+ *
+ * Revision 4.3 1995/08/01 20:44:33 madden
+ * traditional functions have BlastReportStructPtr as argument,
+ * fixed purify errors.
+ *
+ * Revision 4.2 1995/08/01 14:51:32 madden
+ * replaced the array ralpha with a call to GetResidueForSymbol.
+ *
+ * Revision 4.1 1995/07/28 16:16:37 madden
+ * Made functions that format individual parts of the traditional
+ * BLAST report non-static.
+ *
+ * Revision 4.0 1995/07/26 13:55:34 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.4 1995/07/19 15:00:44 madden
+ * Changed some spacings in TraditionalHistBlastOutput.
+ *
+ * Revision 1.3 1995/07/18 21:06:51 madden
+ * changed p-value etc. to p_value etc.
+ *
+ * Revision 1.2 1995/06/22 17:03:44 madden
+ * HitDataPtr replaced by BLAST0ResultPtr.
+ *
+ * Revision 1.1 1995/06/16 11:26:47 epstein
+ * Initial revision
+ *
+*/
+
+#include <ncbi.h>
+#include <objseq.h>
+#include <objsset.h>
+#include <sequtil.h>
+#include <seqport.h>
+#define NLM_GENERATED_CODE_PROTO
+#include <objblst2.h>
+#include <blast2.h>
+
+#define BLASTCLI_MATRIX_SIZE 26
+#define QUERY_HREF "http://www.ncbi.nlm.nih.gov"
+
+static Pointer find PROTO((BLAST0ResponsePtr p, Uint1 v));
+static void doindent PROTO((FILE *fp, int ncols));
+static CharPtr gish_str_strand PROTO ((Uint2 strand));
+static Int2 format_an_id PROTO ((CharPtr id, ValNodePtr vnp, Int2 max_id_length, Boolean get_gi));
+static Int2 get_max_ID_length PROTO ((BLAST0HitListPtr hlp, Boolean get_gi));
+static void get_frame PROTO ((BLAST0SeqIntervalPtr loc, CharPtr array, Int4 total_length));
+static Boolean LIBCALL TraditionalBlastOutputInternal(BLAST0ResultPtr hdp, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp, Int4 type);
+
+/**** MISC ****/
+
+static CharPtr
+gish_str_strand(Uint2 strand)
+{
+ switch (strand)
+ {
+ case BLAST0_Seq_interval_strand_plus:
+ case BLAST0_Seq_interval_strand_plus_rf:
+ return "Plus"; /* plus */
+ case BLAST0_Seq_interval_strand_minus:
+ case BLAST0_Seq_interval_strand_minus_rf:
+ return "Minus"; /* minus */
+ case BLAST0_Seq_interval_strand_both:
+ default: /* unknown, or unable to convert */
+ return "Undefined";
+ }
+}
+
+static BLAST0ResponsePtr _find(BLAST0ResponsePtr p, Uint1 v)
+{
+ BLAST0ResponsePtr b;
+
+ for (b = p; b != NULL && b->choice != v; b = b->next)
+ ;
+ return b;
+}
+
+static Pointer find(BLAST0ResponsePtr p, Uint1 v)
+{
+ BLAST0ResponsePtr b;
+
+ for (b = p; b != NULL && b->choice != v; b = b->next)
+ ;
+
+ return (b == NULL) ? NULL : b->data.ptrvalue;
+}
+
+/*
+ static Int2 PrivateGetNumberOfDigits(Int4 number)
+
+ This function calculates the lenght of "number" when printed.
+*/
+
+static Int2
+PrivateGetNumberOfDigits(Int4 number)
+{
+
+ Char temp[20];
+ int length;
+
+ length = sprintf(temp, "%ld", (long) number);
+ return (Int2) length;
+}
+
+/***************************************************************************
+*
+* Format the query and database acknowledgement of BLAST
+*
+*Query= 195747|Mitochondrion Rupicapra rupi
+* (646 letters)
+*
+*Database: Non-redundant PDB+GBupdate+GenBank+EMBLupdate+EMBL
+* 248,447 sequences; 236,652,708 total letters.
+*Searching..................................................done
+*
+**************************************************************************/
+Boolean LIBCALL
+TraditionalHeadBlastOutput(BlastReportStructPtr blrp)
+{
+ BLAST0ResponsePtr a, blresp;
+ BLAST0StatusPtr status;
+ BLAST0SequencePtr query;
+ BLAST0DbDescPtr db;
+ BLAST0JobDescPtr jobd;
+ Boolean found_top, found_bottom;
+ Int2 strand_value;
+ Int4 progress;
+ CharPtr program, string;
+ ValNodePtr parms;
+ FILE *fp;
+
+ if (blrp == NULL)
+ return FALSE;
+
+ blresp = blrp->blresp;
+ fp = blrp->bpsp->fp;
+ program = blrp->program;
+
+/* The next section looks through the "parms" (i.e., BLAST command-line options
+to set values needed by the function acknowledge_blast_request */
+ found_top = FALSE;
+ found_bottom = FALSE;
+ if ((parms = find(blresp, BLAST0Response_parms)) != NULL)
+ {
+ while (parms != NULL)
+ {
+ string = parms->data.ptrvalue;
+ if (StringCmp(string, "-top") == 0)
+ found_top = TRUE;
+ else if (StringCmp(string, "-bottom") == 0)
+ found_bottom = TRUE;
+ parms = parms->next;
+ }
+ }
+
+ strand_value=0;
+ if (StringCmp(program, "blastx") == 0 ||
+ StringCmp(program, "tblastx") == 0)
+ {
+ strand_value = 3; /* if neither top or bottom are found
+ then both are TRUE! */
+ if (found_top == TRUE && found_bottom == TRUE)
+ strand_value = 3;
+ else if (found_top == TRUE && found_bottom == FALSE)
+ strand_value = 1;
+ else if (found_top == FALSE && found_bottom == TRUE)
+ strand_value = 2;
+ }
+
+ if ((query = find(blresp, BLAST0Response_query)) != NULL)
+ {
+ acknowledge_blast_request(program, query, strand_value, blrp->qoffset, fp, blrp->type);
+ }
+
+ if ((db = find(blresp, BLAST0Response_dbdesc)) != NULL) {
+ string = db->def;
+ if(blrp->type & HTML_OUTPUT)
+ blast2_wrap(fp, "\n<b>Database:</b> ", string, Nlm_StringLen(string), 79, 11);
+ else /* blrp->type == TEXT_OUTPUT */
+ blast2_wrap(fp, "\nDatabase: ", string, Nlm_StringLen(string), 79, 11);
+
+ fprintf(fp, " %s sequences; %s total letters.\n",
+ Nlm_Ultostr((long)(db->count), 1), Nlm_Ultostr(db->totlen, 1));
+ }
+
+ a = blresp;
+ while ((a = _find(a, BLAST0Response_job_start)) != NULL) {
+ jobd = a->data.ptrvalue;
+ if (jobd->jid != BLAST0_Job_desc_jid_search) {
+ a = a->next;
+ continue;
+ }
+ fprintf(fp, "%s", jobd->desc);
+ fflush(fp);
+ progress = BLAST0Response_job_progress;
+ for (a = a->next; a != NULL && a->choice == progress; a = a->next) {
+ fprintf(fp, ".");
+ fflush(fp);
+ }
+ if (a != NULL && a->choice == BLAST0Response_job_done) {
+ fprintf(fp, "done\n");
+ } else {
+ fprintf(fp, "Interrupted!!!\n");
+ }
+ fflush(fp);
+ }
+
+ if ((status = find(blresp, BLAST0Response_status)) != NULL) {
+ if (status->code != 0) {
+ fprintf(fp, "ERROR: %ld\n", (long) status->code);
+ fprintf(fp, "reason: %s\n", status->reason);
+ }
+ }
+ fflush(fp);
+
+ return TRUE;
+}
+
+#define DEF_AND_ID_CUTOFF 59
+#define BLASTCLI_ID_MAX 35
+
+/**************************************************************************
+*
+* This function formats the One-line summaries of the traditional
+* BLAST output. This includes the High-Scoring Segment Pair (HSP)
+* id, the defline of the HSP, the high score of that HSP, the P
+* value, and the number of HSP's found. If a translation
+* was performed on the database, the frame is also printed. An
+* example is:
+*
+* Smallest
+* Sum
+* High Probability
+*Sequences producing High-scoring Segment Pairs: Score P(N) N
+*
+*dbj|D32197|RURMTCB27 Mitochondrion Rupicapra rupicapra ge... 3230 7.0e-264 1
+*dbj|D32191|CCRMTCB21 Mitochondrion Capricornis crispus ge... 2609 1.8e-212 1
+*gb|U17862|OMU17862 Ovibos moschatus moschatus cytochrom... 2600 1.0e-211 1
+*dbj|D32195|CCRMTCB25 Mitochondrion Capricornis sumatrensi... 2582 5.6e-210 1
+*gb|U17861|NCU17861 Nemorhaedus caudatus cytochrome b ge... 2573 1.8e-209 1
+*
+* and so on.
+******************************************************************************/
+
+Boolean LIBCALL
+TraditionalTopBlastOutput(BlastReportStructPtr blrp)
+{
+ BlastPrintStructurePtr bpsp;
+ BLAST0HitListPtr hlp;
+ BLAST0ResultPtr hdp;
+ BLAST0SegmentPtr segp;
+ /* Int4 dim; */
+ BLAST0SeqDescPtr sdp, sdp1;
+ CharPtr defline=NULL, ptr;
+ Char frame_array[3], buffer[DEF_AND_ID_CUTOFF+5];
+ ScorePtr score;
+ CharPtr scoreDescr;
+ BLAST0HSPPtr hsp;
+ Int4 highScore, string_length;
+ FloatHi poissonScore;
+ Int2 max_id_length, max_def_length, length, length_left, old_length, total_length;
+ Int4 nScore, query_length;
+ Int4 TemphighScore;
+ FloatHi TemppoissonScore;
+ Int4 TempnScore, max_defline_number=blrp->num_of_defline, defline_num;
+ CharPtr str1, program;
+ Char str2[DEF_AND_ID_CUTOFF+4];
+ Char id[BLASTCLI_ID_MAX+1];
+
+ /* HTML stuff */
+
+ ValNodePtr vnp1;
+ Int4 HTML_gi;
+ Char HTML_tmp[512];
+ Char HTML_tmp1[512];
+ CharPtr HTML_database;
+ register Int4 i, n;
+ Boolean use_text_id = FALSE;
+ CharPtr HTML_text_id;
+ Int4 HTML_query_len;
+ Int4 num_of_alignments = 0, max_alignment_number=blrp->num_of_align;
+ /* ------------- */
+
+ if (blrp == NULL)
+ return FALSE;
+
+ bpsp = blrp->bpsp;
+
+ hdp = blrp->result;
+ query_length = blrp->query_length;
+ program = blrp->program;
+
+
+ BlastPrintStart(bpsp, 0, 0);
+ BlastPrintNewLine(bpsp);
+ BlastPrintTabToColumn(bpsp, 70);
+ BlastPrintStringAdd(bpsp, "Smallest");
+ BlastPrintNewLine(bpsp);
+ BlastPrintTabToColumn(bpsp, 72);
+ BlastPrintStringAdd(bpsp, "Sum");
+ if (StringCmp("blastn", program) == 0 ||
+ StringCmp("blastp", program) == 0)
+ {
+ BlastPrintNewLine(bpsp);
+ BlastPrintTabToColumn(bpsp, 63);
+ BlastPrintStringAdd(bpsp, "High Probability");
+ BlastPrintNewLine(bpsp);
+ BlastPrintStringAdd(bpsp, "Sequences producing High-scoring Segment Pairs:");
+ BlastPrintTabToColumn(bpsp, 62);
+ BlastPrintStringAdd(bpsp, "Score P(N) N");
+ BlastPrintNewLine(bpsp);
+ }
+ else
+ {
+ BlastPrintNewLine(bpsp);
+ BlastPrintTabToColumn(bpsp, 54);
+ BlastPrintStringAdd(bpsp, "Reading High Probability");
+ BlastPrintNewLine(bpsp);
+ BlastPrintStringAdd(bpsp, "Sequences producing High-scoring Segment Pairs:");
+ BlastPrintTabToColumn(bpsp, 56);
+ BlastPrintStringAdd(bpsp, "Frame Score P(N) N");
+ BlastPrintNewLine(bpsp);
+ }
+
+ if (hdp == NULL || hdp->hitlists == NULL) {
+ if (hdp->hitlists == NULL) {
+ BlastPrintStart(bpsp, 0, 0);
+ BlastPrintNewLine(bpsp);
+ BlastPrintStringAdd(bpsp, " *** NONE ***");
+ }
+ return FALSE;
+ }
+ BlastPrintEnd(bpsp);
+
+/* dim = hdp->dim;*/ /* should be 2, or 3 for BLAST3 */
+
+ max_id_length = get_max_ID_length(hdp->hitlists, blrp->get_gi);
+ if (StringCmp("blastn", program) == 0 ||
+ StringCmp("blastp", program) == 0)
+ max_def_length = DEF_AND_ID_CUTOFF - max_id_length;
+ else
+ max_def_length = DEF_AND_ID_CUTOFF - max_id_length - 3;
+
+ defline_num=0;
+ for (hlp = hdp->hitlists; hlp != NULL; hlp = hlp->next)
+ {
+ defline_num++;
+ if (defline_num > max_defline_number)
+ break;
+
+ if (hlp->hsps != NULL)
+ {
+ hsp = hlp->hsps; /* first HSP */
+ segp = hsp->segs;
+ if (segp != NULL && segp->next != NULL &&
+ segp->next->loc != NULL)
+ {
+ if (hlp->seqs != NULL)
+ {
+ defline = NULL;
+ sdp = hlp->seqs->desc;
+ if (sdp->defline != NULL) {
+ defline = sdp->defline;
+ }
+ }
+
+ highScore = -1;
+ TemphighScore = highScore;
+ poissonScore = 99999;
+ TemppoissonScore = poissonScore;
+ nScore = 0;
+ for (; hsp != NULL; hsp = hsp->next)
+ { /* If value associated with BLAST0_Score_sid_sum_n is 1,
+ then this is not set in the ASN.1 */
+ TempnScore = 1;
+ segp = hsp->segs;
+ for (score = (ScorePtr) hsp->scores; score != NULL; score = score->next)
+ {
+ if (score->id->str == NULL)
+ scoreDescr = "";
+ else
+ scoreDescr = score->id->str;
+ if (StrCmp(scoreDescr, "score") == 0)
+ {
+ TemphighScore = score->value.intvalue;
+ } else if (StrCmp(scoreDescr, "p_value") == 0 ||
+ StrCmp(scoreDescr, "poisson_p") == 0 ||
+ StrCmp(scoreDescr, "sum_p") == 0)
+ {
+ TemppoissonScore = score->value.realvalue;
+ } else if (StrCmp(scoreDescr, "poisson_n") == 0 ||
+ StrCmp(scoreDescr, "sum_n") == 0)
+ {
+ TempnScore = score->value.intvalue;
+ } else { /* default */
+ }
+ }
+
+ if (TemphighScore > highScore)
+ {
+ highScore = TemphighScore;
+ if (segp != NULL)
+ {
+ if (StringCmp(program, "blastx") == 0)
+ get_frame(segp->loc, frame_array, query_length);
+ else if (StringCmp(program, "tblastn") == 0)
+ get_frame(segp->next->loc, frame_array, hlp->seqs->length);
+ else if (StringCmp(program, "tblastx") == 0)
+ get_frame(segp->next->loc, frame_array, hlp->seqs->length);
+ }
+ }
+ if (TemppoissonScore < poissonScore)
+ {
+ poissonScore = TemppoissonScore;
+ nScore = TempnScore;
+ }
+ }
+
+/* Add secondary id's (and their deflines) onto the first defline if it isn't
+too long already. */
+ str1 = defline;
+ string_length = 0;
+ if (str1 != NULL)
+ {
+ string_length = StringLen(str1);
+/* secondary ID's get added on if the first defline doesn't exceed the max.*/
+
+ if (string_length <= max_def_length)
+ {
+ if (sdp && sdp->next)
+ {
+ ptr = &buffer[0];
+ StrNCpy(ptr, str1, string_length);
+ ptr += string_length;
+ *ptr = NULLB;
+ total_length = string_length;
+ for (sdp1=sdp->next; sdp1; sdp1=sdp1->next)
+ {
+ length = format_an_id(&id[0], sdp1->id, 0, blrp->get_gi);
+ old_length = total_length;
+ total_length += length;
+ total_length += 2;
+ StringCpy(ptr, " >");
+ ptr += 2;
+ if (total_length > max_def_length)
+ {
+/* Add on part of last (too long) id to agree with Traditional Output.
+There must be some slack (extra room) in buffer for this. */
+ length_left = max_def_length-old_length;
+ if (length_left > 0)
+ {
+ StrNCpy(ptr, id, length_left);
+ ptr += length_left;
+ *ptr = '\0';
+ }
+ else
+ {
+ StrNCpy(ptr, "...", 3);
+ ptr += 3;
+ *ptr = '\0';
+ }
+ break;
+ }
+ StrNCpy(ptr, id, length);
+ ptr += length;
+ *ptr = ' '; ptr++;
+ *ptr = NULLB;
+ total_length++;
+ if (sdp1->defline)
+ {
+ length = StringLen(sdp1->defline);
+ }
+ else
+ {
+ length = 0;
+ }
+ if ((total_length+length) > max_def_length)
+ {
+/* Add on part of last (too long) id to agree with Traditional Output.
+There must be some slack (extra room) in buffer for this. */
+ length = max_def_length-total_length;
+ length += 3;
+ if (length > 0)
+ {
+ StrNCpy(ptr, sdp1->defline, length);
+ ptr += length;
+ }
+ else
+ {
+ StrNCpy(ptr, sdp1->defline, 1);
+ ptr++;
+ }
+ *ptr = NULLB;
+ break;
+ }
+ else
+ total_length += length;
+ StrNCpy(ptr, sdp1->defline, length);
+ ptr += length;
+ *ptr = '\0';
+ }
+ str1 = &buffer[0];
+ }
+ }
+ }
+
+ if (str1 != NULL)
+ string_length = StringLen(str1);
+ else
+ string_length = 0;
+ if (string_length > max_def_length)
+ {
+ StrNCpy (str2, str1, max_def_length);
+ str2[max_def_length-3] = '.';
+ str2[max_def_length-2] = '.';
+ str2[max_def_length-1] = '.';
+ str2[max_def_length] = '\0';
+ }
+ else
+ {
+ if (str1 != NULL)
+ StrNCpy (str2, str1, string_length);
+ str2[string_length] = NULLB;
+ }
+ str1 = str2;
+
+
+
+ format_an_id(&id[0], sdp->id, max_id_length, blrp->get_gi);
+
+/* Cutoff the id's after max_id_length characters to agree with Traditional
+Output */
+
+ id[max_id_length] = '\0';
+
+ BlastPrintStart(bpsp, 0, 0);
+
+
+ /* HTML stuff */
+
+ if(blrp->type & HTML_OUTPUT) {
+
+ /* setting database to use in Entrez query */
+ HTML_database = malloc(3);
+ if(!StringICmp(program, "blastx") ||
+ !StringICmp(program, "blastp"))
+ HTML_database = "p";
+ else
+ HTML_database = "n";
+
+ /* determine HTML_gi variable - main reference point */
+ HTML_gi = 0;
+ use_text_id = FALSE;
+ for (vnp1=sdp->id; vnp1 != NULL; vnp1=vnp1->next) {
+ if (vnp1->choice == BLAST0SeqId_giid) {
+ HTML_gi=vnp1->data.intvalue;
+ break;
+ }
+ }
+ if (HTML_gi == 0) { /* use text id as main reference point */
+ use_text_id = TRUE;
+ /* Look for text id's */
+ for (vnp1=sdp->id; vnp1 != NULL; vnp1=vnp1->next) {
+ if (vnp1->choice == BLAST0SeqId_textid) {
+ HTML_text_id = StringSave(vnp1->data.ptrvalue);
+ break;
+ }
+ }
+ }
+
+ /* filtering ">" and "<" characters to "/" */
+
+ for(i = 0; i < StringLen(str1); i++)
+ if ((str1[i] == '<') || (str1[i] == '>'))
+ str1[i] = '/';
+
+ /* preparing Entrez reference */
+
+ if (use_text_id) {
+ sprintf(HTML_tmp, "<a href=\""
+ "%s/htbin-post/Entrez/query?form=6&dopt=g&db=%s&"
+ "uid=%s\">",
+ blrp->type & ABSOLUTE_LINKS ? QUERY_HREF : "",
+ HTML_database, HTML_text_id);
+
+ HTML_query_len = StringLen(HTML_tmp) + 4;
+ sprintf(HTML_tmp1, "%s</a>", id);
+ strcat(HTML_tmp, HTML_tmp1);
+ } else {
+ sprintf(HTML_tmp, "<a href=\""
+ "%s/htbin-post/Entrez/query?form=6&dopt=g&db=%s&"
+ "uid=%08ld\">",
+ blrp->type & ABSOLUTE_LINKS ? QUERY_HREF : "",
+ HTML_database, (long) HTML_gi);
+ HTML_query_len = StringLen(HTML_tmp) + 4;
+ sprintf(HTML_tmp1, "%s</a>", id);
+ strcat(HTML_tmp, HTML_tmp1);
+ }
+ /* some formatting to follow Traditional output */
+ for ( i =StringLen(HTML_tmp);
+ i < (HTML_query_len + max_id_length +1) ; i++)
+ strcat(HTML_tmp, " ");
+
+ strcat(HTML_tmp, str1);
+
+
+ if (StringCmp("blastx", program) == 0 ||
+ StringCmp("tblastn", program) == 0 ||
+ StringCmp("tblastx", program) == 0) {
+
+ for ( i =StringLen(HTML_tmp); i < (HTML_query_len + 58) ; i++)
+ strcat(HTML_tmp, " ");
+ strcat(HTML_tmp, frame_array);
+ }
+
+ fprintf(bpsp->fp, "%s", HTML_tmp); /* actual printing */
+
+ for ( i =StringLen(HTML_tmp); i < (HTML_query_len +61) ; i++)
+ BlastPrintCharAdd(bpsp, ' ');
+
+ } else { /* if(blrp->type == HTML_OUTPUT) */
+
+ BlastPrintStringAdd(bpsp, id);
+ BlastPrintTabToColumn(bpsp, max_id_length+1);
+ BlastPrintCharAdd(bpsp, ' ');
+ BlastPrintStringAdd(bpsp, str1);
+ BlastPrintCharAdd(bpsp, ' ');
+
+ if (StringCmp("blastx", program) == 0 ||
+ StringCmp("tblastn", program) == 0 ||
+ StringCmp("tblastx", program) == 0)
+ {
+ BlastPrintTabToColumn(bpsp, DEF_AND_ID_CUTOFF);
+ BlastPrintStringAdd(bpsp, frame_array);
+ BlastPrintCharAdd(bpsp, ' ');
+ } else {
+ BlastPrintTabToColumn(bpsp, DEF_AND_ID_CUTOFF+3);
+ }
+ } /* blrp->type == TEXT_OUTPUT */
+
+ if(blrp->type & HTML_OUTPUT &&
+ num_of_alignments < max_alignment_number) {
+
+ sprintf(HTML_tmp,"%ld", (long) highScore);
+ n = StringLen(HTML_tmp);
+ for(i = 0; i < (5 - n); i++)
+ BlastPrintCharAdd(bpsp, ' ');
+
+ if(!use_text_id)
+ sprintf(HTML_tmp,
+ "<a href = #%08ld>%ld</a>",
+ HTML_gi, (long) highScore);
+ else
+ sprintf(HTML_tmp,
+ "<a href = #%s>%ld</a>",
+ HTML_text_id, (long) highScore);
+
+ BlastPrintStringAdd(bpsp, HTML_tmp);
+
+ } else /* blrp->type == TEXT_OUTPUT */
+
+ BlastPrintIntegerAdd(bpsp, "%5ld", highScore);
+
+ num_of_alignments++;
+
+/* The following code was lifted from "print_header" in blastapp/lib/prt_hdr.c to match the traditional output. */
+ if (poissonScore <= 0.99)
+ {
+ if (poissonScore != 0.)
+ BlastPrintDoubleAdd(bpsp, " %#-8.2lg", (double) poissonScore);
+ else
+ BlastPrintDoubleAdd(bpsp, " %#-8.2lg", 0.);
+ }
+ else if (poissonScore <= 0.999)
+ BlastPrintDoubleAdd(bpsp, " %#-8.3lg", (double) poissonScore);
+ else if (poissonScore <= 0.9999)
+ BlastPrintDoubleAdd(bpsp, " %#-8.4lg", (double) poissonScore);
+ else if (poissonScore <= 0.99999)
+ BlastPrintDoubleAdd(bpsp, " %#-8.5lg", (double) poissonScore);
+ else if (poissonScore < 0.9999995)
+ BlastPrintDoubleAdd(bpsp, " %#-8.6lg", (double) poissonScore);
+ else
+ BlastPrintDoubleAdd(bpsp, " %#-8.7lg", (double) 1.0);
+ BlastPrintIntegerAdd(bpsp, "%3ld", (int) nScore);
+ BlastPrintEnd(bpsp);
+ }
+ }
+ }
+ return TRUE;
+}
+
+/* The traditional BLAST output uses fasta style id's and not gi's. Look
+for a textid (i.e., fasta) and use this, otherwise use the first id.
+This function operates in two modes: if id is NULL, then the length of
+the id is returned; if id is not NULL, then the formatted id is returned in
+"id", which should already contain space for this operation. The ValNodePtr
+vnp is actually BLAST0SeqDesc.id
+The parameter max_id_length should be greater than zero if id is not NULL
+and one wishes to pad the end of the id with white spaces.
+If the gi should be prepended to the FASTA output then set get_gi should be
+TRUE.
+*/
+
+static Int2
+format_an_id (CharPtr id, ValNodePtr vnp, Int2 max_id_length, Boolean get_gi)
+
+{
+ Boolean found_id;
+ Char temp[100];
+ Int2 index, length;
+ Int4 gi=0;
+ ValNodePtr vnp1;
+
+ if (id != NULL)
+ id[0] = '\0';
+
+ found_id = FALSE;
+ length=0;
+
+/* IF gi was requested, then look for that first. */
+ if (get_gi)
+ {
+ for (vnp1=vnp; vnp1 != NULL; vnp1=vnp1->next)
+ {
+ if (vnp1->choice == BLAST0SeqId_giid)
+ {
+ gi=vnp->data.intvalue;
+ length = PrivateGetNumberOfDigits(gi);
+ length += 3; /* 3 extra chars for "gi|" */
+ }
+ }
+ }
+
+/* Look for text id's */
+ for (vnp1=vnp; vnp1 != NULL; vnp1=vnp1->next)
+ {
+ if (vnp1->choice == BLAST0SeqId_textid)
+ {
+ if (length > 0)
+ length++; /* add in room for dividing "|" */
+ length += StringLen(vnp1->data.ptrvalue);
+ if (id != NULL)
+ {
+ if (get_gi)
+ sprintf(temp, "gi|%ld|%s", (long) gi, vnp1->data.ptrvalue);
+ else
+ sprintf(temp, "%s", vnp1->data.ptrvalue);
+ }
+ found_id = TRUE;
+ break;
+ }
+ }
+
+/* If no textid, but a gi, then use that. */
+ if (found_id == FALSE && gi != 0)
+ {
+ sprintf(temp, "gi|%ld", (long) gi);
+ length = PrivateGetNumberOfDigits(gi);
+ length += 3; /* 3 extra chars for "gi|" */
+ found_id=TRUE;
+ }
+
+
+/* Id's of last resort. */
+ if (found_id == FALSE)
+ switch (vnp->choice)
+ {
+ default:
+ if (id != NULL)
+ sprintf(temp, "Unknown");
+ length = 7;
+ break;
+ case BLAST0SeqId_giid:
+ length = PrivateGetNumberOfDigits(vnp->data.intvalue);
+ length += 3;
+ if (id != NULL)
+ {
+ sprintf(temp, "gi|%ld", (long) vnp->data.intvalue);
+ temp[length] = NULLB;
+ }
+ break;
+ case BLAST0SeqId_textid:
+ length = StringLen(vnp->data.ptrvalue);
+ if (id != NULL)
+ {
+ sprintf(temp, "%s", vnp->data.ptrvalue);
+ temp[length] = NULLB;
+ }
+ break;
+ }
+
+ if (max_id_length > 0)
+ {
+ if (max_id_length < length)
+ length = max_id_length;
+ }
+ else
+ {
+ if (BLASTCLI_ID_MAX < length)
+ length = BLASTCLI_ID_MAX;
+ }
+
+ if (id)
+ {
+ for (index=0; index<length; index++)
+ id[index] = temp[index];
+ id[index] = '\0';
+ }
+
+ return length;
+}
+
+/***************************************************************************
+* Get the length of an id, truncate if necessary.
+***************************************************************************/
+static Int2
+get_max_ID_length(BLAST0HitListPtr hlp, Boolean get_gi)
+
+{
+ BLAST0SeqDescPtr sdp;
+ Int2 length, id_length=0;
+
+ for (; hlp != NULL; hlp=hlp->next)
+ {
+ if (hlp->seqs != NULL)
+ {
+ sdp = hlp->seqs->desc;
+ if (sdp)
+ {
+ length = format_an_id(NULL, sdp->id, 0, get_gi);
+ if (length > BLASTCLI_ID_MAX)
+ id_length = BLASTCLI_ID_MAX;
+ if (length > id_length)
+ id_length = length;
+ }
+ }
+ }
+ return id_length;
+}
+
+static Int4 get_pos(BLAST0SeqIntervalPtr loc, Int4 interval)
+{
+
+ Int4 position=0;
+
+ position = loc->from + interval + 1; /* plus, default */
+
+ switch (loc->strand)
+ {
+ case BLAST0_Seq_interval_strand_minus:
+ case BLAST0_Seq_interval_strand_minus_rf:
+ position = loc->to - interval + 1; /* minus */
+ break;
+ default:
+ break;
+ }
+
+ return position;
+}
+
+/*
+"get_frame" gets the frame and puts it into an array, which the user
+should provide. The array should have room for three characters.
+*/
+
+static void get_frame(BLAST0SeqIntervalPtr loc, CharPtr array, Int4 total_length)
+{
+
+ Int2 frame;
+ Int4 from;
+
+ switch (loc->strand)
+ {
+ case BLAST0_Seq_interval_strand_minus:
+ case BLAST0_Seq_interval_strand_minus_rf:
+ from = total_length-(loc->to + 1);
+ frame = (Int2) (from%3) + 1;
+ array[0] = '-';
+ if (frame == 1)
+ array[1] = '1';
+ else if (frame == 2)
+ array[1] = '2';
+ else if (frame == 3)
+ array[1] = '3';
+ break;
+ default:
+ from = loc->from;
+ frame = (Int2) (from%3) + 1;
+ array[0] = '+';
+ if (frame == 1)
+ array[1] = '1';
+ else if (frame == 2)
+ array[1] = '2';
+ else if (frame == 3)
+ array[1] = '3';
+ break;
+ }
+ array[2] = '\0';
+}
+
+/************************************************************************
+* Set up a SeqPort to allow the user to retrive residues/basepairs
+* one at a time. Note that the BioseqPtr is really just there
+* to allow the opening of the SeqPortPtr, and is just a skeletal
+* Bioseq.
+*********************************************************************/
+static SeqPortPtr portnew(BioseqPtr bsp, ValNodePtr str, Int4 len)
+{
+ Uint1 code;
+
+ BLAST0SeqData2Bioseq(bsp, str, len);
+ switch (bsp->mol)
+ {
+ case Seq_mol_aa:
+ code = Seq_code_ncbieaa;
+ break;
+ case Seq_mol_na:
+ code = Seq_code_iupacna;
+ break;
+ default:
+ return NULL;
+ }
+ return SeqPortNew(bsp, 0, -1, 0, code);
+}
+
+void LIBCALL
+TraditionalBlastWarning(BlastReportStructPtr blrp)
+
+{
+ BLAST0ResponsePtr blresp, var;
+ BLAST0WarningPtr bwp;
+ CharPtr warning;
+
+ if (blrp == NULL)
+ return;
+
+ blresp = blrp->blresp;
+
+ for (var=blresp; var; var=var->next)
+ {
+ if (var->choice == BLAST0Response_warning)
+ {
+ bwp = var->data.ptrvalue;
+ warning = bwp->reason;
+ ErrPostEx(SEV_WARNING, 0, 0, "%s", warning);
+ }
+ }
+}
+
+typedef struct _residue_symbol_array {
+ Uint1Ptr _letters, /* The actual array that was allocated
+ and should be deallocated. */
+ letters; /* Offset from _letter by start of alphabet.*/
+ Uint1 first_letter, /* 1st valid letter in alphabet. */
+ last_letter; /* last valid letter in alphabet. */
+ } ResidueSymbolArray, PNTR ResidueSymbolArrayPtr;
+
+static int LIBCALLBACK
+sort_letters(VoidPtr vp1, VoidPtr vp2)
+
+{
+ Uint1Ptr letter1=vp1, letter2=vp2;
+
+ if (*letter1 < *letter2)
+ return -1;
+ if (*letter1 > *letter2)
+ return 1;
+ return 0;
+}
+
+/******************************************************************************
+*
+* Sorts all the residues for an alphabet into an array so that they
+* can be quickly retrieved.
+*
+*******************************************************************************/
+
+static ResidueSymbolArrayPtr
+ResidueSymbolArrayNew(SeqCodeTablePtr sctp)
+
+{
+ ResidueSymbolArrayPtr rsa;
+ Int2 index;
+ Uint1 first_letter, last_letter;
+ Uint1Ptr sctp_letters, letters, _letters;
+
+ if (sctp == NULL)
+ return NULL;
+
+ if (! sctp->one_letter)
+ return NULL;
+
+ rsa = (ResidueSymbolArrayPtr) MemNew(sizeof(ResidueSymbolArray));
+ if (rsa == NULL)
+ return NULL;
+
+ sctp_letters = MemNew((sctp->num + 1)*sizeof(Uint1));
+
+ for (index=0; index < (Int2)sctp->num; index++)
+ {
+ sctp_letters[index] = sctp->letters[index];
+ }
+
+ HeapSort((Nlm_VoidPtr)sctp_letters, (size_t)sctp->num, sizeof(Uint1), sort_letters);
+
+ first_letter = (Uint1) sctp_letters[0];
+ last_letter = (Uint1) sctp_letters[sctp->num - 1];
+
+ sctp_letters = MemFree(sctp_letters);
+
+ _letters = MemNew((last_letter-first_letter+1)*sizeof(Uint1));
+
+ MemSet(_letters, INVALID_RESIDUE, (last_letter-first_letter+1));
+
+ letters = _letters - first_letter;
+
+ for (index=0; index < (Int2)sctp->num; index++)
+ {
+ letters[sctp->letters[index]] = (Uint1) index + sctp->start_at;
+ }
+
+ rsa->letters = letters;
+ rsa->_letters = _letters;
+ rsa->first_letter = first_letter;
+ rsa->last_letter = last_letter;
+
+ return rsa;
+}
+
+static ResidueSymbolArrayPtr
+ResidueSymbolArrayDestroy(ResidueSymbolArrayPtr rsa)
+
+{
+ if (rsa == NULL)
+ return NULL;
+
+ rsa->_letters = MemFree(rsa->_letters);
+ rsa->letters = NULL;
+ rsa = MemFree(rsa);
+
+ return rsa;
+}
+
+/***********************************************************************
+*
+* Translates letter chh, after checking that a valid translation
+* exists. If no valid translation exists, return INVALID_RESIDUE.
+*
+* A ResidueSymbolArrayPtr must be initialized first.
+*
+*************************************************************************/
+
+static Uint1 ResidueSymbolTranslate(ResidueSymbolArrayPtr rsa, Uint1 chh)
+
+{
+ if (rsa == NULL)
+ return INVALID_RESIDUE;
+
+ if (chh < rsa->first_letter || chh > rsa->last_letter)
+ return INVALID_RESIDUE;
+
+ return rsa->letters[chh];
+}
+
+#define BLSTOUT_PRINT_LEN 60
+
+/************************************************************************
+*
+* Print out the alignment portion of the traditional BLAST output,
+* that is:
+*
+*>dbj|D32197|RURMTCB27 Mitochondrion Rupicapra rupicapra gene for cytochrome b.
+* >emb|D32197|MIRRCB27 Mitochondrion Rupicapra rupicapra gene for
+* cytochrome b.
+* Length = 646
+*
+* Plus Strand HSPs:
+*
+* Score = 3230 (892.5 bits), Expect = 7.0e-264, P = 7.0e-264
+* Identities = 646/646 (100%), Positives = 646/646 (100%), Strand = Plus / Plus
+*
+*Query: 1 AATACACTACACATCCGATACAGCAACAGCATTCTCCTCTGTAACCCACATTTGCCGAGA 60
+* ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+*Sbjct: 1 AATACACTACACATCCGATACAGCAACAGCATTCTCCTCTGTAACCCACATTTGCCGAGA 60
+*
+*Query: 61 TGTAAACTACGGCTGAATCATCCGATACATACATGCAAATGGAGCATCAATATTTTTCAT 120
+* ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+*Sbjct: 61 TGTAAACTACGGCTGAATCATCCGATACATACATGCAAATGGAGCATCAATATTTTTCAT 120
+*
+* and so on.
+***************************************************************************/
+Boolean LIBCALL
+TraditionalBottomBlastOutput(BlastReportStructPtr blrp)
+{
+ SeqPortPtr spps, sppq, spp;
+ SeqCodeTablePtr sctp;
+ Int2 num_open, num, sum_n;
+ static Bioseq bios, bioq;
+ BLAST0ResultPtr hdp;
+ BLAST0ResponsePtr blresp;
+ BLAST0SegmentPtr seg;
+ BLAST0SeqIntervalPtr loc, loc1, loc2, loc_next, loc_s;
+ BLAST0HitListPtr hlp;
+ Int4 nbr_ident, nbr_pos, pos_temp;
+ Int2 index1, index2;
+ Scores_scaled_intsPtr sco;
+ ValNodePtr ints, mat_sc;
+ BLAST0KABlkPtr ka;
+ BLAST0MatrixPtr ma;
+ BLAST0SeqDescPtr sdp;
+ Char ch, chh, qchh, chh_std, qchh_std;
+ Char frame_array[3];
+ CharPtr defline, cp, head, s;
+ CharPtr program, strand1, strand2;
+ ResidueSymbolArrayPtr rsa=NULL;
+ ScorePtr score;
+ CharPtr scoreDescr;
+ BLAST0HSPPtr hsp;
+ int i, sc=0, ldef; /* Left as "int" for use in Warren's blast2_wrap */
+ FloatHi pv=0, ev=0;
+ Int4 j, pos, range, spos, query_length;
+ Int4 first, width;
+ Int4 hsp_length, qposition, sposition;
+ Int4 matr[BLASTCLI_MATRIX_SIZE+1][BLASTCLI_MATRIX_SIZE+1];
+ Int4 num_of_alignments, max_alignment_number=blrp->num_of_align;
+ Uint2 prev_strand;
+ double la2;
+ FILE *fp;
+
+ /* HTML stuff */
+
+ ValNodePtr vnp1;
+ Int4 HTML_gi;
+ CharPtr HTML_database;
+ Int4 count;
+ Boolean use_text_id = FALSE;
+ CharPtr HTML_text_id;
+ /* ---------- */
+
+ if (blrp == NULL)
+ return FALSE;
+
+ hdp = blrp->result;
+ query_length = blrp->query_length;
+ program = blrp->program;
+ fp = blrp->bpsp->fp;
+ blresp = blrp->blresp;
+
+/* Extra work is required for alignment of (translated) proteins */
+ if (blrp->is_prot)
+ {
+/* Find the SeqCodeTablePtr to convert for the matrices */
+ sctp = SeqCodeTableFind(Seq_code_ncbistdaa);
+/* Read in the matrix */
+ if ((ma = find(blresp, BLAST0Response_matrix)) != NULL)
+ {
+ mat_sc = ma->Scores_scores;
+ sco = mat_sc->data.ptrvalue;
+ ints = sco->ints;
+ if (ints)
+ {
+ for (index1=0; index1<BLASTCLI_MATRIX_SIZE; index1++)
+ for (index2=0; index2<BLASTCLI_MATRIX_SIZE; index2++)
+ {
+ matr[index1][index2] = ints->data.intvalue;
+ if (ints->next == NULL)
+ { /* Get out of both loops! */
+ index1 = BLASTCLI_MATRIX_SIZE;
+ index2 = BLASTCLI_MATRIX_SIZE;
+ break;
+ }
+ ints = ints->next;
+ }
+ }
+ }
+ rsa = ResidueSymbolArrayNew(sctp);
+ }
+ else
+ {
+ sctp = NULL;
+ rsa = NULL;
+ }
+
+/* Get lambda over ln(2) */
+ if ((ka = find(blresp, BLAST0Response_kablk)) != NULL)
+ la2 = ka->lambda / log(2.); /* lambda / ln2 */
+
+ num_of_alignments=0;
+/* Start of main loop that runs throughout the function. */
+ for (hlp = hdp->hitlists; hlp != NULL; hlp = hlp->next) {
+ num_of_alignments++;
+ if (num_of_alignments > max_alignment_number)
+ break;
+ if ((hsp = hlp->hsps) == NULL) {
+ continue;
+ }
+ if (hlp->seqs == NULL) {
+ continue;
+ }
+ if ((sdp = hlp->seqs->desc) == NULL) {
+ continue;
+ }
+ ldef = 0;
+ for (sdp = hlp->seqs->desc; sdp != NULL; sdp = sdp->next) {
+ if (sdp->defline)
+ {
+ ldef += StringLen(sdp->defline) + 1;
+ }
+ else
+ {
+ ldef++;
+ }
+ ldef += format_an_id(NULL, sdp->id, 0, blrp->get_gi);
+ ldef += 2;
+ }
+ s = defline = MemNew(ldef + 201);
+ count = 0;
+ for (sdp = hlp->seqs->desc; sdp != NULL; sdp = sdp->next)
+ {
+ if (s != defline) {
+ sprintf(s++, " ");
+ }
+
+ if(blrp->type == TEXT_OUTPUT)
+ sprintf(s++, "%c", '>');
+
+ /* HTML stuff */
+
+ if(blrp->type & HTML_OUTPUT && (count < 1)) {
+
+ /* HTML database for link to Entrez */
+
+ if(!StringICmp(program, "blastx") ||
+ !StringICmp(program, "blastp"))
+ HTML_database = "p";
+ else
+ HTML_database = "n";
+
+ /* Calculating HTML_gi */
+
+ use_text_id = FALSE;
+
+ for (vnp1=sdp->id; vnp1 != NULL; vnp1=vnp1->next) {
+ if (vnp1->choice == BLAST0SeqId_giid) {
+ HTML_gi=sdp->id->data.intvalue;
+ }
+ }
+ if(HTML_gi == 0)
+ use_text_id = TRUE;
+
+ if(!use_text_id) {
+ fprintf(fp, "\n<a name =%08ld> "
+ "</a><a href=\""
+ "%s/htbin-post/Entrez/query?form=6&dopt=g&db=%s&"
+ "uid=%08ld\"><b>",(long) HTML_gi,
+ blrp->type & ABSOLUTE_LINKS ? QUERY_HREF : "",
+
+ HTML_database, (long) HTML_gi);
+ } else { /* use text id as main reference point */
+ /* Look for text id's */
+ for (vnp1=sdp->id; vnp1 != NULL; vnp1=vnp1->next) {
+ if (vnp1->choice == BLAST0SeqId_textid) {
+ HTML_text_id = StringSave(vnp1->data.ptrvalue);
+ break;
+ }
+ }
+ fprintf(fp, "\n<a name =%s></a> <a href=\""
+ "%s/htbin-post/Entrez/query?form=6&dopt=g&db=%s&"
+ "uid=%s\"><b>",
+ HTML_text_id,
+ blrp->type & ABSOLUTE_LINKS ? QUERY_HREF : "",
+ HTML_database,
+ HTML_text_id);
+ }
+ } /* if(blrp->type == HTML_OUTPUT) */
+
+/* Don't pad the id here, as it's secondary and goes into the def line */
+ format_an_id(s, sdp->id, 0, blrp->get_gi);
+ s += StringLen(s);
+ if (blrp->type & HTML_OUTPUT && (count < 1)) {
+ strcat(s, "</b></a>");
+ s += StringLen(s);
+ }
+ if (sdp->defline)
+ sprintf(s, " %s", sdp->defline);
+ s += StringLen(s);
+ count++;
+ }
+
+ if (defline != NULL) {
+ for (cp = defline; ((ch = *cp) != NULLB && !IS_WHITESP(ch)); cp++);
+ for (; IS_WHITESP(*cp); cp++) ;
+ i = cp - defline;
+ i = MIN(i, 12);
+ fprintf(fp, "\n\n");
+ blast2_wrap(fp, "", defline, ldef, 79, i);
+ defline = MemFree(defline);
+ }
+ fprintf(fp, "%*sLength = %s\n", i, "",
+ Ltostr(hlp->seqs->length, 1));
+ prev_strand = UINT2_MAX; /* Value that will not be used*/
+ for (; hsp != NULL; hsp = hsp->next) {
+ sum_n = 1; /* Default (one) not in structure */
+ for (score = (ScorePtr) hsp->scores; score != NULL; score = score->next) {
+ if (score->id->str == NULL)
+ scoreDescr = "";
+ else
+ scoreDescr = score->id->str;
+ if (StrCmp(scoreDescr, "score") == 0)
+ {
+ sc = score->value.intvalue;
+ } else if (StrCmp(scoreDescr, "p_value") == 0 ||
+ StrCmp(scoreDescr, "poisson_p") == 0 ||
+ StrCmp(scoreDescr, "sum_p") == 0)
+ {
+ pv = score->value.realvalue;
+ } else if (StrCmp(scoreDescr, "e_value") == 0 ||
+ StrCmp(scoreDescr, "poisson_e") == 0 ||
+ StrCmp(scoreDescr, "sum_e") == 0)
+ {
+ ev = score->value.realvalue;
+ } else if (StrCmp(scoreDescr, "poisson_n") == 0 ||
+ StrCmp(scoreDescr, "sum_n") == 0)
+ {
+ sum_n = score->value.intvalue;
+ } else { /* default */
+ }
+ }
+ hsp_length = hsp->len;
+/* loc1 is the query; loc2 is the subject. */
+ loc1 = hsp->segs->loc;
+ loc2 = hsp->segs->next->loc;
+/* loc and loc_s are set to loc1 or loc2, depending on which "Strand" should
+be printed out below. */
+ if (StringCmp(program, "blastn") == 0 ||
+ StringCmp(program, "blastp") == 0)
+ {
+ loc = loc1;
+ loc_s = loc2;
+ }
+ else if (StringCmp(program, "blastx") == 0)
+ {
+ loc = loc1;
+ loc_s = loc2;
+ }
+ else if (StringCmp(program, "tblastn") == 0)
+ {
+ loc_s = loc1;
+ loc = loc2;
+ }
+ else if (StringCmp(program, "tblastx") == 0)
+ {
+ loc_s = loc1;
+ loc = loc2;
+ }
+
+ if (loc->strand != 0 && loc->strand != prev_strand)
+ {
+ prev_strand = loc->strand;
+ fprintf(fp, "\n %s Strand HSPs:\n",
+ gish_str_strand(loc->strand));
+ }
+ fprintf(fp, "\n Score = %ld (%.1lf bits), Expect = %#0.2lg, ",
+ (long)sc, (double) sc * la2, (double) ev);
+
+ if (sum_n < 2) {
+ fprintf(fp, "P = %#0.2lg\n", (double) pv);
+ } else {
+ fprintf(fp, "Sum P(%u) = %#0.2lg\n", sum_n, (double) pv);
+ }
+
+ nbr_ident = nbr_pos = 0;
+ if ((sppq = portnew(&bioq, hsp->segs->str, hsp_length)) == NULL) {
+ return FALSE;
+ }
+ if ((spps = portnew(&bios, hsp->segs->next->str, hsp_length)) == NULL) {
+ return FALSE;
+ }
+
+ range = loc_s->to - loc_s->from;
+ if (StringCmp(program, "tblastx") == 0)
+ range /= 3;
+ for (pos=0; pos <= range; pos++)
+ {
+ chh = SeqPortGetResidue(spps);
+ qchh = SeqPortGetResidue(sppq);
+ if (chh == qchh)
+ {
+ nbr_ident++;
+ if (StringCmp(program, "blastn") == 0)
+ nbr_pos++;
+ }
+ if (StringCmp(program, "blastn") != 0)
+ {
+ chh_std = ResidueSymbolTranslate(rsa, chh);
+ if (chh_std == INVALID_RESIDUE)
+ chh_std = 0;
+ qchh_std = ResidueSymbolTranslate(rsa, qchh);
+ if (qchh_std == INVALID_RESIDUE)
+ qchh_std = 0;
+ if (matr[chh_std][qchh_std] > 0)
+ nbr_pos++;
+ }
+ }
+
+ fprintf(fp,
+ " Identities = %ld/%ld (%ld%%), Positives = %ld/%ld (%ld%%)",
+ (long) nbr_ident, (long) pos, (long)((100*nbr_ident)/pos),
+ (long) nbr_pos, (long) pos, (long)((100*nbr_pos)/pos) );
+ if (StringCmp( program, "blastn") == 0)
+ {
+ strand1 = gish_str_strand(loc1->strand);
+ strand2 = gish_str_strand(loc2->strand);
+ if (StringCmp(strand1, "Undefined") != 0 &&
+ StringCmp(strand2, "Undefined") != 0)
+ fprintf(fp, ", Strand = %s / %s", strand1, strand2);
+ }
+ else if (StringCmp( program, "blastx") == 0)
+ {
+ loc = hsp->segs->loc;
+ get_frame(loc, frame_array, query_length);
+ fprintf(fp, ", Frame = %s", frame_array);
+ }
+ else if (StringCmp( program, "tblastn") == 0)
+ {
+ loc = hsp->segs->next->loc;
+ get_frame(loc, frame_array, hlp->seqs->length);
+ fprintf(fp, ", Frame = %s", frame_array);
+ }
+ else if (StringCmp( program, "tblastx") == 0)
+ {
+ loc = hsp->segs->loc;
+ get_frame(loc, frame_array, query_length);
+ fprintf(fp, ", Frame = %s", frame_array);
+ loc = hsp->segs->next->loc;
+ get_frame(loc, frame_array, hlp->seqs->length);
+ fprintf(fp, " / %s", frame_array);
+ }
+ putc('\n', fp);
+ num_open = 1;
+/* Print out the actual alignment. */
+ for (pos=0; pos < hsp_length; pos += BLSTOUT_PRINT_LEN) {
+ head = "Query";
+ first = TRUE;
+ num = 0;
+ for (seg = hsp->segs; seg != NULL; seg = seg->next, num++) {
+ loc = seg->loc;
+ if (first)
+ {
+ qposition = get_pos(loc, pos);
+ if (StringCmp(head, "Query") == 0)
+ width = MAX(5, Lwidth(qposition, 1));
+ loc_next = seg->next->loc;
+ sposition = get_pos(loc_next, pos);
+ width = MAX(width, Lwidth(sposition, 1));
+ }
+ if (!first) {
+ SeqPortSeek(sppq, pos, 0);
+ if (num_open != num) {
+ spps = portnew(&bios, seg->str, hsp_length);
+ if (spps == NULL) {
+ return FALSE;
+ }
+ num_open = num;
+ }
+ SeqPortSeek(spps, pos, 0);
+ for (j=0; j<(width+8); j++)
+ putc(' ', fp);
+/*
+ fprintf(fp, "%s", " ");
+*/
+ for (j=0; j+pos < hsp_length && j < BLSTOUT_PRINT_LEN; j++) {
+ chh = SeqPortGetResidue(spps);
+ qchh = SeqPortGetResidue(sppq);
+ if (blrp->is_prot) {
+ if (chh == qchh) {
+ putc(chh, fp);
+ } else {
+ chh_std = ResidueSymbolTranslate(rsa, chh);
+ if (chh_std == INVALID_RESIDUE)
+ chh_std = 0;
+ qchh_std = ResidueSymbolTranslate(rsa, qchh);
+ if (qchh_std == INVALID_RESIDUE)
+ qchh_std = 0;
+ putc((matr[chh_std][qchh_std]>0) ? '+' : ' ', fp);
+ }
+ } else {
+ putc((chh == qchh) ? '|' : ' ', fp);
+ }
+ }
+ spp = spps;
+ } else {
+ spp = sppq;
+ }
+ fprintf(fp, "\n");
+ SeqPortSeek(spp, pos, 0);
+ if (pos+BLSTOUT_PRINT_LEN < hsp_length)
+ spos = BLSTOUT_PRINT_LEN - 1;
+ else
+ spos = hsp_length - pos - 1;
+ pos_temp = pos;
+ if (StringCmp( program, "tblastx") == 0)
+ {
+ pos_temp *= 3;
+ }
+ else if (StringCmp(head, "Query") == 0)
+ {
+ if (StringCmp(program, "blastx") == 0)
+ {
+ pos_temp *= 3;
+ }
+ }
+ else if (StringCmp(head, "Sbjct") == 0)
+ {
+ if (StringCmp(program, "tblastn") == 0)
+ {
+ pos_temp *= 3;
+ }
+ }
+ qposition = get_pos(loc, pos_temp);
+ fprintf(fp, "%s: %*ld ", head, (int) width, (long) qposition);
+ for (j=0; j <= spos; j++) {
+ chh = SeqPortGetResidue(spp);
+ fputc(chh ,fp);
+ }
+ pos_temp = j-1+pos;
+ if (StringCmp( program, "tblastx") == 0)
+ {
+ pos_temp *= 3;
+ pos_temp += 2;
+ }
+ else if (StringCmp(head, "Query") == 0)
+ {
+ if (StringCmp(program, "blastx") == 0 ||
+ StringCmp( program, "tblastx") == 0)
+ {
+ pos_temp *= 3;
+ pos_temp += 2;
+ }
+ }
+ else if (StringCmp(head, "Sbjct") == 0)
+ {
+ if (StringCmp(program, "tblastn") == 0)
+ {
+ pos_temp *= 3;
+ pos_temp += 2;
+ }
+ }
+ qposition = get_pos(loc, pos_temp);
+ fprintf(fp, " %ld\n", (long) qposition);
+ head = "Sbjct";
+ first = FALSE;
+ }
+ }
+ SeqPortFree(sppq);
+ SeqPortFree(spps);
+ }
+ }
+ fprintf(fp, "\n");
+ rsa = ResidueSymbolArrayDestroy(rsa);
+ return TRUE;
+}
+
+/********************************************************************
+*
+* Formats the parameters (e.g., command line options) sent
+* back by the server and the statistics found at the bottom
+* of the output.
+*********************************************************************/
+Boolean LIBCALL
+TraditionalTailBlastOutput(BlastReportStructPtr blrp)
+{
+ BLAST0ResponsePtr blresp;
+ FILE *fp;
+ ValNodePtr stack;
+
+ blresp = blrp->blresp;
+ fp = blrp->bpsp->fp;
+
+ if ((stack = find(blresp, BLAST0Response_parms)) != NULL)
+ BlastPrintValNodeStack(stack, "Parameters", fp);
+
+ if ((stack = find(blresp, BLAST0Response_stats)) != NULL)
+ BlastPrintValNodeStack(stack, "Statistics", fp);
+
+ return TRUE;
+}
+
+Boolean LIBCALL TraditionalBlastOutput(BLAST0ResultPtr hdp, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp) {
+ return TraditionalBlastOutputInternal(hdp, blresp,
+ program, fp,
+ TEXT_OUTPUT);
+}
+Boolean LIBCALL TraditionalBlastOutputHTML(BLAST0ResultPtr hdp, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp) {
+ return TraditionalBlastOutputInternal(hdp, blresp,
+ program, fp,
+ HTML_OUTPUT|ABSOLUTE_LINKS);
+}
+Boolean LIBCALL TraditionalBlastOutputHTML2(BLAST0ResultPtr hdp, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp) {
+ return TraditionalBlastOutputInternal(hdp, blresp,
+ program, fp,
+ HTML_OUTPUT);
+}
+
+static Boolean LIBCALL TraditionalBlastOutputInternal(BLAST0ResultPtr hdp, BLAST0ResponsePtr blresp, CharPtr program, FILE *fp, Int4 type)
+{
+
+ BlastReportStructPtr blrp;
+
+ blrp = TraditionalBlastReportSetUp(hdp, blresp, program, fp, type);
+
+ if (blrp == NULL)
+ return FALSE;
+
+ if (PrintTraditionalBlastPreface(blrp) == FALSE)
+ return FALSE;
+
+ if (!TraditionalHeadBlastOutput(blrp)) {
+ return FALSE;
+ }
+
+ if (!TraditionalHistBlastOutput(blrp)) {
+ return FALSE;
+ }
+
+
+ if (TraditionalTopBlastOutput(blrp))
+ {
+ TraditionalBlastWarning(blrp);
+ if (!TraditionalBottomBlastOutput(blrp)) {
+ return FALSE;
+ }
+ }
+ if (!TraditionalTailBlastOutput(blrp)) {
+ return FALSE;
+ }
+
+ blrp = TraditionalBlastReportCleanUp(blrp);
+
+ return TRUE;
+}
diff --git a/network/blast2/client/netblap2.c b/network/blast2/client/netblap2.c
new file mode 100644
index 00000000..73a209b6
--- /dev/null
+++ b/network/blast2/client/netblap2.c
@@ -0,0 +1,2813 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: netblap2.c
+*
+* Author: Epstein, Madden
+*
+* Version Creation Date: 06/16/95
+*
+* $Revision: 6.4 $
+*
+* File Description:
+* API for BLAST service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 2/24/94 Tatusov Moved "traditional" BLAST output to blastout.c
+* 8/12/94 Epstein Fixed order of blresp messages in BlastBioseq
+* 2/17/95 Madden Addition of BlastBioseq2
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: netblap2.c,v $
+* Revision 6.4 1998/08/05 21:22:03 madden
+* Fix for FMR by reassigning asn pointers after reconnect
+*
+* Revision 6.3 1998/02/19 21:13:04 shavirin
+* Fixed reconnection in MT Save mode
+*
+* Revision 6.2 1997/09/12 13:48:55 madden
+* Correction to virtual fix.
+*
+* Revision 6.1 1997/09/11 21:28:35 madden
+* Use SeqPortSet_do_virtual so delta seqs are accepted
+*
+* Revision 6.0 1997/08/25 18:34:12 madden
+* Revision changed to 6.0
+*
+* Revision 5.13 1997/05/13 01:09:22 shavirin
+* Changed default timeout for connection from 10 minutes to 2 minutes
+*
+ * Revision 5.12 1997/04/11 15:18:38 madden
+ * renamed callbackWithMon Blast2callbackWithMon, made non-static.
+ *
+ * Revision 5.11 1996/12/05 21:24:05 madden
+ * Added protection against virtual sequences.
+ *
+ * Revision 5.10 1996/11/25 19:24:14 shavirin
+ * In function BlastInitMT() changed function NlmMutexInit due to
+ * changed definition of this function
+ *
+ * Revision 5.9 1996/07/30 14:39:53 madden
+ * Produce "local" ID in PrepareRequest if there is no other ID.
+ *
+ * Revision 5.8 1996/07/01 21:18:37 shavirin
+ * Added new function BlastSeqLocMon() allows to user set callback.
+ *
+ * Revision 5.7 1996/06/06 17:58:14 shavirin
+ * Removed BlastFiniMT() call inside BlastInitMT
+ *
+ * Revision 5.6 1996/06/05 20:23:07 madden
+ * Check that ptr to defline is not NULL before dereferencing.
+ *
+ * Revision 5.5 1996/06/05 20:17:52 shavirin
+ * Rewritten function BlastInitMT .
+ *
+ * Revision 5.4 1996/06/04 12:19:37 madden
+ * Stripping non-printing characters before putting into ASN.1
+ *
+ * Revision 5.3 1996/05/31 20:45:22 shavirin
+ * Removed possibility of deadlock in function BlastMTInit()
+ *
+ * Revision 5.2 1996/05/28 20:31:04 madden
+ * Removed unused variables found by CodeWarrior.
+ *
+ * Revision 5.1 1996/05/28 14:37:06 madden
+ * Fixed incorrect assignments found by CodeWarrior.
+ *
+ * Revision 4.26 1996/05/22 18:05:00 madden
+ * Fixed leak (purify nit), changed build of QUery ID because of leak.
+ *
+ * Revision 4.25 1996/05/20 13:57:03 shavirin
+ * Removed NULL pointer, resulted in segmentation fault of bmserver
+ *
+ * Revision 4.24 1996/05/13 17:46:52 kans
+ * uses new name of ncbi thread header
+ *
+ * Revision 4.23 1996/05/10 21:05:48 madden
+ * Removed defines needed for "direct" connections.
+ *
+ * Revision 4.22 1996/05/10 20:44:49 madden
+ * MT safe function calls added.
+ *
+ * Revision 4.21 1996/04/16 19:11:36 madden
+ * BLAST0Response_queued added to default case.
+ *
+ * Revision 4.20 1996/01/04 19:11:13 madden
+ * Added BlastSetUserErrorString and BlastDeleteUserErrorString.
+ *
+ * Revision 4.19 1995/12/22 17:51:58 madden
+ * Added check in PrepareRequest that a textid has a "|" in it.
+ *
+ * Revision 4.18 1995/10/23 20:21:23 madden
+ * Added "static" declarations to RealSubmit functions.
+ *
+ * Revision 4.17 1995/10/18 21:34:04 madden
+ * Client now tries to reconnect to server if connection is dropped.
+ *
+ * Revision 4.16 1995/10/17 15:03:12 madden
+ * Added function CheckIfBlastJobCancelled to determine if the
+ * "cancel" button on the progress bar has been used.
+ *
+ * Revision 4.15 1995/10/17 14:01:05 madden
+ * Replaced NetInit with BlastInit when service ptr need to be reinitialized.
+ *
+ * Revision 4.14 1995/10/06 12:42:17 madden
+ * Check return value of GetOffsetInLoc in AdjustOffSetInSeqAnnot.
+ *
+ * Revision 4.13 1995/10/05 16:37:54 madden
+ * called BioseqUnlockById at the end of BlastSeqLoc2.
+ *
+ * Revision 4.12 1995/10/05 16:22:07 madden
+ * Set slp to NULL on ever (outer) loop of MaskTheResidues.
+ *
+ * Revision 4.11 1995/10/05 14:49:59 madden
+ * Set *blrespPtr to NULL in SubmitBlastRequest if blrespPtr is non-NULL.
+ *
+ * Revision 4.10 1995/10/05 14:30:24 madden
+ * Check that blrespPtr is not NULL before dereferencing.
+ *
+ * Revision 4.9 1995/09/21 20:55:31 madden
+ * PrepareRequest now replaces invalid residues/basepairs by "A".
+ *
+ * Revision 4.8 1995/09/07 12:20:41 madden
+ * Added "static" to StringToBioseq definition.
+ *
+ * Revision 4.7 1995/09/01 22:07:52 madden
+ * converted some variable to "static" if they are only referenced in this file.
+ *
+ * Revision 4.6 1995/09/01 20:10:26 madden
+ * Converted a "blast1" string to "blast2".
+ *
+ * Revision 4.5 1995/09/01 16:43:46 madden
+ * changes to allow cancellation of jobs through "Cancel" button of prog. bar.
+ *
+ * Revision 4.4 1995/08/29 21:51:04 madden
+ * removed unused variables that were lint complaints.
+ *
+ * Revision 4.3 1995/08/03 21:21:52 madden
+ * intitialized "result" to NULL in SubmitResultBlastRequest.
+ *
+ * Revision 4.2 1995/08/01 20:44:33 madden
+ * "textid" buffer length increased to accommodate SeqIdWrite.
+ *
+ * Revision 4.1 1995/07/28 14:18:56 madden
+ * Added function BlastAnIUPACString.
+ *
+ * Revision 4.0 1995/07/26 13:55:34 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.19 1995/07/25 15:02:28 madden
+ * Added print_usage to print out options.
+ *
+ * Revision 1.17 1995/07/24 17:33:08 madden
+ * removed debugging code that AsnWrites the response to a temp file.
+ *
+ * Revision 1.16 1995/07/24 16:34:25 madden
+ * replaced NETBLAP1_BUFFER_SIZE by NETBLAP2_BUFLEN.
+ *
+ * Revision 1.15 1995/07/24 16:26:35 madden
+ * Added MaskTheResidues to mask a number of residues at once. Removed
+ * MaskThisResidue.
+ *
+ * Revision 1.14 1995/07/20 18:52:00 madden
+ * Replaced SeqIdPrint by SeqIdWrite.
+ *
+ * Revision 1.13 1995/07/19 14:03:56 madden
+ * Changed AdjustOffSetInSeqAnnot to adjust StdSegPtr.
+ *
+ * Revision 1.12 1995/07/18 21:06:03 madden
+ * Added call to AdjustOffSetInSeqAnnot to BlastSeqLoc2.
+ *
+ * Revision 1.11 1995/07/18 20:05:36 madden
+ * Changed masking of BlastSeqLoc2 for cases where blast does not start at
+ * the beginning of the SeqLoc.
+ *
+ * Revision 1.10 1995/07/12 17:42:29 madden
+ * Added parameter to BlastBioseq, BlastSeqLoc, BlastBioseq2, and BlastSeqLoc2
+ * to allow parts of sequence to be masked. Also added the function
+ * MaskThisResidue to mask sequences with "N" or "X".
+ *
+ * Revision 1.9 1995/06/28 20:08:38 madden
+ * Added Boolean get_seqalign argument to SubmitBlastRequest.
+ *
+ * Revision 1.8 1995/06/28 18:28:07 madden
+ * Changed BlastBioseq2 and BlastSeqLoc2 to take an additional argument:
+ * a "BLAST0ResponsePtr PNTR".
+ *
+ * Revision 1.7 1995/06/28 15:38:17 madden
+ * BlastBioseq2 and BlastSeqLoc2 return NULL if no results.
+ *
+ * Revision 1.6 1995/06/23 22:14:53 madden
+ * Fixed problems identified by lint.
+ *
+ * Revision 1.5 1995/06/23 21:39:51 madden
+ * Sixth argument in BlastBioseq now takes a Uint4 rather than a BoolPtr.
+ *
+ * Revision 1.4 1995/06/22 17:06:04 madden
+ * Added functions SubmitSeqAlignBlastRequest and SubmitResultBlastRequest,
+ * changed BlastBioseq2 and BlastSeqLoc2 to take SeqAlignPtr directly from
+ * the BLAST output.
+ *
+ * Revision 1.3 1995/06/22 13:19:01 madden
+ * Added five Booleans to PrepRequestInfoPtr that control the amount of
+ * output, these correspond to the five Uint1's on BLAST0SearchPtr that
+ * determine whether a matrix, query seq, db seq, etc is returned.
+ *
+ * Revision 1.2 1995/06/22 12:54:45 madden
+ * Changed HitDataPtr to BLAST0ResultPtr.
+ *
+ * Revision 1.1 1995/06/16 11:26:59 epstein
+ * Initial revision
+ *
+ * Revision 1.28 95/05/17 17:59:27 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <asn.h>
+#include <ncbi.h>
+#include <objseq.h>
+#include <objsset.h>
+#include <prtutil.h>
+#include <seqport.h>
+#include <sequtil.h>
+#include <netblap2.h>
+#include <ncbinet.h>
+#include <ncbithr.h>
+
+#define BLAST_SERVER_RETRIES 2
+#define NETBLAP2_BUFLEN 200
+#define NETBLAP2_SHORT_BUFLEN 25
+#define STANDALONE
+#define BLAST_REQUEST_TIMEOUT 120
+
+extern void MsgSetReadTimeout PROTO((NI_HandPtr mh, int t));
+
+static Boolean ReestablishNetBlast PROTO((void));
+static Boolean NetInit PROTO((void));
+static Boolean ForceNetInit PROTO((void));
+static Boolean NetFini PROTO((void));
+static Boolean GenericReestablishNet PROTO((CharPtr svcName, Boolean showErrs));
+
+static ByteStorePtr StoreResiduesInBS PROTO ((Uint1Ptr buffer, Int4 buf_len, ByteStorePtr bsp, Uint1Ptr bitctr_to, Uint1 newcode, Uint1 oldcode, Int4 len));
+
+static BLAST0RequestPtr PrepareRequest PROTO ((PrepRequestInfoPtr prip));
+
+static SeqAlignPtr RealSubmitSeqAlignBlastRequest PROTO((BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback));
+
+static BLAST0ResultPtr RealSubmitResultBlastRequest PROTO((BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback));
+
+static VoidPtr SubmitBlastRequest PROTO((BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback, Boolean get_seqalign));
+
+static BLAST0ResultPtr LIBCALL BlastSeqLoc PROTO ((SeqLocPtr slp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, ProgressCallback progCallback));
+
+static void MaskTheResidues PROTO((Uint1Ptr buffer, Int4 max_length, Uint1 mask_residue, Int4 offset, SeqLocPtr mask_slp));
+
+
+static BioseqPtr LIBCALL StringToBioseq PROTO((CharPtr sequence, Boolean is_na, Int4 length, CharPtr id, CharPtr defline));
+
+static void AdjustOffSetInSeqAnnot PROTO ((SeqAnnotPtr sap, SeqLocPtr slp));
+
+static SeqAnnotPtr LIBCALL
+BlastSeqLocInternal(SeqLocPtr slp, CharPtr progname, CharPtr dbname, CharPtr blast_params, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Boolean useMonitors, ProgressCallback userCallback);
+
+
+/* ----- definitions of MT Safe and non-safe functions ----- */
+
+static VoidPtr
+SubmitBlastRequestInternal(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback, Boolean get_seqalign, Boolean MTSafe, BlastMTHandlePtr BlastMThp);
+
+static BLAST0ResultPtr
+SubmitResultBlastRequestMT(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback, BlastMTHandlePtr BlastMThp);
+static SeqAlignPtr
+SubmitSeqAlignBlastRequestMT(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback, BlastMTHandlePtr BlastMThp);
+static BLAST0ResultPtr
+SubmitResultBlastRequestNew(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback);
+static SeqAlignPtr
+SubmitSeqAlignBlastRequestNew(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback);
+
+static BLAST0ResponsePtr
+SubmitInfoRequestInternal (BLAST0RequestPtr blreqp, BlastMTHandlePtr BlastMThp, Boolean MTSafe);
+
+
+/* ---------------------------------------------------------------------- */
+
+static NI_HandPtr svcp = NULL;
+static AsnIoPtr asnin = NULL;
+static AsnIoPtr asnout = NULL;
+static Boolean num_attached = 0;
+static NI_DispatcherPtr dispatcher;
+static Boolean job_cancelled;
+/* error_occurred and old_error_hook should not be accessed directly.
+The functions BlastSetErrorStatus, BlastGetErrorStatus, and BlastSetErrorHook
+will change these variables. */
+static Boolean error_occurred;
+static ErrHookProc old_error_hook;
+
+static Boolean MutexIsSet = FALSE;
+static TNlmMutex mp;
+static Boolean DispatcherOK;
+
+/*****************************************************************************
+*
+* BlastInit ()
+*
+*****************************************************************************/
+
+Boolean LIBCALL
+BlastInit (CharPtr clientId, Boolean ignoreErrs)
+
+{
+ if (clientId != NULL && StrCmp(clientId, "blasttest") == 0)
+ {
+ asnin = AsnIoOpen("blserver.inp", "r");
+ asnout = AsnIoOpen("blclient.out", "w");
+
+ if (asnin == NULL || asnout == NULL)
+ return FALSE;
+ } else {
+ if (! NetInit())
+ return FALSE;
+
+ svcp = NI_GenericGetService(dispatcher, NULL, "BLAST", "blast2", FALSE);
+ if (svcp == NULL)
+ {
+ ErrPost(CTX_UNKNOWN, 1, "NI_ServiceGet [%s] (%s)", ni_errlist[ni_errno], ni_errtext);
+ BlastFini();
+ return FALSE;
+ }
+
+ MsgSetReadTimeout(svcp, BLAST_REQUEST_TIMEOUT);
+ asnin = svcp->raip;
+ asnout = svcp->waip;
+ }
+
+ return TRUE;
+}
+
+
+/*****************************************************************************
+*
+* BlastInitMT ()
+*
+* storage for BlastMTHandlePtr provided on upper layers
+*
+*****************************************************************************/
+Boolean LIBCALL BlastInitMT(BlastMTHandlePtr BlastMThp,
+ CharPtr clientId, Boolean ignoreErrs)
+{
+ Int4 count=0;
+
+
+ if(!MutexIsSet) {
+ MutexIsSet = TRUE;
+ NlmMutexInit(&mp);
+ }
+
+ BlastMThp->svcp = NULL;
+ BlastMThp->asnin = NULL;
+ BlastMThp->asnout = NULL;
+ BlastMThp->error = NULL;
+
+ NlmMutexLock(mp); /* locking access to Network library */
+
+
+ while (count < 2) {
+ if(DispatcherOK == FALSE) {
+ if((dispatcher =
+ NI_GenericInit(NULL, NULL, TRUE, NULL, 0)) == NULL) {
+ BlastMThp->error = StringSave("BlastInitMT: "
+ "Cannot connect to dispatcher");
+ BlastMThp->svcp = NULL;
+ NlmMutexUnlock(mp); /* clear access to the Network library */
+ return FALSE; /* bad - dispatcher is down ... */
+ }
+ DispatcherOK = TRUE;
+ }
+
+ if((BlastMThp->svcp =
+ NI_GenericGetService(dispatcher,
+ NULL, "BLAST", "blast2", FALSE)) == NULL) {
+ BlastMThp->error = StringSave("NI_ServiceGet: Cannot get service");
+ /* BlastFiniMT(BlastMThp); */
+ DispatcherOK = FALSE;
+ count++;
+
+ } else { /* we got valid svcp pointer */
+
+ MsgSetReadTimeout(BlastMThp->svcp, BLAST_REQUEST_TIMEOUT);
+ BlastMThp->asnin = BlastMThp->svcp->raip;
+ BlastMThp->asnout = BlastMThp->svcp->waip;
+ NlmMutexUnlock(mp); /* clear access to the Network library */
+ return TRUE; /* Yep - no errors ! */
+ }
+ } /* svcp == NULL mean that blast is not available and this must
+ terminate calling thread */
+
+ NlmMutexUnlock(mp); /* clear access to the Network library */
+ return FALSE; /* cannot get service in few attempts */
+}
+
+/*****************************************************************************
+*
+* BlastFini ()
+*
+*****************************************************************************/
+
+Boolean LIBCALL
+BlastFini()
+
+{
+ NetFini();
+ return TRUE;
+}
+/*****************************************************************************
+*
+* BlastFiniMT ()
+*
+*****************************************************************************/
+
+Boolean LIBCALL BlastFiniMT(BlastMTHandlePtr BlastMThp)
+{
+ NI_DispatcherPtr local_dispatcher;
+
+ NlmMutexLock(mp); /* locking access to Network library */
+
+ if(BlastMThp->svcp != NULL) {
+ local_dispatcher = BlastMThp->svcp->disp;
+ NI_ServiceDisconnect(BlastMThp->svcp);
+ BlastMThp->svcp = NULL;
+ }
+
+ BlastMThp->asnin = NULL;
+ BlastMThp->asnout = NULL;
+ /* NI_EndServices (local_dispatcher); */
+
+ NlmMutexUnlock(mp); /* clear access to the Network library */
+
+ MemFree(BlastMThp->error);
+ BlastMThp->error = NULL;
+
+ return TRUE;
+}
+
+
+
+Boolean LIBCALLBACK
+Blast2callbackWithMon (BLAST0ResponsePtr brp, Boolean PNTR cancel)
+{
+ static MonitorPtr mon=NULL, queue_mon=NULL;
+ Boolean retval;
+ BLAST0JobProgressPtr jprogp;
+ BLAST0QueuedPtr queue;
+ Char buffer[40];
+ BLAST0JobDescPtr jdescp;
+
+ *cancel=FALSE;
+
+/* Check for "queued" messages first. */
+ if (brp->choice == BLAST0Response_queued)
+ {
+ if((queue=brp->data.ptrvalue) == NULL)
+ return FALSE;
+
+ if (queue_mon == NULL)
+ {
+ queue_mon=Nlm_MonitorStrNew ("Queued", 20);
+ sprintf(buffer, "Waiting for %ld jobs to finish", queue->length);
+ retval = Nlm_MonitorStrValue (queue_mon, buffer);
+ if (retval == FALSE)
+ { /* If cancelled, then shutdown monitor */
+ *cancel = TRUE;
+ queue_mon = MonitorFree(queue_mon);
+ return FALSE;
+ }
+ }
+ else
+ {
+ retval = Nlm_MonitorStrValue (queue_mon, "still waiting");
+ if (retval == FALSE)
+ { /* If cancelled, then shutdown monitor */
+ *cancel = TRUE;
+ queue_mon = MonitorFree(queue_mon);
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ else if (queue_mon != NULL)
+ {
+ queue_mon = MonitorFree(queue_mon);
+ }
+
+ switch (brp->choice)
+ {
+ case BLAST0Response_job_start:
+ if ((jdescp = (BLAST0JobDescPtr) brp->data.ptrvalue) == NULL)
+ {
+ return TRUE;
+ }
+ if (mon != NULL)
+ {
+ MonitorFree(mon);
+ mon = NULL;
+ }
+ mon = MonitorIntNew(jdescp->desc == NULL ? "BLAST" : jdescp->desc,
+ 0, jdescp->size);
+ return TRUE;
+ case BLAST0Response_job_progress:
+ if (mon != NULL)
+ {
+ if ((jprogp = (BLAST0JobProgressPtr) brp->data.ptrvalue) != NULL)
+ {
+ retval = MonitorIntValue(mon, jprogp->done);
+ if (retval == FALSE)
+ { /* If cancelled, then shutdown monitor */
+ *cancel = TRUE;
+ MonitorFree(mon);
+ mon = NULL;
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+ case BLAST0Response_job_done:
+ if (mon != NULL)
+ {
+ MonitorFree(mon);
+ mon = NULL;
+ }
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/*
+ The next five functions set an error hook and detect
+ whether an error occurred (i.e., contact with the
+ server was lost).
+
+ BlastSetErrorHook should be called first, the function
+ BlastErrHookProc is set as the "handler"; BlastSetErrorStatus
+ should then be called to set the error status to FALSE;
+ BlastGetErrorStatus should be called to determine if an error
+ occurred; and then BlastResetOldHook should be called to restore
+ the original hook, in case BLAST is called from within another
+ application that uses this (original) hook.
+
+ BlastSetErrorStatus is also called, to set the error status
+ sometimes if a BlastAsnRead fails. This is taken as evidence
+ of an error, even if none is reported.
+*/
+
+static int LIBCALLBACK
+BlastErrHookProc(const ErrDesc *err)
+
+{
+ error_occurred = TRUE;
+ return 1;
+}
+
+static void
+BlastSetErrorHook(void)
+
+{
+ old_error_hook = Nlm_ErrSetHandler(BlastErrHookProc);
+ return;
+}
+
+static void
+BlastSetErrorStatus(Boolean status)
+
+{
+ error_occurred = status;
+}
+
+static Boolean
+BlastGetErrorStatus(void)
+
+{
+ return error_occurred;
+}
+
+static void
+BlastResetOldHook(void)
+
+{
+ Nlm_ErrSetHandler(old_error_hook);
+ return;
+}
+
+/*
+ The following functions fill a the Error user string with
+ text to identify BLAST and the entry being worked on.
+ The SeqIdPtr is used to make a FASTA id, which is appended
+ to string.
+
+ A Uint1 is returned, which allows Nlm_ErrUserDelete to delete
+ this error string when it's done.
+*/
+
+static Uint1
+BlastSetUserErrorString(CharPtr string, SeqIdPtr sip)
+
+{
+ Char buffer[2*NETBLAP2_SHORT_BUFLEN], textid[NETBLAP2_SHORT_BUFLEN];
+ CharPtr buf_start, ptr;
+ Int2 length;
+
+ ptr = buf_start = &buffer[0];
+
+ StringNCpy(ptr, string, NETBLAP2_SHORT_BUFLEN);
+ if (sip != NULL)
+ {
+ length = StringLen(string);
+ if (length > NETBLAP2_SHORT_BUFLEN)
+ length = NETBLAP2_SHORT_BUFLEN;
+
+ ptr += length;
+
+ SeqIdWrite(sip, textid, PRINTID_FASTA_LONG, NETBLAP2_SHORT_BUFLEN-1);
+ StringNCpy(ptr, textid, NETBLAP2_SHORT_BUFLEN-1);
+ }
+ return Nlm_ErrUserInstall (buf_start, 0);
+}
+
+static void
+BlastDeleteUserErrorString(Uint1 err_id)
+
+{
+ Nlm_ErrUserDelete(err_id);
+ return;
+}
+
+
+/***************************************************************************
+*
+* Function to submit a BLAST request using an IUPAC string.
+*
+* sequence: contains the sequence, one residue or base per byte
+* length: number of residues or bases
+* id: (preferably) FASTA id or just a string to identify the sequence by
+* defline: FASTA defline (no ">")
+* progname: one of blastn, blastp, blastx, tblastn, or tblastx
+* dbname: name of the database (e.g., "nr")
+* cmdLineOptions: BLAST options, separated by spaces (e.g.,
+* "B=20 S=70 S2=70")
+* blrespPtr: BLAST0ResponsePtr to send information back by.
+* mask_seqloc: which parts of the sequence should be masked
+* output: output mode, see note on BlastBioseq
+* progCallback: reports progress by Callback
+*****************************************************************************/
+BLAST0ResultPtr LIBCALL
+BlastAnIUPACString(CharPtr sequence, Int4 length, CharPtr id, CharPtr defline, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Uint4 output, ProgressCallback progCallback)
+
+{
+ BLAST0ResultPtr result;
+ BioseqPtr bsp;
+ Boolean is_na;
+
+
+ if (sequence == NULL || *sequence == NULLB)
+ return NULL;
+
+ *blrespPtr = NULL;
+
+ if (StringCmp(progname, "blastn") == 0 ||
+ StringCmp(progname, "blastx") == 0 ||
+ StringCmp(progname, "tblastx") == 0)
+ is_na = TRUE;
+ else
+ is_na = FALSE;
+
+ bsp = StringToBioseq(sequence, is_na, length, id, defline);
+ result = BlastBioseq(bsp, progname, dbname, cmdLineOptions, blrespPtr, mask_seqloc, output, progCallback);
+
+ return result;
+}
+
+/********************************************************************************
+* This function takes a IUPAC string of sequence and stores it in a
+* BioseqPtr, for use by BlastBioseq or BlastBioseq2. "sequence"
+* contains the sequence, "is_na" specifies that the sequence is
+* nucleotide, "length" specifies how many residues/basepairs.
+*
+*****************************************************************************/
+
+static BioseqPtr LIBCALL
+StringToBioseq (CharPtr sequence, Boolean is_na, Int4 length, CharPtr fasta_id, CharPtr defline)
+
+{
+ BioseqPtr bsp;
+ ByteStorePtr byte_store;
+ SeqIdPtr sip;
+ ObjectIdPtr oid;
+ ValNodePtr vnp;
+
+ if (sequence == NULL || *sequence == NULLB)
+ return NULL;
+
+ bsp = BioseqNew();
+
+/* Get the id, copied from MakeSeqID in tofasta.c */
+ sip = NULL;
+ if (fasta_id && StringChr(fasta_id, '|') != NULL)
+ sip = SeqIdParse(fasta_id);
+ else
+ {
+ sip = ValNodeNew(NULL);
+ oid = ObjectIdNew();
+ if (fasta_id != NULL && *fasta_id != NULLB)
+ oid->str = StringSave(fasta_id);
+ else
+ oid->str = StringSave("unknown");
+ sip->choice = SEQID_LOCAL;
+ sip->data.ptrvalue = (Pointer) oid;
+ }
+ bsp->id = sip;
+
+/* This is "real" sequence and not virtual */
+ bsp->repr = Seq_repr_raw;
+
+/* What type of molecule? */
+ if (is_na)
+ {
+ bsp->mol = Seq_mol_na;
+ bsp->seq_data_type = Seq_code_iupacna;
+ }
+ else
+ {
+ bsp->mol = Seq_mol_aa;
+ bsp->seq_data_type = Seq_code_ncbieaa;
+ }
+
+/* Put the defline in the Bioseq.descr */
+ if (defline != NULL && *defline != NULLB)
+ {
+ vnp = ValNodeNew (NULL);
+ vnp->choice = Seq_descr_title;
+ vnp->data.ptrvalue = StringSave(defline);
+ bsp->descr = vnp;
+ }
+ else
+ bsp->descr = NULL;
+
+/* Store the sequence in a ByteStore and attach to Bioseq */
+ byte_store = BSNew(length);
+ sequence[length] = '\0';
+ BSWrite(byte_store, (VoidPtr) sequence, length);
+ bsp->seq_data = byte_store;
+ bsp->length = length;
+
+ return bsp;
+}
+
+BLAST0ResultPtr LIBCALL
+SimpleBlastBioseq(BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, Boolean useMonitors)
+{
+ return BlastBioseq(bsp, progname, dbname, cmdLineOptions, NULL, NULL, 15, useMonitors ? Blast2callbackWithMon : NULL);
+}
+
+/***************************************************************************
+*
+* Run BLAST on the BioseqPtr with the program "progname" and database
+* "dbname". By setting bits on the Uint4 one can determine the
+* amount of output returned. These correspond to four of the five
+* Uint1's in BLAST0Search:
+*
+* 1st bit, if set omit matrix (return_matrix is FALSE);
+* 2nd bit, if set omit query (return_query is FALSE);
+* 3rd bit, if set omit query seq (return_query_seq_in_seg is FALSE);
+* 4th bit, if set omit db seq (return_db_seq_in_seg is FALSE);
+*
+* "mask_seqloc" gives the position of the sequence to be masked.
+* A filtering program (e.g., dust or seg should return a SeqLocPtr),
+* indicating which sequence should be masked.
+*
+************************************************************************/
+
+static BLAST0ResultPtr LIBCALL
+BlastBioseqInternal(BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Uint4 output, ProgressCallback progCallback, Boolean MTSafe, BlastMTHandlePtr BlastMThp);
+
+BLAST0ResultPtr LIBCALL
+BlastBioseq(BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Uint4 output, ProgressCallback progCallback) {
+
+ return BlastBioseqInternal(bsp, progname,
+ dbname,
+ cmdLineOptions,
+ blrespPtr,
+ mask_seqloc,
+ output,
+ progCallback,
+ FALSE,
+ NULL
+ );
+}
+
+BLAST0ResultPtr LIBCALL
+BlastBioseqMT(BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Uint4 output, ProgressCallback progCallback, BlastMTHandlePtr BlastMThp) {
+
+ return BlastBioseqInternal(bsp, progname,
+ dbname,
+ cmdLineOptions,
+ blrespPtr,
+ mask_seqloc,
+ output,
+ progCallback,
+ TRUE,
+ BlastMThp
+ );
+}
+
+static BLAST0ResultPtr LIBCALL
+BlastBioseqInternal(BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Uint4 output, ProgressCallback progCallback, Boolean MTSafe, BlastMTHandlePtr BlastMThp)
+{
+ BLAST0RequestPtr blreqp;
+ Boolean is_na;
+ BLAST0ResultPtr retval = NULL;
+ Int4 gi = -1;
+ Char textid[NETBLAP2_BUFLEN+1];
+ CharPtr ptr, ptr_textid;
+ PrepRequestInfo pri;
+ SeqPortPtr spp;
+ Uint1 err_id;
+ ValNodePtr vnp;
+
+ if (bsp == NULL)
+ return NULL;
+
+ err_id = BlastSetUserErrorString("blast2:", bsp->id);
+
+ if (ISA_na(bsp->mol))
+ is_na = TRUE;
+ else
+ is_na = FALSE;
+
+ if (is_na)
+ spp = SeqPortNew(bsp, 0, -1, 0, Seq_code_iupacna);
+ else
+ spp = SeqPortNew(bsp, 0, -1, 0, Seq_code_iupacaa);
+
+ if (spp == NULL) {
+ if(MTSafe == TRUE)
+ BlastMThp->error = StringSave("BlastBioseq: Unable to open SeqPort");
+ else
+ ErrPostEx(SEV_ERROR, 0, 0, "BlastBioseq: Unable to open SeqPort");
+ return NULL;
+ }
+
+
+ SeqIdWrite(bsp->id, textid, PRINTID_FASTA_LONG, NETBLAP2_BUFLEN);
+ ptr_textid = textid;
+ /* If the textid starts with gi, then strip it off, as the gi is listed
+ separately. */
+ if (StringNCmp(textid, "gi|", 3) == 0)
+ {
+ ptr_textid += 3;
+ while (*ptr_textid != NULLB && *ptr_textid != '|')
+ ptr_textid++;
+ if (*ptr_textid == '|')
+ ptr_textid++;
+ }
+
+ pri.is_na = is_na;
+ ptr = pri.defline = BioseqGetTitle(bsp);
+/* Strip out all non-printing characters. (Important as NCBI ASN1 doesn't
+support this).*/
+ if (ptr != NULL)
+ {
+ while (*ptr != NULLB)
+ {
+ if (*ptr < ' ' || *ptr > '~' || *ptr == '\n' || *ptr == '\r')
+ *ptr = ' ';
+ ptr++;
+ }
+ }
+
+ pri.options = cmdLineOptions;
+ pri.dbname = dbname;
+ if (ptr_textid != NULL && *ptr_textid != NULLB)
+ {
+ pri.textid = StringSave(ptr_textid);
+ }
+ else
+ {
+ pri.textid = NULL;
+ }
+ pri.progname = progname;
+ pri.length = BioseqGetLen(bsp);
+ if ((vnp = bsp->id) != NULL)
+ {
+ while (vnp)
+ {
+ if (vnp->choice == SEQID_GI)
+ {
+ gi = vnp->data.intvalue;
+ break;
+ }
+ vnp = vnp->next;
+ }
+ }
+ pri.gi = gi;
+ pri.spp = spp;
+
+/* Set flags in "pri" that control the amount returned. */
+
+ if (output & BLAST_SERVER_OMIT_MATRIX)
+ pri.return_matrix = FALSE;
+ else
+ pri.return_matrix = TRUE;
+
+ if (output & BLAST_SERVER_OMIT_QUERY)
+ pri.return_query = FALSE;
+ else
+ pri.return_query = TRUE;
+
+ if (output & BLAST_SERVER_OMIT_QUERY_SEQ_IN_SEG)
+ pri.return_query_seq_in_seg = FALSE;
+ else
+ pri.return_query_seq_in_seg = TRUE;
+
+ if (output & BLAST_SERVER_OMIT_DB_SEQ_IN_SEG)
+ pri.return_db_seq_in_seg = FALSE;
+ else
+ pri.return_db_seq_in_seg = TRUE;
+
+ pri.return_BLAST0result = TRUE; /* always a BLAST0Result */
+
+ pri.mask = mask_seqloc;
+ pri.start = 0;
+
+ blreqp = PrepareRequest(&pri);
+
+ if (pri.spp)
+ pri.spp = SeqPortFree(pri.spp);
+
+ if (blreqp == NULL)
+ return NULL;
+
+ if (MTSafe == TRUE)
+ retval = SubmitResultBlastRequestMT(blreqp,
+ blrespPtr,
+ progCallback,
+ BlastMThp
+ );
+ else
+ retval = SubmitResultBlastRequestNew(blreqp,
+ blrespPtr,
+ progCallback
+ );
+
+ BLAST0RequestFree(blreqp);
+
+ BlastDeleteUserErrorString(err_id);
+
+ return retval;
+}
+
+/************************************************************************
+* Perform BLAST on the sequence from a SeqLoc. The use of SeqLocId
+* ensures that each SeqLoc is associated with only one SeqId,
+* otherwise NULL is returned.
+************************************************************************/
+
+static BLAST0ResultPtr LIBCALL
+BlastSeqLoc(SeqLocPtr slp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, ProgressCallback progCallback)
+{
+ BLAST0RequestPtr blreqp;
+ BioseqPtr bsp;
+ Boolean is_na;
+ BLAST0ResultPtr retval = NULL;
+ Int2 mol_type;
+ Int4 gi = -1;
+ Char textid[NETBLAP2_BUFLEN+1];
+ PrepRequestInfo pri;
+ SeqIdPtr sip;
+ SeqPortPtr spp;
+ Uint1 err_id;
+ ValNodePtr vnp;
+
+ sip = SeqLocId(slp);
+ if (sip == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "BlastSeqLoc: Unable to get SeqId");
+ return NULL;
+ }
+
+/* Find the bsp for the title (i.e., defline) */
+ bsp = BioseqLockById(sip);
+ if (bsp == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "BlastSeqLoc: Unable to get Bioseq");
+ return NULL;
+ }
+
+ err_id = BlastSetUserErrorString("blast2:", bsp->id);
+
+ mol_type = SeqLocMol(slp);
+
+ if (ISA_na(mol_type))
+ is_na = TRUE;
+ else
+ is_na = FALSE;
+
+ if (is_na)
+ spp = SeqPortNewByLoc(slp, Seq_code_iupacna);
+ else
+ spp = SeqPortNewByLoc(slp, Seq_code_iupacaa);
+
+ if (spp == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "BlastBioseq: Unable to open SeqPort");
+ return NULL;
+ }
+
+
+ SeqIdWrite(sip, textid, PRINTID_FASTA_LONG, NETBLAP2_BUFLEN);
+
+ pri.is_na = is_na;
+ pri.defline = BioseqGetTitle(bsp);
+ pri.options = cmdLineOptions;
+ pri.dbname = dbname;
+ pri.textid = StringSave(textid);
+ pri.progname = progname;
+ pri.length = SeqLocLen(slp);
+ if ((vnp = sip) != NULL)
+ {
+ while (vnp)
+ {
+ if (vnp->choice == SEQID_GI)
+ {
+ gi = vnp->data.intvalue;
+ break;
+ }
+ vnp = vnp->next;
+ }
+ }
+ pri.gi = gi;
+ pri.spp = spp;
+
+ pri.mask = mask_seqloc;
+ pri.start = 0;
+
+ blreqp = PrepareRequest(&pri);
+
+ if (blreqp == NULL)
+ return NULL;
+
+
+ retval = SubmitResultBlastRequest(blreqp, blrespPtr, progCallback);
+
+ BLAST0RequestFree(blreqp);
+
+ BlastDeleteUserErrorString(err_id);
+
+ return retval;
+}
+
+/*****************************************************************
+* Submits a BLAST0RequestPtr and returns BLAST0ResponsePtr.
+* This function should not be used to submit search requests,
+* (i.e., perform a BLAST search, BLAST0-Request.search)
+* but for database inquiries etc. To submit a search request
+* use BlastBioseq, BlastBioseq2, SubmitSearchRequest, etc.
+*****************************************************************/
+
+BLAST0ResponsePtr SubmitInfoRequest (BLAST0RequestPtr blreqp)
+{
+ return SubmitInfoRequestInternal(blreqp, NULL, FALSE);
+}
+
+BLAST0ResponsePtr SubmitInfoRequestMT (BLAST0RequestPtr blreqp,
+ BlastMTHandlePtr BlastMThp)
+{
+ return SubmitInfoRequestInternal(blreqp, BlastMThp , TRUE);
+}
+
+static BLAST0ResponsePtr SubmitInfoRequestInternal (BLAST0RequestPtr blreqp, BlastMTHandlePtr BlastMThp, Boolean MTSafe)
+
+{
+ Boolean success;
+ BLAST0ResponsePtr blresp=NULL;
+ Int2 index;
+
+ if(MTSafe == FALSE) {
+ BlastSetErrorHook();
+
+ for(index=0; index<BLAST_SERVER_RETRIES; index++)
+ {
+ BlastSetErrorStatus(FALSE);
+ success = BLAST0RequestAsnWrite (blreqp, asnout, NULL);
+ if (success == FALSE)
+ {
+ ErrPostEx(SEV_WARNING, 0, 0, "BLAST0RequestAsnWrite failed");
+ break; /* Call BlastResetOldHook outside of loop. */
+ }
+ AsnIoReset (asnout);
+ /* read back response */
+ blresp = BLAST0ResponseAsnRead(asnin, NULL);
+ /* Only check for an error if blresp is non-NULL, otherwise take this
+ as an ERROR! */
+ if(blresp && BlastGetErrorStatus() == FALSE)
+ break;
+
+ ReestablishNetBlast();
+
+ }
+ BlastResetOldHook();
+ } else { /* MTSafe = TRUE */
+ for(index=0; index < BLAST_SERVER_RETRIES; index++) {
+ if((success = BLAST0RequestAsnWrite (blreqp,
+ BlastMThp->svcp->waip,
+ NULL)) == FALSE) {
+ BlastMThp->error = StringSave("BLAST0RequestAsnWrite failed");
+ break;
+ }
+ AsnIoReset (BlastMThp->asnout);
+ if((blresp = BLAST0ResponseAsnRead(BlastMThp->svcp->raip,
+ NULL)) == NULL) {
+ if(BlastMThp->svcp != NULL) {
+ BlastFiniMT(BlastMThp);
+ BlastInitMT(BlastMThp, "blast2", FALSE);
+ }
+ } else
+ break;
+ }
+ }
+ return blresp;
+}
+
+/********************************************************************
+*
+* Prepare a request from the information in the PrepRequestInfoPtr.
+* Note that only two alphabets (Seq_code_ncbi4na and
+* Seq_code_ncbistdaa) are supported.
+*********************************************************************/
+static BLAST0RequestPtr PrepareRequest (PrepRequestInfoPtr prip)
+
+{
+
+ Boolean is_na = prip->is_na;
+ BLAST0RequestPtr blreqp;
+ BLAST0SearchPtr blsrchp;
+ BLAST0SequencePtr blseqp;
+ BLAST0SeqDescPtr seqdesc;
+ BLAST0SeqIdPtr id=NULL;
+ Char textid[NETBLAP2_BUFLEN+1];
+ Uint1 seqAlphabet;
+ Int4 index, start, total;
+ Int2 cmdLineLen;
+ Uint1 buffer[NETBLAP2_BUFLEN+1];
+ CharPtr p, pSave, q;
+ CharPtr cmdLineOptions = prip->options;
+ SeqLocPtr mask_slp = prip->mask;
+ Uint1 bitctr, residue, mask_residue;
+ ValNodePtr node;
+ SeqPortPtr spp = prip->spp;
+
+ /* computed values */
+ ByteStorePtr theSequence;
+ Int2 alphabet;
+
+
+ alphabet = is_na ? BLAST0SeqData_ncbi4na : BLAST0SeqData_ncbistdaa;
+ seqAlphabet = is_na ? Seq_code_ncbi4na : Seq_code_ncbistdaa;
+
+ if (is_na)
+ mask_residue = 'N';
+ else
+ mask_residue = 'X';
+
+ /* Turn virtual sequences into ambig. chars. */
+ SeqPortSet_do_virtual(spp, TRUE);
+
+ theSequence = NULL;
+ bitctr = 0;
+ total=0;
+ start = prip->start;
+ while (total < prip->length)
+ {
+ index=0;
+ while ((residue=SeqPortGetResidue(spp)) != SEQPORT_EOF)
+ {
+ if (IS_residue(residue))
+ {
+ buffer[index] = residue;
+ index++;
+ }
+ else if (residue == SEQPORT_EOS)
+ {
+ ErrPostEx(SEV_INFO, 0, 0,"[Segment boundary]\n");
+ }
+ else if (residue == SEQPORT_VIRT)
+ { /* No sequence, return NULL. */
+ ErrPostEx(SEV_WARNING, 0, 0,"[Virtual Sequence]\n");
+ return NULL;
+ }
+ else
+ {
+ buffer[index] = 'A';
+ index++;
+ ErrPostEx(SEV_WARNING,
+ 0, 0,"Unrecognized residue [%d], replaced by A\n", residue);
+ }
+
+ if (index == NETBLAP2_BUFLEN)
+ break;
+ }
+ if (index > 0)
+ MaskTheResidues(buffer, index, mask_residue, (start+total), mask_slp);
+ total += index;
+ if (index > 0)
+ {
+ if (is_na)
+ theSequence = StoreResiduesInBS(buffer, index, theSequence, &bitctr, seqAlphabet, Seq_code_iupacna, prip->length);
+ else
+ theSequence = StoreResiduesInBS(buffer, index, theSequence, &bitctr, seqAlphabet, Seq_code_iupacaa, prip->length);
+ }
+ else if (total == 0)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "PrepareRequest: no sequence");
+ return NULL;
+ }
+ }
+
+ blreqp = ValNodeNew(NULL);
+ blreqp->choice = BLAST0Request_search;
+ blsrchp = BLAST0SearchNew();
+ blreqp->data.ptrvalue = blsrchp;
+ blsrchp->program = StringSave(prip->progname);
+ blsrchp->database = StringSave(prip->dbname);
+ blseqp = BLAST0SequenceNew();
+ blsrchp->query = blseqp;
+ blsrchp->options = NULL;
+/* Go through the string cmdLineOptions taking off leading spaces. */
+/* If cmdLineOptions consists only of spaces it will be rejected. */
+ if (cmdLineOptions)
+ while (*cmdLineOptions == ' ')
+ cmdLineOptions++;
+ if (cmdLineOptions != NULL && *cmdLineOptions != NULLB)
+ { /* parse the string */
+ /* avoid using strtok(), since it's not reentrant */
+ cmdLineLen = StrLen(cmdLineOptions);
+ /* make a copy, and append a space to simplify parsing */
+ pSave = MemNew(cmdLineLen + 2);
+ StrCpy(pSave, cmdLineOptions);
+ pSave[cmdLineLen] = ' ';
+ pSave[cmdLineLen+1] = '\0';
+ p = pSave;
+ while ((q = StrPBrk(p, " \t")) != NULL)
+ {
+ *q = '\0';
+ if (blsrchp->options == NULL)
+ {
+ node = ValNodeNew(NULL);
+ blsrchp->options = node;
+ } else {
+ node = ValNodeNew(blsrchp->options);
+ }
+ node->data.ptrvalue = (VoidPtr) StringSave(p);
+ p = q + 1;
+ /* skip over the white space */
+ while (*p && ( *p == ' ' || *p == '\t'))
+ p++;
+ }
+ MemFree(pSave);
+ }
+
+/* Set the Booleans that determine the amount of output. */
+ blsrchp->return_matrix = prip->return_matrix;
+ blsrchp->return_query = prip->return_query;
+ blsrchp->return_BLAST0result = prip->return_BLAST0result;
+ blsrchp->return_query_seq_in_seg = prip->return_query_seq_in_seg;
+ blsrchp->return_db_seq_in_seg = prip->return_db_seq_in_seg;
+
+ seqdesc = BLAST0SeqDescNew();
+ blseqp->desc = seqdesc;
+
+ id = NULL;
+ if (prip->gi != -1)
+ {
+ id = seqdesc->id = ValNodeNew(NULL);
+ id->choice = BLAST0SeqId_giid;
+ id->data.intvalue = prip->gi;
+ }
+/* Make sure every textid has a "|" in the body. */
+ if (prip->textid)
+ {
+ if (id)
+ {
+ id->next = ValNodeNew(NULL);
+ id = id->next;
+ }
+ else
+ {
+ id = seqdesc->id = ValNodeNew(NULL);
+ }
+
+ if (StringChr(prip->textid, '|') == NULL)
+ {
+ sprintf(textid, "lcl|%s", prip->textid);
+ }
+ else
+ {
+ sprintf(textid, "%s", prip->textid);
+ }
+ id->data.ptrvalue = StringSave(textid);
+ id->choice = BLAST0SeqId_textid;
+ }
+/* ID is required, make up one if none is available. */
+ if (seqdesc->id == NULL)
+ {
+ id = seqdesc->id = ValNodeNew(NULL);
+ id->data.ptrvalue = StringSave("lcl|unknown");
+ id->choice = BLAST0SeqId_textid;
+ }
+ prip->textid = MemFree(prip->textid);
+ seqdesc->defline = StringSave(prip->defline);
+
+ blseqp->length = prip->length;
+ blseqp->gcode = 1;
+ blseqp->seq = ValNodeNew(NULL);
+ blseqp->seq->choice = alphabet;
+ blseqp->seq->data.ptrvalue = theSequence;
+
+ return blreqp;
+
+}
+
+/*************************************************************************
+*
+* MaskTheResidues masks up to max_length residues in buffer.
+* The residue to be used for masking (generally 'N' for nucleotides
+* and 'X' for proteins) is mask_residue. offset tells how far
+* along the sequence the first residue in buffer is. mask_slp
+* specifies which parts of the sequence to mask.
+*
+*************************************************************************/
+
+static void
+MaskTheResidues(Uint1Ptr buffer, Int4 max_length, Uint1 mask_residue, Int4 offset, SeqLocPtr mask_slp)
+
+{
+ SeqLocPtr slp=NULL;
+ Int4 index, position, start, stop;
+
+ while (mask_slp)
+ {
+ slp=NULL;
+ while((slp = SeqLocFindNext(mask_slp, slp))!=NULL)
+ {
+ start = SeqLocStart(slp);
+ stop = SeqLocStop(slp);
+ for (index=0; index<max_length; index++)
+ {
+ position = index+offset;
+ if (position >= start)
+ {
+ if (position <= stop)
+ buffer[index] = mask_residue;
+ else if (position > stop)
+ break;
+ }
+ }
+ }
+ mask_slp = mask_slp->next;
+ }
+
+}
+
+/*
+
+ This function returns the state of the Boolean "job_cancelled".
+ If it is "TRUE", then the BLAST job has been cancelled through
+ the monitor (e.g., Blast2callbackWithMon).
+*/
+Boolean LIBCALL
+CheckIfBlastJobCancelled(void)
+
+{
+ return job_cancelled;
+}
+
+
+/*************************************************************************
+*
+* Submits a BLAST0RequestPtr and returns a SeqAlignPtr.
+*
+* This function checks that no error occurred, which is taken
+* as evidence that the connection has not been dropped by
+* the server.
+*************************************************************************/
+SeqAlignPtr
+SubmitSeqAlignBlastRequest(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback)
+
+{
+ Int2 index;
+ SeqAlignPtr seqalign;
+
+ BlastSetErrorHook();
+ for(index=0; index<BLAST_SERVER_RETRIES; index++)
+ {
+ BlastSetErrorStatus(FALSE);
+
+ seqalign = RealSubmitSeqAlignBlastRequest(blreqp, blrespPtr, progCallback);
+
+ if (job_cancelled == TRUE)
+ {
+ seqalign = SeqAlignFree(seqalign);
+ ReestablishNetBlast();
+ break;
+ }
+
+ if(BlastGetErrorStatus() == FALSE)
+ break;
+
+ ReestablishNetBlast();
+ }
+ BlastResetOldHook();
+
+ return seqalign;
+
+}
+
+/**************************************************************************
+* Submits a BLAST0RequestPtr and returns a SeqAlignPtr.
+* Checking is done that the BLAST0SearchPtr really specifies that a
+* SeqAlignPtr should be returned.
+*
+* This function should be called from SubmitSeqAlignBlastRequest,
+* which checks that the server didn't drop the session.
+************************************************************************/
+static SeqAlignPtr
+RealSubmitSeqAlignBlastRequest(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback)
+
+{
+ BLAST0SearchPtr search;
+ SeqAlignPtr seqalign;
+
+ if (blreqp && blreqp->choice == BLAST0Request_search)
+ {
+ search = (BLAST0SearchPtr) blreqp->data.ptrvalue;
+ if (search->return_BLAST0result == FALSE)
+ seqalign = (SeqAlignPtr) SubmitBlastRequest(blreqp, blrespPtr, progCallback, TRUE);
+ else
+ ErrPostEx(SEV_WARNING, 0, 0, "SubmitSeqAlignBlastRequest: wrong type of BLAST0Search");
+ }
+ return seqalign;
+}
+
+
+/**************************************************************************
+*
+* Submits a BLAST0RequestPtr and returns a BLAST0ResultPtr.
+* Checking is done that the BLAST0SearchPtr really specifies that a
+* BLAST0ResultPtr should be returned.
+* If the Request is NULL, then NULL is returned.
+************************************************************************/
+BLAST0ResultPtr
+SubmitResultBlastRequest(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback)
+
+{
+ BLAST0ResultPtr result=NULL;
+ Int2 index;
+
+ BlastSetErrorHook();
+ for(index=0; index<BLAST_SERVER_RETRIES; index++)
+ {
+ BlastSetErrorStatus(FALSE);
+
+ result = RealSubmitResultBlastRequest(blreqp, blrespPtr, progCallback);
+
+ if (job_cancelled == TRUE)
+ {
+ result = BLAST0ResultFree(result);
+ *blrespPtr = BLAST0ResponseFree(*blrespPtr);
+ ReestablishNetBlast();
+ break;
+ }
+
+ if(BlastGetErrorStatus() == FALSE)
+ break;
+
+ ReestablishNetBlast();
+ }
+
+ BlastResetOldHook();
+
+ return result;
+}
+
+/**************************************************************************
+*
+* Submits a BLAST0RequestPtr and returns a BLAST0ResultPtr.
+* Checking is done that the BLAST0SearchPtr really specifies that a
+* BLAST0ResultPtr should be returned.
+* If the Request is NULL, then NULL is returned.
+************************************************************************/
+static BLAST0ResultPtr
+RealSubmitResultBlastRequest(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback)
+
+{
+ BLAST0SearchPtr search;
+ BLAST0ResultPtr result=NULL;
+
+ if (blreqp && blreqp->choice == BLAST0Request_search)
+ {
+ search = (BLAST0SearchPtr) blreqp->data.ptrvalue;
+ if (search->return_BLAST0result == TRUE)
+ result = (BLAST0ResultPtr) SubmitBlastRequest(blreqp, blrespPtr, progCallback, FALSE);
+ else
+ ErrPostEx(SEV_WARNING, 0, 0, "SubmitResultBlastRequest: wrong type of BLAST0Search");
+ }
+
+ return result;
+}
+
+/**************************************************************************
+*
+* Submit a BLAST search request (i.e., a BLAST0-Search) using a
+* BLAST0RequestPtr. The return value is a VoidPtr, which must
+* be recast as either a BLAST0ResultPtr or a SeqAlignPtr by
+* the calling function. The type of data returned is determined
+* by BLAST0Search.return_BLAST0result. This should be checked by
+* the submitting function!
+*
+*************************************************************************/
+
+static VoidPtr
+SubmitBlastRequest(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback, Boolean get_seqalign)
+
+{
+ Boolean cancel=FALSE, done = FALSE, freeIt, success;
+ BLAST0ResponsePtr bllist = NULL, blresp;
+ BLAST0ResultPtr blastResult;
+ SeqAlignPtr seqalign;
+ VoidPtr retval = NULL;
+
+/* NULL out *blrespPtr if it's not already. */
+ if (blrespPtr != NULL)
+ if (*blrespPtr != NULL)
+ *blrespPtr = NULL;
+
+/* set the "cancel" flag to FALSE. */
+ job_cancelled = FALSE;
+
+ success = BLAST0RequestAsnWrite (blreqp, asnout, NULL);
+ if (success == FALSE || asnout == NULL)
+ {
+ ErrPostEx(SEV_WARNING, 0, 0, "BLAST0RequestAsnWrite failed");
+ return NULL;
+ }
+ AsnIoReset (asnout);
+
+ success=FALSE;
+ /* now read back response */
+ while (!done && (blresp = BLAST0ResponseAsnRead(asnin, NULL)) != NULL)
+ {
+ success=TRUE;
+ switch (blresp->choice) {
+ case BLAST0Response_ack:
+ done = TRUE;
+ break;
+ case BLAST0Response_result:
+ blastResult = (BLAST0ResultPtr) blresp->data.ptrvalue;
+ if (blastResult != NULL)
+ {
+ retval = (VoidPtr) blastResult;
+ blresp->data.ptrvalue = NULL; /* for clean free */
+
+ BLAST0ResponseFree(blresp);
+ }
+ break;
+ case BLAST0Response_seqalign:
+ seqalign = (SeqAlignPtr) blresp->data.ptrvalue;
+ if (seqalign != NULL)
+ {
+ retval = (VoidPtr) seqalign;
+ blresp->data.ptrvalue = NULL; /* for clean free */
+
+ BLAST0ResponseFree(blresp);
+ }
+ break;
+
+ case BLAST0Response_job_start:
+ case BLAST0Response_job_progress:
+ case BLAST0Response_job_done:
+ case BLAST0Response_queued:
+ default:
+ freeIt = TRUE;
+ if (progCallback != NULL)
+ {
+ if (! progCallback(blresp, &cancel))
+ { /* otherwise, make a linked list of other portions of response */
+ if (cancel == TRUE)
+ {
+ job_cancelled = TRUE;
+ done = TRUE;
+ }
+
+
+ if (blrespPtr != NULL && get_seqalign == FALSE)
+ {
+ if (bllist != NULL)
+ {
+ bllist->next = blresp;
+ } else {
+ *blrespPtr = blresp;
+ }
+
+ blresp->next = NULL;
+ bllist = blresp;
+ freeIt = FALSE;
+ }
+ }
+ }
+/* get_seqalign TRUE (BlastBioseq2 or BlastSeqLoc2); only warnings are saved. */
+ if (get_seqalign == TRUE &&
+ blresp->choice == BLAST0Response_status &&
+ blrespPtr != NULL)
+ {
+ *blrespPtr = blresp;
+ break;
+ }
+ if (freeIt)
+ {
+ BLAST0ResponseFree(blresp);
+ }
+ break;
+ }
+ }
+
+/* If success was never reset to TRUE (i.e., loop never ran) then
+set it to TRUE to indicate that an error DID occur! */
+ if (success == FALSE)
+ BlastSetErrorStatus(TRUE);
+
+ return retval;
+}
+
+
+static BLAST0ResultPtr
+SubmitResultBlastRequestMT(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback, BlastMTHandlePtr BlastMThp) {
+
+ return (BLAST0ResultPtr)
+ SubmitBlastRequestInternal( blreqp,
+ blrespPtr,
+ progCallback,
+ FALSE, TRUE,
+ BlastMThp
+ );
+}
+
+static SeqAlignPtr
+SubmitSeqAlignBlastRequestMT(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback, BlastMTHandlePtr BlastMThp) {
+
+ return (SeqAlignPtr)
+ SubmitBlastRequestInternal( blreqp,
+ blrespPtr,
+ progCallback,
+ TRUE, TRUE,
+ BlastMThp
+ );
+}
+static BLAST0ResultPtr
+SubmitResultBlastRequestNew(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback) {
+
+ return (BLAST0ResultPtr)
+ SubmitBlastRequestInternal( blreqp,
+ blrespPtr,
+ progCallback,
+ FALSE, FALSE,
+ NULL
+ );
+}
+
+static SeqAlignPtr
+SubmitSeqAlignBlastRequestNew(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback) {
+
+ return (SeqAlignPtr)
+ SubmitBlastRequestInternal( blreqp,
+ blrespPtr,
+ progCallback,
+ TRUE, FALSE,
+ NULL
+ );
+}
+static VoidPtr
+SubmitBlastRequestInternal(BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback, Boolean get_seqalign, Boolean MTSafe, BlastMTHandlePtr BlastMThp)
+
+{
+ Boolean cancel=FALSE, done = FALSE, freeIt, success;
+ BLAST0ResponsePtr bllist = NULL, blresp;
+ BLAST0SearchPtr search;
+ SeqAlignPtr seqalign;
+ VoidPtr retval = NULL;
+ Int2 index;
+ AsnIoPtr local_asnin;
+ AsnIoPtr local_asnout;
+
+ if(MTSafe == TRUE) {
+ local_asnin = BlastMThp->svcp->raip;
+ local_asnout = BlastMThp->svcp->waip;
+ } else {
+ local_asnin = asnin; /* assigning to globals */
+ local_asnout = asnout;
+ }
+
+ /* --------- stuff from previous functions ---------- */
+
+
+ if (blreqp && blreqp->choice != BLAST0Request_search)
+ return NULL;
+ else {
+ search = (BLAST0SearchPtr) blreqp->data.ptrvalue;
+ if (search->return_BLAST0result != TRUE) {
+ if(MTSafe == TRUE)
+ BlastMThp->error =
+ StringSave("SubmitResultBlastRequest: wrong type of BLAST0Search");
+ else
+ ErrPostEx(SEV_WARNING, 0, 0,
+ "SubmitResultBlastRequest: wrong type of BLAST0Search");
+ return NULL;
+ }
+ }
+ if(MTSafe == FALSE)
+ BlastSetErrorHook();
+
+ for(index=0; index < BLAST_SERVER_RETRIES; index++) {
+ if(MTSafe == FALSE)
+ BlastSetErrorStatus(FALSE);
+
+ /* NULL out *blrespPtr if it's not already. */
+ if (blrespPtr != NULL)
+ if (*blrespPtr != NULL)
+ *blrespPtr = NULL;
+
+
+ if((success = BLAST0RequestAsnWrite (blreqp,
+ local_asnout,
+ NULL)) == FALSE) {
+ if(MTSafe == TRUE)
+ BlastMThp->error = StringSave("BLAST0RequestAsnWrite failed");
+ else /* MTSafe == FALSE */
+ ErrPostEx(SEV_WARNING, 0, 0, "BLAST0RequestAsnWrite failed");
+ return NULL;
+ }
+
+ AsnIoReset (local_asnout);
+
+ success=FALSE;
+ /* now read back response */
+
+ while (!done &&
+ (blresp = BLAST0ResponseAsnRead(local_asnin, NULL)) != NULL) {
+
+ success=TRUE;
+ switch (blresp->choice) {
+
+ case BLAST0Response_ack:
+ BLAST0ResponseFree(blresp);
+ done = TRUE;
+ break;
+
+ case BLAST0Response_result:
+ retval = blresp->data.ptrvalue;
+ blresp->data.ptrvalue = NULL; /* for clean free */
+ BLAST0ResponseFree(blresp);
+ break;
+
+ case BLAST0Response_seqalign:
+ retval = blresp->data.ptrvalue;
+ blresp->data.ptrvalue = NULL; /* for clean free */
+ BLAST0ResponseFree(blresp);
+ break;
+
+ case BLAST0Response_job_start:
+ case BLAST0Response_job_progress:
+ case BLAST0Response_job_done:
+ case BLAST0Response_queued:
+ default:
+ freeIt = TRUE;
+ if (progCallback != NULL) {
+ if (! progCallback(blresp, &cancel)) {
+ /* otherwise, make a linked list of other portions of response */
+ if (cancel == TRUE) {
+ job_cancelled = TRUE;
+ done = TRUE;
+ }
+ if (blrespPtr != NULL && get_seqalign == FALSE) {
+ if (bllist != NULL) {
+ bllist->next = blresp;
+ } else {
+ *blrespPtr = blresp;
+ }
+
+ blresp->next = NULL;
+ bllist = blresp;
+ freeIt = FALSE;
+ }
+ }
+ }
+ /* get_seqalign TRUE (BlastBioseq2 or BlastSeqLoc2);
+ only warnings are saved. */
+
+ if (get_seqalign == TRUE &&
+ blresp->choice == BLAST0Response_status &&
+ blrespPtr != NULL) {
+ *blrespPtr = blresp;
+ break;
+ }
+ if (freeIt) {
+ BLAST0ResponseFree(blresp);
+ }
+ break;
+ }
+ }
+
+ if(cancel == TRUE ) {
+ if(get_seqalign == FALSE)
+ BLAST0ResultFree((BLAST0ResultPtr) retval);
+ else
+ seqalign = SeqAlignFree((SeqAlignPtr) retval);
+
+ *blrespPtr = BLAST0ResponseFree(*blrespPtr);
+ if (MTSafe == TRUE) {
+ BlastFiniMT(BlastMThp);
+ BlastInitMT(BlastMThp, "blast2", FALSE);
+ local_asnin = BlastMThp->svcp->raip;
+ local_asnout = BlastMThp->svcp->waip;
+ } else {
+ ReestablishNetBlast();
+ local_asnin = asnin; /* assigning to globals */
+ local_asnout = asnout;
+ }
+ break; /* We will not try to connect once again */
+ }
+
+ if (success == FALSE) {
+ if(MTSafe == TRUE) {
+ BlastFiniMT(BlastMThp);
+ BlastInitMT(BlastMThp, "blast2", FALSE);
+ local_asnin = BlastMThp->svcp->raip;
+ local_asnout = BlastMThp->svcp->waip;
+ } else {
+ ReestablishNetBlast();
+ local_asnin = asnin; /* assigning to globals */
+ local_asnout = asnout;
+ }
+ } else if (MTSafe == TRUE){
+ break;
+ }
+
+ if(MTSafe == FALSE && BlastGetErrorStatus() == FALSE)
+ break;
+
+ } /* for (index=0; ... */
+
+ if(MTSafe == FALSE)
+ BlastResetOldHook();
+
+ return retval;
+} /* SubmitBlastRequestMT() */
+
+/***************************************************************************
+*
+* Produce a SeqAnnot from the BLAST data, that was produced using a
+* Bioseq.
+*
+* BLAST0ResponsePtr PNTR blrespPtr is used to return ONLY the
+* BLAST0ResponsePtr of type warning ("BLAST0Response_warning"),
+* if an error occurs (e.g., bad option).
+*
+***************************************************************************/
+SeqAnnotPtr LIBCALL
+BlastBioseq2(BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr blast_params, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Boolean useMonitors)
+
+{
+ BLAST0RequestPtr blreqp;
+ Boolean is_na;
+ SeqAnnotPtr seqannot;
+ SeqAlignPtr seqalign;
+ Int4 gi = -1;
+ Char textid[NETBLAP2_BUFLEN+1];
+ PrepRequestInfo pri;
+ SeqPortPtr spp;
+ Uint1 err_id;
+ ValNodePtr vnp;
+
+ if (bsp == NULL)
+ return NULL;
+
+ err_id = BlastSetUserErrorString("blast2:", bsp->id);
+
+ if (ISA_na(bsp->mol))
+ is_na = TRUE;
+ else
+ is_na = FALSE;
+
+ if (is_na)
+ spp = SeqPortNew(bsp, 0, -1, 0, Seq_code_iupacna);
+ else
+ spp = SeqPortNew(bsp, 0, -1, 0, Seq_code_iupacaa);
+
+ if (spp == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "BlastBioseq: Unable to open SeqPort");
+ return NULL;
+ }
+
+
+ SeqIdWrite(bsp->id, textid, PRINTID_FASTA_LONG, NETBLAP2_BUFLEN);
+
+ pri.is_na = is_na;
+ pri.defline = BioseqGetTitle(bsp);
+ pri.options = blast_params;
+ pri.dbname = dbname;
+ pri.textid = StringSave(textid);
+ pri.progname = progname;
+ pri.length = BioseqGetLen(bsp);
+ if ((vnp = bsp->id) != NULL)
+ {
+ while (vnp)
+ {
+ if (vnp->choice == SEQID_GI)
+ {
+ gi = vnp->data.intvalue;
+ break;
+ }
+ vnp = vnp->next;
+ }
+ }
+ pri.gi = gi;
+ pri.spp = spp;
+
+/* None of these are required. */
+ pri.return_matrix = FALSE;
+ pri.return_query = FALSE;
+ pri.return_query_seq_in_seg = FALSE;
+ pri.return_db_seq_in_seg = FALSE;
+ pri.return_BLAST0result = FALSE;
+ pri.mask = mask_seqloc;
+ pri.start = 0;
+
+ blreqp = PrepareRequest(&pri);
+
+ if (pri.spp)
+ pri.spp = SeqPortFree(pri.spp);
+
+ if (blreqp == NULL)
+ return NULL;
+
+ seqalign = SubmitSeqAlignBlastRequest(blreqp, blrespPtr, useMonitors ? Blast2callbackWithMon : NULL);
+
+ if (seqalign)
+ {
+ seqannot = SeqAnnotNew();
+ seqannot->type = 2;
+ seqannot->data = seqalign;
+ }
+ else
+ seqannot = NULL;
+
+ BLAST0RequestFree(blreqp);
+
+ BlastDeleteUserErrorString(err_id);
+
+ return seqannot;
+}
+
+/***************************************************************************
+*
+* Produce a SeqAnnot from the BLAST data, that was produced using a
+* SeqLoc. This function have user defined callback for monitoring
+*
+* BLAST0ResponsePtr PNTR blrespPtr is used to return ONLY the
+* BLAST0ResponsePtr of type warning ("BLAST0Response_warning"),
+* if an error occurs (e.g., bad option).
+*
+***************************************************************************/
+SeqAnnotPtr LIBCALL
+BlastSeqLocMon(SeqLocPtr slp, CharPtr progname, CharPtr dbname, CharPtr blast_params, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, ProgressCallback userCallback)
+{
+ return BlastSeqLocInternal(slp, progname, dbname,
+ blast_params, blrespPtr,
+ mask_seqloc, FALSE,
+ userCallback);
+}
+/***************************************************************************
+*
+* Produce a SeqAnnot from the BLAST data, that was produced using a
+* SeqLoc.
+*
+* BLAST0ResponsePtr PNTR blrespPtr is used to return ONLY the
+* BLAST0ResponsePtr of type warning ("BLAST0Response_warning"),
+* if an error occurs (e.g., bad option).
+*
+***************************************************************************/
+SeqAnnotPtr LIBCALL
+BlastSeqLoc2(SeqLocPtr slp, CharPtr progname, CharPtr dbname, CharPtr blast_params, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Boolean useMonitors)
+{
+ return BlastSeqLocInternal(slp, progname, dbname,
+ blast_params, blrespPtr,
+ mask_seqloc, useMonitors,
+ NULL);
+}
+
+/***************************************************************************
+*
+* Produce a SeqAnnot from the BLAST data, that was produced using a
+* SeqLoc.
+*
+* This is internal function for BlastSeqLoc2() abd BlastSeqLocMon()
+*
+***************************************************************************/
+static SeqAnnotPtr LIBCALL
+BlastSeqLocInternal(SeqLocPtr slp, CharPtr progname, CharPtr dbname, CharPtr blast_params, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Boolean useMonitors, ProgressCallback userCallback)
+
+{
+ SeqAlignPtr seqalign;
+ SeqAnnotPtr seqannot;
+ BioseqPtr bsp;
+ BLAST0RequestPtr blreqp;
+ Boolean is_na;
+ Int2 mol_type;
+ Int4 gi = -1;
+ Char textid[NETBLAP2_BUFLEN+1];
+ PrepRequestInfo pri;
+ SeqIdPtr sip;
+ SeqPortPtr spp;
+ Uint1 err_id;
+ ValNodePtr vnp;
+
+ sip = SeqLocId(slp);
+ if (sip == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "BlastSeqLoc: Unable to get SeqId");
+ return NULL;
+ }
+
+/* Find the bsp for the title (i.e., defline) */
+ bsp = BioseqLockById(sip);
+ if (bsp == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "BlastSeqLoc: Unable to get Bioseq");
+ return NULL;
+ }
+
+ err_id = BlastSetUserErrorString("blast2:", bsp->id);
+
+ mol_type = SeqLocMol(slp);
+
+ if (ISA_na(mol_type))
+ is_na = TRUE;
+ else
+ is_na = FALSE;
+
+ if (is_na)
+ spp = SeqPortNewByLoc(slp, Seq_code_iupacna);
+ else
+ spp = SeqPortNewByLoc(slp, Seq_code_iupacaa);
+
+ if (spp == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "BlastBioseq: Unable to open SeqPort");
+ return NULL;
+ }
+
+
+ SeqIdWrite(sip, textid, PRINTID_FASTA_LONG, NETBLAP2_BUFLEN);
+
+
+ pri.is_na = is_na;
+ pri.defline = BioseqGetTitle(bsp);
+ pri.options = blast_params;
+ pri.dbname = dbname;
+ pri.textid = StringSave(textid);
+ pri.progname = progname;
+ pri.length = SeqLocLen(slp);
+ if ((vnp = sip) != NULL)
+ {
+ while (vnp)
+ {
+ if (vnp->choice == SEQID_GI)
+ {
+ gi = vnp->data.intvalue;
+ break;
+ }
+ vnp = vnp->next;
+ }
+ }
+ pri.gi = gi;
+ pri.spp = spp;
+
+ pri.return_matrix = FALSE;
+ pri.return_query = FALSE;
+ pri.return_query_seq_in_seg = FALSE;
+ pri.return_db_seq_in_seg = FALSE;
+ pri.return_BLAST0result = FALSE;
+ pri.mask = mask_seqloc;
+ pri.start = SeqLocStart(slp);
+
+ blreqp = PrepareRequest(&pri);
+
+ if (pri.spp)
+ pri.spp = SeqPortFree(pri.spp);
+
+ if (blreqp == NULL)
+ return NULL;
+
+ if(userCallback != NULL)
+ seqalign = SubmitSeqAlignBlastRequest(blreqp, blrespPtr, userCallback);
+ else
+ seqalign = SubmitSeqAlignBlastRequest(blreqp, blrespPtr,
+ useMonitors ? Blast2callbackWithMon : NULL);
+
+ if (seqalign)
+ {
+ seqannot = SeqAnnotNew();
+ seqannot->type = 2;
+ seqannot->data = seqalign;
+ }
+ else
+ seqannot = NULL;
+
+ if (seqannot)
+ AdjustOffSetInSeqAnnot(seqannot, slp);
+
+ BLAST0RequestFree(blreqp);
+
+ BioseqUnlockById(sip);
+
+ BlastDeleteUserErrorString(err_id);
+
+ return seqannot;
+}
+
+/***********************************************************************
+*
+* Adjust the Offset in the SeqAnnot to correspond to the beginning
+* of the sequence and not where BLAST started.
+*
+* This function works on SeqAnnot's that contain SeqAlignPtr's of
+* type DenseDiagPtr and StdSegPtr, which is what BLAST returns.
+*
+* The first id in each DenseDiag or StdSeg should correspond to the
+* original BLAST'ed sequence. The offset is only found once as it
+* should be the same for every pair of hits.
+*
+**********************************************************************/
+
+static void
+AdjustOffSetInSeqAnnot(SeqAnnotPtr sap, SeqLocPtr slp)
+
+{
+ CharPtr err_string1, err_string2;
+ DenseDiagPtr ddp;
+ Int4 offset;
+ SeqAlignPtr salp;
+ SeqIdPtr sip=NULL;
+ SeqIntPtr seq_int;
+ SeqLocPtr seqloc, whole_slp;
+ StdSegPtr ssp;
+
+ if (sap != NULL)
+ {
+ if (sap->type == 2)
+ {
+ salp = sap->data;
+ while (salp)
+ {
+ if (salp->segtype == 1)
+ {
+ ddp = salp->segs;
+ while (ddp)
+ { /* Get the offset on the first call. */
+ if (sip == NULL)
+ {
+ sip = ddp->id;
+ whole_slp =
+ ValNodeAddPointer(NULL, SEQLOC_WHOLE, sip);
+ offset =
+ GetOffsetInLoc(slp, whole_slp, SEQLOC_START);
+ if (offset == -1)
+ {
+ err_string1 = SeqLocPrint(slp);
+ err_string2 = SeqLocPrint(whole_slp);
+ ErrPostEx(SEV_ERROR, 0, 0, "AdjustOffSetInSeqAnnot: %s not in %s", err_string1, err_string2);
+ }
+ whole_slp = ValNodeFree(whole_slp);
+ }
+ ddp->starts[0] += offset;
+ ddp = ddp->next;
+ }
+ }
+ else if (salp->segtype == 3)
+ {
+ ssp = salp->segs;
+ while (ssp)
+ {
+ if (sip == NULL)
+ {
+ sip = ssp->ids;
+ whole_slp =
+ ValNodeAddPointer(NULL, SEQLOC_WHOLE, sip);
+ offset =
+ GetOffsetInLoc(slp, whole_slp, SEQLOC_START);
+ if (offset == -1)
+ {
+ err_string1 = SeqLocPrint(slp);
+ err_string2 = SeqLocPrint(whole_slp);
+ ErrPostEx(SEV_ERROR, 0, 0, "AdjustOffSetInSeqAnnot: %s not in %s", err_string1, err_string2);
+ }
+ whole_slp = ValNodeFree(whole_slp);
+ }
+ seqloc = ssp->loc;
+ seq_int = seqloc->data.ptrvalue;
+ seq_int->from += offset;
+ seq_int->to += offset;
+ ssp = ssp->next;
+ }
+ }
+ salp = salp->next;
+ }
+ }
+ }
+}
+
+
+/********************************************************************
+*CharPtr FormatResultWithTemplate (HitdataPtr hitdata, StdPrintOptionsPtr Spop)
+*
+* This function formats the data in the BLAST0ResultPtr using the
+* PrintTemplate functions found in the NCBI toolbox. The data
+* in the BLAST0ResultPtr corresponds to the data in the ASN.1
+* structure "BLAST0-Result".
+***********************************************************************/
+
+CharPtr
+FormatResultWithTemplate (BLAST0ResultPtr blresp, StdPrintOptionsPtr Spop)
+
+{
+ if (blresp == NULL || Spop == NULL)
+ return NULL;
+
+ if (! StdFormatPrint((Pointer)blresp,
+ (AsnWriteFunc)BLAST0ResultAsnWrite, "StdBLAST0Result", Spop))
+ ErrPostEx(SEV_ERROR, 0, 0, "StdFormatPrint failed");
+
+ if (Spop->ptr != NULL && *((CharPtr) (Spop->ptr)) != '\0')
+ return Spop->ptr;
+ else
+ return NULL;
+} /* FormatResultWithTemplate */
+
+
+/* convert from BLAST format to SeqFeat format */
+static Int2
+ConvertStrand(Int2 strand)
+{
+ switch (strand)
+ {
+ case BLAST0_Seq_interval_strand_plus:
+ case BLAST0_Seq_interval_strand_plus_rf:
+ return 1; /* plus */
+ case BLAST0_Seq_interval_strand_minus:
+ case BLAST0_Seq_interval_strand_minus_rf:
+ return 2; /* minus */
+ case BLAST0_Seq_interval_strand_both:
+ return 3; /* both */
+ default: /* unknown, or unable to convert */
+ return 0;
+ }
+}
+
+
+SeqAnnotPtr LIBCALL HitDataToSeqAnnotAlignment(BLAST0ResultPtr hdp, SeqIdPtr sip)
+{
+ SeqAnnotPtr sep;
+ SeqAlignPtr sap;
+ SeqAlignPtr last;
+ /* Int4 dim; */ /* number of entries per BLAST0-segment */
+ DenseDiagPtr ddp, lastddp;
+ ScorePtr dstscore, lastscore;
+ BLAST0HitListPtr hlp;
+ BLAST0HSPPtr hsp;
+ BLAST0SegmentPtr segp;
+ BLAST0SeqIntervalPtr query;
+ BLAST0SeqIntervalPtr hit;
+ ScorePtr srcscore;
+ Boolean giidNotFound;
+ BLAST0SeqDescPtr sdp;
+ ValNodePtr vnp;
+ SeqIdPtr hitid;
+
+ if (hdp == NULL || hdp->hitlists == NULL)
+ return NULL;
+
+ SeqAsnLoad();
+
+ sep = SeqAnnotNew();
+ sep->type = 2; /* alignments */
+
+ /* dim = hdp->dim;*/ /* should be 2, or 3 for BLAST3 */
+
+ for (hlp = hdp->hitlists; hlp != NULL; hlp = hlp->next)
+ {
+ sap = SeqAlignNew();
+ if (sep->data == NULL)
+ {
+ sep->data = sap;
+ } else {
+ last->next = sap;
+ }
+ last = sap;
+ sap->type = 2; /* diags */
+ sap->segtype = 1; /* dendiag */
+/* sap->dim = dim;*/
+ sap->score = NULL;
+ sap->segs = NULL;
+ for (hsp = hlp->hsps; hsp != NULL; hsp = hsp->next)
+ {
+ segp = hsp->segs;
+ if (segp != NULL && segp->next != NULL &&
+ (query = segp->loc) != NULL && (hit = segp->next->loc))
+ {
+ ddp = DenseDiagNew();
+ if (sap->segs == NULL)
+ {
+ sap->segs = ddp;
+ } else {
+ lastddp->next = ddp;
+ }
+ lastddp = ddp;
+/* ddp->dim = dim;*/
+ ddp->len = hsp->len;
+ ddp->scores = NULL;
+ ddp->starts = (Int4Ptr) MemNew(2 * sizeof(Int4));
+ ddp->starts[0] = query->from;
+ ddp->starts[1] = hit->from;
+ ddp->strands = (Uint1Ptr) MemNew(2 * sizeof(Uint1));
+ ddp->strands[0] = ConvertStrand(query->strand);
+ ddp->strands[1] = ConvertStrand(hit->strand);
+
+ if (hlp->seqs != NULL)
+ {
+ sdp = hlp->seqs->desc;
+ giidNotFound = TRUE;
+ hitid = NULL;
+ for (vnp = sdp->id; vnp != NULL; vnp = vnp->next)
+ {
+ if (vnp->choice == BLAST0SeqId_giid &&
+ vnp->data.intvalue > 0)
+ {
+ SeqIdFree(hitid);
+ hitid = ValNodeNew(NULL);
+ hitid->choice = SEQID_GI;
+ hitid->data.intvalue = vnp->data.intvalue;
+ giidNotFound = FALSE;
+ } else {
+ if (vnp->choice == BLAST0SeqId_textid &&
+ giidNotFound && vnp->data.ptrvalue != NULL)
+ {
+ hitid = SeqIdParse(vnp->data.ptrvalue);
+ }
+ }
+ }
+ ddp->id = SeqIdDup(sip);
+ ddp->id->next = hitid;
+ }
+ for (srcscore = (ScorePtr) hsp->scores; srcscore != NULL; srcscore = srcscore->next)
+ { /* just copy the scores */
+ dstscore = ScoreNew();
+ if (ddp->scores == NULL)
+ {
+ ddp->scores = dstscore;
+ } else {
+ lastscore->next = dstscore;
+ }
+ lastscore = dstscore;
+ dstscore->id = ObjectIdDup(srcscore->id);
+ dstscore->value = srcscore->value;
+ dstscore->choice = srcscore->choice;
+ }
+ }
+ }
+ }
+
+ return sep;
+}
+
+SeqAnnotPtr LIBCALL HitDataToSeqAnnot(BLAST0ResultPtr hdp, SeqIdPtr sip)
+{
+ SeqAnnotPtr sep;
+ SeqFeatPtr sfp, last;
+ BLAST0HitListPtr hlp;
+ BLAST0SegmentPtr segp;
+ /* Int4 dim;*/ /* number of entries per BLAST0-segment */
+ BLAST0SeqIntervalPtr query;
+ BLAST0SeqIntervalPtr hit;
+ SeqLocPtr querySeqLoc;
+ SeqLocPtr hitSeqLoc;
+ SeqIntPtr querySeqInt;
+ SeqIntPtr hitSeqInt;
+ Boolean giidNotFound;
+ BLAST0SeqDescPtr sdp;
+ ValNodePtr vnp;
+
+ if (hdp == NULL || hdp->hitlists == NULL)
+ return NULL;
+
+ SeqAsnLoad();
+
+ sep = SeqAnnotNew();
+ sep->type = 1; /* Feature table */
+
+/* dim = hdp->dim;*/ /* should be 2, or 3 for BLAST3 */
+
+ for (hlp = hdp->hitlists; hlp != NULL; hlp = hlp->next)
+ {
+ if (hlp->hsps != NULL)
+ {
+ segp = hlp->hsps->segs; /* ignore any other HSPs */
+ if (segp != NULL && segp->next != NULL &&
+ (query = segp->loc) != NULL && (hit = segp->next->loc))
+ {
+ sfp = SeqFeatNew();
+ if (sep->data == NULL)
+ {
+ sep->data = sfp;
+ } else {
+ last->next = sfp;
+ }
+ last = sfp;
+
+ sfp->data.choice = SEQFEAT_SEQ; /* value for seq int */
+ sfp->data.value.ptrvalue = (Pointer) ValNodeNew(NULL);
+ hitSeqLoc = sfp->data.value.ptrvalue;
+ hitSeqLoc->choice = SEQLOC_INT;
+ hitSeqInt = SeqIntNew();
+ hitSeqLoc->data.ptrvalue = (Pointer) hitSeqInt;
+ hitSeqInt->strand = ConvertStrand(hit->strand);
+ hitSeqInt->from = hit->from;
+ hitSeqInt->to = hit->to;
+
+ if (hlp->seqs != NULL)
+ {
+ sdp = hlp->seqs->desc;
+ if (sdp->defline != NULL)
+ {
+ sfp->comment = StringSave(sdp->defline);
+ }
+ giidNotFound = TRUE;
+ for (vnp = sdp->id; vnp != NULL; vnp = vnp->next)
+ {
+ if (vnp->choice == BLAST0SeqId_giid &&
+ vnp->data.intvalue > 0)
+ {
+ SeqIdFree(hitSeqInt->id);
+ hitSeqInt->id = ValNodeNew(NULL);
+ hitSeqInt->id->choice = SEQID_GI;
+ hitSeqInt->id->data.intvalue = vnp->data.intvalue;
+ giidNotFound = FALSE;
+ } else {
+ if (vnp->choice == BLAST0SeqId_textid &&
+ giidNotFound && vnp->data.ptrvalue != NULL)
+ {
+ hitSeqInt->id = SeqIdParse(vnp->data.ptrvalue);
+ }
+ }
+ }
+ }
+
+ sfp->location = ValNodeNew(NULL);
+ querySeqLoc = sfp->location;
+ querySeqLoc->choice = SEQLOC_INT;
+ querySeqInt = SeqIntNew();
+ querySeqLoc->data.ptrvalue = (Pointer) querySeqInt;
+ querySeqInt->strand = ConvertStrand(query->strand);
+ querySeqInt->from = query->from;
+ querySeqInt->to = query->to;
+ querySeqInt->id = SeqIdDup(sip);
+ }
+ }
+ }
+
+ return sep;
+}
+
+
+static Boolean ReestablishNetBlast(void)
+{
+ return GenericReestablishNet("blast2", TRUE);
+}
+
+static Boolean GenericReestablishNet(CharPtr svcName, Boolean showErrs)
+{
+ MonitorPtr mon = NULL;
+ Boolean retval;
+ CharPtr buf;
+
+ buf = MemNew(2 * StrLen(svcName) + 60);
+
+ if (showErrs) {
+ sprintf (buf, "Re-establishing %s Service", svcName);
+ mon = MonitorStrNew(buf, 40);
+ sprintf (buf, "Requesting %s service", svcName);
+ MonitorStrValue(mon, buf);
+ }
+ NetFini();
+ retval = TRUE;
+
+ if (! BlastInit(NULL, showErrs))
+ {
+ sprintf (buf, "%s get failed; re-contacting dispatcher", svcName);
+ MonitorStrValue(mon, buf);
+ retval = FALSE;
+ if (ForceNetInit())
+ { /* successfully established contact w/dispatcher */
+ sprintf (buf, "%s get failed; re-requesting %s service",
+ svcName, svcName);
+ MonitorStrValue(mon, buf);
+ retval = BlastInit(NULL, showErrs);
+ }
+ else {
+ ErrPost(CTX_UNKNOWN, 1, "Unable to re-contact dispatcher");
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+ }
+
+ MonitorFree(mon);
+
+ if (! retval )
+ {
+ sprintf (buf, "Unable to re-establish %s service", svcName);
+ ErrPost(CTX_UNKNOWN, 1, buf);
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+
+ MemFree(buf);
+ return retval;
+}
+
+static Boolean
+NetInit(void)
+{
+ if (num_attached++ > 0)
+ return TRUE;
+
+ return ((dispatcher = NI_GenericInit(NULL, NULL, TRUE, NULL, 0)) != NULL);
+}
+
+
+static Boolean ForceNetInit(void)
+{
+ Boolean retval;
+
+ num_attached = 0; /* force re-attempt to contact dispatcher */
+ retval = BlastInit(NULL, TRUE);
+
+ return retval;
+}
+
+static Boolean NetFini(void)
+{
+ if (num_attached > 0)
+ num_attached--;
+
+ if (num_attached == 0)
+ {
+ NI_ServiceDisconnect(svcp);
+ svcp = NULL;
+ NI_EndServices (dispatcher);
+ dispatcher = NULL;
+ }
+
+ return TRUE;
+}
+/*****************************************************************************
+*
+* StoreResiduesInBS(Uint1Ptr, newcode, oldcode, len)
+ Transfers the residues in buffer to the ByteStore "to".
+* On the first call the ByteStore "to" should be NULL
+* and len should indicate the total number of residues in
+* the sequence. bitctr_to may be any number. On subsequent
+* calls bitctr_to and to should be passed back in.
+* On every call buf_len should indicate how many residues are
+* to be transferred from buffer to "to".
+*
+* At present (2/22/95) this only works with oldcode of iupac[na]a.
+*
+*****************************************************************************/
+static ByteStorePtr StoreResiduesInBS (Uint1Ptr buffer, Int4 buf_len, ByteStorePtr to, Uint1Ptr bitctr_to, Uint1 newcode, Uint1 oldcode, Int4 len)
+
+{
+ Boolean first_time;
+ Int4 index, storelen;
+ Uint1 byte_from, residue_from, bitctr_from, mask_from, lshift_from,
+ rshift_from, bc_from ,
+ byte_to, lshift_to[5], bc_to, byte_tmp;
+ SeqMapTablePtr smtp;
+
+ if ((! oldcode) || (! newcode) || (len <= 0))
+ return NULL;
+
+ if (to)
+ first_time = FALSE;
+ else
+ first_time = TRUE;
+
+ if ((smtp = SeqMapTableFind(newcode, oldcode)) == NULL)
+ return NULL;
+
+ if (newcode == Seq_code_ncbi2na)
+ storelen = (len / 4) + 1;
+ else if (newcode == Seq_code_ncbi4na)
+ storelen = (len / 2) + 1;
+ else
+ storelen = len;
+
+ if (first_time)
+ to = BSNew((Uint4)storelen);
+
+ if (to == NULL)
+ return NULL;
+
+ switch (oldcode)
+ {
+ case Seq_code_ncbi2na:
+ bc_from = 4; /* bit shifts needed */
+ rshift_from = 6;
+ lshift_from = 2;
+ mask_from = 192;
+ break;
+ case Seq_code_ncbi4na:
+ bc_from = 2;
+ rshift_from = 4;
+ lshift_from = 4;
+ mask_from = 240;
+ break;
+ default:
+ bc_from = 1;
+ rshift_from = 0;
+ lshift_from = 0;
+ mask_from = 255;
+ break;
+ }
+
+ lshift_to[1] = 0;
+ switch (newcode)
+ {
+ case Seq_code_ncbi2na:
+ bc_to = 4; /* bit shifts needed */
+ lshift_to[2] = 2;
+ lshift_to[3] = 4;
+ lshift_to[4] = 6;
+ break;
+ case Seq_code_ncbi4na:
+ bc_to = 2;
+ lshift_to[2] = 4;
+ break;
+ default:
+ bc_to = 1;
+ break;
+ }
+
+ if (first_time)
+ *bitctr_to = bc_to;
+ byte_to = 0;
+ bitctr_from = 0;
+
+ index = 0;
+ while (index < buf_len)
+ {
+ if (! bitctr_from) /* need a new byte */
+ {
+ byte_from = buffer[index];
+ bitctr_from = bc_from;
+ }
+ residue_from = byte_from & mask_from;
+ residue_from >>= rshift_from;
+ byte_from <<= lshift_from;
+ bitctr_from--;
+
+ byte_tmp = SeqMapTableConvert(smtp, residue_from);
+ if (byte_tmp == INVALID_RESIDUE)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "StoreResiduesInBS: invalid residue [%d=%c]",
+ (int)residue_from, (char)residue_from);
+ BSFree(to);
+ return NULL;
+ }
+ byte_tmp <<= lshift_to[*bitctr_to];
+ byte_to |= byte_tmp;
+ (*bitctr_to)--;
+ if (! *bitctr_to)
+ {
+ BSPutByte(to, byte_to);
+ *bitctr_to = bc_to;
+ byte_to = 0;
+ }
+
+ index++;
+ }
+
+ if (*bitctr_to != bc_to) /* partial byte not written */
+ BSPutByte(to, byte_to);
+
+ return to;
+}
+
+/**************************************************************************
+*
+* format the usage for a blast program
+
+* THis function is a clone of print_usage in busage.c in blastapp.
+* This function should be moved to "blast.c" soon, then both
+* server and client versions of BLAST can share it.
+**************************************************************************/
+int
+print_usage(FILE *fp, ValNodePtr vnp)
+{
+ Char buf[512];
+ CharPtr string, ptr;
+
+ if (fp == NULL)
+ return 0;
+
+ if (vnp == NULL)
+ return 0;
+
+ fflush(stdout);
+ fflush(fp);
+
+ while (vnp)
+ {
+ string = vnp->data.ptrvalue;
+ ptr = buf;
+ while (*string != NULLB)
+ {
+/* If the character is a tilde, do a line return; if no tilde precedes the
+end of the string, print without a line return! */
+ if (*string == '~')
+ {
+ *ptr = NULLB;
+ fprintf(fp, "%s\n", buf);
+ ptr = buf;
+ string++;
+ while (*string == '~')
+ {
+ fprintf(fp, "\n");
+ string++;
+ }
+ if (*string == NULLB)
+ break;
+ }
+ else if (*(string+1) == NULLB)
+ {
+ ptr++;
+ *ptr = NULLB;
+ fprintf(fp, "%s", buf);
+ }
+ *ptr = *string;
+ ptr++; string++;
+ }
+
+ vnp = vnp->next;
+ }
+
+ return 0;
+}
diff --git a/network/blast2/client/netblap2.h b/network/blast2/client/netblap2.h
new file mode 100644
index 00000000..d1b0967a
--- /dev/null
+++ b/network/blast2/client/netblap2.h
@@ -0,0 +1,298 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: netblap2.h
+*
+* Author: Jonathan Epstein, Tom Madden
+*
+* Version Creation Date: 06/16/95
+*
+* $Revision: 6.1 $
+*
+* File Description:
+* Application Programming Interface (API) for BLAST network server
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: netblap2.h,v $
+* Revision 6.1 1998/02/19 21:13:49 shavirin
+* Added parameter to MT save function BlastBioseqMT()
+*
+* Revision 6.0 1997/08/25 18:34:17 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/04/11 15:18:38 madden
+* renamed callbackWithMon Blast2callbackWithMon, made non-static.
+*
+ * Revision 5.1 1996/07/01 21:20:00 shavirin
+ * Added new function BlastSeqLocMon() allows to user set callback.
+ *
+ * Revision 5.0 1996/05/28 14:09:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.16 1996/05/10 20:44:49 madden
+ * MT safe function calls added.
+ *
+ * Revision 4.15 1996/03/22 17:28:49 madden
+ * Removed formatting prototypes to blast2.h
+ *
+ * Revision 4.14 1995/11/07 17:55:24 madden
+ * removed prototype for PrintTraditionalBlastPreface.
+ *
+ * Revision 4.13 1995/11/01 15:41:25 madden
+ * removed prototypes for TraditionalBlastReportSetUp and TraditionalBlastReportCleanUp
+ *
+ * Revision 4.12 1995/10/27 21:15:57 madden
+ * Removed blast_report_struct (moved to blast2.h).
+ *
+ * Revision 4.11 1995/10/17 15:03:12 madden
+ * added prototype for CheckIfBlastJobCancelled.
+ *
+ * Revision 4.10 1995/09/20 20:57:29 madden
+ * Comments added that describe how to call BlastBioseq.
+ *
+ * Revision 4.9 1995/09/01 16:43:46 madden
+ * changes to allow cancellation of jobs through "Cancel" button of prog. bar.
+ *
+ * Revision 4.8 1995/08/24 17:23:29 madden
+ * Added "get_gi" element to blast_report_struct.
+ *
+ * Revision 4.7 1995/08/23 13:32:14 madden
+ * Added num_of_defline and num_of_align to blast_report_struct.
+ *
+ * Revision 4.6 1995/08/02 16:20:00 madden
+ * Added "qoffset" to BlastReportStruct.
+ *
+ * Revision 4.5 1995/08/01 21:30:45 madden
+ * removed define for BLASTCLI_MATRIX_SIZE.
+ *
+ * Revision 4.4 1995/08/01 20:44:33 madden
+ * Added typdef for BlastReportStruct, changed "traditional" function
+ * prototypes to include BlastReportStruct.
+ *
+ * Revision 4.3 1995/07/28 16:16:37 madden
+ * Added prototypes for formatting individual parts of the traditional
+ * BLAST report.
+ *
+ * Revision 4.2 1995/07/28 12:29:36 madden
+ * Added prototype for BlastAnIUPACString.
+ *
+ * Revision 4.1 1995/07/26 22:29:03 kans
+ * added prototype for print_usage
+ *
+ * Revision 4.0 1995/07/26 13:55:34 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.9 1995/07/24 16:34:49 madden
+ * removed define for NETBLAP1_BUFFER_SIZE.
+ *
+ * Revision 1.8 1995/07/18 20:05:36 madden
+ * Added "start" (for start of SeqLoc) to PrepRequestInfoPtr.
+ *
+ * Revision 1.7 1995/07/12 17:44:32 madden
+ * Changed prototypes to allow SeqLocPtr for masking of sequence.
+ *
+ * Revision 1.6 1995/06/28 18:28:07 madden
+ * Changed BlastBioseq2 and BlastSeqLoc2 to take an additional argument:
+ * a "BLAST0ResponsePtr PNTR".
+ *
+ * Revision 1.5 1995/06/23 21:39:51 madden
+ * Add defines BLAST_SERVER_OMIT_MATRIX, BLAST_SERVER_OMIT_QUERY etc.
+ *
+ * Revision 1.4 1995/06/22 16:08:08 madden
+ * Added prototypes for SubmitResultBlastRequest and SubmitSeqAlignBlastRequest.
+ *
+ * Revision 1.3 1995/06/22 13:19:01 madden
+ * Added five Booleans to PrepRequestInfoPtr that control the amount of
+ * output, these correspond to the five Uint1's on BLAST0SearchPtr that
+ * determine whether a matrix, query seq, db seq, etc is returned.
+ *
+ * Revision 1.2 1995/06/22 12:54:45 madden
+ * Changed HitDataPtr to BLAST0ResultPtr.
+ *
+ * Revision 1.1 1995/06/16 11:27:08 epstein
+ * Initial revision
+ *
+ * Revision 1.15 95/05/17 17:59:30 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NETBLAP2_
+#define _NETBLAP2_
+
+#include <objblst2.h>
+#include <objseq.h>
+#include <seqport.h>
+#include <prtutil.h>
+#include <blast2.h>
+#include <ni_types.h>
+
+#define BLAST_SERVER_OMIT_MATRIX 1
+#define BLAST_SERVER_OMIT_QUERY 2
+#define BLAST_SERVER_OMIT_QUERY_SEQ_IN_SEG 4
+#define BLAST_SERVER_OMIT_DB_SEQ_IN_SEG 8
+
+/*------------the structure for the function PrepareRequest (netblap2.c)---*/
+
+typedef struct preprequestinfo {
+ Boolean is_na; /* Is this a nucleic acid? */
+ CharPtr defline, /* The fasta definition line. */
+ options, /* BLAST command line options */
+ dbname, /* name of the database */
+ textid, /* textid of the entry */
+ progname; /* BLAST program name (e.g., blastn, blastp...) */
+ Int4 gi, /* gi number */
+ length, /* number of residues in entry */
+ start; /* BLAST run starts at this residue */
+ SeqPortPtr spp; /* SeqPort to get sequence data from. */
+/* These Booleans determine the amount of output */
+ Boolean return_matrix, /* Should matrix be returned? */
+ return_query, /* Should query be sent back? */
+ return_BLAST0result, /* Should Blast0ResultPtr be returned;
+ if not, then a Seq-align is returned */
+ return_query_seq_in_seg, /* Should the query sequence for a hit
+ be returned? */
+ return_db_seq_in_seg; /* Should the db sequence for a hit be
+ returned? */
+ SeqLocPtr mask; /* which positions should be masked */
+} PrepRequestInfo, PNTR PrepRequestInfoPtr;
+
+
+/* the following are for backwards-compatability */
+#define HitDataPtr BLAST0ResultPtr
+#define HitDataFree BLAST0ResultFree
+
+typedef Boolean (LIBCALLBACK *ProgressCallback) PROTO((BLAST0ResponsePtr, Boolean PNTR cancel));
+
+/******************************************************************
+ * Multi-Thread safe Blast handle
+ *****************************************************************/
+
+typedef struct BlastMTHandle {
+ NI_HandPtr svcp;
+ AsnIoPtr asnin;
+ AsnIoPtr asnout;
+ Int4 socket;
+ CharPtr error;
+} BlastMTHandle, PNTR BlastMTHandlePtr;
+
+/******************************************************************
+*
+* These initialize and close the connection to the BLAST server.
+* BlastInit should be called at the beginning of a session,
+* BlastFini at the end.
+*****************************************************************/
+Boolean LIBCALL BlastInit PROTO((CharPtr clientId, Boolean ignoreErrs));
+Boolean LIBCALL BlastFini PROTO((void));
+
+Boolean LIBCALL BlastInitMT PROTO((BlastMTHandlePtr BlastMThp,
+ CharPtr clientId,
+ Boolean ignoreErrs));
+
+Boolean LIBCALL BlastFiniMT PROTO((BlastMTHandlePtr BlastMThp));
+
+/******************************************************************
+*
+* BlastBioseq submit the sequence data in a Bioseq ("bsp") to the
+* server. The arguments are:
+* bsp: BioseqPtr containing sequence data,
+* progname: CharPtr with name of program (blastn, blastp, blastx,
+ tblastn, tblastx),
+ dbname: CharPtr with name of the database (most requests
+ use "nr"),
+ cmdLineOptions: CharPtr contains "expert" BLAST options that
+ control output, score cutoffs, etc.
+ blrespPtr: BLAST0ResponsePtr that is filled in by the server.
+ This contains the matrix, progress messages,
+ error messages.
+ mask_seqloc: SeqLocPtr specifying sequence to be masked (with
+ X's for proteins, N's for nucleotides).
+ output: Uint4 that specifies amount of output, this corresponds
+ to four of the five Uint1's in BLAST0Search:
+
+ 1st bit, if set omit matrix (return_matrix is FALSE);
+ 2nd bit, if set omit query (return_query is FALSE);
+ 3rd bit, if set omit query seq (return_query_seq_in_seg is FALSE);
+ 4th bit, if set omit db seq (return_db_seq_in_seg is FALSE);
+
+ ProgressCallback: function that produces progress message.
+
+**********************************************************************/
+BLAST0ResultPtr LIBCALL BlastBioseq PROTO((BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Uint4 output, ProgressCallback progCallback));
+
+BLAST0ResultPtr LIBCALL BlastBioseqMT PROTO((BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Uint4 output, ProgressCallback progCallback, BlastMTHandlePtr BlastMThp));
+
+BLAST0ResultPtr LIBCALL SimpleBlastBioseq PROTO((BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, Boolean useMonitors));
+SeqAnnotPtr LIBCALL BlastBioseq2 PROTO ((BioseqPtr bsp, CharPtr progname, CharPtr dbname, CharPtr blast_params, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Boolean useMonitors));
+SeqAnnotPtr LIBCALL BlastSeqLoc2 PROTO ((SeqLocPtr slp, CharPtr progname, CharPtr dbname, CharPtr blast_params, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Boolean useMonitors));
+SeqAnnotPtr LIBCALL BlastSeqLocMon PROTO ((SeqLocPtr slp, CharPtr progname, CharPtr dbname, CharPtr blast_params, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, ProgressCallback userCallback));
+
+SeqAnnotPtr LIBCALL HitDataToSeqAnnot PROTO((BLAST0ResultPtr, SeqIdPtr));
+SeqAnnotPtr LIBCALL HitDataToSeqAnnotAlignment PROTO((BLAST0ResultPtr, SeqIdPtr));
+
+CharPtr FormatResultWithTemplate PROTO ((BLAST0ResultPtr blresp, StdPrintOptionsPtr Spop));
+
+/**************************************************************************
+ * This defines MT Safe function SubmitInfoRequestMT() and
+ * not MT - safe SubmitInfoRequest() analog
+ *************************************************************************/
+
+BLAST0ResponsePtr SubmitInfoRequest PROTO ((BLAST0RequestPtr blreqp));
+BLAST0ResponsePtr SubmitInfoRequestMT PROTO ((BLAST0RequestPtr blreqp,
+ BlastMTHandlePtr BlastMThp));
+
+BLAST0ResultPtr SubmitResultBlastRequest PROTO ((BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback));
+
+SeqAlignPtr SubmitSeqAlignBlastRequest PROTO ((BLAST0RequestPtr blreqp, BLAST0ResponsePtr PNTR blrespPtr, ProgressCallback progCallback));
+
+int print_usage(FILE *fp, ValNodePtr vnp);
+
+BLAST0ResultPtr LIBCALL BlastAnIUPACString PROTO((CharPtr sequence, Int4 length, CharPtr id, CharPtr defline, CharPtr progname, CharPtr dbname, CharPtr cmdLineOptions, BLAST0ResponsePtr PNTR blrespPtr, SeqLocPtr mask_seqloc, Uint4 output, ProgressCallback progCallback));
+
+
+/*
+ CheckIfBlastJobCancelled returns the state of the Boolean
+ "job_cancelled". If it is "TRUE", then the BLAST job has
+ been cancelled through the monitor (e.g., callbackWithMon).
+ This function need only be called if a "suspicious" return
+ value exists (i.e., NULL was returned by the API function)
+ and the client wishes to distinguish a "cancellation" from
+ an interruption of service or other error.
+
+*/
+Boolean LIBCALL CheckIfBlastJobCancelled PROTO((void));
+
+Boolean LIBCALLBACK Blast2callbackWithMon PROTO((BLAST0ResponsePtr brp, Boolean PNTR cancel));
+
+
+#endif /* _NETBLAP2_ */
diff --git a/network/blast2/client/objblst2.c b/network/blast2/client/objblst2.c
new file mode 100644
index 00000000..2b284429
--- /dev/null
+++ b/network/blast2/client/objblst2.c
@@ -0,0 +1,5857 @@
+#include <asn.h>
+
+#define NLM_GENERATED_CODE_PROTO
+
+#include "blast18p.h"
+#include "objblst2.h"
+
+static Boolean loaded = FALSE;
+
+#include "asnbl18.h"
+
+#ifndef NLM_EXTERN_LOADS
+#define NLM_EXTERN_LOADS {}
+#endif
+
+Boolean LIBCALL
+objblst2AsnLoad(void)
+{
+
+ if ( ! loaded) {
+ NLM_EXTERN_LOADS
+
+ if ( ! AsnLoad ())
+ return FALSE;
+ loaded = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/**************************************************
+* Generated object loaders for Module NCBI-BLAST-1
+* Generated using ASNCODE Revision: 1.17 at Jun 28, 1995 2:37 PM
+*
+**************************************************/
+
+
+/**************************************************
+*
+* BLAST0PrefaceNew()
+*
+**************************************************/
+
+BLAST0PrefacePtr LIBCALL
+BLAST0PrefaceNew(void)
+{
+ BLAST0PrefacePtr ptr = MemNew((size_t) sizeof(BLAST0Preface));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0PrefaceFree()
+*
+**************************************************/
+
+BLAST0PrefacePtr LIBCALL
+BLAST0PrefaceFree(BLAST0PrefacePtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> program);
+ MemFree(ptr -> desc);
+ MemFree(ptr -> version);
+ MemFree(ptr -> dev_date);
+ MemFree(ptr -> bld_date);
+ AsnGenericBaseSeqOfFree(ptr -> cit ,ASNCODE_PTRVAL_SLOT);
+ AsnGenericBaseSeqOfFree(ptr -> notice ,ASNCODE_PTRVAL_SLOT);
+ AsnGenericBaseSeqOfFree(ptr -> prog_usage ,ASNCODE_PTRVAL_SLOT);
+ BLAST0SeqUsageFree(ptr -> susage);
+ BLAST0SeqUsageFree(ptr -> qusage);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0PrefaceAsnRead()
+*
+**************************************************/
+
+BLAST0PrefacePtr LIBCALL
+BLAST0PrefaceAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0PrefacePtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Preface ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_PREFACE);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_PREFACE);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0PrefaceNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_PREFACE_program) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> program = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_PREFACE_desc) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> desc = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_PREFACE_version) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> version = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_PREFACE_dev_date) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> dev_date = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_PREFACE_bld_date) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> bld_date = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_PREFACE_cit) {
+ ptr -> cit = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && ptr -> cit == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_PREFACE_notice) {
+ ptr -> notice = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && ptr -> notice == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_PREFACE_prog_usage) {
+ ptr -> prog_usage = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && ptr -> prog_usage == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_PREFACE_susage) {
+ ptr -> susage = BLAST0SeqUsageAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_PREFACE_qusage) {
+ ptr -> qusage = BLAST0SeqUsageAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0PrefaceFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0PrefaceAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0PrefaceAsnWrite(BLAST0PrefacePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_PREFACE); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> program != NULL) {
+ av.ptrvalue = ptr -> program;
+ retval = AsnWrite(aip, BLAST0_PREFACE_program, &av);
+ }
+ if (ptr -> desc != NULL) {
+ av.ptrvalue = ptr -> desc;
+ retval = AsnWrite(aip, BLAST0_PREFACE_desc, &av);
+ }
+ if (ptr -> version != NULL) {
+ av.ptrvalue = ptr -> version;
+ retval = AsnWrite(aip, BLAST0_PREFACE_version, &av);
+ }
+ if (ptr -> dev_date != NULL) {
+ av.ptrvalue = ptr -> dev_date;
+ retval = AsnWrite(aip, BLAST0_PREFACE_dev_date, &av);
+ }
+ if (ptr -> bld_date != NULL) {
+ av.ptrvalue = ptr -> bld_date;
+ retval = AsnWrite(aip, BLAST0_PREFACE_bld_date, &av);
+ }
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> cit ,ASNCODE_PTRVAL_SLOT, aip, BLAST0_PREFACE_cit, BLAST0_PREFACE_cit_E);
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> notice ,ASNCODE_PTRVAL_SLOT, aip, BLAST0_PREFACE_notice, BLAST0_PREFACE_notice_E);
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> prog_usage ,ASNCODE_PTRVAL_SLOT, aip, BLAST0_PREFACE_prog_usage, BLAST0_PREFACE_prog_usage_E);
+ if (ptr -> susage != NULL) {
+ if ( ! BLAST0SeqUsageAsnWrite(ptr -> susage, aip, BLAST0_PREFACE_susage)) {
+ goto erret;
+ }
+ }
+ if (ptr -> qusage != NULL) {
+ if ( ! BLAST0SeqUsageAsnWrite(ptr -> qusage, aip, BLAST0_PREFACE_qusage)) {
+ goto erret;
+ }
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0JobDescNew()
+*
+**************************************************/
+
+BLAST0JobDescPtr LIBCALL
+BLAST0JobDescNew(void)
+{
+ BLAST0JobDescPtr ptr = MemNew((size_t) sizeof(BLAST0JobDesc));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0JobDescFree()
+*
+**************************************************/
+
+BLAST0JobDescPtr LIBCALL
+BLAST0JobDescFree(BLAST0JobDescPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> desc);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0JobDescAsnRead()
+*
+**************************************************/
+
+BLAST0JobDescPtr LIBCALL
+BLAST0JobDescAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0JobDescPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0JobDesc ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_JOB_DESC);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_JOB_DESC);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0JobDescNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_JOB_DESC_jid) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> jid = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_JOB_DESC_desc) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> desc = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_JOB_DESC_size) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> size = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0JobDescFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0JobDescAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0JobDescAsnWrite(BLAST0JobDescPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_JOB_DESC); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> jid;
+ retval = AsnWrite(aip, BLAST0_JOB_DESC_jid, &av);
+ if (ptr -> desc != NULL) {
+ av.ptrvalue = ptr -> desc;
+ retval = AsnWrite(aip, BLAST0_JOB_DESC_desc, &av);
+ }
+ av.intvalue = ptr -> size;
+ retval = AsnWrite(aip, BLAST0_JOB_DESC_size, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0JobProgressNew()
+*
+**************************************************/
+
+BLAST0JobProgressPtr LIBCALL
+BLAST0JobProgressNew(void)
+{
+ BLAST0JobProgressPtr ptr = MemNew((size_t) sizeof(BLAST0JobProgress));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0JobProgressFree()
+*
+**************************************************/
+
+BLAST0JobProgressPtr LIBCALL
+BLAST0JobProgressFree(BLAST0JobProgressPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0JobProgressAsnRead()
+*
+**************************************************/
+
+BLAST0JobProgressPtr LIBCALL
+BLAST0JobProgressAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0JobProgressPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0JobProgress ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_JOB_PROGRESS);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_JOB_PROGRESS);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0JobProgressNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_JOB_PROGRESS_done) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> done = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_JOB_PROGRESS_positives) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> positives = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0JobProgressFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0JobProgressAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0JobProgressAsnWrite(BLAST0JobProgressPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_JOB_PROGRESS); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> done;
+ retval = AsnWrite(aip, BLAST0_JOB_PROGRESS_done, &av);
+ av.intvalue = ptr -> positives;
+ retval = AsnWrite(aip, BLAST0_JOB_PROGRESS_positives, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SequenceNew()
+*
+**************************************************/
+
+BLAST0SequencePtr LIBCALL
+BLAST0SequenceNew(void)
+{
+ BLAST0SequencePtr ptr = MemNew((size_t) sizeof(BLAST0Sequence));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0SequenceFree()
+*
+**************************************************/
+
+BLAST0SequencePtr LIBCALL
+BLAST0SequenceFree(BLAST0SequencePtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericUserSeqOfFree(ptr -> desc, (AsnOptFreeFunc) BLAST0SeqDescFree);
+ BLAST0SeqDataFree(ptr -> seq);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0SequenceAsnRead()
+*
+**************************************************/
+
+BLAST0SequencePtr LIBCALL
+BLAST0SequenceAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0SequencePtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Sequence ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SEQUENCE);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SEQUENCE);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0SequenceNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_SEQUENCE_desc) {
+ ptr -> desc = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0SeqDescAsnRead, (AsnOptFreeFunc) BLAST0SeqDescFree);
+ if (isError && ptr -> desc == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEQUENCE_length) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> length = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEQUENCE_gcode) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> gcode = av.intvalue;
+ ptr -> OBbits__ |= 1<<0;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEQUENCE_seq) {
+ ptr -> seq = BLAST0SeqDataAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0SequenceFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SequenceAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0SequenceAsnWrite(BLAST0SequencePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_SEQUENCE); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ AsnGenericUserSeqOfAsnWrite(ptr -> desc, (AsnWriteFunc) BLAST0SeqDescAsnWrite, aip, BLAST0_SEQUENCE_desc, BLAST0_SEQUENCE_desc_E);
+ av.intvalue = ptr -> length;
+ retval = AsnWrite(aip, BLAST0_SEQUENCE_length, &av);
+ if (ptr -> gcode || (ptr -> OBbits__ & (1<<0) )){ av.intvalue = ptr -> gcode;
+ retval = AsnWrite(aip, BLAST0_SEQUENCE_gcode, &av);
+ }
+ if (ptr -> seq != NULL) {
+ if ( ! BLAST0SeqDataAsnWrite(ptr -> seq, aip, BLAST0_SEQUENCE_seq)) {
+ goto erret;
+ }
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0KABlkNew()
+*
+**************************************************/
+
+BLAST0KABlkPtr LIBCALL
+BLAST0KABlkNew(void)
+{
+ BLAST0KABlkPtr ptr = MemNew((size_t) sizeof(BLAST0KABlk));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0KABlkFree()
+*
+**************************************************/
+
+BLAST0KABlkPtr LIBCALL
+BLAST0KABlkFree(BLAST0KABlkPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericBaseSeqOfFree(ptr -> frames ,ASNCODE_INTVAL_SLOT);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0KABlkAsnRead()
+*
+**************************************************/
+
+BLAST0KABlkPtr LIBCALL
+BLAST0KABlkAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0KABlkPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0KABlk ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_KA_BLK);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_KA_BLK);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0KABlkNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_KA_BLK_matid) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> matid = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_KA_BLK_frames) {
+ ptr -> frames = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_INTVAL_SLOT, &isError);
+ if (isError && ptr -> frames == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_KA_BLK_lambda) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> lambda = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_KA_BLK_k) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> k = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_KA_BLK_h) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> h = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0KABlkFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0KABlkAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0KABlkAsnWrite(BLAST0KABlkPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_KA_BLK); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> matid;
+ retval = AsnWrite(aip, BLAST0_KA_BLK_matid, &av);
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> frames ,ASNCODE_INTVAL_SLOT, aip, BLAST0_KA_BLK_frames, BLAST0_KA_BLK_frames_E);
+ av.realvalue = ptr -> lambda;
+ retval = AsnWrite(aip, BLAST0_KA_BLK_lambda, &av);
+ av.realvalue = ptr -> k;
+ retval = AsnWrite(aip, BLAST0_KA_BLK_k, &av);
+ av.realvalue = ptr -> h;
+ retval = AsnWrite(aip, BLAST0_KA_BLK_h, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0DbDescNew()
+*
+**************************************************/
+
+BLAST0DbDescPtr LIBCALL
+BLAST0DbDescNew(void)
+{
+ BLAST0DbDescPtr ptr = MemNew((size_t) sizeof(BLAST0DbDesc));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0DbDescFree()
+*
+**************************************************/
+
+BLAST0DbDescPtr LIBCALL
+BLAST0DbDescFree(BLAST0DbDescPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> name);
+ MemFree(ptr -> def);
+ MemFree(ptr -> rel_date);
+ MemFree(ptr -> bld_date);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0DbDescAsnRead()
+*
+**************************************************/
+
+BLAST0DbDescPtr LIBCALL
+BLAST0DbDescAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0DbDescPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0DbDesc ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_DB_DESC);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_DB_DESC);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0DbDescNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_DB_DESC_name) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> name = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_DB_DESC_type) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> type = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_DB_DESC_def) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> def = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_DB_DESC_rel_date) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> rel_date = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_DB_DESC_bld_date) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> bld_date = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_DB_DESC_count) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> count = av.intvalue;
+ ptr -> OBbits__ |= 1<<0;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_DB_DESC_totlen) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> totlen = av.intvalue;
+ ptr -> OBbits__ |= 1<<1;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_DB_DESC_maxlen) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> maxlen = av.intvalue;
+ ptr -> OBbits__ |= 1<<2;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0DbDescFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0DbDescAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0DbDescAsnWrite(BLAST0DbDescPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_DB_DESC); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> name != NULL) {
+ av.ptrvalue = ptr -> name;
+ retval = AsnWrite(aip, BLAST0_DB_DESC_name, &av);
+ }
+ av.intvalue = ptr -> type;
+ retval = AsnWrite(aip, BLAST0_DB_DESC_type, &av);
+ if (ptr -> def != NULL) {
+ av.ptrvalue = ptr -> def;
+ retval = AsnWrite(aip, BLAST0_DB_DESC_def, &av);
+ }
+ if (ptr -> rel_date != NULL) {
+ av.ptrvalue = ptr -> rel_date;
+ retval = AsnWrite(aip, BLAST0_DB_DESC_rel_date, &av);
+ }
+ if (ptr -> bld_date != NULL) {
+ av.ptrvalue = ptr -> bld_date;
+ retval = AsnWrite(aip, BLAST0_DB_DESC_bld_date, &av);
+ }
+ if (ptr -> count || (ptr -> OBbits__ & (1<<0) )){ av.intvalue = ptr -> count;
+ retval = AsnWrite(aip, BLAST0_DB_DESC_count, &av);
+ }
+ if (ptr -> totlen || (ptr -> OBbits__ & (1<<1) )){ av.intvalue = ptr -> totlen;
+ retval = AsnWrite(aip, BLAST0_DB_DESC_totlen, &av);
+ }
+ if (ptr -> maxlen || (ptr -> OBbits__ & (1<<2) )){ av.intvalue = ptr -> maxlen;
+ retval = AsnWrite(aip, BLAST0_DB_DESC_maxlen, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0ResultNew()
+*
+**************************************************/
+
+BLAST0ResultPtr LIBCALL
+BLAST0ResultNew(void)
+{
+ BLAST0ResultPtr ptr = MemNew((size_t) sizeof(BLAST0Result));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0ResultFree()
+*
+**************************************************/
+
+BLAST0ResultPtr LIBCALL
+BLAST0ResultFree(BLAST0ResultPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ BLAST0HistogramFree(ptr -> hist);
+ AsnGenericUserSeqOfFree(ptr -> hitlists, (AsnOptFreeFunc) BLAST0HitListFree);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0ResultAsnRead()
+*
+**************************************************/
+
+BLAST0ResultPtr LIBCALL
+BLAST0ResultAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0ResultPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Result ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_RESULT);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_RESULT);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0ResultNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_RESULT_hist) {
+ ptr -> hist = BLAST0HistogramAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_RESULT_count) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> count = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_RESULT_hitlists) {
+ ptr -> hitlists = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0HitListAsnRead, (AsnOptFreeFunc) BLAST0HitListFree);
+ if (isError && ptr -> hitlists == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0ResultFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0ResultAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0ResultAsnWrite(BLAST0ResultPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_RESULT); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> hist != NULL) {
+ if ( ! BLAST0HistogramAsnWrite(ptr -> hist, aip, BLAST0_RESULT_hist)) {
+ goto erret;
+ }
+ }
+ av.intvalue = ptr -> count;
+ retval = AsnWrite(aip, BLAST0_RESULT_count, &av);
+ AsnGenericUserSeqOfAsnWrite(ptr -> hitlists, (AsnWriteFunc) BLAST0HitListAsnWrite, aip, BLAST0_RESULT_hitlists, BLAST0_RESULT_hitlists_E);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0MatrixNew()
+*
+**************************************************/
+
+BLAST0MatrixPtr LIBCALL
+BLAST0MatrixNew(void)
+{
+ BLAST0MatrixPtr ptr = MemNew((size_t) sizeof(BLAST0Matrix));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* Scores_scaled_intsNew()
+*
+**************************************************/
+static
+Scores_scaled_intsPtr LIBCALL
+Scores_scaled_intsNew(void)
+{
+ Scores_scaled_intsPtr ptr = MemNew((size_t) sizeof(Scores_scaled_ints));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0MatrixFree()
+*
+**************************************************/
+
+BLAST0MatrixPtr LIBCALL
+BLAST0MatrixFree(BLAST0MatrixPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> name);
+ AsnGenericBaseSeqOfFree(ptr -> comments ,ASNCODE_PTRVAL_SLOT);
+ Scores_scoresFree(ptr -> Scores_scores);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* Scores_scoresFree()
+*
+**************************************************/
+static
+Scores_scoresPtr LIBCALL
+Scores_scoresFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case Scores_scores_Scores_ScaledInts:
+ Scores_scaled_intsFree(anp -> data.ptrvalue);
+ break;
+ case Scores_scores_reals:
+ AsnGenericBaseSeqOfFree((ValNodePtr) pnt,ASNCODE_REALVAL_SLOT);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* Scores_scaled_intsFree()
+*
+**************************************************/
+static
+Scores_scaled_intsPtr LIBCALL
+Scores_scaled_intsFree(Scores_scaled_intsPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericBaseSeqOfFree(ptr -> ints ,ASNCODE_INTVAL_SLOT);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0MatrixAsnRead()
+*
+**************************************************/
+
+BLAST0MatrixPtr LIBCALL
+BLAST0MatrixAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0MatrixPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Matrix ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_MATRIX);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_MATRIX);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0MatrixNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_MATRIX_matid) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> matid = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_MATRIX_name) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> name = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_MATRIX_comments) {
+ ptr -> comments = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && ptr -> comments == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_MATRIX_qalpha) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> qalpha = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_MATRIX_salpha) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> salpha = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_MATRIX_scores) {
+ ptr -> Scores_scores = Scores_scoresAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0MatrixFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* Scores_scoresAsnRead()
+*
+**************************************************/
+static
+Scores_scoresPtr LIBCALL
+Scores_scoresAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Scores_scores ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_MATRIX_scores);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_MATRIX_scores); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == MATRIX_scores_scaled_ints) {
+ choice = Scores_scores_Scores_ScaledInts;
+ func = (AsnReadFunc) Scores_scaled_intsAsnRead;
+ }
+ else if (atp == BLAST0_MATRIX_scores_reals) {
+ choice = Scores_scores_reals;
+ anp -> data.ptrvalue =
+ AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_REALVAL_SLOT, &isError);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Scores_scaled_intsAsnRead()
+*
+**************************************************/
+static
+Scores_scaled_intsPtr LIBCALL
+Scores_scaled_intsAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ Scores_scaled_intsPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Scores_scaled_ints ::= (self contained) */
+ atp = AsnReadId(aip, amp, MATRIX_scores_scaled_ints);
+ } else {
+ atp = AsnLinkType(orig, MATRIX_scores_scaled_ints);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = Scores_scaled_intsNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == scores_scaled_ints_scale) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> scale = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == MATRIX_scores_scaled_ints_ints) {
+ ptr -> ints = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_INTVAL_SLOT, &isError);
+ if (isError && ptr -> ints == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = Scores_scaled_intsFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0MatrixAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0MatrixAsnWrite(BLAST0MatrixPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_MATRIX); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> matid;
+ retval = AsnWrite(aip, BLAST0_MATRIX_matid, &av);
+ if (ptr -> name != NULL) {
+ av.ptrvalue = ptr -> name;
+ retval = AsnWrite(aip, BLAST0_MATRIX_name, &av);
+ }
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> comments ,ASNCODE_PTRVAL_SLOT, aip, BLAST0_MATRIX_comments, BLAST0_MATRIX_comments_E);
+ av.intvalue = ptr -> qalpha;
+ retval = AsnWrite(aip, BLAST0_MATRIX_qalpha, &av);
+ av.intvalue = ptr -> salpha;
+ retval = AsnWrite(aip, BLAST0_MATRIX_salpha, &av);
+ if (ptr -> Scores_scores != NULL) {
+ if ( ! Scores_scoresAsnWrite(ptr -> Scores_scores, aip, BLAST0_MATRIX_scores)) {
+ goto erret;
+ }
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* Scores_scoresAsnWrite()
+*
+**************************************************/
+static Boolean LIBCALL
+Scores_scoresAsnWrite(Scores_scoresPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST0_MATRIX_scores); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case Scores_scores_Scores_ScaledInts:
+ writetype = MATRIX_scores_scaled_ints;
+ func = (AsnWriteFunc) Scores_scaled_intsAsnWrite;
+ break;
+ case Scores_scores_reals:
+ retval = AsnGenericBaseSeqOfAsnWrite((Pointer) pnt,ASNCODE_REALVAL_SLOT, aip, BLAST0_MATRIX_scores_reals, BLAST0_MATRIX_scores_reals_E); break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* Scores_scaled_intsAsnWrite()
+*
+**************************************************/
+static Boolean LIBCALL
+Scores_scaled_intsAsnWrite(Scores_scaled_intsPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, MATRIX_scores_scaled_ints); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.realvalue = ptr -> scale;
+ retval = AsnWrite(aip, scores_scaled_ints_scale, &av);
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> ints ,ASNCODE_INTVAL_SLOT, aip, MATRIX_scores_scaled_ints_ints, scores_scaled_ints_ints_E);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0StatusNew()
+*
+**************************************************/
+
+BLAST0StatusPtr LIBCALL
+BLAST0StatusNew(void)
+{
+ BLAST0StatusPtr ptr = MemNew((size_t) sizeof(BLAST0Status));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0StatusFree()
+*
+**************************************************/
+
+BLAST0StatusPtr LIBCALL
+BLAST0StatusFree(BLAST0StatusPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> reason);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0StatusAsnRead()
+*
+**************************************************/
+
+BLAST0StatusPtr LIBCALL
+BLAST0StatusAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0StatusPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Status ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_STATUS);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_STATUS);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0StatusNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_STATUS_code) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> code = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_STATUS_reason) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> reason = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0StatusFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0StatusAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0StatusAsnWrite(BLAST0StatusPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_STATUS); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> code;
+ retval = AsnWrite(aip, BLAST0_STATUS_code, &av);
+ if (ptr -> reason != NULL) {
+ av.ptrvalue = ptr -> reason;
+ retval = AsnWrite(aip, BLAST0_STATUS_reason, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0OutblkFree()
+*
+**************************************************/
+
+BLAST0OutblkPtr LIBCALL
+BLAST0OutblkFree(ValNodePtr anp)
+{
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ AsnGenericChoiceSeqOfFree(anp, (AsnOptFreeFunc) BLAST0Outblk_elementFree);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* BLAST0OutblkAsnRead()
+*
+**************************************************/
+
+BLAST0OutblkPtr LIBCALL
+BLAST0OutblkAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+
+
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Outblk_element ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_OUTBLK);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_OUTBLK); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp =
+ AsnGenericChoiceSeqOfAsnRead(aip, amp, atp, &isError,
+ (AsnReadFunc) BLAST0Outblk_elementAsnRead, (AsnOptFreeFunc) BLAST0Outblk_elementFree);
+ if (isError)
+ goto erret;
+
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BLAST0OutblkAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0OutblkAsnWrite(ValNodePtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST0_OUTBLK); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ retval = AsnGenericChoiceSeqOfAsnWrite(anp,
+ (AsnWriteFunc) BLAST0Outblk_elementAsnWrite, aip, atp, BLAST0_OUTBLK_E);
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* BLAST0Outblk_elementAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0Outblk_elementAsnWrite(BLAST0Outblk_elementPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST0_OUTBLK_E); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case BLAST0Outblk_preface:
+ writetype = BLAST0_OUTBLK_E_preface;
+ func = (AsnWriteFunc) BLAST0PrefaceAsnWrite;
+ break;
+ case BLAST0Outblk_query:
+ writetype = BLAST0_OUTBLK_E_query;
+ func = (AsnWriteFunc) BLAST0SequenceAsnWrite;
+ break;
+ case BLAST0Outblk_dbdesc:
+ writetype = BLAST0_OUTBLK_E_dbdesc;
+ func = (AsnWriteFunc) BLAST0DbDescAsnWrite;
+ break;
+ case BLAST0Outblk_matrix:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BLAST0MatrixAsnWrite, aip, BLAST0_OUTBLK_E_matrix, BLAST0_OUTBLK_E_matrix_E);
+ break;
+ case BLAST0Outblk_kablk:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BLAST0KABlkAsnWrite, aip, BLAST0_OUTBLK_E_kablk, BLAST0_OUTBLK_E_kablk_E);
+ break;
+ case BLAST0Outblk_job_start:
+ writetype = BLAST0_OUTBLK_E_job_start;
+ func = (AsnWriteFunc) BLAST0JobDescAsnWrite;
+ break;
+ case BLAST0Outblk_job_progress:
+ writetype = BLAST0_OUTBLK_E_job_progress;
+ func = (AsnWriteFunc) BLAST0JobProgressAsnWrite;
+ break;
+ case BLAST0Outblk_job_done:
+ writetype = BLAST0_OUTBLK_E_job_done;
+ func = (AsnWriteFunc) BLAST0JobProgressAsnWrite;
+ break;
+ case BLAST0Outblk_result:
+ writetype = BLAST0_OUTBLK_E_result;
+ func = (AsnWriteFunc) BLAST0ResultAsnWrite;
+ break;
+ case BLAST0Outblk_parms:
+ retval = AsnGenericBaseSeqOfAsnWrite((Pointer) pnt,ASNCODE_PTRVAL_SLOT, aip, BLAST0_OUTBLK_E_parms, BLAST0_OUTBLK_E_parms_E); break;
+ case BLAST0Outblk_stats:
+ retval = AsnGenericBaseSeqOfAsnWrite((Pointer) pnt,ASNCODE_PTRVAL_SLOT, aip, BLAST0_OUTBLK_E_stats, BLAST0_OUTBLK_E_stats_E); break;
+ case BLAST0Outblk_warning:
+ writetype = BLAST0_OUTBLK_E_warning;
+ func = (AsnWriteFunc) BLAST0StatusAsnWrite;
+ break;
+ case BLAST0Outblk_status:
+ writetype = BLAST0_OUTBLK_E_status;
+ func = (AsnWriteFunc) BLAST0StatusAsnWrite;
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* BLAST0Outblk_elementAsnRead()
+*
+**************************************************/
+
+BLAST0Outblk_elementPtr LIBCALL
+BLAST0Outblk_elementAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Outblk_element ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_OUTBLK_E);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_OUTBLK_E); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == BLAST0_OUTBLK_E_preface) {
+ choice = BLAST0Outblk_preface;
+ func = (AsnReadFunc) BLAST0PrefaceAsnRead;
+ }
+ else if (atp == BLAST0_OUTBLK_E_query) {
+ choice = BLAST0Outblk_query;
+ func = (AsnReadFunc) BLAST0SequenceAsnRead;
+ }
+ else if (atp == BLAST0_OUTBLK_E_dbdesc) {
+ choice = BLAST0Outblk_dbdesc;
+ func = (AsnReadFunc) BLAST0DbDescAsnRead;
+ }
+ else if (atp == BLAST0_OUTBLK_E_matrix) {
+ choice = BLAST0Outblk_matrix;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0MatrixAsnRead, (AsnOptFreeFunc) BLAST0MatrixFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_OUTBLK_E_kablk) {
+ choice = BLAST0Outblk_kablk;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0KABlkAsnRead, (AsnOptFreeFunc) BLAST0KABlkFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_OUTBLK_E_job_start) {
+ choice = BLAST0Outblk_job_start;
+ func = (AsnReadFunc) BLAST0JobDescAsnRead;
+ }
+ else if (atp == BLAST0_OUTBLK_E_job_progress) {
+ choice = BLAST0Outblk_job_progress;
+ func = (AsnReadFunc) BLAST0JobProgressAsnRead;
+ }
+ else if (atp == BLAST0_OUTBLK_E_job_done) {
+ choice = BLAST0Outblk_job_done;
+ func = (AsnReadFunc) BLAST0JobProgressAsnRead;
+ }
+ else if (atp == BLAST0_OUTBLK_E_result) {
+ choice = BLAST0Outblk_result;
+ func = (AsnReadFunc) BLAST0ResultAsnRead;
+ }
+ else if (atp == BLAST0_OUTBLK_E_parms) {
+ choice = BLAST0Outblk_parms;
+ anp -> data.ptrvalue =
+ AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_OUTBLK_E_stats) {
+ choice = BLAST0Outblk_stats;
+ anp -> data.ptrvalue =
+ AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_OUTBLK_E_warning) {
+ choice = BLAST0Outblk_warning;
+ func = (AsnReadFunc) BLAST0StatusAsnRead;
+ }
+ else if (atp == BLAST0_OUTBLK_E_status) {
+ choice = BLAST0Outblk_status;
+ func = (AsnReadFunc) BLAST0StatusAsnRead;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BLAST0Outblk_elementFree()
+*
+**************************************************/
+
+BLAST0Outblk_elementPtr LIBCALL
+BLAST0Outblk_elementFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case BLAST0Outblk_preface:
+ BLAST0PrefaceFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Outblk_query:
+ BLAST0SequenceFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Outblk_dbdesc:
+ BLAST0DbDescFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Outblk_matrix:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BLAST0MatrixFree);
+ break;
+ case BLAST0Outblk_kablk:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BLAST0KABlkFree);
+ break;
+ case BLAST0Outblk_job_start:
+ BLAST0JobDescFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Outblk_job_progress:
+ BLAST0JobProgressFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Outblk_job_done:
+ BLAST0JobProgressFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Outblk_result:
+ BLAST0ResultFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Outblk_parms:
+ AsnGenericBaseSeqOfFree((ValNodePtr) pnt,ASNCODE_PTRVAL_SLOT);
+ break;
+ case BLAST0Outblk_stats:
+ AsnGenericBaseSeqOfFree((ValNodePtr) pnt,ASNCODE_PTRVAL_SLOT);
+ break;
+ case BLAST0Outblk_warning:
+ BLAST0StatusFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Outblk_status:
+ BLAST0StatusFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* BLAST0RequestFree()
+*
+**************************************************/
+
+BLAST0RequestPtr LIBCALL
+BLAST0RequestFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case BLAST0Request_hello:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Request_usage_info:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Request_matrix_get:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Request_search:
+ BLAST0SearchFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* BLAST0RequestAsnRead()
+*
+**************************************************/
+
+BLAST0RequestPtr LIBCALL
+BLAST0RequestAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Request ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_REQUEST);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_REQUEST); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == BLAST0_REQUEST_hello) {
+ choice = BLAST0Request_hello;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST0_REQUEST_motd) {
+ choice = BLAST0Request_motd;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == BLAST0_REQUEST_prog_info) {
+ choice = BLAST0Request_prog_info;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == BLAST0_REQUEST_usage_info) {
+ choice = BLAST0Request_usage_info;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST0_REQUEST_db_info) {
+ choice = BLAST0Request_db_info;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == BLAST0_REQUEST_matrix_info) {
+ choice = BLAST0Request_matrix_info;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == BLAST0_REQUEST_matrix_get) {
+ choice = BLAST0Request_matrix_get;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST0_REQUEST_search) {
+ choice = BLAST0Request_search;
+ func = (AsnReadFunc) BLAST0SearchAsnRead;
+ }
+ else if (atp == BLAST0_REQUEST_goodbye) {
+ choice = BLAST0Request_goodbye;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BLAST0RequestAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0RequestAsnWrite(BLAST0RequestPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST0_REQUEST); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case BLAST0Request_hello:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST0_REQUEST_hello, &av);
+ break;
+ case BLAST0Request_motd:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, BLAST0_REQUEST_motd, &av);
+ break;
+ case BLAST0Request_prog_info:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, BLAST0_REQUEST_prog_info, &av);
+ break;
+ case BLAST0Request_usage_info:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST0_REQUEST_usage_info, &av);
+ break;
+ case BLAST0Request_db_info:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, BLAST0_REQUEST_db_info, &av);
+ break;
+ case BLAST0Request_matrix_info:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, BLAST0_REQUEST_matrix_info, &av);
+ break;
+ case BLAST0Request_matrix_get:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST0_REQUEST_matrix_get, &av);
+ break;
+ case BLAST0Request_search:
+ writetype = BLAST0_REQUEST_search;
+ func = (AsnWriteFunc) BLAST0SearchAsnWrite;
+ break;
+ case BLAST0Request_goodbye:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, BLAST0_REQUEST_goodbye, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* BLAST0SearchNew()
+*
+**************************************************/
+
+BLAST0SearchPtr LIBCALL
+BLAST0SearchNew(void)
+{
+ BLAST0SearchPtr ptr = MemNew((size_t) sizeof(BLAST0Search));
+
+ ptr -> return_matrix = 1;
+ ptr -> return_query = 1;
+ ptr -> return_BLAST0result = 1;
+ ptr -> return_query_seq_in_seg = 1;
+ ptr -> return_db_seq_in_seg = 1;
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0SearchFree()
+*
+**************************************************/
+
+BLAST0SearchPtr LIBCALL
+BLAST0SearchFree(BLAST0SearchPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> program);
+ MemFree(ptr -> database);
+ BLAST0SequenceFree(ptr -> query);
+ AsnGenericBaseSeqOfFree(ptr -> options ,ASNCODE_PTRVAL_SLOT);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0SearchAsnRead()
+*
+**************************************************/
+
+BLAST0SearchPtr LIBCALL
+BLAST0SearchAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0SearchPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Search ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SEARCH);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SEARCH);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0SearchNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_SEARCH_program) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> program = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEARCH_database) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> database = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEARCH_query) {
+ ptr -> query = BLAST0SequenceAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEARCH_options) {
+ ptr -> options = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && ptr -> options == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEARCH_return_matrix) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> return_matrix = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEARCH_return_query) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> return_query = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SEARCH_return_BLAST0result) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> return_BLAST0result = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SEARCH_return_query_seq_in_seg) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> return_query_seq_in_seg = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SEARCH_return_db_seq_in_seg) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> return_db_seq_in_seg = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0SearchFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SearchAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0SearchAsnWrite(BLAST0SearchPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_SEARCH); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> program != NULL) {
+ av.ptrvalue = ptr -> program;
+ retval = AsnWrite(aip, BLAST0_SEARCH_program, &av);
+ }
+ if (ptr -> database != NULL) {
+ av.ptrvalue = ptr -> database;
+ retval = AsnWrite(aip, BLAST0_SEARCH_database, &av);
+ }
+ if (ptr -> query != NULL) {
+ if ( ! BLAST0SequenceAsnWrite(ptr -> query, aip, BLAST0_SEARCH_query)) {
+ goto erret;
+ }
+ }
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> options ,ASNCODE_PTRVAL_SLOT, aip, BLAST0_SEARCH_options, BLAST0_SEARCH_options_E);
+ av.boolvalue = ptr -> return_matrix;
+ retval = AsnWrite(aip, BLAST0_SEARCH_return_matrix, &av);
+ av.boolvalue = ptr -> return_query;
+ retval = AsnWrite(aip, BLAST0_SEARCH_return_query, &av);
+ av.boolvalue = ptr -> return_BLAST0result;
+ retval = AsnWrite(aip, SEARCH_return_BLAST0result, &av);
+ av.boolvalue = ptr -> return_query_seq_in_seg;
+ retval = AsnWrite(aip, SEARCH_return_query_seq_in_seg, &av);
+ av.boolvalue = ptr -> return_db_seq_in_seg;
+ retval = AsnWrite(aip, SEARCH_return_db_seq_in_seg, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0ResponseFree()
+*
+**************************************************/
+
+BLAST0ResponsePtr LIBCALL
+BLAST0ResponseFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case BLAST0Response_hello:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_motd:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_prog_info:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BLAST0PrefaceFree);
+ break;
+ case BLAST0Response_usage_info:
+ BLAST0PrefaceFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_db_info:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BLAST0DbDescFree);
+ break;
+ case BLAST0Response_matrix_info:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BLAST0MatrixFree);
+ break;
+ case BLAST0Response_ack:
+ BLAST0AckFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_goodbye:
+ BLAST0AckFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_queued:
+ BLAST0QueuedFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_preface:
+ BLAST0PrefaceFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_query:
+ BLAST0SequenceFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_dbdesc:
+ BLAST0DbDescFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_matrix:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BLAST0MatrixFree);
+ break;
+ case BLAST0Response_kablk:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BLAST0KABlkFree);
+ break;
+ case BLAST0Response_job_start:
+ BLAST0JobDescFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_job_progress:
+ BLAST0JobProgressFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_job_done:
+ BLAST0JobProgressFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_score_defs:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BLAST0ScoreInfoFree);
+ break;
+ case BLAST0Response_result:
+ BLAST0ResultFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_seqalign:
+ SeqAlignSetFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_parms:
+ AsnGenericBaseSeqOfFree((ValNodePtr) pnt,ASNCODE_PTRVAL_SLOT);
+ break;
+ case BLAST0Response_stats:
+ AsnGenericBaseSeqOfFree((ValNodePtr) pnt,ASNCODE_PTRVAL_SLOT);
+ break;
+ case BLAST0Response_warning:
+ BLAST0StatusFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0Response_status:
+ BLAST0StatusFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* BLAST0ResponseAsnRead()
+*
+**************************************************/
+
+BLAST0ResponsePtr LIBCALL
+BLAST0ResponseAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Response ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_RESPONSE);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_RESPONSE); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == BLAST0_RESPONSE_hello) {
+ choice = BLAST0Response_hello;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST0_RESPONSE_motd) {
+ choice = BLAST0Response_motd;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST0_RESPONSE_prog_info) {
+ choice = BLAST0Response_prog_info;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0PrefaceAsnRead, (AsnOptFreeFunc) BLAST0PrefaceFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_RESPONSE_usage_info) {
+ choice = BLAST0Response_usage_info;
+ func = (AsnReadFunc) BLAST0PrefaceAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_db_info) {
+ choice = BLAST0Response_db_info;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0DbDescAsnRead, (AsnOptFreeFunc) BLAST0DbDescFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_RESPONSE_matrix_info) {
+ choice = BLAST0Response_matrix_info;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0MatrixAsnRead, (AsnOptFreeFunc) BLAST0MatrixFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_RESPONSE_ack) {
+ choice = BLAST0Response_ack;
+ func = (AsnReadFunc) BLAST0AckAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_goodbye) {
+ choice = BLAST0Response_goodbye;
+ func = (AsnReadFunc) BLAST0AckAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_queued) {
+ choice = BLAST0Response_queued;
+ func = (AsnReadFunc) BLAST0QueuedAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_preface) {
+ choice = BLAST0Response_preface;
+ func = (AsnReadFunc) BLAST0PrefaceAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_query) {
+ choice = BLAST0Response_query;
+ func = (AsnReadFunc) BLAST0SequenceAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_dbdesc) {
+ choice = BLAST0Response_dbdesc;
+ func = (AsnReadFunc) BLAST0DbDescAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_matrix) {
+ choice = BLAST0Response_matrix;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0MatrixAsnRead, (AsnOptFreeFunc) BLAST0MatrixFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_RESPONSE_kablk) {
+ choice = BLAST0Response_kablk;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0KABlkAsnRead, (AsnOptFreeFunc) BLAST0KABlkFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_RESPONSE_job_start) {
+ choice = BLAST0Response_job_start;
+ func = (AsnReadFunc) BLAST0JobDescAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_job_progress) {
+ choice = BLAST0Response_job_progress;
+ func = (AsnReadFunc) BLAST0JobProgressAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_job_done) {
+ choice = BLAST0Response_job_done;
+ func = (AsnReadFunc) BLAST0JobProgressAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_score_defs) {
+ choice = BLAST0Response_score_defs;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0ScoreInfoAsnRead, (AsnOptFreeFunc) BLAST0ScoreInfoFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_RESPONSE_result) {
+ choice = BLAST0Response_result;
+ func = (AsnReadFunc) BLAST0ResultAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_seqalign) {
+ choice = BLAST0Response_seqalign;
+ func = (AsnReadFunc) SeqAlignSetAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_parms) {
+ choice = BLAST0Response_parms;
+ anp -> data.ptrvalue =
+ AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_RESPONSE_stats) {
+ choice = BLAST0Response_stats;
+ anp -> data.ptrvalue =
+ AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST0_RESPONSE_warning) {
+ choice = BLAST0Response_warning;
+ func = (AsnReadFunc) BLAST0StatusAsnRead;
+ }
+ else if (atp == BLAST0_RESPONSE_status) {
+ choice = BLAST0Response_status;
+ func = (AsnReadFunc) BLAST0StatusAsnRead;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BLAST0ResponseAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0ResponseAsnWrite(BLAST0ResponsePtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST0_RESPONSE); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case BLAST0Response_hello:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST0_RESPONSE_hello, &av);
+ break;
+ case BLAST0Response_motd:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST0_RESPONSE_motd, &av);
+ break;
+ case BLAST0Response_prog_info:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BLAST0PrefaceAsnWrite, aip, BLAST0_RESPONSE_prog_info, BLAST0_RESPONSE_prog_info_E);
+ break;
+ case BLAST0Response_usage_info:
+ writetype = BLAST0_RESPONSE_usage_info;
+ func = (AsnWriteFunc) BLAST0PrefaceAsnWrite;
+ break;
+ case BLAST0Response_db_info:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BLAST0DbDescAsnWrite, aip, BLAST0_RESPONSE_db_info, BLAST0_RESPONSE_db_info_E);
+ break;
+ case BLAST0Response_matrix_info:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BLAST0MatrixAsnWrite, aip, BLAST0_RESPONSE_matrix_info, BLAST0_RESPONSE_matrix_info_E);
+ break;
+ case BLAST0Response_ack:
+ writetype = BLAST0_RESPONSE_ack;
+ func = (AsnWriteFunc) BLAST0AckAsnWrite;
+ break;
+ case BLAST0Response_goodbye:
+ writetype = BLAST0_RESPONSE_goodbye;
+ func = (AsnWriteFunc) BLAST0AckAsnWrite;
+ break;
+ case BLAST0Response_queued:
+ writetype = BLAST0_RESPONSE_queued;
+ func = (AsnWriteFunc) BLAST0QueuedAsnWrite;
+ break;
+ case BLAST0Response_preface:
+ writetype = BLAST0_RESPONSE_preface;
+ func = (AsnWriteFunc) BLAST0PrefaceAsnWrite;
+ break;
+ case BLAST0Response_query:
+ writetype = BLAST0_RESPONSE_query;
+ func = (AsnWriteFunc) BLAST0SequenceAsnWrite;
+ break;
+ case BLAST0Response_dbdesc:
+ writetype = BLAST0_RESPONSE_dbdesc;
+ func = (AsnWriteFunc) BLAST0DbDescAsnWrite;
+ break;
+ case BLAST0Response_matrix:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BLAST0MatrixAsnWrite, aip, BLAST0_RESPONSE_matrix, BLAST0_RESPONSE_matrix_E);
+ break;
+ case BLAST0Response_kablk:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BLAST0KABlkAsnWrite, aip, BLAST0_RESPONSE_kablk, BLAST0_RESPONSE_kablk_E);
+ break;
+ case BLAST0Response_job_start:
+ writetype = BLAST0_RESPONSE_job_start;
+ func = (AsnWriteFunc) BLAST0JobDescAsnWrite;
+ break;
+ case BLAST0Response_job_progress:
+ writetype = BLAST0_RESPONSE_job_progress;
+ func = (AsnWriteFunc) BLAST0JobProgressAsnWrite;
+ break;
+ case BLAST0Response_job_done:
+ writetype = BLAST0_RESPONSE_job_done;
+ func = (AsnWriteFunc) BLAST0JobProgressAsnWrite;
+ break;
+ case BLAST0Response_score_defs:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BLAST0ScoreInfoAsnWrite, aip, BLAST0_RESPONSE_score_defs, BLAST0_RESPONSE_score_defs_E);
+ break;
+ case BLAST0Response_result:
+ writetype = BLAST0_RESPONSE_result;
+ func = (AsnWriteFunc) BLAST0ResultAsnWrite;
+ break;
+ case BLAST0Response_seqalign:
+ writetype = BLAST0_RESPONSE_seqalign;
+ func = (AsnWriteFunc) SeqAlignSetAsnWrite;
+ break;
+ case BLAST0Response_parms:
+ retval = AsnGenericBaseSeqOfAsnWrite((Pointer) pnt,ASNCODE_PTRVAL_SLOT, aip, BLAST0_RESPONSE_parms, BLAST0_RESPONSE_parms_E); break;
+ case BLAST0Response_stats:
+ retval = AsnGenericBaseSeqOfAsnWrite((Pointer) pnt,ASNCODE_PTRVAL_SLOT, aip, BLAST0_RESPONSE_stats, BLAST0_RESPONSE_stats_E); break;
+ case BLAST0Response_warning:
+ writetype = BLAST0_RESPONSE_warning;
+ func = (AsnWriteFunc) BLAST0StatusAsnWrite;
+ break;
+ case BLAST0Response_status:
+ writetype = BLAST0_RESPONSE_status;
+ func = (AsnWriteFunc) BLAST0StatusAsnWrite;
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* BLAST0AckNew()
+*
+**************************************************/
+
+BLAST0AckPtr LIBCALL
+BLAST0AckNew(void)
+{
+ BLAST0AckPtr ptr = MemNew((size_t) sizeof(BLAST0Ack));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0AckFree()
+*
+**************************************************/
+
+BLAST0AckPtr LIBCALL
+BLAST0AckFree(BLAST0AckPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> reason);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0AckAsnRead()
+*
+**************************************************/
+
+BLAST0AckPtr LIBCALL
+BLAST0AckAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0AckPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Ack ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_ACK);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_ACK);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0AckNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_ACK_code) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> code = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_ACK_reason) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> reason = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0AckFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0AckAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0AckAsnWrite(BLAST0AckPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_ACK); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> code;
+ retval = AsnWrite(aip, BLAST0_ACK_code, &av);
+ if (ptr -> reason != NULL) {
+ av.ptrvalue = ptr -> reason;
+ retval = AsnWrite(aip, BLAST0_ACK_reason, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0QueuedNew()
+*
+**************************************************/
+
+BLAST0QueuedPtr LIBCALL
+BLAST0QueuedNew(void)
+{
+ BLAST0QueuedPtr ptr = MemNew((size_t) sizeof(BLAST0Queued));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0QueuedFree()
+*
+**************************************************/
+
+BLAST0QueuedPtr LIBCALL
+BLAST0QueuedFree(BLAST0QueuedPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> name);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0QueuedAsnRead()
+*
+**************************************************/
+
+BLAST0QueuedPtr LIBCALL
+BLAST0QueuedAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0QueuedPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Queued ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_QUEUED);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_QUEUED);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0QueuedNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_QUEUED_name) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> name = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_QUEUED_length) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> length = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0QueuedFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0QueuedAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0QueuedAsnWrite(BLAST0QueuedPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_QUEUED); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> name != NULL) {
+ av.ptrvalue = ptr -> name;
+ retval = AsnWrite(aip, BLAST0_QUEUED_name, &av);
+ }
+ av.intvalue = ptr -> length;
+ retval = AsnWrite(aip, BLAST0_QUEUED_length, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0ScoreInfoNew()
+*
+**************************************************/
+
+BLAST0ScoreInfoPtr LIBCALL
+BLAST0ScoreInfoNew(void)
+{
+ BLAST0ScoreInfoPtr ptr = MemNew((size_t) sizeof(BLAST0ScoreInfo));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0ScoreInfoFree()
+*
+**************************************************/
+
+BLAST0ScoreInfoPtr LIBCALL
+BLAST0ScoreInfoFree(BLAST0ScoreInfoPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> tag);
+ MemFree(ptr -> desc);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0ScoreInfoAsnRead()
+*
+**************************************************/
+
+BLAST0ScoreInfoPtr LIBCALL
+BLAST0ScoreInfoAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0ScoreInfoPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0ScoreInfo ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SCORE_INFO);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SCORE_INFO);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0ScoreInfoNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_SCORE_INFO_sid) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> sid = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SCORE_INFO_tag) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> tag = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SCORE_INFO_desc) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> desc = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0ScoreInfoFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0ScoreInfoAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0ScoreInfoAsnWrite(BLAST0ScoreInfoPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_SCORE_INFO); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> sid;
+ retval = AsnWrite(aip, BLAST0_SCORE_INFO_sid, &av);
+ if (ptr -> tag != NULL) {
+ av.ptrvalue = ptr -> tag;
+ retval = AsnWrite(aip, BLAST0_SCORE_INFO_tag, &av);
+ }
+ if (ptr -> desc != NULL) {
+ av.ptrvalue = ptr -> desc;
+ retval = AsnWrite(aip, BLAST0_SCORE_INFO_desc, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SeqUsageNew()
+*
+**************************************************/
+
+BLAST0SeqUsagePtr LIBCALL
+BLAST0SeqUsageNew(void)
+{
+ BLAST0SeqUsagePtr ptr = MemNew((size_t) sizeof(BLAST0SeqUsage));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0SeqUsageFree()
+*
+**************************************************/
+
+BLAST0SeqUsagePtr LIBCALL
+BLAST0SeqUsageFree(BLAST0SeqUsagePtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0SeqUsageAsnRead()
+*
+**************************************************/
+
+BLAST0SeqUsagePtr LIBCALL
+BLAST0SeqUsageAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0SeqUsagePtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0SeqUsage ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SEQ_USAGE);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SEQ_USAGE);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0SeqUsageNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_SEQ_USAGE_raw) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> raw = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEQ_USAGE_cooked) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> cooked = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0SeqUsageFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SeqUsageAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0SeqUsageAsnWrite(BLAST0SeqUsagePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_SEQ_USAGE); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> raw;
+ retval = AsnWrite(aip, BLAST0_SEQ_USAGE_raw, &av);
+ av.intvalue = ptr -> cooked;
+ retval = AsnWrite(aip, BLAST0_SEQ_USAGE_cooked, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0HistogramNew()
+*
+**************************************************/
+
+BLAST0HistogramPtr LIBCALL
+BLAST0HistogramNew(void)
+{
+ BLAST0HistogramPtr ptr = MemNew((size_t) sizeof(BLAST0Histogram));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0HistogramFree()
+*
+**************************************************/
+
+BLAST0HistogramPtr LIBCALL
+BLAST0HistogramFree(BLAST0HistogramPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericUserSeqOfFree(ptr -> bar, (AsnOptFreeFunc) BLAST0HistogramBarFree);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0HistogramAsnRead()
+*
+**************************************************/
+
+BLAST0HistogramPtr LIBCALL
+BLAST0HistogramAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0HistogramPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Histogram ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_HISTOGRAM);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_HISTOGRAM);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0HistogramNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_HISTOGRAM_expect) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> expect = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HISTOGRAM_observed) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> observed = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HISTOGRAM_base) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> base = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HISTOGRAM_nbars) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> nbars = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HISTOGRAM_bar) {
+ ptr -> bar = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0HistogramBarAsnRead, (AsnOptFreeFunc) BLAST0HistogramBarFree);
+ if (isError && ptr -> bar == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0HistogramFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0HistogramAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0HistogramAsnWrite(BLAST0HistogramPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_HISTOGRAM); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.realvalue = ptr -> expect;
+ retval = AsnWrite(aip, BLAST0_HISTOGRAM_expect, &av);
+ av.intvalue = ptr -> observed;
+ retval = AsnWrite(aip, BLAST0_HISTOGRAM_observed, &av);
+ av.intvalue = ptr -> base;
+ retval = AsnWrite(aip, BLAST0_HISTOGRAM_base, &av);
+ av.intvalue = ptr -> nbars;
+ retval = AsnWrite(aip, BLAST0_HISTOGRAM_nbars, &av);
+ AsnGenericUserSeqOfAsnWrite(ptr -> bar, (AsnWriteFunc) BLAST0HistogramBarAsnWrite, aip, BLAST0_HISTOGRAM_bar, BLAST0_HISTOGRAM_bar_E);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0HitListNew()
+*
+**************************************************/
+
+BLAST0HitListPtr LIBCALL
+BLAST0HitListNew(void)
+{
+ BLAST0HitListPtr ptr = MemNew((size_t) sizeof(BLAST0HitList));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0HitListFree()
+*
+**************************************************/
+
+BLAST0HitListPtr LIBCALL
+BLAST0HitListFree(BLAST0HitListPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericUserSeqOfFree(ptr -> kablk, (AsnOptFreeFunc) BLAST0KABlkFree);
+ AsnGenericUserSeqOfFree(ptr -> hsps, (AsnOptFreeFunc) BLAST0HSPFree);
+ AsnGenericUserSeqOfFree(ptr -> seqs, (AsnOptFreeFunc) BLAST0SequenceFree);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0HitListAsnRead()
+*
+**************************************************/
+
+BLAST0HitListPtr LIBCALL
+BLAST0HitListAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0HitListPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0HitList ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_HITLIST);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_HITLIST);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0HitListNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_HITLIST_count) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> count = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HITLIST_kablk) {
+ ptr -> kablk = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0KABlkAsnRead, (AsnOptFreeFunc) BLAST0KABlkFree);
+ if (isError && ptr -> kablk == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HITLIST_hsps) {
+ ptr -> hsps = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0HSPAsnRead, (AsnOptFreeFunc) BLAST0HSPFree);
+ if (isError && ptr -> hsps == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HITLIST_seqs) {
+ ptr -> seqs = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0SequenceAsnRead, (AsnOptFreeFunc) BLAST0SequenceFree);
+ if (isError && ptr -> seqs == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0HitListFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0HitListAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0HitListAsnWrite(BLAST0HitListPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_HITLIST); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> count;
+ retval = AsnWrite(aip, BLAST0_HITLIST_count, &av);
+ AsnGenericUserSeqOfAsnWrite(ptr -> kablk, (AsnWriteFunc) BLAST0KABlkAsnWrite, aip, BLAST0_HITLIST_kablk, BLAST0_HITLIST_kablk_E);
+ AsnGenericUserSeqOfAsnWrite(ptr -> hsps, (AsnWriteFunc) BLAST0HSPAsnWrite, aip, BLAST0_HITLIST_hsps, BLAST0_HITLIST_hsps_E);
+ AsnGenericUserSeqOfAsnWrite(ptr -> seqs, (AsnWriteFunc) BLAST0SequenceAsnWrite, aip, BLAST0_HITLIST_seqs, BLAST0_HITLIST_seqs_E);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0HistogramBarNew()
+*
+**************************************************/
+
+BLAST0HistogramBarPtr LIBCALL
+BLAST0HistogramBarNew(void)
+{
+ BLAST0HistogramBarPtr ptr = MemNew((size_t) sizeof(BLAST0HistogramBar));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0HistogramBarFree()
+*
+**************************************************/
+
+BLAST0HistogramBarPtr LIBCALL
+BLAST0HistogramBarFree(BLAST0HistogramBarPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0HistogramBarAsnRead()
+*
+**************************************************/
+
+BLAST0HistogramBarPtr LIBCALL
+BLAST0HistogramBarAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0HistogramBarPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0HistogramBar ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_HISTOGRAM_BAR);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_HISTOGRAM_BAR);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0HistogramBarNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_HISTOGRAM_BAR_x) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> x = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HISTOGRAM_BAR_n) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> n = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0HistogramBarFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0HistogramBarAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0HistogramBarAsnWrite(BLAST0HistogramBarPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_HISTOGRAM_BAR); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.realvalue = ptr -> x;
+ retval = AsnWrite(aip, BLAST0_HISTOGRAM_BAR_x, &av);
+ av.intvalue = ptr -> n;
+ retval = AsnWrite(aip, BLAST0_HISTOGRAM_BAR_n, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0HSPNew()
+*
+**************************************************/
+
+BLAST0HSPPtr LIBCALL
+BLAST0HSPNew(void)
+{
+ BLAST0HSPPtr ptr = MemNew((size_t) sizeof(BLAST0HSP));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0HSPFree()
+*
+**************************************************/
+
+BLAST0HSPPtr LIBCALL
+BLAST0HSPFree(BLAST0HSPPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ ScoreSetFree(ptr -> scores);
+ AsnGenericUserSeqOfFree(ptr -> segs, (AsnOptFreeFunc) BLAST0SegmentFree);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0HSPAsnRead()
+*
+**************************************************/
+
+BLAST0HSPPtr LIBCALL
+BLAST0HSPAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0HSPPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0HSP ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_HSP);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_HSP);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0HSPNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_HSP_matid) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> matid = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HSP_scores) {
+ ptr -> scores = ScoreSetAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HSP_len) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> len = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_HSP_segs) {
+ ptr -> segs = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BLAST0SegmentAsnRead, (AsnOptFreeFunc) BLAST0SegmentFree);
+ if (isError && ptr -> segs == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0HSPFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0HSPAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0HSPAsnWrite(BLAST0HSPPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_HSP); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> matid;
+ retval = AsnWrite(aip, BLAST0_HSP_matid, &av);
+ if (ptr -> scores != NULL) {
+ if ( ! ScoreSetAsnWrite(ptr -> scores, aip, BLAST0_HSP_scores)) {
+ goto erret;
+ }
+ }
+ av.intvalue = ptr -> len;
+ retval = AsnWrite(aip, BLAST0_HSP_len, &av);
+ AsnGenericUserSeqOfAsnWrite(ptr -> segs, (AsnWriteFunc) BLAST0SegmentAsnWrite, aip, BLAST0_HSP_segs, BLAST0_HSP_segs_E);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SegmentNew()
+*
+**************************************************/
+
+BLAST0SegmentPtr LIBCALL
+BLAST0SegmentNew(void)
+{
+ BLAST0SegmentPtr ptr = MemNew((size_t) sizeof(BLAST0Segment));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0SegmentFree()
+*
+**************************************************/
+
+BLAST0SegmentPtr LIBCALL
+BLAST0SegmentFree(BLAST0SegmentPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ BLAST0SeqIntervalFree(ptr -> loc);
+ BLAST0SeqDataFree(ptr -> str);
+ BLAST0SeqDataFree(ptr -> str_raw);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0SegmentAsnRead()
+*
+**************************************************/
+
+BLAST0SegmentPtr LIBCALL
+BLAST0SegmentAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0SegmentPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0Segment ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SEGMENT);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SEGMENT);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0SegmentNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_SEGMENT_loc) {
+ ptr -> loc = BLAST0SeqIntervalAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEGMENT_str) {
+ ptr -> str = BLAST0SeqDataAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEGMENT_str_raw) {
+ ptr -> str_raw = BLAST0SeqDataAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0SegmentFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SegmentAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0SegmentAsnWrite(BLAST0SegmentPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_SEGMENT); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> loc != NULL) {
+ if ( ! BLAST0SeqIntervalAsnWrite(ptr -> loc, aip, BLAST0_SEGMENT_loc)) {
+ goto erret;
+ }
+ }
+ if (ptr -> str != NULL) {
+ if ( ! BLAST0SeqDataAsnWrite(ptr -> str, aip, BLAST0_SEGMENT_str)) {
+ goto erret;
+ }
+ }
+ if (ptr -> str_raw != NULL) {
+ if ( ! BLAST0SeqDataAsnWrite(ptr -> str_raw, aip, BLAST0_SEGMENT_str_raw)) {
+ goto erret;
+ }
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SeqIntervalNew()
+*
+**************************************************/
+
+BLAST0SeqIntervalPtr LIBCALL
+BLAST0SeqIntervalNew(void)
+{
+ BLAST0SeqIntervalPtr ptr = MemNew((size_t) sizeof(BLAST0SeqInterval));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0SeqIntervalFree()
+*
+**************************************************/
+
+BLAST0SeqIntervalPtr LIBCALL
+BLAST0SeqIntervalFree(BLAST0SeqIntervalPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0SeqIntervalAsnRead()
+*
+**************************************************/
+
+BLAST0SeqIntervalPtr LIBCALL
+BLAST0SeqIntervalAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0SeqIntervalPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0SeqInterval ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SEQ_INTERVAL);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SEQ_INTERVAL);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0SeqIntervalNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_SEQ_INTERVAL_strand) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> strand = av.intvalue;
+ ptr -> OBbits__ |= 1<<0;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEQ_INTERVAL_from) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> from = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEQ_INTERVAL_to) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> to = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0SeqIntervalFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SeqIntervalAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0SeqIntervalAsnWrite(BLAST0SeqIntervalPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_SEQ_INTERVAL); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> strand || (ptr -> OBbits__ & (1<<0) )){ av.intvalue = ptr -> strand;
+ retval = AsnWrite(aip, BLAST0_SEQ_INTERVAL_strand, &av);
+ }
+ av.intvalue = ptr -> from;
+ retval = AsnWrite(aip, BLAST0_SEQ_INTERVAL_from, &av);
+ av.intvalue = ptr -> to;
+ retval = AsnWrite(aip, BLAST0_SEQ_INTERVAL_to, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SeqDataFree()
+*
+**************************************************/
+
+BLAST0SeqDataPtr LIBCALL
+BLAST0SeqDataFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case BLAST0SeqData_ncbistdaa:
+ BSFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0SeqData_ncbi2na:
+ BSFree(anp -> data.ptrvalue);
+ break;
+ case BLAST0SeqData_ncbi4na:
+ BSFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* BLAST0SeqDataAsnRead()
+*
+**************************************************/
+
+BLAST0SeqDataPtr LIBCALL
+BLAST0SeqDataAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0SeqData ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SEQ_DATA);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SEQ_DATA); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == BLAST0_SEQ_DATA_ncbistdaa) {
+ choice = BLAST0SeqData_ncbistdaa;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST0_SEQ_DATA_ncbi2na) {
+ choice = BLAST0SeqData_ncbi2na;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST0_SEQ_DATA_ncbi4na) {
+ choice = BLAST0SeqData_ncbi4na;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BLAST0SeqDataAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0SeqDataAsnWrite(BLAST0SeqDataPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST0_SEQ_DATA); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case BLAST0SeqData_ncbistdaa:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST0_SEQ_DATA_ncbistdaa, &av);
+ break;
+ case BLAST0SeqData_ncbi2na:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST0_SEQ_DATA_ncbi2na, &av);
+ break;
+ case BLAST0SeqData_ncbi4na:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST0_SEQ_DATA_ncbi4na, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* BLAST0SeqDescNew()
+*
+**************************************************/
+
+BLAST0SeqDescPtr LIBCALL
+BLAST0SeqDescNew(void)
+{
+ BLAST0SeqDescPtr ptr = MemNew((size_t) sizeof(BLAST0SeqDesc));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BLAST0SeqDescFree()
+*
+**************************************************/
+
+BLAST0SeqDescPtr LIBCALL
+BLAST0SeqDescFree(BLAST0SeqDescPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ BLAST0SeqIdFree(ptr -> id);
+ MemFree(ptr -> defline);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BLAST0SeqDescAsnRead()
+*
+**************************************************/
+
+BLAST0SeqDescPtr LIBCALL
+BLAST0SeqDescAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BLAST0SeqDescPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0SeqDesc ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SEQ_DESC);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SEQ_DESC);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BLAST0SeqDescNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST0_SEQ_DESC_id) {
+ ptr -> id = BLAST0SeqIdAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST0_SEQ_DESC_defline) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> defline = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BLAST0SeqDescFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SeqDescAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0SeqDescAsnWrite(BLAST0SeqDescPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST0_SEQ_DESC); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> id != NULL) {
+ if ( ! BLAST0SeqIdAsnWrite(ptr -> id, aip, BLAST0_SEQ_DESC_id)) {
+ goto erret;
+ }
+ }
+ if (ptr -> defline != NULL) {
+ av.ptrvalue = ptr -> defline;
+ retval = AsnWrite(aip, BLAST0_SEQ_DESC_defline, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BLAST0SeqIdFree()
+*
+**************************************************/
+
+BLAST0SeqIdPtr LIBCALL
+BLAST0SeqIdFree(ValNodePtr anp)
+{
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ AsnGenericChoiceSeqOfFree(anp, (AsnOptFreeFunc) BLAST0SeqId_elementFree);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* BLAST0SeqIdAsnRead()
+*
+**************************************************/
+
+BLAST0SeqIdPtr LIBCALL
+BLAST0SeqIdAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+
+
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0SeqId_element ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SEQ_ID);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SEQ_ID); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp =
+ AsnGenericChoiceSeqOfAsnRead(aip, amp, atp, &isError,
+ (AsnReadFunc) BLAST0SeqId_elementAsnRead, (AsnOptFreeFunc) BLAST0SeqId_elementFree);
+ if (isError)
+ goto erret;
+
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BLAST0SeqIdAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0SeqIdAsnWrite(ValNodePtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST0_SEQ_ID); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ retval = AsnGenericChoiceSeqOfAsnWrite(anp,
+ (AsnWriteFunc) BLAST0SeqId_elementAsnWrite, aip, atp, BLAST0_SEQ_ID_E);
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* BLAST0SeqId_elementAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+BLAST0SeqId_elementAsnWrite(BLAST0SeqId_elementPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST0_SEQ_ID_E); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case BLAST0SeqId_giid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, BLAST0_SEQ_ID_E_giid, &av);
+ break;
+ case BLAST0SeqId_textid:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST0_SEQ_ID_E_textid, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* BLAST0SeqId_elementAsnRead()
+*
+**************************************************/
+
+BLAST0SeqId_elementPtr LIBCALL
+BLAST0SeqId_elementAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst2AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BLAST0SeqId_element ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST0_SEQ_ID_E);
+ } else {
+ atp = AsnLinkType(orig, BLAST0_SEQ_ID_E); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == BLAST0_SEQ_ID_E_giid) {
+ choice = BLAST0SeqId_giid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == BLAST0_SEQ_ID_E_textid) {
+ choice = BLAST0SeqId_textid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BLAST0SeqId_elementFree()
+*
+**************************************************/
+
+BLAST0SeqId_elementPtr LIBCALL
+BLAST0SeqId_elementFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case BLAST0SeqId_textid:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
diff --git a/network/blast2/client/objblst2.h b/network/blast2/client/objblst2.h
new file mode 100644
index 00000000..7f3c6b93
--- /dev/null
+++ b/network/blast2/client/objblst2.h
@@ -0,0 +1,696 @@
+#ifndef _objblst2_
+#define _objblst2_
+
+#ifdef __cplusplus
+extern "C" { /* } */
+#endif
+
+
+/**************************************************
+*
+* Generated objects for Module NCBI-BLAST-1
+* Generated using ASNCODE Revision: 1.17 at Jun 28, 1995 2:37 PM
+*
+**************************************************/
+
+Boolean LIBCALL
+objblst2AsnLoad PROTO((void));
+
+
+/**************************************************
+*
+* BLAST0Preface
+*
+**************************************************/
+typedef struct struct_BLAST0_Preface {
+ struct struct_BLAST0_Preface PNTR next;
+ Uint4 OBbits__;
+ CharPtr program;
+ CharPtr desc;
+ CharPtr version;
+ CharPtr dev_date;
+ CharPtr bld_date;
+ ValNodePtr cit;
+ ValNodePtr notice;
+ ValNodePtr prog_usage;
+ struct struct_BLAST0_Seq_usage PNTR susage;
+ struct struct_BLAST0_Seq_usage PNTR qusage;
+} BLAST0Preface, PNTR BLAST0PrefacePtr;
+
+
+BLAST0PrefacePtr LIBCALL BLAST0PrefaceFree PROTO ((BLAST0PrefacePtr ));
+BLAST0PrefacePtr LIBCALL BLAST0PrefaceNew PROTO (( void ));
+BLAST0PrefacePtr LIBCALL BLAST0PrefaceAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0PrefaceAsnWrite PROTO (( BLAST0PrefacePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0JobDesc
+*
+**************************************************/
+typedef struct struct_BLAST0_Job_desc {
+ Uint4 OBbits__;
+ Uint2 jid;
+ /* following #defines are for enumerated type, not used by object loaders */
+#define BLAST0_Job_desc_jid_not_set 0
+#define BLAST0_Job_desc_jid_neighborhood 1
+#define BLAST0_Job_desc_jid_search 2
+#define BLAST0_Job_desc_jid_threecomps 3
+
+ CharPtr desc;
+ Int4 size;
+} BLAST0JobDesc, PNTR BLAST0JobDescPtr;
+
+
+BLAST0JobDescPtr LIBCALL BLAST0JobDescFree PROTO ((BLAST0JobDescPtr ));
+BLAST0JobDescPtr LIBCALL BLAST0JobDescNew PROTO (( void ));
+BLAST0JobDescPtr LIBCALL BLAST0JobDescAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0JobDescAsnWrite PROTO (( BLAST0JobDescPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0JobProgress
+*
+**************************************************/
+typedef struct struct_BLAST0_Job_progress {
+ Uint4 OBbits__;
+ Int4 done;
+ Int4 positives;
+} BLAST0JobProgress, PNTR BLAST0JobProgressPtr;
+
+
+BLAST0JobProgressPtr LIBCALL BLAST0JobProgressFree PROTO ((BLAST0JobProgressPtr ));
+BLAST0JobProgressPtr LIBCALL BLAST0JobProgressNew PROTO (( void ));
+BLAST0JobProgressPtr LIBCALL BLAST0JobProgressAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0JobProgressAsnWrite PROTO (( BLAST0JobProgressPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0Sequence
+*
+**************************************************/
+typedef struct struct_BLAST0_Sequence {
+ struct struct_BLAST0_Sequence PNTR next;
+ Uint4 OBbits__;
+ struct struct_BLAST0_Seq_desc PNTR desc;
+ Int4 length;
+#define OB__BLAST0_Sequence_gcode 0
+
+ Int4 gcode;
+ ValNodePtr seq;
+} BLAST0Sequence, PNTR BLAST0SequencePtr;
+
+
+BLAST0SequencePtr LIBCALL BLAST0SequenceFree PROTO ((BLAST0SequencePtr ));
+BLAST0SequencePtr LIBCALL BLAST0SequenceNew PROTO (( void ));
+BLAST0SequencePtr LIBCALL BLAST0SequenceAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0SequenceAsnWrite PROTO (( BLAST0SequencePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0KABlk
+*
+**************************************************/
+typedef struct struct_BLAST0_KA_Blk {
+ struct struct_BLAST0_KA_Blk PNTR next;
+ Uint4 OBbits__;
+ Int4 matid;
+ ValNodePtr frames;
+ FloatHi lambda;
+ FloatHi k;
+ FloatHi h;
+} BLAST0KABlk, PNTR BLAST0KABlkPtr;
+
+
+BLAST0KABlkPtr LIBCALL BLAST0KABlkFree PROTO ((BLAST0KABlkPtr ));
+BLAST0KABlkPtr LIBCALL BLAST0KABlkNew PROTO (( void ));
+BLAST0KABlkPtr LIBCALL BLAST0KABlkAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0KABlkAsnWrite PROTO (( BLAST0KABlkPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0DbDesc
+*
+**************************************************/
+typedef struct struct_BLAST0_Db_Desc {
+ struct struct_BLAST0_Db_Desc PNTR next;
+ Uint4 OBbits__;
+ CharPtr name;
+ Uint2 type;
+ CharPtr def;
+ CharPtr rel_date;
+ CharPtr bld_date;
+#define OB__BLAST0_Db_Desc_count 0
+
+ Int4 count;
+#define OB__BLAST0_Db_Desc_totlen 1
+
+ Int4 totlen;
+#define OB__BLAST0_Db_Desc_maxlen 2
+
+ Int4 maxlen;
+} BLAST0DbDesc, PNTR BLAST0DbDescPtr;
+
+
+BLAST0DbDescPtr LIBCALL BLAST0DbDescFree PROTO ((BLAST0DbDescPtr ));
+BLAST0DbDescPtr LIBCALL BLAST0DbDescNew PROTO (( void ));
+BLAST0DbDescPtr LIBCALL BLAST0DbDescAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0DbDescAsnWrite PROTO (( BLAST0DbDescPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0Result
+*
+**************************************************/
+typedef struct struct_BLAST0_Result {
+ Uint4 OBbits__;
+ struct struct_BLAST0_Histogram PNTR hist;
+ Int4 count;
+ struct struct_BLAST0_HitList PNTR hitlists;
+} BLAST0Result, PNTR BLAST0ResultPtr;
+
+
+BLAST0ResultPtr LIBCALL BLAST0ResultFree PROTO ((BLAST0ResultPtr ));
+BLAST0ResultPtr LIBCALL BLAST0ResultNew PROTO (( void ));
+BLAST0ResultPtr LIBCALL BLAST0ResultAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0ResultAsnWrite PROTO (( BLAST0ResultPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0Matrix
+*
+**************************************************/
+typedef struct struct_BLAST0_Matrix {
+ struct struct_BLAST0_Matrix PNTR next;
+ Uint4 OBbits__;
+ Int4 matid;
+ CharPtr name;
+ ValNodePtr comments;
+ Uint2 qalpha;
+ Uint2 salpha;
+ ValNodePtr Scores_scores;
+} BLAST0Matrix, PNTR BLAST0MatrixPtr;
+
+
+BLAST0MatrixPtr LIBCALL BLAST0MatrixFree PROTO ((BLAST0MatrixPtr ));
+BLAST0MatrixPtr LIBCALL BLAST0MatrixNew PROTO (( void ));
+BLAST0MatrixPtr LIBCALL BLAST0MatrixAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0MatrixAsnWrite PROTO (( BLAST0MatrixPtr , AsnIoPtr, AsnTypePtr));
+
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+typedef ValNodePtr Scores_scoresPtr;
+typedef ValNode Scores_scores;
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+#define Scores_scores_Scores_ScaledInts 1
+#define Scores_scores_reals 2
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+static Scores_scoresPtr LIBCALL Scores_scoresFree PROTO ((Scores_scoresPtr ));
+static Scores_scoresPtr LIBCALL Scores_scoresAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+static Boolean LIBCALL Scores_scoresAsnWrite PROTO (( Scores_scoresPtr , AsnIoPtr, AsnTypePtr));
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+
+
+/**************************************************
+*
+* Scores_scaled_ints
+*
+**************************************************/
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+typedef struct struct_Scores_ScaledInts {
+ Uint4 OBbits__;
+ FloatHi scale;
+ ValNodePtr ints;
+} Scores_scaled_ints, PNTR Scores_scaled_intsPtr;
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+static Scores_scaled_intsPtr LIBCALL Scores_scaled_intsFree PROTO ((Scores_scaled_intsPtr ));
+static Scores_scaled_intsPtr LIBCALL Scores_scaled_intsNew PROTO (( void ));
+static Scores_scaled_intsPtr LIBCALL Scores_scaled_intsAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+static Boolean LIBCALL Scores_scaled_intsAsnWrite PROTO (( Scores_scaled_intsPtr , AsnIoPtr, AsnTypePtr));
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+
+
+/**************************************************
+*
+* BLAST0Warning
+*
+**************************************************/
+#define BLAST0Warning BLAST0Status
+#define BLAST0WarningPtr BLAST0StatusPtr
+#define BLAST0WarningFree BLAST0StatusFree
+#define BLAST0WarningNew BLAST0StatusNew
+#define BLAST0WarningAsnRead BLAST0StatusAsnRead
+#define BLAST0WarningAsnWrite BLAST0StatusAsnWrite
+
+
+/**************************************************
+*
+* BLAST0Status
+*
+**************************************************/
+typedef struct struct_BLAST0_Status {
+ Uint4 OBbits__;
+ Int4 code;
+ CharPtr reason;
+} BLAST0Status, PNTR BLAST0StatusPtr;
+
+
+BLAST0StatusPtr LIBCALL BLAST0StatusFree PROTO ((BLAST0StatusPtr ));
+BLAST0StatusPtr LIBCALL BLAST0StatusNew PROTO (( void ));
+BLAST0StatusPtr LIBCALL BLAST0StatusAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0StatusAsnWrite PROTO (( BLAST0StatusPtr , AsnIoPtr, AsnTypePtr));
+
+typedef ValNodePtr BLAST0OutblkPtr;
+typedef ValNode BLAST0Outblk;
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+BLAST0OutblkPtr LIBCALL BLAST0OutblkFree PROTO ((BLAST0OutblkPtr ));
+BLAST0OutblkPtr LIBCALL BLAST0OutblkAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0OutblkAsnWrite PROTO (( BLAST0OutblkPtr , AsnIoPtr, AsnTypePtr));
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+typedef ValNodePtr BLAST0Outblk_elementPtr;
+typedef ValNode BLAST0Outblk_element;
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+#define BLAST0Outblk_preface 1
+#define BLAST0Outblk_query 2
+#define BLAST0Outblk_dbdesc 3
+#define BLAST0Outblk_matrix 4
+#define BLAST0Outblk_kablk 5
+#define BLAST0Outblk_job_start 6
+#define BLAST0Outblk_job_progress 7
+#define BLAST0Outblk_job_done 8
+#define BLAST0Outblk_result 9
+#define BLAST0Outblk_parms 10
+#define BLAST0Outblk_stats 11
+#define BLAST0Outblk_warning 12
+#define BLAST0Outblk_status 13
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+BLAST0Outblk_elementPtr LIBCALL BLAST0Outblk_elementFree PROTO ((BLAST0Outblk_elementPtr ));
+BLAST0Outblk_elementPtr LIBCALL BLAST0Outblk_elementAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0Outblk_elementAsnWrite PROTO (( BLAST0Outblk_elementPtr , AsnIoPtr, AsnTypePtr));
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+typedef ValNodePtr BLAST0RequestPtr;
+typedef ValNode BLAST0Request;
+#define BLAST0Request_hello 1
+#define BLAST0Request_motd 2
+#define BLAST0Request_prog_info 3
+#define BLAST0Request_usage_info 4
+#define BLAST0Request_db_info 5
+#define BLAST0Request_matrix_info 6
+#define BLAST0Request_matrix_get 7
+#define BLAST0Request_search 8
+#define BLAST0Request_goodbye 9
+
+
+BLAST0RequestPtr LIBCALL BLAST0RequestFree PROTO ((BLAST0RequestPtr ));
+BLAST0RequestPtr LIBCALL BLAST0RequestAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0RequestAsnWrite PROTO (( BLAST0RequestPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0Search
+*
+**************************************************/
+typedef struct struct_BLAST0_Search {
+ Uint4 OBbits__;
+ CharPtr program;
+ CharPtr database;
+ struct struct_BLAST0_Sequence PNTR query;
+ ValNodePtr options;
+ Uint1 return_matrix;
+ Uint1 return_query;
+ Uint1 return_BLAST0result;
+ Uint1 return_query_seq_in_seg;
+ Uint1 return_db_seq_in_seg;
+} BLAST0Search, PNTR BLAST0SearchPtr;
+
+
+BLAST0SearchPtr LIBCALL BLAST0SearchFree PROTO ((BLAST0SearchPtr ));
+BLAST0SearchPtr LIBCALL BLAST0SearchNew PROTO (( void ));
+BLAST0SearchPtr LIBCALL BLAST0SearchAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0SearchAsnWrite PROTO (( BLAST0SearchPtr , AsnIoPtr, AsnTypePtr));
+
+typedef ValNodePtr BLAST0ResponsePtr;
+typedef ValNode BLAST0Response;
+#define BLAST0Response_hello 1
+#define BLAST0Response_motd 2
+#define BLAST0Response_prog_info 3
+#define BLAST0Response_usage_info 4
+#define BLAST0Response_db_info 5
+#define BLAST0Response_matrix_info 6
+#define BLAST0Response_ack 7
+#define BLAST0Response_goodbye 8
+#define BLAST0Response_queued 9
+#define BLAST0Response_preface 10
+#define BLAST0Response_query 11
+#define BLAST0Response_dbdesc 12
+#define BLAST0Response_matrix 13
+#define BLAST0Response_kablk 14
+#define BLAST0Response_job_start 15
+#define BLAST0Response_job_progress 16
+#define BLAST0Response_job_done 17
+#define BLAST0Response_score_defs 18
+#define BLAST0Response_result 19
+#define BLAST0Response_seqalign 20
+#define BLAST0Response_parms 21
+#define BLAST0Response_stats 22
+#define BLAST0Response_warning 23
+#define BLAST0Response_status 24
+
+
+BLAST0ResponsePtr LIBCALL BLAST0ResponseFree PROTO ((BLAST0ResponsePtr ));
+BLAST0ResponsePtr LIBCALL BLAST0ResponseAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0ResponseAsnWrite PROTO (( BLAST0ResponsePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0Ack
+*
+**************************************************/
+typedef struct struct_BLAST0_Ack {
+ Uint4 OBbits__;
+ Int4 code;
+ CharPtr reason;
+} BLAST0Ack, PNTR BLAST0AckPtr;
+
+
+BLAST0AckPtr LIBCALL BLAST0AckFree PROTO ((BLAST0AckPtr ));
+BLAST0AckPtr LIBCALL BLAST0AckNew PROTO (( void ));
+BLAST0AckPtr LIBCALL BLAST0AckAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0AckAsnWrite PROTO (( BLAST0AckPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0Queued
+*
+**************************************************/
+typedef struct struct_BLAST0_Queued {
+ Uint4 OBbits__;
+ CharPtr name;
+ Int4 length;
+} BLAST0Queued, PNTR BLAST0QueuedPtr;
+
+
+BLAST0QueuedPtr LIBCALL BLAST0QueuedFree PROTO ((BLAST0QueuedPtr ));
+BLAST0QueuedPtr LIBCALL BLAST0QueuedNew PROTO (( void ));
+BLAST0QueuedPtr LIBCALL BLAST0QueuedAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0QueuedAsnWrite PROTO (( BLAST0QueuedPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0ScoreInfo
+*
+**************************************************/
+typedef struct struct_BLAST0_Score_Info {
+ struct struct_BLAST0_Score_Info PNTR next;
+ Uint4 OBbits__;
+ Int4 sid;
+ CharPtr tag;
+ CharPtr desc;
+} BLAST0ScoreInfo, PNTR BLAST0ScoreInfoPtr;
+
+
+BLAST0ScoreInfoPtr LIBCALL BLAST0ScoreInfoFree PROTO ((BLAST0ScoreInfoPtr ));
+BLAST0ScoreInfoPtr LIBCALL BLAST0ScoreInfoNew PROTO (( void ));
+BLAST0ScoreInfoPtr LIBCALL BLAST0ScoreInfoAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0ScoreInfoAsnWrite PROTO (( BLAST0ScoreInfoPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0SeqUsage
+*
+**************************************************/
+typedef struct struct_BLAST0_Seq_usage {
+ Uint4 OBbits__;
+ Uint2 raw;
+ Uint2 cooked;
+} BLAST0SeqUsage, PNTR BLAST0SeqUsagePtr;
+
+
+BLAST0SeqUsagePtr LIBCALL BLAST0SeqUsageFree PROTO ((BLAST0SeqUsagePtr ));
+BLAST0SeqUsagePtr LIBCALL BLAST0SeqUsageNew PROTO (( void ));
+BLAST0SeqUsagePtr LIBCALL BLAST0SeqUsageAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0SeqUsageAsnWrite PROTO (( BLAST0SeqUsagePtr , AsnIoPtr, AsnTypePtr));
+
+/* following #defines are for enumerated type, not used by object loaders */
+#define BLAST0_Alphatype_not_set 0
+#define BLAST0_Alphatype_amino_acid 1
+#define BLAST0_Alphatype_nucleic_acid 2
+#define BLAST0_Alphatype_other 255
+
+
+
+/**************************************************
+*
+* BLAST0Histogram
+*
+**************************************************/
+typedef struct struct_BLAST0_Histogram {
+ Uint4 OBbits__;
+ FloatHi expect;
+ Int4 observed;
+ Int4 base;
+ Int4 nbars;
+ struct struct_BLAST0_Histogram_bar PNTR bar;
+} BLAST0Histogram, PNTR BLAST0HistogramPtr;
+
+
+BLAST0HistogramPtr LIBCALL BLAST0HistogramFree PROTO ((BLAST0HistogramPtr ));
+BLAST0HistogramPtr LIBCALL BLAST0HistogramNew PROTO (( void ));
+BLAST0HistogramPtr LIBCALL BLAST0HistogramAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0HistogramAsnWrite PROTO (( BLAST0HistogramPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0HitList
+*
+**************************************************/
+typedef struct struct_BLAST0_HitList {
+ struct struct_BLAST0_HitList PNTR next;
+ Uint4 OBbits__;
+ Int4 count;
+ struct struct_BLAST0_KA_Blk PNTR kablk;
+ struct struct_BLAST0_HSP PNTR hsps;
+ struct struct_BLAST0_Sequence PNTR seqs;
+} BLAST0HitList, PNTR BLAST0HitListPtr;
+
+
+BLAST0HitListPtr LIBCALL BLAST0HitListFree PROTO ((BLAST0HitListPtr ));
+BLAST0HitListPtr LIBCALL BLAST0HitListNew PROTO (( void ));
+BLAST0HitListPtr LIBCALL BLAST0HitListAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0HitListAsnWrite PROTO (( BLAST0HitListPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0HistogramBar
+*
+**************************************************/
+typedef struct struct_BLAST0_Histogram_bar {
+ struct struct_BLAST0_Histogram_bar PNTR next;
+ Uint4 OBbits__;
+ FloatHi x;
+ Int4 n;
+} BLAST0HistogramBar, PNTR BLAST0HistogramBarPtr;
+
+
+BLAST0HistogramBarPtr LIBCALL BLAST0HistogramBarFree PROTO ((BLAST0HistogramBarPtr ));
+BLAST0HistogramBarPtr LIBCALL BLAST0HistogramBarNew PROTO (( void ));
+BLAST0HistogramBarPtr LIBCALL BLAST0HistogramBarAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0HistogramBarAsnWrite PROTO (( BLAST0HistogramBarPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0HSP
+*
+**************************************************/
+typedef struct struct_BLAST0_HSP {
+ struct struct_BLAST0_HSP PNTR next;
+ Uint4 OBbits__;
+ Int4 matid;
+ struct struct_Score PNTR scores;
+ Int4 len;
+ struct struct_BLAST0_Segment PNTR segs;
+} BLAST0HSP, PNTR BLAST0HSPPtr;
+
+
+BLAST0HSPPtr LIBCALL BLAST0HSPFree PROTO ((BLAST0HSPPtr ));
+BLAST0HSPPtr LIBCALL BLAST0HSPNew PROTO (( void ));
+BLAST0HSPPtr LIBCALL BLAST0HSPAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0HSPAsnWrite PROTO (( BLAST0HSPPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0Segment
+*
+**************************************************/
+typedef struct struct_BLAST0_Segment {
+ struct struct_BLAST0_Segment PNTR next;
+ Uint4 OBbits__;
+ struct struct_BLAST0_Seq_interval PNTR loc;
+ ValNodePtr str;
+ ValNodePtr str_raw;
+} BLAST0Segment, PNTR BLAST0SegmentPtr;
+
+
+BLAST0SegmentPtr LIBCALL BLAST0SegmentFree PROTO ((BLAST0SegmentPtr ));
+BLAST0SegmentPtr LIBCALL BLAST0SegmentNew PROTO (( void ));
+BLAST0SegmentPtr LIBCALL BLAST0SegmentAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0SegmentAsnWrite PROTO (( BLAST0SegmentPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0SeqInterval
+*
+**************************************************/
+typedef struct struct_BLAST0_Seq_interval {
+ Uint4 OBbits__;
+#define OB__BLAST0_Seq_interval_strand 0
+
+ Uint2 strand;
+ /* following #defines are for enumerated type, not used by object loaders */
+#define BLAST0_Seq_interval_strand_plus 1
+#define BLAST0_Seq_interval_strand_minus 2
+#define BLAST0_Seq_interval_strand_both 3
+#define BLAST0_Seq_interval_strand_plus_rf 5
+#define BLAST0_Seq_interval_strand_minus_rf 6
+
+ Int4 from;
+ Int4 to;
+} BLAST0SeqInterval, PNTR BLAST0SeqIntervalPtr;
+
+
+BLAST0SeqIntervalPtr LIBCALL BLAST0SeqIntervalFree PROTO ((BLAST0SeqIntervalPtr ));
+BLAST0SeqIntervalPtr LIBCALL BLAST0SeqIntervalNew PROTO (( void ));
+BLAST0SeqIntervalPtr LIBCALL BLAST0SeqIntervalAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0SeqIntervalAsnWrite PROTO (( BLAST0SeqIntervalPtr , AsnIoPtr, AsnTypePtr));
+
+typedef ValNodePtr BLAST0SeqDataPtr;
+typedef ValNode BLAST0SeqData;
+#define BLAST0SeqData_ncbistdaa 1
+#define BLAST0SeqData_ncbi2na 2
+#define BLAST0SeqData_ncbi4na 3
+
+
+BLAST0SeqDataPtr LIBCALL BLAST0SeqDataFree PROTO ((BLAST0SeqDataPtr ));
+BLAST0SeqDataPtr LIBCALL BLAST0SeqDataAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0SeqDataAsnWrite PROTO (( BLAST0SeqDataPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BLAST0SeqDesc
+*
+**************************************************/
+typedef struct struct_BLAST0_Seq_desc {
+ struct struct_BLAST0_Seq_desc PNTR next;
+ Uint4 OBbits__;
+ ValNodePtr id;
+ CharPtr defline;
+} BLAST0SeqDesc, PNTR BLAST0SeqDescPtr;
+
+
+BLAST0SeqDescPtr LIBCALL BLAST0SeqDescFree PROTO ((BLAST0SeqDescPtr ));
+BLAST0SeqDescPtr LIBCALL BLAST0SeqDescNew PROTO (( void ));
+BLAST0SeqDescPtr LIBCALL BLAST0SeqDescAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0SeqDescAsnWrite PROTO (( BLAST0SeqDescPtr , AsnIoPtr, AsnTypePtr));
+
+typedef ValNodePtr BLAST0SeqIdPtr;
+typedef ValNode BLAST0SeqId;
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+BLAST0SeqIdPtr LIBCALL BLAST0SeqIdFree PROTO ((BLAST0SeqIdPtr ));
+BLAST0SeqIdPtr LIBCALL BLAST0SeqIdAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0SeqIdAsnWrite PROTO (( BLAST0SeqIdPtr , AsnIoPtr, AsnTypePtr));
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+typedef ValNodePtr BLAST0SeqId_elementPtr;
+typedef ValNode BLAST0SeqId_element;
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+#define BLAST0SeqId_giid 1
+#define BLAST0SeqId_textid 2
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+BLAST0SeqId_elementPtr LIBCALL BLAST0SeqId_elementFree PROTO ((BLAST0SeqId_elementPtr ));
+BLAST0SeqId_elementPtr LIBCALL BLAST0SeqId_elementAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL BLAST0SeqId_elementAsnWrite PROTO (( BLAST0SeqId_elementPtr , AsnIoPtr, AsnTypePtr));
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+/* following #defines are for enumerated type, not used by object loaders */
+#define BLAST0_Alpha_ID_ncbi4na 4
+#define BLAST0_Alpha_ID_ncbistdaa 11
+
+#ifdef __cplusplus
+/* { */ }
+#endif
+
+#endif /* _objblst2_ */
diff --git a/network/blast3/client/blastcl3.c b/network/blast3/client/blastcl3.c
new file mode 100644
index 00000000..6c882a7a
--- /dev/null
+++ b/network/blast3/client/blastcl3.c
@@ -0,0 +1,507 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: blastcl3.c
+*
+* Author: Tom Madden
+*
+* Version Creation Date: 05/16/95
+*
+* $Revision: 1.9 $
+*
+* File Description:
+* Simulates "traditional" BLAST output
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: blastcl3.c,v $
+* Revision 1.9 1999/01/03 22:33:20 kans
+* now calls UseLocalAsnloadDataAndErrMsg
+*
+* Revision 1.8 1998/12/09 15:27:04 madden
+* Add wordsize
+*
+* Revision 1.7 1998/11/05 17:55:25 madden
+* Removed unused global_fp
+*
+* Revision 1.6 1998/05/02 20:39:38 kans
+* global_fp is extern, removed unused callback function, removed unused variables, added newlines in long prompts
+*
+* Revision 1.5 1998/04/23 14:18:43 egorov
+* Add number_of_hits parameter to TraditionalBlastReportLoc
+*
+* Revision 1.4 1998/04/22 19:58:06 egorov
+* Fix minor bug after previous commit
+*
+* Revision 1.3 1998/04/22 18:10:06 egorov
+* Add support for SeqLoc to blastcl3
+*
+* Revision 1.2 1998/04/16 19:35:30 madden
+* Added Int4Ptr arg to TraditionalBlastReport specifying the numbers of hits
+*
+* Revision 1.1 1997/10/08 19:24:56 madden
+* Main (command-line) client file
+*
+ *
+*/
+#define BLASTCLI_BUF_SIZE 255
+#include <sequtil.h>
+#include <prtutil.h>
+#include <tofasta.h>
+#include <objblst3.h>
+#include <netblap3.h>
+#include <blastpri.h>
+#include <dust.h>
+#include <txalign.h>
+#include <accentr.h>
+#include <sqnutils.h>
+
+
+static Boolean LIBCALL
+SeqAlignToFasta(SeqAlignPtr sap, FILE *fp)
+
+{
+ BioseqPtr bsp;
+ SeqIdPtr last_id=NULL, id;
+
+ if (sap == NULL || fp == NULL)
+ return FALSE;
+
+ while (sap)
+ {
+ id = TxGetSubjectIdFromSeqAlign(sap);
+ if (last_id)
+ {
+ if(SeqIdComp(id, last_id) != SIC_YES)
+ {
+ bsp = BioseqLockById(id);
+ BioseqToFasta(bsp, fp, ISA_na(bsp->mol));
+ BioseqUnlock(bsp);
+ }
+ }
+ last_id = id;
+ sap = sap->next;
+ }
+
+ return TRUE;
+}
+
+/* find the last nucleotide bioseq in the bioseqset */
+static void FindNuc(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
+{
+ BioseqPtr PNTR bp;
+ BioseqPtr local_bsp;
+
+ bp = (BioseqPtr PNTR) data;
+ if (IS_Bioseq(sep))
+ {
+ local_bsp = (BioseqPtr) sep->data.ptrvalue;
+ if (ISA_na(local_bsp->mol))
+ *bp = local_bsp;
+ }
+}
+
+/* find the last protein bioseq in the bioseqset */
+static void FindProt(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
+{
+ BioseqPtr PNTR bp;
+ BioseqPtr local_bsp;
+
+ bp = (BioseqPtr PNTR) data;
+ if (IS_Bioseq(sep))
+ {
+ local_bsp = (BioseqPtr) sep->data.ptrvalue;
+ if (ISA_aa(local_bsp->mol))
+ *bp = local_bsp;
+ }
+}
+/*
+ Montior hook to print to stderr for UNIX clients.
+*/
+
+static int LIBCALLBACK UNIXMontiorHook(Nlm_MonitorPtr mon, MonCode code)
+
+{
+ switch (code)
+ {
+#ifdef OS_UNIX
+ case MonCode_Create :
+ fprintf(stderr, "%s\n", (Nlm_CharPtr) mon->strTitle);
+ break;
+ case MonCode_StrValue :
+ fprintf(stderr, "%s\n", (Nlm_CharPtr) mon->strValue);
+ break;
+#endif
+ default :
+ break;
+ }
+ return 0;
+
+}
+
+
+static void
+PrintMotd(CharPtr string, FILE *fp, Boolean html_format)
+
+{
+ Char buffer[100];
+ CharPtr ptr;
+
+ if (string == NULL)
+ return;
+
+ buffer[0] = NULLB;
+ ptr = buffer;
+
+ if (html_format)
+ {
+ fprintf(fp, "<PRE>\n");
+ }
+
+ while (*string != NULLB)
+ {
+ if (*string == '~')
+ {
+ *ptr = NULLB;
+ fprintf(fp, "%s\n", buffer);
+ buffer[0] = NULLB;
+ ptr = buffer;
+ string++;
+ if (*string == NULLB)
+ break;
+ }
+ else
+ {
+ *ptr=*string;
+ ptr++; string++;
+ }
+ }
+ *ptr = NULLB;
+ fprintf(fp, "%s\n", buffer);
+
+ if (html_format)
+ {
+ fprintf(fp, "</PRE>\n");
+ }
+
+ fflush(fp);
+}
+
+
+#define NUMARGS 25
+
+static Args myargs [NUMARGS] = {
+ { "Program Name",
+ NULL, NULL, NULL, FALSE, 'p', ARG_STRING, 0.0, 0, NULL},
+ { "Database",
+ "nr", NULL, NULL, FALSE, 'd', ARG_STRING, 0.0, 0, NULL},
+ { "Query File",
+ "stdin", NULL, NULL, FALSE, 'i', ARG_FILE_IN, 0.0, 0, NULL},
+ { "Expectation value (E)",
+ "10.0", NULL, NULL, FALSE, 'e', ARG_FLOAT, 0.0, 0, NULL},
+ { "alignment view options:\n0 = pairwise,\n1 = master-slave showing identities,\n2 = master-slave no identities,\n3 = flat master-slave, show identities,\n4 = flat master-slave, no identities,\n5 = master-slave no identities and blunt ends,\n6 = flat master-slave, no identities and blunt ends",
+ "0", NULL, NULL, FALSE, 'm', ARG_INT, 0.0, 0, NULL},
+ { "BLAST report Output File",
+ "stdout", NULL, NULL, TRUE, 'o', ARG_FILE_OUT, 0.0, 0, NULL},
+ { "Filter query sequence (DUST with blastn, SEG with others)",
+ "T", NULL, NULL, FALSE, 'F', ARG_BOOLEAN, 0.0, 0, NULL},
+ { "Cost to open a gap (zero invokes default behavior)",
+ "0", NULL, NULL, FALSE, 'G', ARG_INT, 0.0, 0, NULL},
+ { "Cost to extend a gap (zero invokes default behavior)",
+ "0", NULL, NULL, FALSE, 'E', ARG_INT, 0.0, 0, NULL},
+ { "X dropoff value for gapped alignment (in bits)\n(zero invokes default behavior)",
+ "0", NULL, NULL, FALSE, 'X', ARG_INT, 0.0, 0, NULL},
+ { "Show GI's in deflines",
+ "F", NULL, NULL, FALSE, 'I', ARG_BOOLEAN, 0.0, 0, NULL},
+ { "Penalty for a nucleotide mismatch (blastn only)",
+ "-3", NULL, NULL, FALSE, 'q', ARG_INT, 0.0, 0, NULL},
+ { "Reward for a nucleotide match (blastn only)",
+ "1", NULL, NULL, FALSE, 'r', ARG_INT, 0.0, 0, NULL},
+ { "Number of one-line descriptions (V)",
+ "500", NULL, NULL, FALSE, 'v', ARG_INT, 0.0, 0, NULL},
+ { "Number of alignments to show (B)",
+ "250", NULL, NULL, FALSE, 'b', ARG_INT, 0.0, 0, NULL},
+ { "Threshold for extending hits, default if zero",
+ "0", NULL, NULL, FALSE, 'f', ARG_INT, 0.0, 0, NULL},
+ { "Perfom gapped alignment (not available with tblastx)",
+ "T", NULL, NULL, FALSE, 'g', ARG_BOOLEAN, 0.0, 0, NULL},
+ { "Query Genetic code to use",
+ "1", NULL, NULL, FALSE, 'Q', ARG_INT, 0.0, 0, NULL},
+ { "DB Genetic code (for tblast[nx] only)",
+ "1", NULL, NULL, FALSE, 'D', ARG_INT, 0.0, 0, NULL},
+ { "Number of processors to use",
+ "1", NULL, NULL, FALSE, 'a', ARG_INT, 0.0, 0, NULL},
+ { "SeqAlign file",
+ NULL, NULL, NULL, TRUE, 'O', ARG_FILE_OUT, 0.0, 0, NULL},
+ { "Believe the query defline",
+ "F", NULL, NULL, FALSE, 'J', ARG_BOOLEAN, 0.0, 0, NULL},
+ { "Word size, default if zero",
+ "0", NULL, NULL, FALSE, 'W', ARG_INT, 0.0, 0, NULL},
+ { "Start of the sequence",
+ "1", NULL, NULL, FALSE, 'A', ARG_INT, 0.0, 0, NULL},
+ { "End of the sequence (-1 is entire sequence)",
+ "-1", NULL, NULL, FALSE, 'B', ARG_INT, 0.0, 0, NULL},
+};
+
+/*********************************************************************
+* "main" function to call blast for the client.
+*
+* This function checks the command-line arguments, opens the
+* connection to the server, processes all the entries in
+* the FASTA file (obtained using FastaToSeqEntry), and
+* closes the connection.
+*********************************************************************/
+Int2 Main (void)
+
+{
+ BLAST_OptionsBlkPtr options;
+ BLAST_KarlinBlkPtr ka_params=NULL, ka_params_gap=NULL;
+ BlastResponsePtr response;
+ BioseqPtr query_bsp;
+ BlastNet3Hptr bl3hp;
+ BlastVersionPtr blast_version;
+ Boolean db_is_na, query_is_na, show_gi, believe_query=FALSE;
+ CharPtr ret_buffer=NULL, params_buffer=NULL;
+ CharPtr date, motd, version;
+ Int2 num_of_queries, retval;
+ Int4 number_of_descriptions, number_of_alignments;
+ SeqEntryPtr sep;
+ SeqIdPtr seqid_list=NULL;
+ TxDfDbInfoPtr dbinfo=NULL;
+ Uint1 align_type, align_view;
+ Uint4 align_options, print_options;
+ Int4 startloc, endloc;
+ SeqLocPtr slp;
+
+ CharPtr blast_program, blast_database, blast_inputfile, blast_outputfile;
+ FILE *infp, *outfp;
+
+ if (! GetArgs ("blastcl3", NUMARGS, myargs))
+ {
+ return (1);
+ }
+
+ UseLocalAsnloadDataAndErrMsg ();
+
+ if (! SeqEntryLoad())
+ return 1;
+
+ blast_program = myargs [0].strvalue;
+ blast_database = myargs [1].strvalue;
+ blast_inputfile = myargs [2].strvalue;
+ blast_outputfile = myargs [5].strvalue;
+
+ if ((infp = FileOpen(blast_inputfile, "r")) == NULL)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "blast: Unable to open input file %s\n", blast_inputfile);
+ return (1);
+ }
+
+ outfp = NULL;
+ if (blast_outputfile != NULL)
+ {
+ if ((outfp = FileOpen(blast_outputfile, "w")) == NULL)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "blast: Unable to open output file %s\n", blast_outputfile);
+ return (1);
+ }
+ }
+
+ align_view = (Int1) myargs[4].intvalue;
+
+ align_type = BlastGetTypes(blast_program, &query_is_na, &db_is_na);
+ if (StringICmp("blastx", blast_program) == 0)
+ {
+ if (align_view != 0)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "This option is not available with blastx");
+ return 1;
+ }
+ }
+ else if (StringICmp("tblastx", blast_program) == 0)
+ {
+ if (align_view != 0)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "This option is not available with tblastx");
+ return 1;
+ }
+ }
+
+ believe_query = FALSE;
+ if (myargs[21].intvalue != 0)
+ believe_query = TRUE;
+
+ if (believe_query == FALSE && myargs[20].strvalue)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "-J option must be TRUE to produce a SeqAlign file");
+ }
+
+ options = BLASTOptionNew(blast_program, (Boolean) myargs [16].intvalue);
+ if (options == NULL)
+ return 3;
+
+ options->expect_value = (Nlm_FloatHi) myargs [3].floatvalue;
+ number_of_descriptions = myargs[13].intvalue;
+ number_of_alignments = myargs[14].intvalue;
+ options->hitlist_size = MAX(number_of_descriptions, number_of_alignments);
+ if (myargs[7].intvalue != 0)
+ options->gap_open = myargs[7].intvalue;
+ if (myargs[8].intvalue != 0)
+ options->gap_extend = myargs[8].intvalue;
+ if (myargs[9].intvalue != 0)
+ options->gap_x_dropoff = myargs[9].intvalue;
+ options->filter = FILTER_NONE;
+ if (myargs[6].intvalue != 0)
+ {
+ if (StringICmp("blastn", blast_program) == 0)
+ options->filter = FILTER_DUST;
+ else
+ options->filter = FILTER_SEG;
+ }
+
+ show_gi = (Boolean) myargs[10].intvalue;
+ if (StringICmp("blastn", blast_program) == 0)
+ {
+ options->penalty = myargs[11].intvalue;
+ options->reward = myargs[12].intvalue;
+ }
+ else
+ {
+ if (myargs[15].intvalue != 0)
+ {
+ options->threshold_first = myargs[15].intvalue;
+ options->threshold_second = myargs[15].intvalue;
+ }
+ }
+
+ options->genetic_code = myargs[17].intvalue;
+ options->db_genetic_code = myargs[18].intvalue;
+ options->number_of_cpus = myargs[19].intvalue;
+ if (myargs[22].intvalue != 0)
+ options->wordsize = myargs[22].intvalue;
+
+
+ print_options = 0;
+ align_options = 0;
+ align_options += TXALIGN_COMPRESS;
+ align_options += TXALIGN_END_NUM;
+ if (StringICmp("blastx", blast_program) == 0)
+ {
+ align_options += TXALIGN_BLASTX_SPECIAL;
+ }
+ if (show_gi) {
+ align_options += TXALIGN_SHOW_GI;
+ print_options += TXALIGN_SHOW_GI;
+ }
+ if (myargs[16].intvalue == 0)
+ print_options += TXALIGN_SHOW_NO_OF_SEGS;
+
+ if (align_view)
+ {
+ align_options += TXALIGN_MASTER;
+ if (align_view == 1 || align_view == 3)
+ align_options += TXALIGN_MISMATCH;
+ if (align_view == 3 || align_view == 4 || align_view == 6)
+ align_options += TXALIGN_FLAT_INS;
+ if (align_view == 5 || align_view == 6)
+ align_options += TXALIGN_BLUNT_END;
+ }
+ else
+ {
+ align_options += TXALIGN_MATRIX_VAL;
+ align_options += TXALIGN_SHOW_QS;
+ }
+
+ if (! BlastInit("blastcl3", &bl3hp, &response)) {
+ ErrPostEx(SEV_FATAL, 0, 0, "Unable to initialize BLAST service");
+ return (1);
+ }
+
+ if (response && response->choice == BlastResponse_init)
+ {
+ blast_version = response->data.ptrvalue;
+ version = blast_version->version;
+ date = blast_version->date;
+ }
+
+ BlastNetBioseqFetchEnable(bl3hp, blast_database, db_is_na, TRUE);
+
+ motd = Blast3GetMotd(bl3hp);
+ PrintMotd(motd, outfp, FALSE);
+ motd = MemFree(motd);
+
+ BlastPrintVersionInfoEx(blast_program, FALSE, version, date, outfp);
+ fprintf(outfp, "\n");
+ BlastPrintReference(FALSE, 80, outfp);
+ fprintf(outfp, "\n");
+ num_of_queries=0;
+ retval=0;
+ while ((sep = FastaToSeqEntryEx(infp, query_is_na, NULL, believe_query)) != NULL)
+ {
+ query_bsp = NULL;
+ SeqEntryExplore(sep, &query_bsp, query_is_na? FindNuc : FindProt);
+
+ /* Read boundaries of location */
+ startloc = myargs[23].intvalue - 1;
+ if (myargs[24].intvalue == -1)
+ endloc = query_bsp->length - 1;
+ else
+ endloc = myargs[24].intvalue - 1;
+
+ /* Create the SeqLoc */
+ slp = SeqLocIntNew(startloc, endloc, Seq_strand_both, query_bsp->id);
+
+ if (query_bsp == NULL)
+ {
+ ErrPostEx(SEV_FATAL, 0, 0, "Unable to obtain bioseq\n");
+ retval = 2;
+ break;
+ }
+ AcknowledgeBlastQuery(query_bsp, 70, outfp, FALSE, FALSE);
+
+ if (startloc || endloc != query_bsp->length - 1)
+ TraditionalBlastReportLoc(slp, options, bl3hp, blast_program, blast_database,
+ FALSE, outfp, TRUE, print_options, align_options,
+ number_of_descriptions, number_of_alignments, NULL);
+ else
+ TraditionalBlastReport(query_bsp, options, bl3hp, blast_program, blast_database,
+ FALSE, outfp, TRUE, print_options, align_options,
+ number_of_descriptions, number_of_alignments, NULL);
+
+ sep = SeqEntryFree(sep);
+ }
+ options = BLASTOptionDelete(options);
+ FileClose(infp);
+ FileClose (outfp);
+ BlastFini(bl3hp);
+ return retval;
+}
diff --git a/network/blast3/client/blastpat.h b/network/blast3/client/blastpat.h
new file mode 100644
index 00000000..a1bf6830
--- /dev/null
+++ b/network/blast3/client/blastpat.h
@@ -0,0 +1,78 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: blast18p.h
+*
+* Author: Jonathan Epstein
+*
+* Version Creation Date: 06/16/95
+*
+* $Revision: 1.1 $
+*
+* File Description:
+* Header file to patch around constructs which the "ASNCODE" generator
+* is unable to deal with; this file is specific to the BLAST 1.8 ASN.1
+* specification.
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: blastpat.h,v $
+* Revision 1.1 1997/10/08 19:25:38 madden
+* patch header for asncode
+*
+ * Revision 5.0 1996/05/28 14:09:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.0 1995/07/26 13:55:34 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.2 1995/06/21 17:18:11 epstein
+ * use Seq-align set instead of SET OF Seq-align (hack-around via SpecialSeqAlignSetAsn{Read,Write})
+ *
+ * Revision 1.1 95/06/16 11:26:14 epstein
+ * Initial revision
+ *
+*/
+
+#include <objalign.h>
+#include <objseq.h>
+
+#define NLM_EXTERN_LOADS { SeqAlignAsnLoad(); }
+
+#define struct_Score score
+
+#define SeqAlignSetAsnWrite SpecialSeqAlignSetAsnWrite
+#define SeqAlignSetAsnRead SpecialSeqAlignSetAsnRead
+
+#define struct_Bioseq bioseq
+
+
diff --git a/network/blast3/client/blstspc.asn b/network/blast3/client/blstspc.asn
new file mode 100644
index 00000000..c6fb2ea9
--- /dev/null
+++ b/network/blast3/client/blstspc.asn
@@ -0,0 +1,245 @@
+--$Revision: 1.7 $
+--********************************************************************
+--
+-- Network BLAST
+-- Tom Madden, January 1997
+--
+--*********************************************************************
+--
+-- blstspc.asn
+--
+--*********************************************************************
+
+NCBI-Blast DEFINITIONS ::=
+BEGIN
+
+EXPORTS Blast-search, Blast-request,
+ Blast-response, Blast-parameters,
+ Blast-dbinfo, Blast-mask, Blast-KABlk;
+
+
+IMPORTS Bioseq FROM NCBI-Sequence
+ Seq-id, Seq-loc FROM NCBI-Seqloc
+ Seq-align-set FROM NCBI-Seqalign;
+
+
+Blast-request ::= CHOICE {
+ init VisibleString , -- Init of connection, client name may be sent.
+ motd NULL , -- Get the message of the day.
+ -- db-info returns information on all available databases.
+ -- db-info-specific returns information on one databases.
+ db-info NULL ,
+ db-info-specific Blast-dbinfo-get , -- Get blast-dbinfo on a specific db.
+ -- retrieve a sequence from the BLAST database. It is expected that most
+ -- database sequences will be retrieved from Entrez. This request should be
+ -- used if the database is not in Entrez.
+ matrix-get VisibleString , -- Get a Blast-matrix
+ search Blast-search , -- perform a search, return a SeqAlignSet
+ db-seq-get Blast-seq-id , -- Get a db sequence.
+ db-redundant-ids-get Blast-seq-id, -- Get the ID's of identical sequences, but different entries.
+ db-redundant-descr-get Blast-seq-id, -- Get the ID's and deflines of identical sequences, but different entries.
+ fini NULL
+}
+
+Blast-search ::= SEQUENCE {
+ program ENUMERATED {
+ blastn (0), -- nucl. query vs. nucl. database
+ blastp (1), -- prot. query vs. prot. database
+ blastx (2), -- transl. nucl. query vs. prot. database
+ tblastn (3), -- prot. query vs. transl. nucl. database
+ tblastx (4) -- transl. nucl. query vs. transl. nucl. database
+ },
+ query Bioseq, -- Bioseq contains query.
+ database VisibleString , -- BLAST db to search
+ parameters Blast-parameters OPTIONAL, -- search parameters
+ mask Seq-loc OPTIONAL, -- locations on query to mask
+ matrix Blast-matrix OPTIONAL -- PSI-BLAST matrix to use in search.
+}
+
+
+Blast-dbinfo-get ::= SEQUENCE {
+ name VisibleString , -- name of database
+ type ENUMERATED { -- protein or nt.
+ unknown (0),
+ protein (1),
+ nucleotide (2)
+ }
+}
+
+Blast-dbinfo ::= SEQUENCE {
+ is-protein BOOLEAN , -- Is the database protein
+ name VisibleString , -- name of database
+ definition VisibleString , -- description of database contents
+ date VisibleString , -- timestamp of database
+ total-length INTEGER , -- total length of database
+ number-seqs INTEGER -- how many sequence in database.
+}
+
+
+Blast-matrix ::= SEQUENCE {
+ is-protein BOOLEAN , -- Is the matrix for proteins
+ name VisibleString , -- name of matrix (e.g., "BLOSUM62")
+ comments SEQUENCE OF VisibleString OPTIONAL, -- comments on matrix.
+ -- The dimensions of the matrix are returned so the client can
+ -- verify that all data was received. Both dimensions are returned for
+ -- non-symmetric matrices (psi-blast uses these).
+ row-length INTEGER , -- length of rows
+ column-length INTEGER , -- number of columns
+ -- The matrix values are presented in order of the alphabet
+ -- ncbistdaa is used for protein, ncbi4na for nucl.
+ -- for proteins the values returned correspond to (-,-), (-,A), (-,B), (-,C) ...
+ -- (A,-), (A,A), (A,B), (A,C) ...
+ scores SEQUENCE OF INTEGER , -- integer values of matrix
+ karlinK REAL -- Karlin/Altschul parameter calculated with this matrix
+}
+
+-- Describes a sequence for the BLAST retriveal system
+Blast-seq-id ::= SEQUENCE {
+ is-protein BOOLEAN , -- is this a protein sequence
+ database VisibleString , -- name of the BLAST database (e.g., swissprot, nr).
+ id Seq-id -- The ID of the sequence.
+}
+
+-- The most common and often used options are listed here. Other options
+-- demanded by expert users (as well as new options) can be place in the
+-- "other-options" VisibleString.
+Blast-parameters ::= SEQUENCE {
+ first-threshold INTEGER OPTIONAL , -- threshold value for 1st pass
+ second-threshold INTEGER OPTIONAL , -- threshold value for 2nd pass
+ -- Cutoff values can be chosen by expect value (which depends on the db and
+ -- query size) or by nominal score.
+ cutoff CHOICE { -- cutoff value to determine whether to report hit
+ evalue REAL , -- The expect value,
+ score INTEGER -- A nominal score
+ } OPTIONAL ,
+ cutoff2 CHOICE { -- cutoff value for individual hits or HSP's
+ evalue REAL , -- An evalue for the individual hit
+ score INTEGER -- A nominal score value for the hit
+ } OPTIONAL ,
+ hitlist-size INTEGER OPTIONAL , -- determines how many hits are returned
+ nucl-penalty INTEGER OPTIONAL , -- penalty used in blastn comparisons
+ nucl-reward INTEGER OPTIONAL , -- reward used in blastn comparisons
+ genetic-code INTEGER OPTIONAL , -- genetic code used to translate query (blastx or tblastx)
+ db-genetic-code INTEGER OPTIONAL , -- genetic code used to translate db (tblast[nx])
+ low-complexity-filtering INTEGER OPTIONAL , -- filtering for low-complexity regions.
+ -- 0 = none, 1 = dust (for blastn), 2 = seg (other programs)
+ -- should a gapped alignment be performed.
+ gapped-alignment BOOLEAN , -- perform gapped alignment if TRUE,
+ -- Cost to open and extend a gap.
+ gap-open INTEGER OPTIONAL ,
+ gap-extend INTEGER OPTIONAL ,
+ -- the next two options are for "ranged" blast, which restricts the building of
+ -- words to a certain region. Hits may be extended beyond this range.
+ required-start INTEGER OPTIONAL , -- start of word range
+ required-end INTEGER OPTIONAL , -- end of words range (-1 denotes end of query)
+ -- PSI-BLAST parameters:
+ ethresh REAL OPTIONAL ,
+ max-num-passes INTEGER OPTIONAL ,
+ pseudo-count-const INTEGER OPTIONAL ,
+
+ other-options VisibleString OPTIONAL, -- other options not listed above
+
+ gilist SEQUENCE OF INTEGER OPTIONAL, -- list of gis
+ gifile VisibleString OPTIONAL, -- file with list of gis on server side
+
+ matrix VisibleString OPTIONAL, -- specifies a matrix to use
+ filter-string VisibleString OPTIONAL, -- filtering commands to be executed
+ entrez-query VisibleString OPTIONAL, -- query to Entrez
+ word-size INTEGER OPTIONAL -- word-size used in BLAST search.
+}
+
+ -- series of these when the request is queued
+Blast-Queued ::= SEQUENCE {
+ length INTEGER -- length gives no. of jobs ahead of the request
+}
+
+
+Blast-Progress ::= SEQUENCE {
+ completed INTEGER -- "completed" specifies number of db sequences that have been searched.
+}
+
+
+Blast-KABlk ::= SEQUENCE {
+ -- (for a description of lambda, k and h see Karlin and Altschul,
+ -- Proc. Natl. Acad. Sci. USA, 87:2264-68 (1990)).
+ lambda REAL , -- Lambda value for calculation.
+ k REAL , -- K value used in calculation.
+ h REAL , -- H value used in calculation.
+ gapped BOOLEAN -- do theses values apply to a gapped alignment?
+}
+
+Blast-defline ::= SEQUENCE {
+ id Seq-id , -- The ID
+ defline VisibleString -- The FASTA defline
+}
+
+Blast-mask ::= SEQUENCE {
+ location SEQUENCE OF Seq-loc , -- The location masked.
+ frame ENUMERATED { -- What frame
+ notset (0),
+ plus1 (1),
+ plus2 (2),
+ plus3 (3),
+ minus1 (4),
+ minus2 (5),
+ minus3 (6)
+ }
+}
+
+Blast-version ::= SEQUENCE {
+ version VisibleString , -- the version number of the program
+ date VisibleString -- date the program was released
+}
+
+Blast-error ::= SEQUENCE {
+ level ENUMERATED {
+ none (0), -- not an error, just a message
+ info (1), -- informational error
+ warn (2),
+ error (3),
+ fatal (4)
+ },
+ msg VisibleString OPTIONAL
+}
+
+
+Blast-response ::= CHOICE {
+ init Blast-version , -- acknowledges init
+ motd VisibleString , -- Message of the day, new-lines inidcated by "~"
+ error Blast-error , -- Error code, or informational message
+ db-seq-get Bioseq , -- Bioseq from BLAST database.
+ -- db-redundant-ids-get is a list of ID's for sequences that are absolutely
+ -- identical, but are really from different entries.
+ db-redundant-ids-get SEQUENCE OF Seq-id , --
+ -- Both the ID and defline for redundant sequences.
+ db-redundant-descr-get SEQUENCE OF Blast-defline ,--
+ db-info SEQUENCE OF Blast-dbinfo , -- Information about all database.
+ db-info-specific Blast-dbinfo , -- Information about one database.
+ matrix Blast-matrix , -- BLAST matrix requested by matrix-get
+ --
+ -- The type of SeqAlign returned depends on the request:
+ -- For ungapped requests where both query and db are of the same type
+ -- (e.g., blastn) a discontinuous Dense-diag is used.
+ -- (A discont. SeqAlign must be used to convey the information about which
+ -- HSP's belong together).
+ -- For ungapped requests with different query and db (e.g., blastx)
+ -- a discontinuous Std-seg is used.
+ -- For gapped alignments (blastn or blastp) a Dense-seg is used.
+ --
+ alignment Seq-align-set , -- The results as a SeqAlign
+ -- If a gapped alignment is performed, then two Blast-KABlk will
+ -- be returned, one for the ungapped portion of BLAST, the other for
+ -- the (final) gapped calculations. These Blast-KABlk's can be
+ -- differentiated by the BOOLEAN gapped.
+ mask Blast-mask, -- what was masked on server (e.g., by seg or dust).
+ kablk Blast-KABlk , -- Karlin-Altschul parameters.
+ -- parameters, stats. about search etc., new lines indicated by "~".
+ parameters VisibleString ,
+ queued Blast-Queued , -- emitted when queued.
+ start Blast-Progress , -- one emitted at start of search
+ progress Blast-Progress ,-- regular messages emitted during search
+ done Blast-Progress , -- one emitted at end of search
+ fini NULL -- acknowledge fini
+}
+
+END
diff --git a/network/blast3/client/netblap3.c b/network/blast3/client/netblap3.c
new file mode 100644
index 00000000..424a6690
--- /dev/null
+++ b/network/blast3/client/netblap3.c
@@ -0,0 +1,2010 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: netblap3.c
+*
+* Author: Tom Madden
+*
+* Version Creation Date: 05/8/97
+*
+* File Description:
+* Application Programming Interface (API) for BLAST network server
+*
+* RCS Modification History:
+* $Log: netblap3.c,v $
+* Revision 1.27 1999/01/12 21:05:58 victorov
+* server will now report an error if the ni-queue if full
+*
+* Revision 1.26 1998/12/09 15:27:05 madden
+* Add wordsize
+*
+* Revision 1.25 1998/11/03 21:46:19 egorov
+* Add support for entrez-query and org-name
+*
+* Revision 1.24 1998/10/26 19:42:57 madden
+* Check for NULL matrix or filter_string
+*
+* Revision 1.23 1998/10/06 18:28:07 egorov
+* Fix MT problem with dispatcher_lock
+*
+* Revision 1.22 1998/09/22 16:12:53 egorov
+* Use BlastErrorPrintExtra instead of BlastErrorPrint to redirect error messages both to log and to program output file
+*
+* Revision 1.21 1998/09/01 20:17:03 madden
+* Fixed uninitialzed problem in BlastNetBioseqFetchDisable, changed prototype
+*
+* Revision 1.20 1998/08/14 17:43:26 madden
+* non-NULL f_order and g_order in formatting
+*
+* Revision 1.19 1998/08/14 16:04:48 egorov
+* Create TLS for BlastNetFetchStruct to make it multi-thread safe. Using some of global variables is commented out
+*
+* Revision 1.18 1998/07/28 16:57:51 egorov
+* Make StringSave() for some CharPtr in assignments to save memory and avoid memory crashes
+*
+* Revision 1.16 1998/06/08 21:58:36 madden
+* Check for NULL Bioseq in FetchFunc, print out Error message if NULL
+*
+* Revision 1.15 1998/05/08 21:40:15 vakatov
+* fixed a tiny type cast(one more *)
+*
+* Revision 1.14 1998/05/08 20:56:22 madden
+* Fix PC compile warnings, rename callback
+*
+* Revision 1.13 1998/05/08 01:08:09 madden
+* Removed unused variables
+*
+* Revision 1.12 1998/04/24 18:35:50 madden
+* Do not send Seq-descr to server
+*
+* Revision 1.11 1998/04/24 16:01:41 egorov
+* Remove BlastErrorPrint from BlastSeqLocNetCore
+*
+* Revision 1.10 1998/04/23 14:19:31 egorov
+* Allow other_returns in BlastSeqLocNet to be NULL
+*
+* Revision 1.9 1998/04/22 18:10:06 egorov
+* Add support for SeqLoc to blastcl3
+*
+* Revision 1.8 1998/04/17 19:24:00 madden
+* Transmit expect value, hitlist_size, and genetic codes to server
+*
+* Revision 1.7 1998/04/16 19:35:31 madden
+* Added Int4Ptr arg to TraditionalBlastReport specifying the numbers of hits
+*
+* Revision 1.6 1998/04/09 16:16:33 madden
+* Added BlastNetFetchCompare function
+*
+* Revision 1.5 1997/12/16 19:10:51 madden
+* Fixed Codecenter errors
+*
+* Revision 1.4 1997/12/01 22:05:51 madden
+* Changed call to BlastValidateOptionsEx
+*
+* Revision 1.3 1997/11/28 18:17:39 madden
+* Changes for multiple db searches
+*
+* Revision 1.1 1997/10/08 19:27:20 madden
+* Network support for gapped blast
+*
+*/
+
+#include <ncbinet.h>
+#include <ncbithr.h>
+#include <txalign.h>
+#include <jzmisc.h>
+#include <blastpat.h>
+#include <netblap3.h>
+
+
+#define BLAST_SERVER_RETRIES 2
+
+#define BLASTNET_SHORT_BUFLEN 25
+#define BLASTNET_BUF_SIZE 255
+#define BLASTNET_INIT 0
+#define BLASTNET_READY 1
+#define BLASTNET_DISABLE 2
+
+typedef struct _blastnetbioseqfetch {
+ Uint1 BlastNetFetchState;
+ CharPtr dbname; /* Name of the database. */
+ BlastNet3Hptr bl3hp; /* Network connection. */
+ Uint2 ctr;
+ Boolean is_prot; /* Is it a protein or not. */
+} BlastNetFetchStruct, PNTR BlastNetFetchStructPtr;
+
+static TNlmTls blastnetfetch_tls = NULL;
+
+static Int2 num_attached = 0;
+static NI_DispatcherPtr dispatcher = NULL;
+/* Mutex for dispatcher. */
+TNlmMutex dispatcher_lock = NULL;
+
+static TNlmMutex formating_mutex; /* Mutex to regulate formating in TraditionalBlastReport */
+
+static Boolean BlastInitEx PROTO((CharPtr program_name, BlastNet3Hptr bl3hp, BlastResponsePtr PNTR respp));
+
+static Boolean SubmitRequest PROTO((BlastNet3Hptr bl3hptr, BlastRequestPtr blreqp, BlastResponsePtr PNTR response, NetProgressCallback callback));
+static Boolean RealSubmitRequest PROTO((BlastNet3Hptr bl3hptr, BlastRequestPtr blreqp, BlastResponsePtr PNTR response, NetProgressCallback callback));
+
+/* error_occurred and old_error_hook should not be accessed directly.
+The functions BlastSetErrorStatus, BlastGetErrorStatus, and BlastSetErrorHook
+will change these variables. */
+static Boolean error_occurred;
+static ErrHookProc old_error_hook;
+
+/*
+ The next five functions set an error hook and detect
+ whether an error occurred (i.e., contact with the
+ server was lost).
+
+ BlastSetErrorHook should be called first, the function
+ BlastErrHookProc is set as the "handler"; BlastSetErrorStatus
+ should then be called to set the error status to FALSE;
+ BlastGetErrorStatus should be called to determine if an error
+ occurred; and then BlastResetOldHook should be called to restore
+ the original hook, in case BLAST is called from within another
+ application that uses this (original) hook.
+
+ BlastSetErrorStatus is also called, to set the error status
+ sometimes if a BlastAsnRead fails. This is taken as evidence
+ of an error, even if none is reported.
+*/
+
+static int LIBCALLBACK
+BlastErrHookProc(const ErrDesc *err)
+
+{
+ error_occurred = TRUE;
+ return 1;
+}
+
+static void
+BlastSetErrorHook(void)
+
+{
+ old_error_hook = Nlm_ErrSetHandler(BlastErrHookProc);
+ return;
+}
+
+static void
+BlastSetErrorStatus(Boolean status)
+
+{
+ error_occurred = status;
+}
+
+static Boolean
+BlastGetErrorStatus(void)
+
+{
+ return error_occurred;
+}
+
+static void
+BlastResetOldHook(void)
+
+{
+ Nlm_ErrSetHandler(old_error_hook);
+ return;
+}
+
+/*
+ The following functions fill a the Error user string with
+ text to identify BLAST and the entry being worked on.
+ The SeqIdPtr is used to make a FASTA id, which is appended
+ to string.
+
+ A Uint1 is returned, which allows Nlm_ErrUserDelete to delete
+ this error string when it's done.
+*/
+
+static Uint1
+BlastSetUserErrorString(CharPtr string, SeqIdPtr sip)
+
+{
+ Char buffer[2*BLASTNET_SHORT_BUFLEN], textid[BLASTNET_SHORT_BUFLEN];
+ CharPtr buf_start, ptr;
+ Int2 length;
+
+ ptr = buf_start = &buffer[0];
+
+ StringNCpy(ptr, string, BLASTNET_SHORT_BUFLEN);
+ if (sip != NULL)
+ {
+ length = StringLen(string);
+ if (length > BLASTNET_SHORT_BUFLEN)
+ length = BLASTNET_SHORT_BUFLEN;
+
+ ptr += length;
+
+ SeqIdWrite(sip, textid, PRINTID_FASTA_LONG, BLASTNET_SHORT_BUFLEN-1);
+ StringNCpy(ptr, textid, BLASTNET_SHORT_BUFLEN-1);
+ }
+ return Nlm_ErrUserInstall (buf_start, 0);
+}
+
+static void
+BlastDeleteUserErrorString(Uint1 err_id)
+
+{
+ Nlm_ErrUserDelete(err_id);
+ return;
+}
+
+/*****************************************************************************
+*
+* NetInit ()
+*
+*****************************************************************************/
+
+static Boolean NetInit(void)
+{
+ Boolean retval = FALSE;
+
+ NlmMutexLockEx(&dispatcher_lock);
+
+ if(num_attached++ > 0)
+ {
+ NlmMutexUnlock(dispatcher_lock);
+ return TRUE;
+ }
+
+ dispatcher = NI_GenericInit(NULL, NULL, TRUE, NULL, 0);
+
+ if (dispatcher)
+ retval = TRUE;
+
+ NlmMutexUnlock(dispatcher_lock);
+
+ return retval;
+}
+
+
+/*****************************************************************************
+*
+* ForceNetInit ()
+*
+*****************************************************************************/
+
+static Boolean ForceNetInit(void)
+{
+ Boolean retval;
+
+ NlmMutexLockEx(&dispatcher_lock);
+
+ num_attached = 0; /* force re-attempt to contact dispatcher */
+ retval = NetInit();
+
+ NlmMutexUnlock(dispatcher_lock);
+
+ return retval;
+}
+
+/*****************************************************************************
+*
+* NetFini ()
+
+ BlastNet3Hptr bl3hp: was returned by BlastInit
+ Boolean deallocate: should BlastNet3Hptr be deallocated (or will it be reused for
+ a reconnection).
+*
+*****************************************************************************/
+
+static Boolean NetFini(BlastNet3Hptr bl3hp, Boolean deallocate)
+{
+ NlmMutexLockEx(&dispatcher_lock);
+
+ if (num_attached > 0)
+ num_attached--;
+
+ if (bl3hp != NULL)
+ {
+ NI_ServiceDisconnect(bl3hp->svcp);
+ if (deallocate)
+ bl3hp = MemFree(bl3hp);
+
+ if (num_attached == 0)
+ { /* Disconnect if last service to dispatcher. */
+ NI_EndServices (dispatcher);
+ dispatcher = NULL;
+ }
+ }
+
+ NlmMutexUnlock(dispatcher_lock);
+
+ return TRUE;
+}
+
+
+/*****************************************************************************
+*
+* GenericReestablishNet ()
+*
+*****************************************************************************/
+
+static Boolean GenericReestablishNet(CharPtr svcName, Boolean showErrs, BlastNet3Hptr bl3hp)
+{
+ Handle mon = NULL;
+ Boolean retval;
+ CharPtr buf;
+
+ buf = MemNew(2 * StrLen(svcName) + 60);
+
+ if (showErrs) {
+ sprintf (buf, "Re-establishing %s Service", svcName);
+ mon = MonitorStrNew(buf, 40);
+ sprintf (buf, "Requesting %s service", svcName);
+ MonitorStrValue(mon, buf);
+ }
+
+ NetFini(bl3hp, FALSE);
+
+ retval = BlastInitEx(NULL, bl3hp, NULL);
+
+ if (!retval)
+ {
+ sprintf (buf, "%s get failed; re-contacting dispatcher", svcName);
+ MonitorStrValue(mon, buf);
+ retval = FALSE;
+ if (ForceNetInit())
+ { /* successfully established contact w/dispatcher */
+ sprintf (buf, "%s get failed; re-requesting %s service",
+ svcName, svcName);
+ MonitorStrValue(mon, buf);
+ retval = BlastInitEx(NULL, bl3hp, NULL);
+ }
+ else {
+ ErrPost(CTX_UNKNOWN, 1, "Unable to re-contact dispatcher");
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+ }
+
+ MonitorFree(mon);
+
+ if (! retval )
+ {
+ sprintf (buf, "Unable to re-establish %s service", svcName);
+ ErrPost(CTX_UNKNOWN, 1, buf);
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+
+ MemFree(buf);
+ return retval;
+}
+
+/*****************************************************************************
+*
+* ReestablishNetBlast ()
+*
+*****************************************************************************/
+
+static Boolean ReestablishNetBlast(BlastNet3Hptr bl3hp)
+{
+ return GenericReestablishNet("NETBLAST", TRUE, bl3hp);
+}
+
+/*****************************************************************************
+*
+* BlastInit ()
+*
+*****************************************************************************/
+
+static Boolean BlastInitEx (CharPtr program_name, BlastNet3Hptr bl3hp, BlastResponsePtr PNTR respp)
+
+{
+ BlastRequestPtr request;
+ BlastResponsePtr response;
+ NI_HandPtr svcp = NULL;
+
+ if (bl3hp == NULL)
+ {
+ return FALSE;
+ }
+
+
+ if (!NetInit())
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "NI_ServiceGet [%s] (%s)", ni_errlist[ni_errno], ni_errtext);
+ return FALSE;
+ }
+
+ svcp = NI_GenericGetService(dispatcher, NULL, "NETBLAST", "blast3", FALSE);
+ if (svcp == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "NI_ServiceGet [%s] (%s)", ni_errlist[ni_errno], ni_errtext);
+ BlastFini(NULL);
+ return FALSE;
+ }
+
+ bl3hp->svcp = svcp;
+
+
+ request = ValNodeNew(NULL);
+ request->choice = BlastRequest_init;
+ SubmitRequest(bl3hp, request, &response, NULL);
+ BlastRequestFree (request);
+ if (respp)
+ *respp = response;
+ else
+ BlastResponseFree (response);
+
+ return TRUE;
+
+}
+
+/*****************************************************************************
+*
+* BlastInit ()
+*
+*****************************************************************************/
+
+Boolean LIBCALL
+BlastInit (CharPtr program_name, BlastNet3Hptr PNTR bl3hpp, BlastResponsePtr PNTR respp)
+
+{
+ BlastNet3Hptr bl3hp_pri;
+
+ if (bl3hpp == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "BlastInitMT, BlastNet3Hptr PNTR is NULL");
+ return FALSE;
+ }
+
+ bl3hp_pri = MemNew(sizeof(BlastNet3Hptr));
+ if (bl3hp_pri == NULL)
+ return FALSE;
+
+ *bl3hpp = bl3hp_pri;
+
+ return BlastInitEx(program_name, bl3hp_pri, respp);
+}
+
+/*****************************************************************************
+*
+* BlastFini ()
+*
+*****************************************************************************/
+
+static Boolean s_BlastFini (BlastNet3Hptr bl3hptr)
+
+{
+ Boolean retval = TRUE;
+ BlastRequestPtr request;
+ BlastResponsePtr response;
+
+
+ if (bl3hptr == NULL || bl3hptr->svcp == NULL)
+ return FALSE;
+
+ request = ValNodeNew(NULL);
+ request->choice = BlastRequest_fini;
+ SubmitRequest(bl3hptr, request, &response, NULL);
+ BlastRequestFree (request);
+ BlastResponseFree (response);
+
+ NetFini(bl3hptr, TRUE);
+ return retval;
+}
+
+/* the only thing done here is to suppress errors */
+
+Boolean LIBCALL
+BlastFini (BlastNet3Hptr bl3hptr)
+
+{
+ short erract;
+ ErrDesc err;
+ Boolean retval;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ retval = s_BlastFini(bl3hptr);
+
+ ErrSetOpts(erract, 0);
+ ErrFetch(&err);
+
+ return retval;
+}
+
+BlastParametersPtr LIBCALL
+BlastOptionsToParameters (BLAST_OptionsBlkPtr options)
+
+{
+ BlastParametersPtr parameters;
+
+
+ if (options == NULL)
+ {
+ return NULL;
+ }
+
+ parameters = BlastParametersNew();
+ parameters->gapped_alignment = options->gapped_calculation;
+ if (options->cutoff_s == 0)
+ {
+ parameters->Cutoff_cutoff = ValNodeAddFloat(NULL, Cutoff_cutoff_evalue, options->expect_value);
+ }
+ else
+ {
+ parameters->Cutoff_cutoff = ValNodeAddInt(NULL, Cutoff_cutoff_score, options->cutoff_s);
+ }
+ if (options->cutoff_s2 == 0)
+ {
+ parameters->Cutoff2_cutoff2 = ValNodeAddFloat(NULL, Cutoff2_cutoff2_evalue, options->e2);
+ }
+ else
+ {
+ parameters->Cutoff2_cutoff2 = ValNodeAddInt(NULL, Cutoff2_cutoff2_score, options->cutoff_s2);
+ }
+ parameters->hitlist_size = options->hitlist_size;
+ parameters->first_threshold = options->threshold_first;
+ parameters->second_threshold = options->threshold_second;
+ parameters->nucl_penalty = options->penalty;
+ parameters->nucl_reward = options->reward;
+ parameters->gap_open = options->gap_open;
+ parameters->gap_extend = options->gap_extend;
+ parameters->genetic_code = options->genetic_code;
+ parameters->db_genetic_code = options->db_genetic_code;
+ parameters->low_complexity_filtering = options->filter;
+ parameters->ethresh = options->ethresh;
+ parameters->max_num_passes = options->maxNumPasses;
+ parameters->pseudo_count_const = options->pseudoCountConst;
+
+ parameters->gifile = StringSave(options->gifile);
+ parameters->gilist = options->gilist;
+ parameters->matrix = StringSave(options->matrix);
+ parameters->filter_string = StringSave(options->filter_string);
+ parameters->entrez_query = StringSave(options->entrez_query);
+ parameters->word_size = options->wordsize;
+
+ return parameters;
+}
+
+/*
+ Translates the BlastDbinfoPtr into TxDfDbInfoPtr.
+*/
+
+TxDfDbInfoPtr LIBCALL
+NetDbinfo2TxDbinfo(BlastDbinfoPtr net_dbinfo)
+
+
+{
+ TxDfDbInfoPtr dbinfo=NULL, dbinfo_head;
+
+ dbinfo_head = NULL;
+ while (net_dbinfo)
+ {
+ dbinfo = TxDfDbInfoNew(dbinfo);
+ dbinfo->is_protein = net_dbinfo->is_protein;
+ dbinfo->name = StringSave(net_dbinfo->name);
+ dbinfo->definition = StringSave(net_dbinfo->definition);
+ dbinfo->date = StringSave(net_dbinfo->date);
+ dbinfo->total_length = net_dbinfo->total_length;
+ dbinfo->number_seqs = net_dbinfo->number_seqs;
+ if (dbinfo_head == NULL)
+ dbinfo_head = dbinfo;
+ net_dbinfo = net_dbinfo->next;
+ }
+
+ return dbinfo_head;
+}
+
+BlastNet3BlockPtr LIBCALL
+BlastNet3BlockDestruct(BlastNet3BlockPtr blnet)
+
+{
+ BlastResponsePtr response;
+ if (blnet == NULL)
+ return NULL;
+
+ BlastParametersFree(blnet->parameters);
+ /* individual elements freed elsewhere. */
+ response = blnet->response;
+ while(response)
+ {
+ response->data.ptrvalue = NULL;
+ response = response->next;
+ }
+ BlastResponseFree(blnet->response);
+ MemFree(blnet->dbname);
+
+ return NULL;
+}
+
+/*
+ Creates a new BlastNet3BlockNew, used for searching.
+*/
+BlastNet3BlockPtr LIBCALL
+BlastNet3BlockNew(CharPtr program, CharPtr dbname)
+
+{
+ BlastNet3BlockPtr retval=NULL;
+
+ retval = MemNew(sizeof(BlastNet3Block));
+
+ if (retval)
+ {
+ if (StringICmp("blastn", program) == 0)
+ retval->prog_type = Blast_search_program_blastn;
+ else if (StringICmp("blastp", program) == 0)
+ retval->prog_type = Blast_search_program_blastp;
+ else if (StringICmp("blastx", program) == 0)
+ retval->prog_type = Blast_search_program_blastx;
+ else if (StringICmp("tblastn", program) == 0)
+ retval->prog_type = Blast_search_program_tblastn;
+ else if (StringICmp("tblastx", program) == 0)
+ retval->prog_type = Blast_search_program_tblastx;
+ if (dbname)
+ retval->dbname = StringSave(dbname);
+ }
+
+ return retval;
+}
+
+static Boolean
+QueryIsProteinFromType(Uint2 type)
+{
+ switch (type)
+ {
+ case Blast_search_program_blastn:
+ return FALSE;
+ case Blast_search_program_blastp:
+ return TRUE;
+ case Blast_search_program_blastx:
+ return FALSE;
+ case Blast_search_program_tblastn:
+ return TRUE;
+ case Blast_search_program_tblastx:
+ return FALSE;
+ default:
+ return FALSE;
+ }
+}
+
+static BlastResponsePtr GetResponsePtr(BlastResponsePtr response, Nlm_Uint1 choice)
+
+{
+ while (response)
+ {
+ if (response->choice == choice)
+ {
+ break;
+ }
+ response = response->next;
+ }
+
+ return response;
+}
+
+
+BlastDbinfoPtr LIBCALL
+BlastRequestDbInfo (BlastNet3Hptr bl3hp, CharPtr database, Boolean is_prot)
+
+{
+ BlastRequestPtr request=NULL;
+ BlastResponsePtr response=NULL;
+ BlastDbinfoPtr dbinfo=NULL;
+ BlastDbinfoGetPtr dbinfo_get;
+
+
+ dbinfo_get = BlastDbinfoGetNew();
+ dbinfo_get->name = database;
+
+ if (is_prot)
+ dbinfo_get->type = Blast_dbinfo_get_type_protein;
+ else
+ dbinfo_get->type = Blast_dbinfo_get_type_nucleotide;
+
+ ValNodeAddPointer(&request, BlastRequest_db_info_specific, dbinfo_get);
+ SubmitRequest(bl3hp, request, &response, NULL);
+ response = GetResponsePtr(response, BlastResponse_db_info_specific);
+
+ if (response)
+ dbinfo = response->data.ptrvalue;
+
+ dbinfo_get->name = NULL; /* Not owned by this function. */
+ BlastRequestFree(request);
+
+ return dbinfo;
+}
+
+BlastDbinfoPtr LIBCALL
+BlastGetDbInfo (BlastNet3BlockPtr blnet3blkptr)
+
+{
+ BlastResponsePtr response;
+ BlastDbinfoPtr dbinfo=NULL, dbinfo_head, last;
+
+ last = NULL;
+ dbinfo = NULL;
+ dbinfo_head = NULL;
+ response = blnet3blkptr->response;
+ while (response)
+ {
+ response = GetResponsePtr(response, BlastResponse_db_info_specific);
+ if (response)
+ {
+ last = dbinfo;
+ dbinfo = response->data.ptrvalue;
+ if (dbinfo_head == NULL)
+ dbinfo_head = dbinfo;
+ if (last)
+ last->next = dbinfo;
+ response = response->next;
+ }
+ }
+
+ return dbinfo_head;
+}
+
+BlastMatrixPtr LIBCALL
+NetBlastGetMatrix(BlastNet3BlockPtr blnet3blkptr)
+
+{
+ BlastResponsePtr response;
+ BlastMatrixPtr matrix=NULL;
+
+
+ response = GetResponsePtr(blnet3blkptr->response, BlastResponse_matrix);
+
+ if (response)
+ matrix = response->data.ptrvalue;
+
+ return matrix;
+}
+
+CharPtr LIBCALL
+BlastGetParameterBuffer (BlastNet3BlockPtr blnet3blkptr)
+
+{
+ BlastResponsePtr response;
+ CharPtr buffer=NULL;
+
+ response = GetResponsePtr(blnet3blkptr->response, BlastResponse_parameters);
+
+ if (response)
+ buffer = response->data.ptrvalue;
+
+ return buffer;
+}
+
+/*
+ Find the BlastKABlkPtr of the type (gapped or ungapped) specified.
+*/
+BlastKABlkPtr LIBCALL
+BlastGetKaParams (BlastNet3BlockPtr blnet3blkptr, Boolean gapped)
+
+{
+ BlastResponsePtr response;
+ BlastKABlkPtr kablk=NULL;
+
+
+ response = blnet3blkptr->response;
+ while (response)
+ {
+ response = GetResponsePtr(response, BlastResponse_kablk);
+ if (response)
+ {
+ kablk = response->data.ptrvalue;
+ if (kablk->gapped == gapped)
+ break;
+ response = response->next;
+ }
+ }
+
+ return kablk;
+}
+
+/*
+ Converts 'standard' BLAST matrix to network matrix.
+*/
+BlastMatrixPtr LIBCALL
+BlastMatrixToBlastNetMatrix(BLAST_MatrixPtr matrix)
+
+{
+ BlastMatrixPtr net_matrix;
+ Int4 index1, index2;
+ ValNodePtr vnp=NULL;
+
+ if (matrix == NULL)
+ return NULL;
+
+ net_matrix = MemNew(sizeof(BlastMatrix));
+
+ net_matrix->is_protein = matrix->is_prot;
+ net_matrix->name = StringSave(matrix->name);
+ net_matrix->row_length = matrix->rows;
+ net_matrix->column_length = matrix->columns;
+ net_matrix->karlinK = matrix->karlinK;
+
+ for (index1=0; index1<matrix->rows; index1++)
+ {
+ for (index2=0; index2<matrix->columns; index2++)
+ {
+ ValNodeAddInt(&vnp, 0, matrix->matrix[index1][index2]);
+ }
+ }
+ net_matrix->scores = vnp;
+
+ return net_matrix;
+
+}
+
+/*
+ Coverts the 'network' matrix to a 'tools' matrix.
+*/
+BLAST_MatrixPtr LIBCALL
+BlastNetMatrixToBlastMatrix (BlastMatrixPtr net_matrix)
+
+{
+ BLAST_MatrixPtr blast_matrix;
+ Int4 index1, index2;
+ Int4Ptr PNTR matrix;
+ ValNodePtr vnp;
+
+ if (net_matrix == NULL)
+ return NULL;
+
+ blast_matrix = MemNew(sizeof(BLAST_Matrix));
+
+ blast_matrix->is_prot = net_matrix->is_protein;
+ blast_matrix->name = StringSave(net_matrix->name);
+ blast_matrix->rows = net_matrix->row_length;
+ blast_matrix->columns = net_matrix->column_length;
+ blast_matrix->karlinK = net_matrix->karlinK;
+
+ vnp = net_matrix->scores;
+ matrix = (Int4Ptr PNTR) MemNew(blast_matrix->rows*sizeof(Int4Ptr));
+ for (index1=0; index1<blast_matrix->rows; index1++)
+ {
+ matrix[index1] = MemNew(blast_matrix->columns*sizeof(Int4));
+ for (index2=0; index2<blast_matrix->columns; index2++)
+ {
+ matrix[index1][index2] = (Int4) vnp->data.intvalue;
+ vnp = vnp->next;
+ }
+ }
+ blast_matrix->matrix = matrix;
+
+ return blast_matrix;
+}
+
+ValNodePtr LIBCALL
+BlastGetMaskedLoc (BlastNet3BlockPtr blnet3blkptr)
+
+{
+ BlastResponsePtr response;
+ BlastMaskPtr blast_mask;
+ ValNodePtr mask_loc=NULL;
+
+ response = blnet3blkptr->response;
+
+ while (response)
+ {
+ response = GetResponsePtr(response, BlastResponse_mask);
+ if (response)
+ {
+ blast_mask = response->data.ptrvalue;
+ ValNodeAddPointer(&mask_loc, blast_mask->frame, blast_mask->location);
+ response = response->next;
+ }
+ }
+
+ return mask_loc;
+}
+
+static BioseqPtr
+PrivateBlastGetBioseq(BlastNet3Hptr bl3hptr, CharPtr database, SeqIdPtr sip, Boolean is_prot)
+
+{
+ BioseqPtr bsp=NULL;
+ BlastSeqIdPtr blast_sip;
+ BlastRequestPtr request = NULL;
+ BlastResponsePtr response;
+
+ blast_sip = BlastSeqIdNew();
+ blast_sip->is_protein = is_prot;
+ blast_sip->database = database;
+ blast_sip->id = sip;
+ ValNodeAddPointer(&request, BlastRequest_db_seq_get, blast_sip);
+ SubmitRequest(bl3hptr, request, &response, NULL);
+
+ response = GetResponsePtr(response, BlastResponse_db_seq_get);
+ if (response)
+ {
+ bsp = response->data.ptrvalue;
+ response->data.ptrvalue = NULL;
+ BlastResponseFree(response);
+ }
+
+ /* These two were not allocated here. */
+ blast_sip->id = NULL;
+ blast_sip->database = NULL;
+ BlastRequestFree(request);
+
+ return bsp;
+}
+
+BioseqPtr LIBCALL
+BlastGetBioseq(BlastNet3BlockPtr blnet3blkptr, SeqIdPtr sip)
+
+{
+ BioseqPtr bsp;
+
+ bsp = PrivateBlastGetBioseq(blnet3blkptr->bl3hptr, blnet3blkptr->dbname, sip, QueryIsProteinFromType(blnet3blkptr->prog_type));
+
+ return bsp;
+}
+
+/*
+ Basic functions to submit BLAST runs.
+
+*/
+
+SeqAlignPtr LIBCALL
+BlastBioseq (BlastNet3BlockPtr blnet3blkptr, ValNodePtr *error_returns)
+
+{
+ BlastRequestPtr request = NULL;
+ BlastSearchPtr search = NULL;
+ BlastResponsePtr response;
+ ValNodePtr node;
+ SeqAlignPtr seqalign=NULL;
+ Uint1 err_id;
+
+#if 0
+ err_id = BlastSetUserErrorString("netblast:", blnet3blkptr->bsp->id);
+#endif
+
+ search = BlastSearchNew();
+ search->program = blnet3blkptr->prog_type;
+/*
+ search->query = (struct struct_Bioseq *) blnet3blkptr->bsp;
+*/
+ search->query = blnet3blkptr->bsp;
+ search->database = blnet3blkptr->dbname;
+ search->parameters = blnet3blkptr->parameters;
+ search->mask = blnet3blkptr->mask;
+ search->matrix = BlastMatrixToBlastNetMatrix(blnet3blkptr->blast_matrix);
+ ValNodeAddPointer(&request, BlastRequest_search, search);
+ SubmitRequest(blnet3blkptr->bl3hptr, request, &response, blnet3blkptr->callback);
+
+ blnet3blkptr->response = response;
+ node = GetResponsePtr(response, BlastResponse_alignment);
+ if (node)
+ seqalign = node->data.ptrvalue;
+ *error_returns = GetResponsePtr(response, BlastResponse_error);
+
+ /* These four are not allocated here. */
+ search->query = NULL;
+ search->database = NULL;
+ search->parameters = NULL;
+ search->mask = NULL;
+ BlastRequestFree(request);
+#if 0
+ BlastDeleteUserErrorString(err_id);
+#endif
+
+ return seqalign;
+}
+
+CharPtr LIBCALL
+Blast3GetMotd(BlastNet3Hptr bl3hptr)
+
+{
+ BlastResponsePtr response=NULL;
+ BlastRequestPtr request=NULL;
+ CharPtr string;
+
+ request = ValNodeNew(NULL);
+ request->choice = BlastRequest_motd;
+ SubmitRequest(bl3hptr, request, &response, NULL);
+ BlastRequestFree (request);
+ if (response == NULL || response->choice != BlastResponse_motd)
+ return NULL;
+
+ string = StringSave(response->data.ptrvalue);
+
+ BlastResponseFree(response);
+
+ return string;
+}
+
+static Boolean
+SubmitRequest(BlastNet3Hptr bl3hptr, BlastRequestPtr blreqp, BlastResponsePtr PNTR response, NetProgressCallback callback)
+
+{
+ Boolean status;
+ Int2 index;
+
+#if 0
+ BlastSetErrorHook();
+#endif
+ for(index=0; index<BLAST_SERVER_RETRIES; index++)
+ {
+#if 0
+ BlastSetErrorStatus(FALSE);
+#endif
+
+ status = RealSubmitRequest(bl3hptr, blreqp, response, callback);
+
+#if 0
+ if(status == TRUE && BlastGetErrorStatus() == FALSE)
+ break;
+#else
+ if (status == TRUE)
+ break;
+#endif
+
+ ReestablishNetBlast(bl3hptr);
+ }
+#if 0
+ BlastResetOldHook();
+#endif
+
+ return status;
+
+}
+
+/*
+ Status returned indicates a (potential) error. if not done, this is an error.
+*/
+#define PRINT_DEBUG_ASN 0
+#if PRINT_DEBUG_ASN
+static tmpi = 0;
+#endif
+
+static Boolean
+RealSubmitRequest(BlastNet3Hptr bl3hptr, BlastRequestPtr blreqp, BlastResponsePtr PNTR response, NetProgressCallback callback)
+
+{
+ AsnIoPtr asnin, asnout;
+ Boolean cancel, done;
+ BlastResponsePtr bllist, blresp, head;
+#if PRINT_DEBUG_ASN
+ AsnIoPtr asnout_test;
+ Char buf[1024];
+#endif
+
+ if (bl3hptr == NULL)
+ return FALSE;
+
+ if (response == NULL)
+ return FALSE;
+
+ asnout = bl3hptr->svcp->waip;
+ asnin = bl3hptr->svcp->raip;
+
+#if PRINT_DEBUG_ASN
+ sprintf(buf, "request.%d.out", ++tmpi);
+ asnout_test = AsnIoOpen(buf, "w");
+ BlastRequestAsnWrite(blreqp, asnout_test, NULL);
+#endif
+
+ done = BlastRequestAsnWrite(blreqp, asnout, NULL);
+ if (done == FALSE)
+ return FALSE;
+
+#if PRINT_DEBUG_ASN
+ AsnIoReset(asnout_test);
+ AsnIoClose(asnout_test);
+#endif
+ AsnIoReset(asnout);
+
+ head = NULL;
+ done = FALSE;
+ while (!done && (blresp = BlastResponseAsnRead(asnin, NULL)) != NULL)
+ {
+ switch (blresp->choice)
+ {
+ case BlastResponse_done:
+ done = TRUE;
+ blresp = BlastResponseFree(blresp);
+ break;
+
+ case BlastResponse_queued:
+ case BlastResponse_start:
+ case BlastResponse_progress:
+ if (callback)
+ {
+ if (callback(blresp, &cancel) == TRUE)
+ {
+ blresp = BlastResponseFree(blresp);
+ }
+ else
+ {
+ blresp = BlastResponseFree(blresp);
+ done = TRUE;
+ }
+ }
+ break;
+
+ case BlastResponse_init:
+ case BlastResponse_motd:
+ case BlastResponse_fini:
+ done = TRUE;
+
+ default:
+ if (head == NULL)
+ {
+ head = blresp;
+ bllist = blresp;
+ }
+ else
+ {
+ bllist->next = blresp;
+ bllist = bllist->next;
+ }
+ break;
+ }
+ }
+ *response = head;
+ return done;
+}
+
+
+static void BlastNetFetchCleanup (TNlmTls tls, VoidPtr ptr)
+{
+ BlastNetFetchStructPtr bnfsp = (BlastNetFetchStructPtr) ptr;
+
+ MemFree(bnfsp);
+ return;
+}
+
+/*
+ Checks the chain of BlastNetFetchStructPtr's for one
+ which belongs to the calling thread. If none is found,
+ NULL isreturned; otherwise the BlastNetFetchStructPtr is
+ returned.
+*/
+static BlastNetFetchStructPtr
+BlastNetFindFetchStruct(BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na)
+
+{
+ BlastNetFetchStructPtr bnfsp = NULL;
+
+ if (NlmTlsGetValue(blastnetfetch_tls, (VoidPtr *)(&bnfsp)))
+ {
+ if (bnfsp == NULL)
+ {
+ bnfsp = MemNew(sizeof(BlastNetFetchStruct));
+ bnfsp->dbname = StringSave(dbname);
+ bnfsp->is_prot = (is_na == TRUE) ? FALSE : TRUE;
+ bnfsp->bl3hp = bl3hp;
+ bnfsp->BlastNetFetchState = BLASTNET_INIT;
+ NlmTlsSetValue(&blastnetfetch_tls, bnfsp,
+ BlastNetFetchCleanup);
+ }
+ }
+
+ return bnfsp;
+}
+
+static Boolean BlastNetInit(BlastNetFetchStructPtr bnfsp)
+
+{
+ return TRUE;
+
+}
+
+
+/**********************************************************************
+
+ Fetches the Bioseq, based on the ordinal number of the
+ sequence in the database.
+
+************************************************************************/
+
+static Int2 LIBCALLBACK BlastNetBioseqFetchFunc(Pointer data)
+{
+ Boolean status;
+ Char buffer[64];
+ OMProcControlPtr ompcp;
+ ObjMgrProcPtr ompp;
+ OMUserDataPtr omdp;
+ SeqIdPtr sip, best_id;
+ BlastNetFetchStructPtr blfsp;
+ SeqEntryPtr sep;
+ BioseqPtr bsp, core_bsp;
+
+ ompcp = (OMProcControlPtr)data;
+ ompp = ompcp->proc;
+
+ blfsp = BlastNetFindFetchStruct(NULL, NULL, FALSE);
+
+ if (blfsp->BlastNetFetchState == BLASTNET_INIT)
+ {
+ status = BlastNetInit(blfsp);
+ if (status == FALSE)
+ return OM_MSG_RET_OK;
+ blfsp->BlastNetFetchState = BLASTNET_READY;
+ }
+
+ sip = (SeqIdPtr) (ompcp->input_data);
+
+ best_id = SeqIdFindBest(sip, SEQID_GI);
+
+ if (best_id == NULL)
+ {
+ core_bsp = BioseqFindCore(sip);
+ if (core_bsp)
+ best_id = SeqIdFindBest(core_bsp->id, SEQID_GI);
+ }
+
+ if (best_id == NULL)
+ return OM_MSG_RET_OK;
+
+
+ /* A BioseqPtr is returned by this function. */
+ bsp = PrivateBlastGetBioseq(blfsp->bl3hp, blfsp->dbname, best_id, blfsp->is_prot);
+ if (bsp == NULL)
+ {
+ SeqIdWrite(best_id, buffer, PRINTID_FASTA_LONG, sizeof(buffer));
+ ErrPost(CTX_UNKNOWN, 1, "Unable to retrieve %s", buffer);
+ return OM_MSG_RET_ERROR;
+ }
+ sep = SeqEntryNew();
+ sep->choice = 1;
+ sep->data.ptrvalue = bsp;
+ SeqMgrSeqEntry(SM_BIOSEQ, (Pointer)bsp, sep);
+ ompcp->output_data = (Pointer)bsp;
+ ompcp->output_entityID = ObjMgrGetEntityIDForChoice(sep);
+ omdp = ObjMgrAddUserData(ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
+
+ return OM_MSG_RET_DONE;
+}
+
+/*
+ Compare BlastNetFetchStructPtr structures with some traits. TRUE if identical, otherwise
+ FALSE.
+*/
+static Boolean
+BlastNetFetchCompare (BlastNetFetchStructPtr blfsp1, BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na)
+
+{
+ if (blfsp1 == NULL)
+ return FALSE;
+
+ if (StringCmp(blfsp1->dbname, dbname) != 0)
+ return FALSE;
+ if (blfsp1->is_prot == is_na)
+ return FALSE;
+ if (blfsp1->bl3hp != bl3hp)
+ return FALSE;
+
+ return TRUE;
+}
+
+/*********************************************************************
+
+ Enables the fetching. Initializes needed structures and calls
+ BlastNetInit.
+
+**********************************************************************/
+
+Boolean LIBCALL
+BlastNetBioseqFetchEnable(BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na, Boolean now)
+
+{
+ Boolean result;
+ BlastNetFetchStructPtr blfsp = NULL;
+ ObjMgrPtr omp;
+ ObjMgrProcPtr ompp;
+
+ /* check if already enabled ***/
+
+ omp = ObjMgrGet();
+ ompp = ObjMgrProcFind(omp, 0, "BlastNetBioseqFetch", OMPROC_FETCH);
+ if (ompp != NULL) /* already initialized */
+ {
+ blfsp = BlastNetFindFetchStruct(bl3hp, dbname, is_na);
+ if (BlastNetFetchCompare(blfsp, bl3hp, dbname, is_na) == FALSE)
+ {
+ blfsp->dbname = MemFree(blfsp->dbname);
+ blfsp->dbname = StringSave(dbname);
+ blfsp->is_prot = (is_na == TRUE) ? FALSE : TRUE;
+ blfsp->bl3hp = bl3hp;
+
+ }
+ }
+ else
+ {
+ blfsp = BlastNetFindFetchStruct(bl3hp, dbname, is_na);
+
+ ObjMgrProcLoad(OMPROC_FETCH, "BlastNetBioseqFetch",
+ "BlastNetBioseqFetch", OBJ_SEQID, 0,OBJ_BIOSEQ,0,
+ (Pointer)blfsp, BlastNetBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
+
+ blfsp->BlastNetFetchState = BLASTNET_INIT;
+ }
+
+ blfsp->ctr++; /* count number of enables */
+
+ if (blfsp->BlastNetFetchState == BLASTNET_READY)
+ {
+ return TRUE;
+ }
+
+ if (now)
+ {
+ result = BlastNetInit(blfsp);
+ if (! result)
+ {
+ return result;
+ }
+ blfsp->BlastNetFetchState = BLASTNET_READY;
+ }
+ else
+ {
+ blfsp->BlastNetFetchState = BLASTNET_INIT;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************
+*
+* BlastNetBioseqFetchDisable()
+*
+* Calls readdb_destruct if necessary to deallocate resources.
+*
+*****************************************************************************/
+void LIBCALL BlastNetBioseqFetchDisable(BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na)
+{
+ ObjMgrPtr omp;
+ ObjMgrProcPtr ompp;
+ BlastNetFetchStructPtr blfsp;
+
+ omp = ObjMgrGet();
+ ompp = ObjMgrProcFind(omp, 0, "BlastNetBioseqFetch", OMPROC_FETCH);
+ if (ompp == NULL) /* not initialized */
+ return;
+
+ blfsp = BlastNetFindFetchStruct(bl3hp, dbname, is_na);
+ if (! blfsp->ctr) /* no enables active */
+ return;
+
+ blfsp->ctr--;
+ if (blfsp->ctr) /* connection still pending */
+ return;
+
+ if (blfsp->BlastNetFetchState == BLASTNET_READY)
+ {
+ blfsp->BlastNetFetchState = BLASTNET_DISABLE; /* not active */
+ }
+
+ return;
+}
+
+/*
+ Runs a BLAST request and returns a SeqAlignPtr for formatting.
+ Note that the network connection must be established beforehand
+ (i.e., BlastNet3BlockPtr blnet should be initialized).
+*/
+SeqAlignPtr LIBCALL
+BlastBioseqNet(BlastNet3Hptr bl3hp, BioseqPtr bsp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback)
+
+{
+ return BlastBioseqNetCore(bl3hp, bsp, program, database, options, other_returns, error_returns, callback, NULL);
+}
+
+SeqAlignPtr LIBCALL
+BlastSeqLocNet(BlastNet3Hptr bl3hp, SeqLocPtr slp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback)
+
+{
+ return BlastSeqLocNetCore(bl3hp, slp, program, database, options, other_returns, error_returns, callback, NULL);
+}
+
+
+SeqAlignPtr LIBCALL
+BlastBioseqNetCore(BlastNet3Hptr bl3hp, BioseqPtr bsp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback, BLAST_MatrixPtr blast_matrix)
+
+{
+ BlastKABlkPtr ka_blk;
+ BlastDbinfoPtr dbinfo;
+ BlastMatrixPtr net_matrix;
+ BLAST_MatrixPtr matrix;
+ BlastNet3BlockPtr blnet;
+ Boolean options_allocated = FALSE;
+ CharPtr params_buffer;
+ Int2 status;
+ SeqAlignPtr seqalign = NULL;
+ TxDfDbInfoPtr txdbinfo;
+ ValNodePtr descr, mask;
+
+ if (bl3hp == NULL || bsp == NULL || program == NULL || database == NULL)
+ return NULL;
+
+ if (error_returns)
+ *error_returns = NULL;
+
+ if (other_returns)
+ *other_returns = NULL;
+
+ /* If no options, use default. */
+ if (options == NULL)
+ {
+ options = BLASTOptionNew(program, FALSE);
+ options_allocated = TRUE;
+ }
+
+ status = BLASTOptionValidateEx(options, program, error_returns);
+ if (status != 0)
+ { /* error messages in other_returns? */
+ return NULL;
+ }
+
+ blnet = BlastNet3BlockNew(program, database);
+ /*
+ Remove the Seq-descr as this is not needed for
+ BLASTing and the title often contains none-ASCII
+ characters. Keep the pointer and replace.
+ */
+ descr = bsp->descr;
+ bsp->descr = NULL;
+
+ blnet->bsp = bsp;
+ blnet->parameters = BlastOptionsToParameters(options);
+ if (options_allocated)
+ {
+ options = BLASTOptionDelete(options);
+ }
+
+ blnet->callback = callback;
+ blnet->bl3hptr = bl3hp;
+ blnet->blast_matrix = blast_matrix;
+
+ seqalign = BlastBioseq(blnet, error_returns);
+ if (other_returns)
+ {
+ *other_returns = NULL;
+ mask = BlastGetMaskedLoc(blnet);
+ if (mask)
+ ValNodeLink(other_returns, mask);
+ dbinfo = BlastGetDbInfo(blnet);
+ txdbinfo = NetDbinfo2TxDbinfo(dbinfo);
+ ValNodeAddPointer (other_returns, TXDBINFO, txdbinfo);
+ dbinfo = BlastDbinfoFree(dbinfo);
+ params_buffer = BlastGetParameterBuffer(blnet);
+ ValNodeAddPointer(other_returns, TXPARAMETERS, params_buffer);
+ ka_blk = BlastGetKaParams(blnet, FALSE);
+ if (ka_blk)
+ ValNodeAddPointer (other_returns, TXKABLK_NOGAP, ka_blk);
+ ka_blk = BlastGetKaParams(blnet, TRUE);
+ if (ka_blk)
+ ValNodeAddPointer (other_returns, TXKABLK_GAP, ka_blk);
+ net_matrix = NetBlastGetMatrix(blnet);
+ matrix = BlastNetMatrixToBlastMatrix(net_matrix);
+ if (matrix)
+ ValNodeAddPointer (other_returns, TXMATRIX, matrix);
+ }
+
+ bsp->descr = descr;
+
+ return seqalign;
+}
+
+SeqAlignPtr LIBCALL
+BlastSeqLocNetCore(BlastNet3Hptr bl3hp, SeqLocPtr slp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback, BLAST_MatrixPtr blast_matrix)
+
+{
+ SeqAlignPtr seqalign = NULL;
+ ValNodePtr vnp;
+
+ SeqPortPtr spp;
+ Bioseq bs;
+ BioseqPtr bsp = &bs;
+ Int4 the_len, res_index;
+ Int2 residue;
+ ByteStorePtr bp;
+ SeqLocPtr whole_slp;
+ ValNodePtr mask_loc;
+
+ /* get Bioseq by SeqLoc */
+
+
+ the_len = SeqLocLen(slp);
+ bp = BSNew((Uint4)the_len);
+
+ if (ISA_na(SeqLocMol(slp)))
+ spp = SeqPortNewByLoc (slp, Seq_code_iupacna);
+ else
+ spp = SeqPortNewByLoc (slp, Seq_code_iupacaa);
+
+ MemSet((Pointer)bsp, 0, sizeof(Bioseq));
+ bsp->length = (Int4)the_len;
+ bsp->repr = Seq_repr_raw;
+ bsp->mol = (Uint1) SeqLocMol(slp);
+ bsp->id = SeqLocId(slp);
+
+ if (ISA_na(bsp->mol))
+ bsp->seq_data_type = Seq_code_iupacna;
+ else
+ bsp->seq_data_type = Seq_code_iupacaa;
+
+ SeqPortSeek(spp, 0, SEEK_SET);
+ BSSeek(bp, 0, SEEK_SET);
+ for (res_index = 0; res_index < the_len; res_index++)
+ {
+ residue = SeqPortGetResidue(spp);
+ BSPutByte(bp, residue);
+ }
+ bsp->seq_data = bp;
+
+ SeqPortFree(spp);
+
+ /* perform search */
+
+ seqalign = BlastBioseqNet(bl3hp, bsp, program, database, options,
+ other_returns, error_returns, callback);
+
+ /* offset the alignment */
+
+ AdjustOffSetsInSeqAlign(seqalign, slp, NULL);
+
+ if (other_returns) {
+ mask_loc = NULL;
+ for (vnp=*other_returns; vnp; vnp = vnp->next)
+ {
+ switch (vnp->choice) {
+ case SEQLOC_MASKING_NOTSET:
+ case SEQLOC_MASKING_PLUS1:
+ case SEQLOC_MASKING_PLUS2:
+ case SEQLOC_MASKING_PLUS3:
+ case SEQLOC_MASKING_MINUS1:
+ case SEQLOC_MASKING_MINUS2:
+ case SEQLOC_MASKING_MINUS3:
+ ValNodeAddPointer(&mask_loc, vnp->choice, vnp->data.ptrvalue);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* adjust offset in mask_loc */
+
+ if (mask_loc && slp) {
+ SeqLocPtr maskslp;
+ SeqIntPtr masksip;
+ Int4 offset;
+ ValNodePtr vnp;
+
+ whole_slp = NULL;
+
+ ValNodeAddPointer(&whole_slp, SEQLOC_WHOLE, SeqIdDup(SeqIdFindBest(bsp->id, SEQID_GI)));
+
+ offset = GetOffsetInLoc(slp, whole_slp, SEQLOC_START);
+
+ for (vnp = mask_loc; vnp; vnp = vnp->next) {
+
+ for (maskslp = (SeqLocPtr) vnp->data.ptrvalue; maskslp; maskslp = maskslp->next) {
+ masksip = (SeqIntPtr) maskslp->data.ptrvalue;
+
+ masksip->from += offset;
+ masksip->to += offset;
+ }
+ }
+ }
+ }
+
+ return seqalign;
+}
+
+#if EA
+FILE *global_fp;
+#endif
+
+static Boolean LIBCALLBACK
+callback (BlastResponsePtr brp, Boolean PNTR cancel)
+
+{
+
+#if EA
+ fprintf(global_fp, ".");
+ fflush(global_fp);
+#endif
+ return TRUE;
+}
+
+/*
+ Formats a 'traditional' BLAST report.
+*/
+
+Boolean LIBCALL
+TraditionalBlastReport(BioseqPtr bsp, BLAST_OptionsBlkPtr options, BlastNet3Hptr bl3hp, CharPtr program, CharPtr database, Boolean html, FILE *outfp, Boolean verbose, Uint4 print_options, Uint4 align_options, Int4 number_of_descriptions, Int4 number_of_alignments, Int4Ptr number_of_hits)
+
+{
+ BlastDbinfoPtr dbinfo;
+ BLAST_KarlinBlkPtr ka_params=NULL, ka_params_gap=NULL;
+ BlastPruneSapStructPtr prune;
+ BLAST_MatrixPtr matrix;
+ Boolean query_is_na, db_is_na;
+ CharPtr params_buffer=NULL;
+ Int4 number_of_hits_private=0;
+ SeqAlignPtr seqalign;
+ SeqAnnotPtr seqannot=NULL;
+ TxDfDbInfoPtr tx_dbinfo=NULL, tx_dbinfo_head;
+ ValNodePtr mask_loc, other_returns, error_returns, vnp;
+ Uint1 align_type;
+ Uint1 f_order[FEATDEF_ANY], g_order[FEATDEF_ANY];
+
+ MemSet((Pointer)(g_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
+ MemSet((Pointer)(f_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
+
+ if (bsp == NULL || bl3hp == NULL || program == NULL || database == NULL || outfp == NULL)
+ return FALSE;
+
+#if EA
+NlmMutexLockEx(&formating_mutex);
+#endif
+
+ align_type = BlastGetTypes(program, &query_is_na, &db_is_na);
+#if EA
+ global_fp = outfp;
+#endif
+
+ init_buff_ex(85);
+ dbinfo = BlastRequestDbInfo(bl3hp, database, !db_is_na);
+ if (dbinfo)
+ PrintDbInformationBasic(database, !db_is_na, 70, dbinfo->definition, dbinfo->number_seqs, dbinfo->total_length, outfp, html);
+ dbinfo = BlastDbinfoFree(dbinfo);
+ free_buff();
+#if EA
+NlmMutexUnlock(formating_mutex);
+#endif
+
+ fprintf(outfp, "Searching");
+
+ seqalign = BlastBioseqNet(bl3hp, bsp, program, database, options, &other_returns, &error_returns, callback);
+
+ fprintf(outfp, "done");
+
+ BlastErrorPrintExtra(error_returns, TRUE, outfp);
+
+ mask_loc = NULL;
+ for (vnp=other_returns; vnp; vnp = vnp->next)
+ {
+ switch (vnp->choice) {
+ case TXDBINFO:
+ tx_dbinfo = vnp->data.ptrvalue;
+ break;
+ case TXKABLK_NOGAP:
+ ka_params = vnp->data.ptrvalue;
+ break;
+ case TXKABLK_GAP:
+ ka_params_gap = vnp->data.ptrvalue;
+ break;
+ case TXPARAMETERS:
+ params_buffer = vnp->data.ptrvalue;
+ break;
+ case TXMATRIX:
+ matrix = vnp->data.ptrvalue;
+ break;
+ case SEQLOC_MASKING_NOTSET:
+ case SEQLOC_MASKING_PLUS1:
+ case SEQLOC_MASKING_PLUS2:
+ case SEQLOC_MASKING_PLUS3:
+ case SEQLOC_MASKING_MINUS1:
+ case SEQLOC_MASKING_MINUS2:
+ case SEQLOC_MASKING_MINUS3:
+ ValNodeAddPointer(&mask_loc, vnp->choice, vnp->data.ptrvalue);
+ break;
+ default:
+ break;
+ }
+ }
+
+#if EA
+NlmMutexLockEx(&formating_mutex);
+#endif
+
+ if (seqalign)
+ {
+ seqannot = SeqAnnotNew();
+ seqannot->type = 2;
+ AddAlignInfoToSeqAnnot(seqannot, align_type);
+ seqannot->data = seqalign;
+ prune = BlastPruneHitsFromSeqAlign(seqalign, number_of_descriptions, NULL);
+ ObjMgrSetHold();
+ init_buff_ex(85);
+ PrintDefLinesFromSeqAlign(prune->sap, 80, outfp, print_options, FIRST_PASS, NULL);
+ free_buff();
+
+ prune = BlastPruneHitsFromSeqAlign(seqalign, number_of_alignments, prune);
+ seqannot->data = prune->sap;
+ if (align_options & TXALIGN_MASTER)
+ ShowTextAlignFromAnnot(seqannot, 60, outfp, f_order, g_order, align_options, NULL, mask_loc, NULL);
+ else
+ ShowTextAlignFromAnnot(seqannot, 60, outfp, f_order, g_order, align_options, NULL, mask_loc, FormatScoreFunc);
+ seqannot->data = seqalign;
+ number_of_hits_private = prune->original_number;
+ prune = BlastPruneSapStructDestruct(prune);
+ ObjMgrClearHold();
+ }
+
+ if (verbose)
+ {
+ init_buff_ex(85);
+ tx_dbinfo_head = tx_dbinfo;
+ while (tx_dbinfo)
+ {
+ PrintDbReport(tx_dbinfo, 70, outfp);
+ tx_dbinfo = tx_dbinfo->next;
+ }
+ tx_dbinfo_head = TxDfDbInfoDestruct(tx_dbinfo_head);
+
+ if (ka_params)
+ {
+ PrintKAParameters(ka_params->Lambda, ka_params->K, ka_params->H, 70, outfp, FALSE);
+ MemFree(ka_params);
+ }
+
+ if (ka_params_gap)
+ {
+ PrintKAParameters(ka_params_gap->Lambda, ka_params_gap->K, ka_params_gap->H, 70, outfp, TRUE);
+ MemFree(ka_params_gap);
+ }
+
+ PrintTildeSepLines(params_buffer, 70, outfp);
+ MemFree(params_buffer);
+ free_buff();
+ }
+
+#if EA
+NlmMutexUnlock(formating_mutex);
+#endif
+ if (seqannot)
+ seqannot = SeqAnnotFree(seqannot);
+
+ if (number_of_hits)
+ *number_of_hits = number_of_hits_private;
+
+ return TRUE;
+}
+
+Boolean LIBCALL
+TraditionalBlastReportLoc(SeqLocPtr slp, BLAST_OptionsBlkPtr options, BlastNet3Hptr bl3hp, CharPtr program, CharPtr database, Boolean html, FILE *outfp, Boolean verbose, Uint4 print_options, Uint4 align_options, Int4 number_of_descriptions, Int4 number_of_alignments, Int4Ptr number_of_hits)
+
+{
+ BlastDbinfoPtr dbinfo;
+ BLAST_KarlinBlkPtr ka_params=NULL, ka_params_gap=NULL;
+ BlastPruneSapStructPtr prune;
+ BLAST_MatrixPtr matrix;
+ Boolean query_is_na, db_is_na;
+ CharPtr params_buffer=NULL;
+ SeqAlignPtr seqalign;
+ SeqAnnotPtr seqannot=NULL;
+ TxDfDbInfoPtr tx_dbinfo=NULL, tx_dbinfo_head;
+ ValNodePtr mask_loc, other_returns, error_returns, vnp;
+ Uint1 align_type;
+ Uint1 f_order[FEATDEF_ANY], g_order[FEATDEF_ANY];
+
+ MemSet((Pointer)(g_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
+ MemSet((Pointer)(f_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
+
+
+ if (slp == NULL || bl3hp == NULL || program == NULL || database == NULL || outfp == NULL)
+ return FALSE;
+
+ align_type = BlastGetTypes(program, &query_is_na, &db_is_na);
+#if EA
+ global_fp = outfp;
+#endif
+
+ init_buff_ex(85);
+ dbinfo = BlastRequestDbInfo(bl3hp, database, !db_is_na);
+ if (dbinfo)
+ PrintDbInformationBasic(database, !db_is_na, 70, dbinfo->definition, dbinfo->number_seqs, dbinfo->total_length, outfp, html);
+ dbinfo = BlastDbinfoFree(dbinfo);
+ free_buff();
+
+ fprintf(outfp, "Searching");
+
+ seqalign = BlastSeqLocNet(bl3hp, slp, program, database, options, &other_returns, &error_returns, callback);
+
+ fprintf(outfp, "done");
+
+ mask_loc = NULL;
+
+ BlastErrorPrintExtra(error_returns, TRUE, outfp);
+
+ for (vnp=other_returns; vnp; vnp = vnp->next)
+ {
+ switch (vnp->choice) {
+ case TXDBINFO:
+ tx_dbinfo = vnp->data.ptrvalue;
+ break;
+ case TXKABLK_NOGAP:
+ ka_params = vnp->data.ptrvalue;
+ break;
+ case TXKABLK_GAP:
+ ka_params_gap = vnp->data.ptrvalue;
+ break;
+ case TXPARAMETERS:
+ params_buffer = vnp->data.ptrvalue;
+ break;
+ case TXMATRIX:
+ matrix = vnp->data.ptrvalue;
+ break;
+ case SEQLOC_MASKING_NOTSET:
+ case SEQLOC_MASKING_PLUS1:
+ case SEQLOC_MASKING_PLUS2:
+ case SEQLOC_MASKING_PLUS3:
+ case SEQLOC_MASKING_MINUS1:
+ case SEQLOC_MASKING_MINUS2:
+ case SEQLOC_MASKING_MINUS3:
+#if 1
+ ValNodeAddPointer(&mask_loc, vnp->choice, vnp->data.ptrvalue);
+#endif
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (seqalign)
+ {
+
+ seqannot = SeqAnnotNew();
+ seqannot->type = 2;
+ AddAlignInfoToSeqAnnot(seqannot, align_type);
+ seqannot->data = seqalign;
+ prune = BlastPruneHitsFromSeqAlign(seqalign, number_of_descriptions, NULL);
+ ObjMgrSetHold();
+ init_buff_ex(85);
+ PrintDefLinesFromSeqAlign(prune->sap, 80, outfp, print_options, FIRST_PASS, NULL);
+ free_buff();
+
+ prune = BlastPruneHitsFromSeqAlign(seqalign, number_of_alignments, prune);
+ seqannot->data = prune->sap;
+
+ if (align_options & TXALIGN_MASTER)
+ ShowTextAlignFromAnnot(seqannot, 60, outfp, f_order, g_order, align_options, NULL, mask_loc, NULL);
+ else
+ ShowTextAlignFromAnnot(seqannot, 60, outfp, f_order, g_order, align_options, NULL, mask_loc, FormatScoreFunc);
+ seqannot->data = seqalign;
+ prune = BlastPruneSapStructDestruct(prune);
+ ObjMgrClearHold();
+ }
+
+ if (verbose)
+ {
+ init_buff_ex(85);
+ tx_dbinfo_head = tx_dbinfo;
+ while (tx_dbinfo)
+ {
+ PrintDbReport(tx_dbinfo, 70, outfp);
+ tx_dbinfo = tx_dbinfo->next;
+ }
+ tx_dbinfo_head = TxDfDbInfoDestruct(tx_dbinfo_head);
+
+ if (ka_params)
+ {
+ PrintKAParameters(ka_params->Lambda, ka_params->K, ka_params->H, 70, outfp, FALSE);
+ MemFree(ka_params);
+ }
+
+ if (ka_params_gap)
+ {
+ PrintKAParameters(ka_params_gap->Lambda, ka_params_gap->K, ka_params_gap->H, 70, outfp, TRUE);
+ MemFree(ka_params_gap);
+ }
+
+ PrintTildeSepLines(params_buffer, 70, outfp);
+ MemFree(params_buffer);
+ free_buff();
+ }
+
+ if (seqannot)
+ seqannot = SeqAnnotFree(seqannot);
+
+
+ return TRUE;
+}
+
+
+/*
+ Converst the BlastParametersPtr (used by network service) to
+ BLAST_OptionsBlkPtr (used by blast).
+*/
+
+BLAST_OptionsBlkPtr
+parametersToOptions (BlastParametersPtr parameters, CharPtr program, ValNodePtr PNTR error_return)
+
+{
+ BLAST_OptionsBlkPtr options;
+ Int2 status;
+
+ if (program == NULL)
+ return NULL;
+
+ if (parameters == NULL)
+ {
+ options = BLASTOptionNew(program, TRUE);
+ }
+ else
+ {
+ options = BLASTOptionNew(program, (Boolean) parameters->gapped_alignment);
+ options->threshold_first = parameters->first_threshold;
+ options->threshold_second = parameters->second_threshold;
+ if (parameters->Cutoff_cutoff)
+ {
+ if (parameters->Cutoff_cutoff->choice == Cutoff_cutoff_evalue)
+ options->expect_value = parameters->Cutoff_cutoff->data.realvalue;
+ else if (parameters->Cutoff_cutoff->choice == Cutoff_cutoff_score)
+ options->cutoff_s = parameters->Cutoff_cutoff->data.intvalue;
+ }
+ if (parameters->Cutoff2_cutoff2)
+ {
+ if (parameters->Cutoff2_cutoff2->choice == Cutoff2_cutoff2_evalue)
+ options->e2 = parameters->Cutoff2_cutoff2->data.realvalue;
+ else if (parameters->Cutoff2_cutoff2->choice == Cutoff2_cutoff2_score)
+ options->cutoff_s2 = parameters->Cutoff2_cutoff2->data.intvalue;
+ }
+ /* compensates for client not providing this. Remove this at some point? */
+ if (parameters->hitlist_size != 0)
+ options->hitlist_size = parameters->hitlist_size;
+ options->penalty = parameters->nucl_penalty;
+ options->reward = parameters->nucl_reward;
+ options->gap_open = parameters->gap_open;
+ options->gap_extend = parameters->gap_extend;
+ /* compensates for client not providing this. Remove this at some point? */
+ if (parameters->genetic_code != 0)
+ options->genetic_code = parameters->genetic_code;
+ /* compensates for client not providing this. Remove this at some point? */
+ if (parameters->db_genetic_code != 0)
+ options->db_genetic_code = parameters->db_genetic_code;
+
+ options->filter = parameters->low_complexity_filtering;
+ options->ethresh = parameters->ethresh;
+ options->maxNumPasses = parameters->max_num_passes;
+ options->pseudoCountConst = parameters->pseudo_count_const;
+
+ options->gifile = StringSave(parameters->gifile);
+ options->gilist = parameters->gilist;
+ if (parameters->matrix)
+ options->matrix = StringSave(parameters->matrix);
+ if (parameters->filter_string)
+ options->filter_string = StringSave(parameters->filter_string);
+ if (parameters->entrez_query)
+ options->entrez_query = StringSave(parameters->entrez_query);
+ /* compensates for client not providing this. Remove this at some point? */
+ if (parameters->word_size)
+ options->wordsize = parameters->word_size;
+ }
+
+ if (status = BLASTOptionValidateEx(options, program, error_return)) {
+ return NULL;
+ }
+
+ return options;
+}
diff --git a/network/blast3/client/netblap3.h b/network/blast3/client/netblap3.h
new file mode 100644
index 00000000..127635c1
--- /dev/null
+++ b/network/blast3/client/netblap3.h
@@ -0,0 +1,183 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: netblap3.h
+*
+* Author: Tom Madden
+*
+* Version Creation Date: 05/12/97
+*
+* File Description:
+* Application Programming Interface (API) for BLAST network server
+*
+* RCS Modification History:
+* $Log: netblap3.h,v $
+* Revision 1.11 1999/01/12 21:05:58 victorov
+* server will now report an error if the ni-queue if full
+*
+* Revision 1.10 1998/12/14 19:38:31 egorov
+* add file #defines
+*
+* Revision 1.9 1998/09/22 16:14:07 egorov
+* Add prototype for parametersToOptions()
+*
+* Revision 1.8 1998/09/01 20:17:04 madden
+* Fixed uninitialzed problem in BlastNetBioseqFetchDisable, changed prototype
+*
+* Revision 1.7 1998/05/08 21:41:47 vakatov
+* use NetProgressCallback in the function prototypes
+*
+* Revision 1.6 1998/05/08 20:56:23 madden
+* Fix PC compile warnings, rename callback
+*
+* Revision 1.5 1998/04/23 14:18:42 egorov
+* Add number_of_hits parameter to TraditionalBlastReportLoc
+*
+* Revision 1.4 1998/04/22 18:10:07 egorov
+* Add support for SeqLoc to blastcl3
+*
+* Revision 1.3 1998/04/16 19:35:32 madden
+* Added Int4Ptr arg to TraditionalBlastReport specifying the numbers of hits
+*
+* Revision 1.2 1997/11/25 14:43:36 madden
+* Changes to allow iterative searches
+*
+* Revision 1.1 1997/10/08 19:27:22 madden
+* Network support for gapped blast
+*
+*/
+
+#ifndef _NETBLAP3_
+#define _NETBLAP3_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ncbi.h>
+#include <sequtil.h>
+#include <blstspc.h>
+#include <objblst3.h>
+#include <ni_types.h>
+#include <blastdef.h>
+#include <blastpri.h>
+
+typedef Boolean (LIBCALLBACK *NetProgressCallback) PROTO((BlastResponsePtr response, Boolean PNTR cancel));
+
+
+typedef struct _blastnet3h {
+ NI_HandPtr svcp;
+} BlastNet3H, PNTR BlastNet3Hptr;
+
+typedef struct _blastnet3_block {
+ BioseqPtr bsp; /* The query. */
+ Uint2 prog_type; /* blast[npx], tblast[nx] */
+ CharPtr dbname; /* Name of database. */
+ BlastParametersPtr parameters;
+ BlastResponsePtr response; /* Response from server. */
+ SeqLocPtr mask; /* Sequence to be masked */
+ BlastNet3Hptr bl3hptr; /* BlastNet 3 handler returned from BlastInit. */
+ NetProgressCallback callback;
+ BLAST_MatrixPtr blast_matrix; /* Matrix to be sent to server. */
+} BlastNet3Block, PNTR BlastNet3BlockPtr;
+
+/*
+BlastNet3Hptr PNTR bl3hpp must not be NULL when this is called,
+it must be saved and used to call BlastBioseq, as well as BlastFini.
+BlastResponsePtr PNTR resp contains a response pointer of type BlastResponse_init.
+This function is MT-safe.
+*/
+
+Boolean LIBCALL BlastInit PROTO((CharPtr program_name, BlastNet3Hptr PNTR bl3hpp, BlastResponsePtr PNTR resp));
+
+/*
+The BlastNet3Hptr returned by BlastInitMt must be passed in.
+*/
+
+Boolean LIBCALL BlastFini PROTO((BlastNet3Hptr bl3hptr));
+
+/*
+ Function to get a Bioseq for a give SeqIdPtr. Should be used
+ for BioseqFetch function.
+*/
+
+BioseqPtr LIBCALL BlastGetBioseq PROTO((BlastNet3BlockPtr blnet3blkptr, SeqIdPtr sip));
+
+/*
+ Function to submit blast queries.
+
+*/
+
+SeqAlignPtr LIBCALL BlastBioseq PROTO ((BlastNet3BlockPtr blnet3blkptr, ValNodePtr *error_returns));
+
+BlastNet3BlockPtr LIBCALL BlastNet3BlockNew PROTO((CharPtr program, CharPtr dbname));
+
+BlastNet3BlockPtr LIBCALL BlastNet3BlockDestruct PROTO((BlastNet3BlockPtr blnet));
+
+CharPtr LIBCALL Blast3GetMotd PROTO((BlastNet3Hptr bl3hptr));
+
+SeqLocPtr LIBCALL BlastGetMaskedLoc PROTO((BlastNet3BlockPtr blnet3blkptr));
+
+Boolean LIBCALL BlastNetBioseqFetchEnable PROTO((BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na, Boolean now));
+
+void LIBCALL BlastNetBioseqFetchDisable PROTO((BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na));
+
+BlastParametersPtr LIBCALL BlastOptionsToParameters PROTO((BLAST_OptionsBlkPtr options));
+
+
+CharPtr LIBCALL BlastGetParameterBuffer PROTO((BlastNet3BlockPtr blnet3blkptr));
+
+BlastKABlkPtr LIBCALL BlastGetKaParams PROTO((BlastNet3BlockPtr blnet3blkptr, Boolean gapped));
+
+BlastDbinfoPtr LIBCALL BlastRequestDbInfo PROTO((BlastNet3Hptr bl3hp, CharPtr database, Boolean is_prot));
+
+BlastDbinfoPtr LIBCALL BlastGetDbInfo PROTO((BlastNet3BlockPtr blnet3blkptr));
+
+TxDfDbInfoPtr LIBCALL NetDbinfo2TxDbinfo PROTO((BlastDbinfoPtr net_dbinfo));
+
+Boolean LIBCALL TraditionalBlastReport PROTO((BioseqPtr bsp, BLAST_OptionsBlkPtr options, BlastNet3Hptr bl3hp, CharPtr program, CharPtr database, Boolean html, FILE *outfp, Boolean verbose, Uint4 print_options, Uint4 align_options, Int4 number_of_descriptions, Int4 number_of_alignments, Int4Ptr number_of_hits));
+
+Boolean LIBCALL TraditionalBlastReportLoc PROTO((SeqLocPtr slp, BLAST_OptionsBlkPtr options, BlastNet3Hptr bl3hp, CharPtr program, CharPtr database, Boolean html, FILE *outfp, Boolean verbose, Uint4 print_options, Uint4 align_options, Int4 number_of_descriptions, Int4 number_of_alignments, Int4Ptr number_of_hits));
+
+SeqAlignPtr LIBCALL BlastBioseqNet PROTO((BlastNet3Hptr bl3hp, BioseqPtr bsp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback));
+
+SeqAlignPtr LIBCALL BlastSeqLocNet PROTO((BlastNet3Hptr bl3hp, SeqLocPtr slp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback));
+
+SeqAlignPtr LIBCALL BlastBioseqNetCore PROTO((BlastNet3Hptr bl3hp, BioseqPtr bsp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback, BLAST_MatrixPtr blast_matrix));
+
+SeqAlignPtr LIBCALL BlastSeqLocNetCore PROTO((BlastNet3Hptr bl3hp, SeqLocPtr slp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback, BLAST_MatrixPtr blast_matrix));
+
+BLAST_MatrixPtr LIBCALL BlastNetMatrixToBlastMatrix PROTO((BlastMatrixPtr net_matrix));
+
+BlastMatrixPtr LIBCALL BlastMatrixToBlastNetMatrix PROTO((BLAST_MatrixPtr matrix));
+
+BLAST_OptionsBlkPtr parametersToOptions (BlastParametersPtr parameters, CharPtr program,
+ ValNodePtr PNTR error_returns);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETBLAP3 */
diff --git a/network/blast3/client/objblst3.c b/network/blast3/client/objblst3.c
new file mode 100644
index 00000000..870d3057
--- /dev/null
+++ b/network/blast3/client/objblst3.c
@@ -0,0 +1,3524 @@
+#include <asn.h>
+
+#define NLM_GENERATED_CODE_PROTO
+
+#include <blastpat.h>
+#include <objblst3.h>
+
+static Boolean loaded = FALSE;
+
+#include <blstspc.h>
+
+#ifndef NLM_EXTERN_LOADS
+#define NLM_EXTERN_LOADS {}
+#endif
+
+NLM_EXTERN Boolean LIBCALL
+objblst3AsnLoad(void)
+{
+
+ if ( ! loaded) {
+ NLM_EXTERN_LOADS
+
+ if ( ! AsnLoad ())
+ return FALSE;
+ loaded = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/**************************************************
+* Generated object loaders for Module NCBI-Blast
+* Generated using ASNCODE Revision: 6.0 at Dec 21, 1998 9:44 AM
+*
+**************************************************/
+
+
+/**************************************************
+*
+* BlastSearchNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastSearchPtr LIBCALL
+BlastSearchNew(void)
+{
+ BlastSearchPtr ptr = MemNew((size_t) sizeof(BlastSearch));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastSearchFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastSearchPtr LIBCALL
+BlastSearchFree(BlastSearchPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ BioseqFree(ptr -> query);
+ MemFree(ptr -> database);
+ BlastParametersFree(ptr -> parameters);
+ SeqLocFree(ptr -> mask);
+ BlastMatrixFree(ptr -> matrix);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastSearchAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastSearchPtr LIBCALL
+BlastSearchAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastSearchPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastSearch ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_SEARCH);
+ } else {
+ atp = AsnLinkType(orig, BLAST_SEARCH);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastSearchNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_SEARCH_program) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> program = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_SEARCH_query) {
+ ptr -> query = BioseqAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_SEARCH_database) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> database = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_SEARCH_parameters) {
+ ptr -> parameters = BlastParametersAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_SEARCH_mask) {
+ ptr -> mask = SeqLocAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_SEARCH_matrix) {
+ ptr -> matrix = BlastMatrixAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastSearchFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastSearchAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastSearchAsnWrite(BlastSearchPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_SEARCH); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> program;
+ retval = AsnWrite(aip, BLAST_SEARCH_program, &av);
+ if (ptr -> query != NULL) {
+ if ( ! BioseqAsnWrite(ptr -> query, aip, BLAST_SEARCH_query)) {
+ goto erret;
+ }
+ }
+ if (ptr -> database != NULL) {
+ av.ptrvalue = ptr -> database;
+ retval = AsnWrite(aip, BLAST_SEARCH_database, &av);
+ }
+ if (ptr -> parameters != NULL) {
+ if ( ! BlastParametersAsnWrite(ptr -> parameters, aip, BLAST_SEARCH_parameters)) {
+ goto erret;
+ }
+ }
+ if (ptr -> mask != NULL) {
+ if ( ! SeqLocAsnWrite(ptr -> mask, aip, BLAST_SEARCH_mask)) {
+ goto erret;
+ }
+ }
+ if (ptr -> matrix != NULL) {
+ if ( ! BlastMatrixAsnWrite(ptr -> matrix, aip, BLAST_SEARCH_matrix)) {
+ goto erret;
+ }
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastRequestFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastRequestPtr LIBCALL
+BlastRequestFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case BlastRequest_init:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case BlastRequest_db_info_specific:
+ BlastDbinfoGetFree(anp -> data.ptrvalue);
+ break;
+ case BlastRequest_matrix_get:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case BlastRequest_search:
+ BlastSearchFree(anp -> data.ptrvalue);
+ break;
+ case BlastRequest_db_seq_get:
+ BlastSeqIdFree(anp -> data.ptrvalue);
+ break;
+ case BlastRequest_db_redundant_ids_get:
+ BlastSeqIdFree(anp -> data.ptrvalue);
+ break;
+ case BlastRequest_db_redundant_descr_get:
+ BlastSeqIdFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* BlastRequestAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastRequestPtr LIBCALL
+BlastRequestAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastRequest ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_REQUEST);
+ } else {
+ atp = AsnLinkType(orig, BLAST_REQUEST); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == BLAST_REQUEST_init) {
+ choice = BlastRequest_init;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST_REQUEST_motd) {
+ choice = BlastRequest_motd;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == BLAST_REQUEST_db_info) {
+ choice = BlastRequest_db_info;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == BLAST_REQUEST_db_info_specific) {
+ choice = BlastRequest_db_info_specific;
+ func = (AsnReadFunc) BlastDbinfoGetAsnRead;
+ }
+ else if (atp == BLAST_REQUEST_matrix_get) {
+ choice = BlastRequest_matrix_get;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST_REQUEST_search) {
+ choice = BlastRequest_search;
+ func = (AsnReadFunc) BlastSearchAsnRead;
+ }
+ else if (atp == BLAST_REQUEST_db_seq_get) {
+ choice = BlastRequest_db_seq_get;
+ func = (AsnReadFunc) BlastSeqIdAsnRead;
+ }
+ else if (atp == BLAST_REQUEST_db_redundant_ids_get) {
+ choice = BlastRequest_db_redundant_ids_get;
+ func = (AsnReadFunc) BlastSeqIdAsnRead;
+ }
+ else if (atp == BLAST_REQUEST_db_redundant_descr_get) {
+ choice = BlastRequest_db_redundant_descr_get;
+ func = (AsnReadFunc) BlastSeqIdAsnRead;
+ }
+ else if (atp == BLAST_REQUEST_fini) {
+ choice = BlastRequest_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BlastRequestAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastRequestAsnWrite(BlastRequestPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST_REQUEST); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case BlastRequest_init:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST_REQUEST_init, &av);
+ break;
+ case BlastRequest_motd:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, BLAST_REQUEST_motd, &av);
+ break;
+ case BlastRequest_db_info:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, BLAST_REQUEST_db_info, &av);
+ break;
+ case BlastRequest_db_info_specific:
+ writetype = BLAST_REQUEST_db_info_specific;
+ func = (AsnWriteFunc) BlastDbinfoGetAsnWrite;
+ break;
+ case BlastRequest_matrix_get:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST_REQUEST_matrix_get, &av);
+ break;
+ case BlastRequest_search:
+ writetype = BLAST_REQUEST_search;
+ func = (AsnWriteFunc) BlastSearchAsnWrite;
+ break;
+ case BlastRequest_db_seq_get:
+ writetype = BLAST_REQUEST_db_seq_get;
+ func = (AsnWriteFunc) BlastSeqIdAsnWrite;
+ break;
+ case BlastRequest_db_redundant_ids_get:
+ writetype = BLAST_REQUEST_db_redundant_ids_get;
+ func = (AsnWriteFunc) BlastSeqIdAsnWrite;
+ break;
+ case BlastRequest_db_redundant_descr_get:
+ writetype = BLAST_REQUEST_db_redundant_descr_get;
+ func = (AsnWriteFunc) BlastSeqIdAsnWrite;
+ break;
+ case BlastRequest_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, BLAST_REQUEST_fini, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* BlastResponseFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastResponsePtr LIBCALL
+BlastResponseFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case BlastResponse_init:
+ BlastVersionFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_motd:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_error:
+ BlastErrorFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_db_seq_get:
+ BioseqFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_db_redundant_ids_get:
+ AsnGenericChoiceSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) SeqIdFree);
+ break;
+ case BlastResponse_db_redundant_descr_get:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BlastDeflineFree);
+ break;
+ case BlastResponse_db_info:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) BlastDbinfoFree);
+ break;
+ case BlastResponse_db_info_specific:
+ BlastDbinfoFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_matrix:
+ BlastMatrixFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_alignment:
+ SeqAlignSetFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_mask:
+ BlastMaskFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_kablk:
+ BlastKABlkFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_parameters:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_queued:
+ BlastQueuedFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_start:
+ BlastProgressFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_progress:
+ BlastProgressFree(anp -> data.ptrvalue);
+ break;
+ case BlastResponse_done:
+ BlastProgressFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* BlastResponseAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastResponsePtr LIBCALL
+BlastResponseAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastResponse ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_RESPONSE);
+ } else {
+ atp = AsnLinkType(orig, BLAST_RESPONSE); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == BLAST_RESPONSE_init) {
+ choice = BlastResponse_init;
+ func = (AsnReadFunc) BlastVersionAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_motd) {
+ choice = BlastResponse_motd;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST_RESPONSE_error) {
+ choice = BlastResponse_error;
+ func = (AsnReadFunc) BlastErrorAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_db_seq_get) {
+ choice = BlastResponse_db_seq_get;
+ func = (AsnReadFunc) BioseqAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_db_redundant_ids_get) {
+ choice = BlastResponse_db_redundant_ids_get;
+ anp -> data.ptrvalue =
+ AsnGenericChoiceSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) SeqIdAsnRead, (AsnOptFreeFunc) SeqIdFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST_RESPONSE_db_redundant_descr_get) {
+ choice = BlastResponse_db_redundant_descr_get;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BlastDeflineAsnRead, (AsnOptFreeFunc) BlastDeflineFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST_RESPONSE_db_info) {
+ choice = BlastResponse_db_info;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) BlastDbinfoAsnRead, (AsnOptFreeFunc) BlastDbinfoFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == BLAST_RESPONSE_db_info_specific) {
+ choice = BlastResponse_db_info_specific;
+ func = (AsnReadFunc) BlastDbinfoAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_matrix) {
+ choice = BlastResponse_matrix;
+ func = (AsnReadFunc) BlastMatrixAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_alignment) {
+ choice = BlastResponse_alignment;
+ func = (AsnReadFunc) SeqAlignSetAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_mask) {
+ choice = BlastResponse_mask;
+ func = (AsnReadFunc) BlastMaskAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_kablk) {
+ choice = BlastResponse_kablk;
+ func = (AsnReadFunc) BlastKABlkAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_parameters) {
+ choice = BlastResponse_parameters;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == BLAST_RESPONSE_queued) {
+ choice = BlastResponse_queued;
+ func = (AsnReadFunc) BlastQueuedAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_start) {
+ choice = BlastResponse_start;
+ func = (AsnReadFunc) BlastProgressAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_progress) {
+ choice = BlastResponse_progress;
+ func = (AsnReadFunc) BlastProgressAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_done) {
+ choice = BlastResponse_done;
+ func = (AsnReadFunc) BlastProgressAsnRead;
+ }
+ else if (atp == BLAST_RESPONSE_fini) {
+ choice = BlastResponse_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BlastResponseAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastResponseAsnWrite(BlastResponsePtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST_RESPONSE); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case BlastResponse_init:
+ writetype = BLAST_RESPONSE_init;
+ func = (AsnWriteFunc) BlastVersionAsnWrite;
+ break;
+ case BlastResponse_motd:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST_RESPONSE_motd, &av);
+ break;
+ case BlastResponse_error:
+ writetype = BLAST_RESPONSE_error;
+ func = (AsnWriteFunc) BlastErrorAsnWrite;
+ break;
+ case BlastResponse_db_seq_get:
+ writetype = BLAST_RESPONSE_db_seq_get;
+ func = (AsnWriteFunc) BioseqAsnWrite;
+ break;
+ case BlastResponse_db_redundant_ids_get:
+ retval = AsnGenericChoiceSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) SeqIdAsnWrite, aip, BLAST_RESPONSE_db_redundant_ids_get, BLAST_RESPONSE_db_redundant_ids_get_E);
+ break;
+ case BlastResponse_db_redundant_descr_get:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BlastDeflineAsnWrite, aip, BLAST_RESPONSE_db_redundant_descr_get, BLAST_RESPONSE_db_redundant_descr_get_E);
+ break;
+ case BlastResponse_db_info:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) BlastDbinfoAsnWrite, aip, BLAST_RESPONSE_db_info, BLAST_RESPONSE_db_info_E);
+ break;
+ case BlastResponse_db_info_specific:
+ writetype = BLAST_RESPONSE_db_info_specific;
+ func = (AsnWriteFunc) BlastDbinfoAsnWrite;
+ break;
+ case BlastResponse_matrix:
+ writetype = BLAST_RESPONSE_matrix;
+ func = (AsnWriteFunc) BlastMatrixAsnWrite;
+ break;
+ case BlastResponse_alignment:
+ writetype = BLAST_RESPONSE_alignment;
+ func = (AsnWriteFunc) SeqAlignSetAsnWrite;
+ break;
+ case BlastResponse_mask:
+ writetype = BLAST_RESPONSE_mask;
+ func = (AsnWriteFunc) BlastMaskAsnWrite;
+ break;
+ case BlastResponse_kablk:
+ writetype = BLAST_RESPONSE_kablk;
+ func = (AsnWriteFunc) BlastKABlkAsnWrite;
+ break;
+ case BlastResponse_parameters:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, BLAST_RESPONSE_parameters, &av);
+ break;
+ case BlastResponse_queued:
+ writetype = BLAST_RESPONSE_queued;
+ func = (AsnWriteFunc) BlastQueuedAsnWrite;
+ break;
+ case BlastResponse_start:
+ writetype = BLAST_RESPONSE_start;
+ func = (AsnWriteFunc) BlastProgressAsnWrite;
+ break;
+ case BlastResponse_progress:
+ writetype = BLAST_RESPONSE_progress;
+ func = (AsnWriteFunc) BlastProgressAsnWrite;
+ break;
+ case BlastResponse_done:
+ writetype = BLAST_RESPONSE_done;
+ func = (AsnWriteFunc) BlastProgressAsnWrite;
+ break;
+ case BlastResponse_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, BLAST_RESPONSE_fini, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* BlastParametersNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastParametersPtr LIBCALL
+BlastParametersNew(void)
+{
+ BlastParametersPtr ptr = MemNew((size_t) sizeof(BlastParameters));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastParametersFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastParametersPtr LIBCALL
+BlastParametersFree(BlastParametersPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ Cutoff_cutoffFree(ptr -> Cutoff_cutoff);
+ Cutoff2_cutoff2Free(ptr -> Cutoff2_cutoff2);
+ MemFree(ptr -> other_options);
+ AsnGenericBaseSeqOfFree(ptr -> gilist ,ASNCODE_INTVAL_SLOT);
+ MemFree(ptr -> gifile);
+ MemFree(ptr -> matrix);
+ MemFree(ptr -> filter_string);
+ MemFree(ptr -> entrez_query);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* Cutoff2_cutoff2Free()
+*
+**************************************************/
+static
+Cutoff2_cutoff2Ptr LIBCALL
+Cutoff2_cutoff2Free(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* BlastParametersAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastParametersPtr LIBCALL
+BlastParametersAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastParametersPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastParameters ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_PARAMETERS);
+ } else {
+ atp = AsnLinkType(orig, BLAST_PARAMETERS);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastParametersNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_PARAMETERS_first_threshold) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> first_threshold = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_second_threshold) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> second_threshold = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_cutoff) {
+ ptr -> Cutoff_cutoff = Cutoff_cutoffAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_cutoff2) {
+ ptr -> Cutoff2_cutoff2 = Cutoff2_cutoff2AsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_hitlist_size) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> hitlist_size = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_nucl_penalty) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> nucl_penalty = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_nucl_reward) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> nucl_reward = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_genetic_code) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> genetic_code = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_db_genetic_code) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> db_genetic_code = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_low_complexity_filtering) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> low_complexity_filtering = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_gapped_alignment) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> gapped_alignment = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_gap_open) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> gap_open = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_gap_extend) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> gap_extend = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_required_start) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> required_start = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_required_end) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> required_end = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_ethresh) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> ethresh = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_max_num_passes) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> max_num_passes = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_pseudo_count_const) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> pseudo_count_const = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_other_options) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> other_options = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_gilist) {
+ ptr -> gilist = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_INTVAL_SLOT, &isError);
+ if (isError && ptr -> gilist == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_gifile) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> gifile = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_matrix) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> matrix = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_filter_string) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> filter_string = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_entrez_query) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> entrez_query = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_PARAMETERS_word_size) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> word_size = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastParametersFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* Cutoff2_cutoff2AsnRead()
+*
+**************************************************/
+static
+Cutoff2_cutoff2Ptr LIBCALL
+Cutoff2_cutoff2AsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Cutoff2_cutoff2 ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_PARAMETERS_cutoff2);
+ } else {
+ atp = AsnLinkType(orig, BLAST_PARAMETERS_cutoff2); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == BLAST_PARAMETERS_cutoff2_evalue) {
+ choice = Cutoff2_cutoff2_evalue;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.realvalue = av.realvalue;
+ }
+ else if (atp == BLAST_PARAMETERS_cutoff2_score) {
+ choice = Cutoff2_cutoff2_score;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* BlastParametersAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastParametersAsnWrite(BlastParametersPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_PARAMETERS); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> first_threshold;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_first_threshold, &av);
+ av.intvalue = ptr -> second_threshold;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_second_threshold, &av);
+ if (ptr -> Cutoff_cutoff != NULL) {
+ if ( ! Cutoff_cutoffAsnWrite(ptr -> Cutoff_cutoff, aip, BLAST_PARAMETERS_cutoff)) {
+ goto erret;
+ }
+ }
+ if (ptr -> Cutoff2_cutoff2 != NULL) {
+ if ( ! Cutoff2_cutoff2AsnWrite(ptr -> Cutoff2_cutoff2, aip, BLAST_PARAMETERS_cutoff2)) {
+ goto erret;
+ }
+ }
+ av.intvalue = ptr -> hitlist_size;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_hitlist_size, &av);
+ av.intvalue = ptr -> nucl_penalty;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_nucl_penalty, &av);
+ av.intvalue = ptr -> nucl_reward;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_nucl_reward, &av);
+ av.intvalue = ptr -> genetic_code;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_genetic_code, &av);
+ av.intvalue = ptr -> db_genetic_code;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_db_genetic_code, &av);
+ av.intvalue = ptr -> low_complexity_filtering;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_low_complexity_filtering, &av);
+ av.boolvalue = ptr -> gapped_alignment;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_gapped_alignment, &av);
+ av.intvalue = ptr -> gap_open;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_gap_open, &av);
+ av.intvalue = ptr -> gap_extend;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_gap_extend, &av);
+ av.intvalue = ptr -> required_start;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_required_start, &av);
+ av.intvalue = ptr -> required_end;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_required_end, &av);
+ av.realvalue = ptr -> ethresh;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_ethresh, &av);
+ av.intvalue = ptr -> max_num_passes;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_max_num_passes, &av);
+ av.intvalue = ptr -> pseudo_count_const;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_pseudo_count_const, &av);
+ if (ptr -> other_options != NULL) {
+ av.ptrvalue = ptr -> other_options;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_other_options, &av);
+ }
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> gilist ,ASNCODE_INTVAL_SLOT, aip, BLAST_PARAMETERS_gilist, BLAST_PARAMETERS_gilist_E);
+ if (ptr -> gifile != NULL) {
+ av.ptrvalue = ptr -> gifile;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_gifile, &av);
+ }
+ if (ptr -> matrix != NULL) {
+ av.ptrvalue = ptr -> matrix;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_matrix, &av);
+ }
+ if (ptr -> filter_string != NULL) {
+ av.ptrvalue = ptr -> filter_string;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_filter_string, &av);
+ }
+ if (ptr -> entrez_query != NULL) {
+ av.ptrvalue = ptr -> entrez_query;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_entrez_query, &av);
+ }
+ av.intvalue = ptr -> word_size;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_word_size, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* Cutoff2_cutoff2AsnWrite()
+*
+**************************************************/
+static Boolean LIBCALL
+Cutoff2_cutoff2AsnWrite(Cutoff2_cutoff2Ptr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST_PARAMETERS_cutoff2); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case Cutoff2_cutoff2_evalue:
+ av.realvalue = anp->data.realvalue;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_cutoff2_evalue, &av);
+ break;
+ case Cutoff2_cutoff2_score:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_cutoff2_score, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* Cutoff_cutoffAsnWrite()
+*
+**************************************************/
+static Boolean LIBCALL
+Cutoff_cutoffAsnWrite(Cutoff_cutoffPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, BLAST_PARAMETERS_cutoff); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case Cutoff_cutoff_evalue:
+ av.realvalue = anp->data.realvalue;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_cutoff_evalue, &av);
+ break;
+ case Cutoff_cutoff_score:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, BLAST_PARAMETERS_cutoff_score, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* Cutoff_cutoffAsnRead()
+*
+**************************************************/
+static
+Cutoff_cutoffPtr LIBCALL
+Cutoff_cutoffAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Cutoff_cutoff ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_PARAMETERS_cutoff);
+ } else {
+ atp = AsnLinkType(orig, BLAST_PARAMETERS_cutoff); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == BLAST_PARAMETERS_cutoff_evalue) {
+ choice = Cutoff_cutoff_evalue;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.realvalue = av.realvalue;
+ }
+ else if (atp == BLAST_PARAMETERS_cutoff_score) {
+ choice = Cutoff_cutoff_score;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Cutoff_cutoffFree()
+*
+**************************************************/
+static
+Cutoff_cutoffPtr LIBCALL
+Cutoff_cutoffFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* BlastDbinfoNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastDbinfoPtr LIBCALL
+BlastDbinfoNew(void)
+{
+ BlastDbinfoPtr ptr = MemNew((size_t) sizeof(BlastDbinfo));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastDbinfoFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastDbinfoPtr LIBCALL
+BlastDbinfoFree(BlastDbinfoPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> name);
+ MemFree(ptr -> definition);
+ MemFree(ptr -> date);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastDbinfoAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastDbinfoPtr LIBCALL
+BlastDbinfoAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastDbinfoPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastDbinfo ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_DBINFO);
+ } else {
+ atp = AsnLinkType(orig, BLAST_DBINFO);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastDbinfoNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_DBINFO_is_protein) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> is_protein = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_DBINFO_name) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> name = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_DBINFO_definition) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> definition = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_DBINFO_date) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> date = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_DBINFO_total_length) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> total_length = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_DBINFO_number_seqs) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> number_seqs = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastDbinfoFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastDbinfoAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastDbinfoAsnWrite(BlastDbinfoPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_DBINFO); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.boolvalue = ptr -> is_protein;
+ retval = AsnWrite(aip, BLAST_DBINFO_is_protein, &av);
+ if (ptr -> name != NULL) {
+ av.ptrvalue = ptr -> name;
+ retval = AsnWrite(aip, BLAST_DBINFO_name, &av);
+ }
+ if (ptr -> definition != NULL) {
+ av.ptrvalue = ptr -> definition;
+ retval = AsnWrite(aip, BLAST_DBINFO_definition, &av);
+ }
+ if (ptr -> date != NULL) {
+ av.ptrvalue = ptr -> date;
+ retval = AsnWrite(aip, BLAST_DBINFO_date, &av);
+ }
+ av.intvalue = ptr -> total_length;
+ retval = AsnWrite(aip, BLAST_DBINFO_total_length, &av);
+ av.intvalue = ptr -> number_seqs;
+ retval = AsnWrite(aip, BLAST_DBINFO_number_seqs, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastMaskNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastMaskPtr LIBCALL
+BlastMaskNew(void)
+{
+ BlastMaskPtr ptr = MemNew((size_t) sizeof(BlastMask));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastMaskFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastMaskPtr LIBCALL
+BlastMaskFree(BlastMaskPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericChoiceSeqOfFree(ptr -> location, (AsnOptFreeFunc) SeqLocFree);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastMaskAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastMaskPtr LIBCALL
+BlastMaskAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastMaskPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastMask ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_MASK);
+ } else {
+ atp = AsnLinkType(orig, BLAST_MASK);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastMaskNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_MASK_location) {
+ ptr -> location = AsnGenericChoiceSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) SeqLocAsnRead, (AsnOptFreeFunc) SeqLocFree);
+ if (isError && ptr -> location == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_MASK_frame) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> frame = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastMaskFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastMaskAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastMaskAsnWrite(BlastMaskPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_MASK); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ AsnGenericChoiceSeqOfAsnWrite(ptr -> location, (AsnWriteFunc) SeqLocAsnWrite, aip, BLAST_MASK_location, BLAST_MASK_location_E);
+ av.intvalue = ptr -> frame;
+ retval = AsnWrite(aip, BLAST_MASK_frame, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastKABlkNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastKABlkPtr LIBCALL
+BlastKABlkNew(void)
+{
+ BlastKABlkPtr ptr = MemNew((size_t) sizeof(BlastKABlk));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastKABlkFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastKABlkPtr LIBCALL
+BlastKABlkFree(BlastKABlkPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastKABlkAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastKABlkPtr LIBCALL
+BlastKABlkAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastKABlkPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastKABlk ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_KABLK);
+ } else {
+ atp = AsnLinkType(orig, BLAST_KABLK);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastKABlkNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_KABLK_lambda) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> lambda = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_KABLK_k) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> k = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_KABLK_h) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> h = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_KABLK_gapped) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> gapped = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastKABlkFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastKABlkAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastKABlkAsnWrite(BlastKABlkPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_KABLK); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.realvalue = ptr -> lambda;
+ retval = AsnWrite(aip, BLAST_KABLK_lambda, &av);
+ av.realvalue = ptr -> k;
+ retval = AsnWrite(aip, BLAST_KABLK_k, &av);
+ av.realvalue = ptr -> h;
+ retval = AsnWrite(aip, BLAST_KABLK_h, &av);
+ av.boolvalue = ptr -> gapped;
+ retval = AsnWrite(aip, BLAST_KABLK_gapped, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastDbinfoGetNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastDbinfoGetPtr LIBCALL
+BlastDbinfoGetNew(void)
+{
+ BlastDbinfoGetPtr ptr = MemNew((size_t) sizeof(BlastDbinfoGet));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastDbinfoGetFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastDbinfoGetPtr LIBCALL
+BlastDbinfoGetFree(BlastDbinfoGetPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> name);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastDbinfoGetAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastDbinfoGetPtr LIBCALL
+BlastDbinfoGetAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastDbinfoGetPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastDbinfoGet ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_DBINFO_GET);
+ } else {
+ atp = AsnLinkType(orig, BLAST_DBINFO_GET);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastDbinfoGetNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_DBINFO_GET_name) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> name = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_DBINFO_GET_type) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> type = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastDbinfoGetFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastDbinfoGetAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastDbinfoGetAsnWrite(BlastDbinfoGetPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_DBINFO_GET); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> name != NULL) {
+ av.ptrvalue = ptr -> name;
+ retval = AsnWrite(aip, BLAST_DBINFO_GET_name, &av);
+ }
+ av.intvalue = ptr -> type;
+ retval = AsnWrite(aip, BLAST_DBINFO_GET_type, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastSeqIdNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastSeqIdPtr LIBCALL
+BlastSeqIdNew(void)
+{
+ BlastSeqIdPtr ptr = MemNew((size_t) sizeof(BlastSeqId));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastSeqIdFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastSeqIdPtr LIBCALL
+BlastSeqIdFree(BlastSeqIdPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> database);
+ SeqIdFree(ptr -> id);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastSeqIdAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastSeqIdPtr LIBCALL
+BlastSeqIdAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastSeqIdPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastSeqId ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_SEQ_ID);
+ } else {
+ atp = AsnLinkType(orig, BLAST_SEQ_ID);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastSeqIdNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_SEQ_ID_is_protein) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> is_protein = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_SEQ_ID_database) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> database = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_SEQ_ID_id) {
+ ptr -> id = SeqIdAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastSeqIdFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastSeqIdAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastSeqIdAsnWrite(BlastSeqIdPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_SEQ_ID); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.boolvalue = ptr -> is_protein;
+ retval = AsnWrite(aip, BLAST_SEQ_ID_is_protein, &av);
+ if (ptr -> database != NULL) {
+ av.ptrvalue = ptr -> database;
+ retval = AsnWrite(aip, BLAST_SEQ_ID_database, &av);
+ }
+ if (ptr -> id != NULL) {
+ if ( ! SeqIdAsnWrite(ptr -> id, aip, BLAST_SEQ_ID_id)) {
+ goto erret;
+ }
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastMatrixNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastMatrixPtr LIBCALL
+BlastMatrixNew(void)
+{
+ BlastMatrixPtr ptr = MemNew((size_t) sizeof(BlastMatrix));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastMatrixFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastMatrixPtr LIBCALL
+BlastMatrixFree(BlastMatrixPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> name);
+ AsnGenericBaseSeqOfFree(ptr -> comments ,ASNCODE_PTRVAL_SLOT);
+ AsnGenericBaseSeqOfFree(ptr -> scores ,ASNCODE_INTVAL_SLOT);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastMatrixAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastMatrixPtr LIBCALL
+BlastMatrixAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastMatrixPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastMatrix ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_MATRIX);
+ } else {
+ atp = AsnLinkType(orig, BLAST_MATRIX);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastMatrixNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_MATRIX_is_protein) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> is_protein = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_MATRIX_name) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> name = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_MATRIX_comments) {
+ ptr -> comments = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && ptr -> comments == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_MATRIX_row_length) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> row_length = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_MATRIX_column_length) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> column_length = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_MATRIX_scores) {
+ ptr -> scores = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_INTVAL_SLOT, &isError);
+ if (isError && ptr -> scores == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_MATRIX_karlinK) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> karlinK = av.realvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastMatrixFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastMatrixAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastMatrixAsnWrite(BlastMatrixPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_MATRIX); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.boolvalue = ptr -> is_protein;
+ retval = AsnWrite(aip, BLAST_MATRIX_is_protein, &av);
+ if (ptr -> name != NULL) {
+ av.ptrvalue = ptr -> name;
+ retval = AsnWrite(aip, BLAST_MATRIX_name, &av);
+ }
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> comments ,ASNCODE_PTRVAL_SLOT, aip, BLAST_MATRIX_comments, BLAST_MATRIX_comments_E);
+ av.intvalue = ptr -> row_length;
+ retval = AsnWrite(aip, BLAST_MATRIX_row_length, &av);
+ av.intvalue = ptr -> column_length;
+ retval = AsnWrite(aip, BLAST_MATRIX_column_length, &av);
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> scores ,ASNCODE_INTVAL_SLOT, aip, BLAST_MATRIX_scores, BLAST_MATRIX_scores_E);
+ av.realvalue = ptr -> karlinK;
+ retval = AsnWrite(aip, BLAST_MATRIX_karlinK, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastQueuedNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastQueuedPtr LIBCALL
+BlastQueuedNew(void)
+{
+ BlastQueuedPtr ptr = MemNew((size_t) sizeof(BlastQueued));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastQueuedFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastQueuedPtr LIBCALL
+BlastQueuedFree(BlastQueuedPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastQueuedAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastQueuedPtr LIBCALL
+BlastQueuedAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastQueuedPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastQueued ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_QUEUED);
+ } else {
+ atp = AsnLinkType(orig, BLAST_QUEUED);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastQueuedNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_QUEUED_length) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> length = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastQueuedFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastQueuedAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastQueuedAsnWrite(BlastQueuedPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_QUEUED); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> length;
+ retval = AsnWrite(aip, BLAST_QUEUED_length, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastProgressNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastProgressPtr LIBCALL
+BlastProgressNew(void)
+{
+ BlastProgressPtr ptr = MemNew((size_t) sizeof(BlastProgress));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastProgressFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastProgressPtr LIBCALL
+BlastProgressFree(BlastProgressPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastProgressAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastProgressPtr LIBCALL
+BlastProgressAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastProgressPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastProgress ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_PROGRESS);
+ } else {
+ atp = AsnLinkType(orig, BLAST_PROGRESS);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastProgressNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_PROGRESS_completed) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> completed = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastProgressFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastProgressAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastProgressAsnWrite(BlastProgressPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_PROGRESS); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> completed;
+ retval = AsnWrite(aip, BLAST_PROGRESS_completed, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastDeflineNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastDeflinePtr LIBCALL
+BlastDeflineNew(void)
+{
+ BlastDeflinePtr ptr = MemNew((size_t) sizeof(BlastDefline));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastDeflineFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastDeflinePtr LIBCALL
+BlastDeflineFree(BlastDeflinePtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ SeqIdFree(ptr -> id);
+ MemFree(ptr -> defline);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastDeflineAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastDeflinePtr LIBCALL
+BlastDeflineAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastDeflinePtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastDefline ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_DEFLINE);
+ } else {
+ atp = AsnLinkType(orig, BLAST_DEFLINE);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastDeflineNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_DEFLINE_id) {
+ ptr -> id = SeqIdAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_DEFLINE_defline) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> defline = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastDeflineFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastDeflineAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastDeflineAsnWrite(BlastDeflinePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_DEFLINE); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> id != NULL) {
+ if ( ! SeqIdAsnWrite(ptr -> id, aip, BLAST_DEFLINE_id)) {
+ goto erret;
+ }
+ }
+ if (ptr -> defline != NULL) {
+ av.ptrvalue = ptr -> defline;
+ retval = AsnWrite(aip, BLAST_DEFLINE_defline, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastVersionNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastVersionPtr LIBCALL
+BlastVersionNew(void)
+{
+ BlastVersionPtr ptr = MemNew((size_t) sizeof(BlastVersion));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastVersionFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastVersionPtr LIBCALL
+BlastVersionFree(BlastVersionPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> version);
+ MemFree(ptr -> date);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastVersionAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastVersionPtr LIBCALL
+BlastVersionAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastVersionPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastVersion ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_VERSION);
+ } else {
+ atp = AsnLinkType(orig, BLAST_VERSION);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastVersionNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_VERSION_version) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> version = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_VERSION_date) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> date = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastVersionFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastVersionAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastVersionAsnWrite(BlastVersionPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_VERSION); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> version != NULL) {
+ av.ptrvalue = ptr -> version;
+ retval = AsnWrite(aip, BLAST_VERSION_version, &av);
+ }
+ if (ptr -> date != NULL) {
+ av.ptrvalue = ptr -> date;
+ retval = AsnWrite(aip, BLAST_VERSION_date, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* BlastErrorNew()
+*
+**************************************************/
+NLM_EXTERN
+BlastErrorPtr LIBCALL
+BlastErrorNew(void)
+{
+ BlastErrorPtr ptr = MemNew((size_t) sizeof(BlastError));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* BlastErrorFree()
+*
+**************************************************/
+NLM_EXTERN
+BlastErrorPtr LIBCALL
+BlastErrorFree(BlastErrorPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> msg);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* BlastErrorAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+BlastErrorPtr LIBCALL
+BlastErrorAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ BlastErrorPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* BlastError ::= (self contained) */
+ atp = AsnReadId(aip, amp, BLAST_ERROR);
+ } else {
+ atp = AsnLinkType(orig, BLAST_ERROR);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = BlastErrorNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == BLAST_ERROR_level) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> level = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == BLAST_ERROR_msg) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> msg = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = BlastErrorFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* BlastErrorAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+BlastErrorAsnWrite(BlastErrorPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objblst3AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, BLAST_ERROR); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> level;
+ retval = AsnWrite(aip, BLAST_ERROR_level, &av);
+ if (ptr -> msg != NULL) {
+ av.ptrvalue = ptr -> msg;
+ retval = AsnWrite(aip, BLAST_ERROR_msg, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
diff --git a/network/blast3/client/objblst3.h b/network/blast3/client/objblst3.h
new file mode 100644
index 00000000..2418c678
--- /dev/null
+++ b/network/blast3/client/objblst3.h
@@ -0,0 +1,421 @@
+#ifndef _objblst3_
+#define _objblst3_
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+
+#ifdef __cplusplus
+extern "C" { /* } */
+#endif
+
+
+/**************************************************
+*
+* Generated objects for Module NCBI-Blast
+* Generated using ASNCODE Revision: 6.0 at Dec 21, 1998 9:44 AM
+*
+**************************************************/
+
+NLM_EXTERN Boolean LIBCALL
+objblst3AsnLoad PROTO((void));
+
+
+/**************************************************
+*
+* BlastSearch
+*
+**************************************************/
+typedef struct struct_Blast_search {
+ Uint2 program;
+ /* following #defines are for enumerated type, not used by object loaders */
+#define Blast_search_program_blastn 0
+#define Blast_search_program_blastp 1
+#define Blast_search_program_blastx 2
+#define Blast_search_program_tblastn 3
+#define Blast_search_program_tblastx 4
+
+ struct struct_Bioseq PNTR query;
+ CharPtr database;
+ struct struct_Blast_parameters PNTR parameters;
+ ValNodePtr mask;
+ struct struct_Blast_matrix PNTR matrix;
+} BlastSearch, PNTR BlastSearchPtr;
+
+
+NLM_EXTERN BlastSearchPtr LIBCALL BlastSearchFree PROTO ((BlastSearchPtr ));
+NLM_EXTERN BlastSearchPtr LIBCALL BlastSearchNew PROTO (( void ));
+NLM_EXTERN BlastSearchPtr LIBCALL BlastSearchAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastSearchAsnWrite PROTO (( BlastSearchPtr , AsnIoPtr, AsnTypePtr));
+
+typedef ValNodePtr BlastRequestPtr;
+typedef ValNode BlastRequest;
+#define BlastRequest_init 1
+#define BlastRequest_motd 2
+#define BlastRequest_db_info 3
+#define BlastRequest_db_info_specific 4
+#define BlastRequest_matrix_get 5
+#define BlastRequest_search 6
+#define BlastRequest_db_seq_get 7
+#define BlastRequest_db_redundant_ids_get 8
+#define BlastRequest_db_redundant_descr_get 9
+#define BlastRequest_fini 10
+
+
+NLM_EXTERN BlastRequestPtr LIBCALL BlastRequestFree PROTO ((BlastRequestPtr ));
+NLM_EXTERN BlastRequestPtr LIBCALL BlastRequestAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastRequestAsnWrite PROTO (( BlastRequestPtr , AsnIoPtr, AsnTypePtr));
+
+typedef ValNodePtr BlastResponsePtr;
+typedef ValNode BlastResponse;
+#define BlastResponse_init 1
+#define BlastResponse_motd 2
+#define BlastResponse_error 3
+#define BlastResponse_db_seq_get 4
+#define BlastResponse_db_redundant_ids_get 5
+#define BlastResponse_db_redundant_descr_get 6
+#define BlastResponse_db_info 7
+#define BlastResponse_db_info_specific 8
+#define BlastResponse_matrix 9
+#define BlastResponse_alignment 10
+#define BlastResponse_mask 11
+#define BlastResponse_kablk 12
+#define BlastResponse_parameters 13
+#define BlastResponse_queued 14
+#define BlastResponse_start 15
+#define BlastResponse_progress 16
+#define BlastResponse_done 17
+#define BlastResponse_fini 18
+
+
+NLM_EXTERN BlastResponsePtr LIBCALL BlastResponseFree PROTO ((BlastResponsePtr ));
+NLM_EXTERN BlastResponsePtr LIBCALL BlastResponseAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastResponseAsnWrite PROTO (( BlastResponsePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastParameters
+*
+**************************************************/
+typedef struct struct_Blast_parameters {
+ Int4 first_threshold;
+ Int4 second_threshold;
+ ValNodePtr Cutoff_cutoff;
+ ValNodePtr Cutoff2_cutoff2;
+ Int4 hitlist_size;
+ Int4 nucl_penalty;
+ Int4 nucl_reward;
+ Int4 genetic_code;
+ Int4 db_genetic_code;
+ Int4 low_complexity_filtering;
+ Uint1 gapped_alignment;
+ Int4 gap_open;
+ Int4 gap_extend;
+ Int4 required_start;
+ Int4 required_end;
+ FloatHi ethresh;
+ Int4 max_num_passes;
+ Int4 pseudo_count_const;
+ CharPtr other_options;
+ ValNodePtr gilist;
+ CharPtr gifile;
+ CharPtr matrix;
+ CharPtr filter_string;
+ CharPtr entrez_query;
+ Int4 word_size;
+} BlastParameters, PNTR BlastParametersPtr;
+
+
+NLM_EXTERN BlastParametersPtr LIBCALL BlastParametersFree PROTO ((BlastParametersPtr ));
+NLM_EXTERN BlastParametersPtr LIBCALL BlastParametersNew PROTO (( void ));
+NLM_EXTERN BlastParametersPtr LIBCALL BlastParametersAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastParametersAsnWrite PROTO (( BlastParametersPtr , AsnIoPtr, AsnTypePtr));
+
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+typedef ValNodePtr Cutoff2_cutoff2Ptr;
+typedef ValNode Cutoff2_cutoff2;
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+#define Cutoff2_cutoff2_evalue 1
+#define Cutoff2_cutoff2_score 2
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+static Cutoff2_cutoff2Ptr LIBCALL Cutoff2_cutoff2Free PROTO ((Cutoff2_cutoff2Ptr ));
+static Cutoff2_cutoff2Ptr LIBCALL Cutoff2_cutoff2AsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+static Boolean LIBCALL Cutoff2_cutoff2AsnWrite PROTO (( Cutoff2_cutoff2Ptr , AsnIoPtr, AsnTypePtr));
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+typedef ValNodePtr Cutoff_cutoffPtr;
+typedef ValNode Cutoff_cutoff;
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+#define Cutoff_cutoff_evalue 1
+#define Cutoff_cutoff_score 2
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+static Cutoff_cutoffPtr LIBCALL Cutoff_cutoffFree PROTO ((Cutoff_cutoffPtr ));
+static Cutoff_cutoffPtr LIBCALL Cutoff_cutoffAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+static Boolean LIBCALL Cutoff_cutoffAsnWrite PROTO (( Cutoff_cutoffPtr , AsnIoPtr, AsnTypePtr));
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+
+
+/**************************************************
+*
+* BlastDbinfo
+*
+**************************************************/
+typedef struct struct_Blast_dbinfo {
+ struct struct_Blast_dbinfo PNTR next;
+ Uint1 is_protein;
+ CharPtr name;
+ CharPtr definition;
+ CharPtr date;
+ Int4 total_length;
+ Int4 number_seqs;
+} BlastDbinfo, PNTR BlastDbinfoPtr;
+
+
+NLM_EXTERN BlastDbinfoPtr LIBCALL BlastDbinfoFree PROTO ((BlastDbinfoPtr ));
+NLM_EXTERN BlastDbinfoPtr LIBCALL BlastDbinfoNew PROTO (( void ));
+NLM_EXTERN BlastDbinfoPtr LIBCALL BlastDbinfoAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastDbinfoAsnWrite PROTO (( BlastDbinfoPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastMask
+*
+**************************************************/
+typedef struct struct_Blast_mask {
+ ValNodePtr location;
+ Uint2 frame;
+ /* following #defines are for enumerated type, not used by object loaders */
+#define Blast_mask_frame_notset 0
+#define Blast_mask_frame_plus1 1
+#define Blast_mask_frame_plus2 2
+#define Blast_mask_frame_plus3 3
+#define Blast_mask_frame_minus1 4
+#define Blast_mask_frame_minus2 5
+#define Blast_mask_frame_minus3 6
+
+} BlastMask, PNTR BlastMaskPtr;
+
+
+NLM_EXTERN BlastMaskPtr LIBCALL BlastMaskFree PROTO ((BlastMaskPtr ));
+NLM_EXTERN BlastMaskPtr LIBCALL BlastMaskNew PROTO (( void ));
+NLM_EXTERN BlastMaskPtr LIBCALL BlastMaskAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastMaskAsnWrite PROTO (( BlastMaskPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastKABlk
+*
+**************************************************/
+typedef struct struct_Blast_KABlk {
+ FloatHi lambda;
+ FloatHi k;
+ FloatHi h;
+ Uint1 gapped;
+} BlastKABlk, PNTR BlastKABlkPtr;
+
+
+NLM_EXTERN BlastKABlkPtr LIBCALL BlastKABlkFree PROTO ((BlastKABlkPtr ));
+NLM_EXTERN BlastKABlkPtr LIBCALL BlastKABlkNew PROTO (( void ));
+NLM_EXTERN BlastKABlkPtr LIBCALL BlastKABlkAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastKABlkAsnWrite PROTO (( BlastKABlkPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastDbinfoGet
+*
+**************************************************/
+typedef struct struct_Blast_dbinfo_get {
+ CharPtr name;
+ Uint2 type;
+ /* following #defines are for enumerated type, not used by object loaders */
+#define Blast_dbinfo_get_type_unknown 0
+#define Blast_dbinfo_get_type_protein 1
+#define Blast_dbinfo_get_type_nucleotide 2
+
+} BlastDbinfoGet, PNTR BlastDbinfoGetPtr;
+
+
+NLM_EXTERN BlastDbinfoGetPtr LIBCALL BlastDbinfoGetFree PROTO ((BlastDbinfoGetPtr ));
+NLM_EXTERN BlastDbinfoGetPtr LIBCALL BlastDbinfoGetNew PROTO (( void ));
+NLM_EXTERN BlastDbinfoGetPtr LIBCALL BlastDbinfoGetAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastDbinfoGetAsnWrite PROTO (( BlastDbinfoGetPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastSeqId
+*
+**************************************************/
+typedef struct struct_Blast_seq_id {
+ Uint1 is_protein;
+ CharPtr database;
+ ValNodePtr id;
+} BlastSeqId, PNTR BlastSeqIdPtr;
+
+
+NLM_EXTERN BlastSeqIdPtr LIBCALL BlastSeqIdFree PROTO ((BlastSeqIdPtr ));
+NLM_EXTERN BlastSeqIdPtr LIBCALL BlastSeqIdNew PROTO (( void ));
+NLM_EXTERN BlastSeqIdPtr LIBCALL BlastSeqIdAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastSeqIdAsnWrite PROTO (( BlastSeqIdPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastMatrix
+*
+**************************************************/
+typedef struct struct_Blast_matrix {
+ Uint1 is_protein;
+ CharPtr name;
+ ValNodePtr comments;
+ Int4 row_length;
+ Int4 column_length;
+ ValNodePtr scores;
+ FloatHi karlinK;
+} BlastMatrix, PNTR BlastMatrixPtr;
+
+
+NLM_EXTERN BlastMatrixPtr LIBCALL BlastMatrixFree PROTO ((BlastMatrixPtr ));
+NLM_EXTERN BlastMatrixPtr LIBCALL BlastMatrixNew PROTO (( void ));
+NLM_EXTERN BlastMatrixPtr LIBCALL BlastMatrixAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastMatrixAsnWrite PROTO (( BlastMatrixPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastQueued
+*
+**************************************************/
+typedef struct struct_Blast_Queued {
+ Int4 length;
+} BlastQueued, PNTR BlastQueuedPtr;
+
+
+NLM_EXTERN BlastQueuedPtr LIBCALL BlastQueuedFree PROTO ((BlastQueuedPtr ));
+NLM_EXTERN BlastQueuedPtr LIBCALL BlastQueuedNew PROTO (( void ));
+NLM_EXTERN BlastQueuedPtr LIBCALL BlastQueuedAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastQueuedAsnWrite PROTO (( BlastQueuedPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastProgress
+*
+**************************************************/
+typedef struct struct_Blast_Progress {
+ Int4 completed;
+} BlastProgress, PNTR BlastProgressPtr;
+
+
+NLM_EXTERN BlastProgressPtr LIBCALL BlastProgressFree PROTO ((BlastProgressPtr ));
+NLM_EXTERN BlastProgressPtr LIBCALL BlastProgressNew PROTO (( void ));
+NLM_EXTERN BlastProgressPtr LIBCALL BlastProgressAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastProgressAsnWrite PROTO (( BlastProgressPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastDefline
+*
+**************************************************/
+typedef struct struct_Blast_defline {
+ struct struct_Blast_defline PNTR next;
+ ValNodePtr id;
+ CharPtr defline;
+} BlastDefline, PNTR BlastDeflinePtr;
+
+
+NLM_EXTERN BlastDeflinePtr LIBCALL BlastDeflineFree PROTO ((BlastDeflinePtr ));
+NLM_EXTERN BlastDeflinePtr LIBCALL BlastDeflineNew PROTO (( void ));
+NLM_EXTERN BlastDeflinePtr LIBCALL BlastDeflineAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastDeflineAsnWrite PROTO (( BlastDeflinePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastVersion
+*
+**************************************************/
+typedef struct struct_Blast_version {
+ CharPtr version;
+ CharPtr date;
+} BlastVersion, PNTR BlastVersionPtr;
+
+
+NLM_EXTERN BlastVersionPtr LIBCALL BlastVersionFree PROTO ((BlastVersionPtr ));
+NLM_EXTERN BlastVersionPtr LIBCALL BlastVersionNew PROTO (( void ));
+NLM_EXTERN BlastVersionPtr LIBCALL BlastVersionAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastVersionAsnWrite PROTO (( BlastVersionPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* BlastError
+*
+**************************************************/
+typedef struct struct_Blast_error {
+ Uint2 level;
+ /* following #defines are for enumerated type, not used by object loaders */
+#define Blast_error_level_none 0
+#define Blast_error_level_info 1
+#define Blast_error_level_warn 2
+#define Blast_error_level_error 3
+#define Blast_error_level_fatal 4
+
+ CharPtr msg;
+} BlastError, PNTR BlastErrorPtr;
+
+
+NLM_EXTERN BlastErrorPtr LIBCALL BlastErrorFree PROTO ((BlastErrorPtr ));
+NLM_EXTERN BlastErrorPtr LIBCALL BlastErrorNew PROTO (( void ));
+NLM_EXTERN BlastErrorPtr LIBCALL BlastErrorAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL BlastErrorAsnWrite PROTO (( BlastErrorPtr , AsnIoPtr, AsnTypePtr));
+
+#ifdef __cplusplus
+/* { */ }
+#endif
+
+#endif /* _objblst3_ */
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
diff --git a/network/encrypt/README b/network/encrypt/README
new file mode 100644
index 00000000..87aec8e6
--- /dev/null
+++ b/network/encrypt/README
@@ -0,0 +1,141 @@
+This is the NCBI README file which provides instructions for how to setup
+the RIPEM/RSAREF software to be compiled in conjunction with the NCBI toolkit.
+Adding RIPEM/RSAREF to the toolkit adds the capability to produce
+client/server software which communicates using DES encryption with other
+clients and servers in the NCBI Dispatcher system, a.k.a. NCBI Network
+Services.
+
+The NCBI Network Services software uses the following scheme for key
+distribution, using a single RSA public-key/private-key pair, where the
+private-key is only known to the Dispatcher.
+
+(1) When connecting to the Dispatcher, a client includes the public key which
+ it knows, if any, within its login message.
+
+(2) When the Dispatcher responds to the login message, it includes the
+ latest public key. If there is a key mismatch, the client software is
+ designed to give the user the option of either accepting the new key
+ or aborting the program. The latter option is necessary because there
+ is a slight risk that the key is being presented by a hostile party
+ which is masquerading as the Dispatcher.
+
+(3) When the client issues a service request, it generates a pseudo-random
+ DES key which it then encrypts using the public RSA key. The Dispatcher
+ decrypts the DES key and passes it in a secure manner to the server
+ daemon for the requested service. The server manager (ncbid) in turn
+ spawns the real server for that service and informs it of the DES key.
+ The subsequent client/server communication takes place using cipher-
+ block-chained DES encryption using the agreed-upon DES key.
+
+ Note that each client<->server session uses a different DES key.
+
+
+To obtain the RIPEM/RSAREF software to include in your application, you
+must follow the procedure described at the end of this document. Note that:
+ (1) The NCBI Network Services software has been tested with the source
+ code from RIPEM 1.1 and RIPEM 1.2, although the latter is recommended.
+ (2) The RIPEM source archive is posted on its FTP server in UNIX compressed
+ tar format. Tools are generally available to uncompress and untar
+ this type of archive for different platforms.
+ (3) After uncompressing the archive, you must copy the tar file to
+ this directory (network/encrypt) and extract the desired components
+ into this directory.
+ You may either extract the entire archive for reference:
+ tar xf ripem-1.2.tar
+ or extract only the portion you need, to save local disk space:
+ tar xf ripem-1.2.tar ripem/rsaref/source
+ (4) It may be necessary to manually modify the resulting global.h file
+ for compatibility with your hardware/software platform
+ (5) The RSAREF source code is compiled as part of the "LIB15" library.
+ See make/makenet.* for details.
+
+
+DISCLAIMER:
+ You must follow all licensing and export regulations described in
+ the RIPEM/RSAREF documentation. Note that NCBI can detect the use of
+ a client which is using encryption to communicate with Dispatcher.
+ Note that NCBI may need to cooperate with U.S. authorities if it
+ appears that U.S. export regulations have been violated.
+
+
+Please direct any questions to toolbox@ncbi.nlm.nih.gov.
+
+The following information is what is required for U.S. and Canadian
+citizens to obtain the RIPEM cryptographic software. Many thanks to Mark
+Riordan and RSA Laboratories for making this software available to NCBI
+and American and Canadian scientists who wish to encrypt their data.
+
+-------------------------- begin included message ---------------------------
+
+Dear FTP user,
+
+To access the RIPEM cryptographic software archive at ripem.msu.edu,
+you must have an "account" on my custom FTP server. Traditional
+anonymous FTP login is allowed, but anonymous users are prevented
+from doing GETs on files containing cryptographic software.
+Anonymous access is allowed so that you can get README-type files
+like this one, and files containing descriptions of software
+licensing terms.
+
+To apply for FTP access to rpub.cl.msu.edu, send an email message
+to ripem@ripem.msu.edu. State the following:
+
+1. Your citizenship (must be USA or Canadian)
+2. Your willingness to comply with relevant export laws.
+3. Your willingness to comply with relevant software license terms.
+ (You should get and read the file "rsaref-license.txt" on this host,
+ so you know what you are agreeing to if you get RIPEM.)
+4. The "canonical" Internet domain name of your host.
+ (If you are not sure of the primary name of your host, FTP to
+ ripem.msu.edu under user anonymous. The FTP server will inform
+ you of your hostname.) Also state the country in which your host
+ resides.
+
+*****
+***** NOTE: It is very important that you get the hostname correct.
+***** As odd as it may seem, many requestors have
+***** not correctly specified their host address. This
+***** causes extra effort for both of us. Please check
+***** (via anonymous FTP) unless you are certain of your
+***** hostname as known by domain name servers. Your
+***** hostname does *** NOT *** have an "@" in it, and
+***** in general cannot be derived from your email address.
+*****
+
+Here's a sample email message you might send to ripem@ripem.msu.edu:
+
+To: ripem@ripem.msu.edu
+Subject: Access to ripem.msu.edu
+
+ Dear Mark,
+
+ Please give me access to ripem.msu.edu. I am an American
+ citizen, and I agree to comply with crypto export laws and
+ RSAREF license terms. My hostname is hobbit.egr.bigu.edu;
+ this host is located in the United States.
+
+ Thank you.
+
+When I receive your message, with luck I'll promptly issue you
+a special FTP username and password by return email. This username
+will work only from the hostname you specify in your message.
+
+In the case of RIPEM, you may redistribute the code, but only
+to others in the USA and Canada, and only under the terms of
+the RSAREF license agreement mentioned above.
+
+Thank you.
+
+This method of distribution is due to local site requirements
+and is not required by RSAREF license terms, FYI.
+
+Mark Riordan mrr@scss3.cl.msu.edu
+
+P.S. I realize that going through this account application process
+is not your idea of a good time. It doesn't take much imagination
+to figure that it isn't my idea of a good time, either. Please
+help this process go smoothly by giving me all the informative
+requested above, so I can issue your account on the first try.
+I receive hundreds of these requests and many are lacking information.
+
+-------------------------- end included message -----------------------------
diff --git a/network/entrez/client/netentr.asn b/network/entrez/client/netentr.asn
new file mode 100644
index 00000000..d60c4f05
--- /dev/null
+++ b/network/entrez/client/netentr.asn
@@ -0,0 +1,369 @@
+--$Revision: 6.0 $
+--*********************************************************************
+--
+-- entrez.asn
+-- Jim Ostell, 1993
+-- revised from epstein/ostell 1992
+--
+-- messages for entrez functions
+--
+--*********************************************************************
+
+NCBI-Entrez DEFINITIONS ::=
+BEGIN
+
+IMPORTS Seq-entry FROM NCBI-SeqSet
+ Seq-id FROM NCBI-SeqLoc
+ Medline-entry FROM NCBI-MedLine
+ Link-set FROM NCBI-Access
+ Biostruc, Biostruc-annot-set FROM MMDB
+ Bioseq FROM NCBI-Sequence
+ Date FROM NCBI-General
+ Cdrom-inf,Docsum FROM NCBI-CdRom;
+
+ --**********************************
+ -- requests
+ --
+
+Entrez-request ::= CHOICE {
+ init SEQUENCE { -- EntrezInit
+ version VisibleString OPTIONAL
+ } ,
+ maxlinks NULL , -- EntGetMaxLinks
+ eval Entrez-termget , -- EntTLEval
+ docsum Entrez-docget , -- DocSum
+ linkuidlist Link-setget , -- LinkUidList
+ uidlinks Link-setget , -- UidLinks
+ byterm Entrez-term-by-term , -- TermListByTerm
+ bypage Entrez-term-by-page , -- TermListByPage
+ findterm Term-lookup , -- EntrezFindTerm
+ fini NULL , -- EntrezFini
+ createnamed Entrez-named-list ,
+ getmle Entrez-docget , -- get MedlineEntry
+ getseq Entrez-seqget , -- get SeqEntry
+ evalX Entrez-termget , -- EntTLEvalX
+ createnamedX Entrez-named-listX ,
+ seqidforgi INTEGER , -- EntrezSeqIdForGI
+ findseqid Seq-id , -- EntrezFindSeqId
+ canneighbortext NULL , -- EntrezCanNeighborText
+ expanded-medline NULL ,
+ get-hierarchy Term-lookup ,
+ neighbortext Entrez-neighbor-text , -- EntrezNeighborText
+ eval-count Entrez-termget , -- EntTLEvalCount
+ initX SEQUENCE { -- new EntrezInit
+ version VisibleString OPTIONAL
+ } ,
+ getbiostr Entrez-docget , -- EntrezBiostrucGet (obselete)
+ getbiostrX SEQUENCE { -- EntrezBiostrucGet
+ complexity INTEGER ,
+ get Entrez-docget ,
+ max-models INTEGER OPTIONAL } ,
+ extrainfo INTEGER , -- obseletes maxlinks, canneighbortext, and expanded-medline
+ blast Entrez-blastreq , -- BLAST request
+ docsumX Entrez-docget , -- DocSum
+ getgenome Entrez-docget , -- get Genome-based Seq-entry
+ cluster-arts Cluster-articles ,
+ getbiostrannot INTEGER ,
+ getbiostr-feat-ids Get-feat-ids ,
+ getbiostr-annot-by-fid Get-by-fid }
+
+Get-by-fid ::= SEQUENCE {
+ mmdbid INTEGER ,
+ feature-id INTEGER ,
+ feature-set-id INTEGER }
+
+Get-feat-ids ::= SEQUENCE {
+ mmdbid INTEGER ,
+ feature-type INTEGER ,
+ feature-set-id INTEGER }
+
+Cluster-articles ::= SEQUENCE {
+ ids Entrez-ids ,
+ fld Entrez-field ,
+ min-cluster INTEGER ,
+ max-cluster INTEGER ,
+ max-terms INTEGER }
+
+Cluster-resp ::= SEQUENCE {
+ count INTEGER ,
+ terms SEQUENCE OF VisibleString ,
+ term-counts SEQUENCE OF INTEGER }
+
+Entrez-blastreq ::= SEQUENCE {
+ bsp Bioseq , -- the sequence to be BLASTed
+ bsp-database Entrez-class ,
+ program VisibleString OPTIONAL ,
+ database VisibleString OPTIONAL ,
+ options VisibleString OPTIONAL ,
+ showprogress BOOLEAN OPTIONAL }
+
+Entrez-docget ::= SEQUENCE {
+ class Entrez-class ,
+ mark-missing BOOLEAN OPTIONAL ,
+ ids Entrez-ids ,
+ defer-count INTEGER OPTIONAL }
+
+Entrez-seqget ::= SEQUENCE { -- SeqEntryGet
+ retype ENUMERATED {
+ fetch-from-id (-2) , -- fetch these entries from the ID service
+ unmatched (-1) , -- an entry which for which SeqIds needn't match
+ entry (0) , -- the "natural" entry for this (nuc-prot)
+ bioseq (1) , -- only the bioseq identified
+ bioseq-set (2) , -- any seg-set it may be part of
+ nuc-prot (3) , -- any nuc-prot it may be part of
+ pub-set (4) } DEFAULT entry ,
+ mark-missing BOOLEAN OPTIONAL ,
+ ids Entrez-ids }
+
+Entrez-termget ::= SEQUENCE { -- terms query
+ max INTEGER OPTIONAL , -- maximum ids to return
+ cls Entrez-class , -- class of data to query
+ terms Entrez-term-list ,
+ date-constraints Date-constraints OPTIONAL }
+
+Date-constraints ::= SEQUENCE {
+ count INTEGER ,
+ date-vec SEQUENCE OF Date-vector
+}
+
+Date-vector ::= SEQUENCE {
+ begin-date Date OPTIONAL ,
+ end-date Date OPTIONAL ,
+ field-abbr VisibleString
+}
+
+Entrez-class ::= ENUMERATED { -- class of document to query
+ medline (0) ,
+ aa (1) ,
+ na (2) ,
+ st (3) ,
+ genome (4) }
+
+Entrez-field ::= INTEGER { -- type of field
+ word (0) , -- words
+ mesh (1) , -- meSH terms
+ keyword (2) , -- keyword
+ author (3) , -- author names
+ journal (4) , -- journal title
+ org (5) , -- organism name
+ accn (6), -- accession number
+ gene (7) , -- gene symbol
+ prot (8) , -- protein name
+ ecno (9) , -- E.C. number
+ hierarchy (10) , -- organism and MeSH hierarchies
+ pubdate (11) , -- publication date
+ fkey (12) , -- feature key
+ prop (13) , -- properties
+ subs (14) , -- substance
+ mloc (15) } -- map location
+
+Entrez-operator ::= ENUMERATED {
+ lparen (1) ,
+ rparen (2) ,
+ andsymbl (3) ,
+ orsymbl (4) ,
+ butnotsymbl (5) }
+
+Special-operand ::= SEQUENCE {
+ term VisibleString ,
+ fld Entrez-field ,
+ type Entrez-class ,
+ high-range VisibleString OPTIONAL }
+
+Total-operand ::= SEQUENCE {
+ term VisibleString ,
+ fld Entrez-field ,
+ type Entrez-class ,
+ high-range VisibleString OPTIONAL }
+
+Entrez-term-list ::= SEQUENCE OF CHOICE {
+ operator Entrez-operator ,
+ sp-operand Special-operand ,
+ tot-operand Total-operand }
+
+Link-setget ::= SEQUENCE {
+ max INTEGER OPTIONAL , -- maximum ids to return
+ link-to-cls Entrez-class , -- class of data to return
+ query-cls Entrez-class , -- class of query
+ mark-missing BOOLEAN DEFAULT FALSE , -- need to know which IDs didn't match
+ query-size INTEGER , -- size of query
+ query SEQUENCE OF INTEGER } -- ids of query
+
+
+Entrez-neighbor-text ::= SEQUENCE {
+ fld Entrez-field ,
+ percent-terms-to-use INTEGER ,
+ max-neighbors INTEGER ,
+ min-score INTEGER ,
+ normal-text VisibleString ,
+ special-text VisibleString }
+
+ --*********************************
+ -- replies (back)
+ --
+
+Entrez-back ::= CHOICE {
+ error INTEGER , -- Generic errors
+ init SEQUENCE { -- EntrezInit
+ e-info Cdrom-inf OPTIONAL
+ } ,
+ maxlinks INTEGER , -- EntGetMaxLinks
+ eval CHOICE { -- EntTLEval
+ bad-count INTEGER , -- if too many UIDs to return set
+ link-set Link-set } ,
+ docsum CHOICE { -- get summarys by term (DocSum)
+ ml Ml-summary-list , -- medline summary list
+ seq Seq-summary-list , -- sequence summary list
+ str Seq-summary-list } , -- biostruc summary list
+ linkuidlist Marked-link-set , -- LinkUidList
+ uidlinks Marked-link-set , -- UidLinks
+ byterm Entrez-term-resp , -- TermListByTerm
+ bypage Entrez-term-resp , -- TermListByPage
+ findterm Term-counts , -- EntrezFindTerm
+ fini NULL , -- EntrezFini
+ createnamed NULL ,
+ getmle Entrez-Medline-entry-list , -- get Medline Entry
+ getseq Entrez-Seq-entry-list , -- get SeqEntry
+ evalX OCTET STRING , -- EntTLEvalX
+ createnamedX NULL ,
+ seqidforgi Seq-id , -- EntrezSeqIdForGI
+ findseqid INTEGER , -- EntrezFindSeqId
+ canneighbortext BOOLEAN , -- EntrezCanNeighborText
+ expanded-medline BOOLEAN ,
+ get-hierarchy Entrez-Tree,
+ neighbortext Link-set ,
+ eval-count INTEGER , -- EntTLEvalCount
+ getbiostr Entrez-Biostruc-list ,-- EntrezBiostrucGet (obselete)
+ getbiostrX Entrez-Biostruc-list ,-- EntrezBiostrucGet
+ extrainfo Entrez-extra-info ,
+ blast CHOICE { -- BLAST
+ bad-count INTEGER , -- if too many UIDs to return set
+ link-set Link-set ,
+ job-start INTEGER ,
+ job-progress INTEGER } ,
+ docsumX New-summary-list ,
+ getgenome Entrez-Seq-entry-list , -- get genome (UNUSED)
+ cluster-arts Cluster-resp ,
+ getbiostrannot Biostruc-annot-set ,
+ getbiostr-feat-ids Link-set ,
+ getbiostr-annot-by-fid Biostruc-annot-set }
+
+Entrez-extra-info ::= SEQUENCE {
+ maxlinks INTEGER ,
+ canneighbortext BOOLEAN ,
+ expanded-medline BOOLEAN ,
+ canblast BOOLEAN }
+
+New-summary-list ::= SEQUENCE {
+ num INTEGER ,
+ type Entrez-class ,
+ data SEQUENCE OF Docsum }
+
+Ml-summary-list ::= SEQUENCE {
+ num INTEGER ,
+ data SEQUENCE OF Ml-summary }
+
+Ml-summary ::= SEQUENCE {
+ muid INTEGER ,
+ no-abstract BOOLEAN DEFAULT FALSE ,
+ translated-title BOOLEAN DEFAULT FALSE ,
+ no-authors BOOLEAN DEFAULT FALSE ,
+ caption VisibleString OPTIONAL ,
+ title VisibleString OPTIONAL }
+
+Seq-summary-list ::= SEQUENCE {
+ num INTEGER ,
+ data SEQUENCE OF Seq-summary }
+
+Seq-summary ::= SEQUENCE {
+ id INTEGER , -- Gi id
+ caption VisibleString OPTIONAL ,
+ title VisibleString OPTIONAL }
+
+Marked-link-set ::= SEQUENCE {
+ link-set Link-set ,
+ uids-processed INTEGER ,
+ marked-missing Entrez-ids OPTIONAL }
+
+Entrez-ids ::= SEQUENCE {
+ numid INTEGER , -- number of ids to follow
+ ids SEQUENCE OF INTEGER } -- the ids
+
+Entrez-term-by-page ::= SEQUENCE {
+ type Entrez-class , -- type of query
+ fld Entrez-field , --
+ page INTEGER , -- starting page number
+ num-pages INTEGER } -- # of pages desired
+
+Entrez-term-by-term ::= SEQUENCE {
+ type Entrez-class , -- type of query
+ fld Entrez-field , --
+ term VisibleString , -- term on which to key
+ num-terms INTEGER } -- # of terms desired
+
+Term-lookup ::= SEQUENCE {
+ type Entrez-class , -- type of query
+ fld Entrez-field , --
+ term VisibleString }
+
+Term-page-info ::= SEQUENCE {
+ term VisibleString ,
+ spec-count INTEGER ,
+ tot-count INTEGER }
+
+Term-counts ::= SEQUENCE {
+ found BOOLEAN , -- was the term found ?
+ spec-count INTEGER ,
+ tot-count INTEGER }
+
+Entrez-term-resp ::= SEQUENCE {
+ num-terms INTEGER ,
+ first-page INTEGER OPTIONAL,
+ pages-read INTEGER ,
+ info SEQUENCE OF Term-page-info }
+
+Entrez-named-list ::= SEQUENCE {
+ term VisibleString ,
+ type Entrez-class , -- type of query
+ fld Entrez-field , --
+ uids Entrez-ids }
+
+Entrez-named-listX ::= SEQUENCE {
+ term VisibleString ,
+ type Entrez-class , -- type of query
+ fld Entrez-field , --
+ uids OCTET STRING }
+
+Entrez-Seq-entry-list ::= SEQUENCE {
+ num INTEGER ,
+ data SEQUENCE OF Seq-entry ,
+ marked-missing Entrez-ids OPTIONAL }
+
+Entrez-Medline-entry-list ::= SEQUENCE {
+ num INTEGER ,
+ data SEQUENCE OF Medline-entry ,
+ marked-missing Entrez-ids OPTIONAL }
+
+Entrez-Biostruc-list ::= SEQUENCE {
+ num INTEGER ,
+ data SEQUENCE OF Biostruc ,
+ marked-missing Entrez-ids OPTIONAL }
+
+
+Entrez-Tree-Child ::= SEQUENCE {
+ name VisibleString ,
+ is-leaf-node BOOLEAN ,
+ special INTEGER ,
+ total INTEGER
+}
+
+Entrez-Tree ::= SEQUENCE {
+ num-in-lineage INTEGER ,
+ num-children INTEGER ,
+ term VisibleString ,
+ lineage SEQUENCE OF VisibleString ,
+ children SEQUENCE OF Entrez-Tree-Child ,
+ canonical-form VisibleString OPTIONAL
+}
+
+END
diff --git a/network/entrez/client/netentr.c b/network/entrez/client/netentr.c
new file mode 100644
index 00000000..1759475e
--- /dev/null
+++ b/network/entrez/client/netentr.c
@@ -0,0 +1,2754 @@
+/* netentr.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: netentr.c
+*
+* Author: Ostell, Kans, Epstein
+*
+* Version Creation Date: 06/02/92
+*
+* $Revision: 6.4 $
+*
+* File Description:
+* entrez index access library for Network Entrez
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 06-08-93 Schuler Changed datatype for Monitor from Handle to MonitorPtr
+*
+* 8-16-94 Brylawski Added routines to access medline term explosion,
+* mesh tree browsing, and on-the-fly neighboring.
+*
+* 11-20-94 Brylawski Modifed on-the-fly neighboring to permit the client
+* to pass more information about user preferences.
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: netentr.c,v $
+* Revision 6.4 1998/08/24 21:00:50 kans
+* fixed -v -fd warnings
+*
+* Revision 6.3 1998/03/20 18:40:07 kans
+* all xxxListAsnRead functions check for NULL, return before dereferencing NULL pointer
+*
+* Revision 6.2 1998/03/18 18:57:15 kans
+* return if selp == NULL to avoid dereferencing
+*
+* Revision 6.1 1998/02/21 22:34:34 kans
+* NetEntHierarchyGet passes type and field
+*
+* Revision 6.0 1997/08/25 18:34:53 madden
+* Revision changed to 6.0
+*
+* Revision 5.7 1997/07/29 21:24:09 vakatov
+* [WIN32,DLL] DLL'zation of "netentr.lib"
+*
+* Revision 5.6 1997/06/05 15:52:14 epstein
+* change name of NetInit function per Eric Hackborn's request
+*
+* Revision 5.5 1997/05/27 18:11:32 kans
+* NI_Service get failure uses ErrPostEx, not Message
+*
+* Revision 5.4 1997/04/02 20:59:49 epstein
+* Increased version number so network entrez server can detect older clients
+*
+ * Revision 5.3 1996/09/24 16:07:21 epstein
+ * Add ASN.1 spec version so server can discriminate between clients based upon their spec version
+ *
+ * Revision 5.2 1996/08/14 22:58:11 epstein
+ * tweaks for biostruc annots
+ *
+ * Revision 5.1 1996/08/14 19:43:54 epstein
+ * add annot get by feat ids, and also add date filtering support
+ *
+ * Revision 5.0 1996/05/28 14:10:21 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.13 1996/03/29 18:55:41 epstein
+ * add support for structure alignments
+ *
+ * Revision 4.12 1996/03/26 16:30:29 epstein
+ * migrate byte-swapping functions to ncbimisc.[ch]
+ *
+ * Revision 4.11 1995/12/27 21:36:02 epstein
+ * eliminate duplicate SkipSpaces() function which conflicts with new ncbistr.c function
+ *
+ * Revision 4.10 1995/11/13 22:02:00 epstein
+ * fix BLAST bad-count bug (per S. Shavirin)
+ *
+ * Revision 4.9 1995/10/02 15:28:27 epstein
+ * support range-checking
+ *
+ * Revision 4.8 1995/09/21 16:17:55 kans
+ * moved prototype for MsgSetReadTimeout
+ *
+ * Revision 4.7 1995/09/21 14:55:46 epstein
+ * add higher timeouts for evaluating boolean expressions
+ *
+ * Revision 4.6 1995/09/11 19:28:49 epstein
+ * add some more bullet-proofing when reestablish connections
+ *
+ * Revision 4.5 1995/08/28 17:27:36 epstein
+ * work around compiler nit
+ *
+ * Revision 4.4 1995/08/24 20:48:35 epstein
+ * adjust timeouts to accomodate slow cluster analysis
+ *
+ * Revision 4.2 1995/08/22 19:35:24 epstein
+ * add clustering support
+ *
+ * Revision 4.1 1995/08/11 20:27:22 epstein
+ * add max-models support for biostrucs
+ *
+ * Revision 4.0 1995/07/26 13:54:59 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.48 1995/07/11 14:51:50 epstein
+ * fix-up for new docsum implementation
+ *
+ * Revision 1.47 1995/06/29 16:36:28 epstein
+ * add biostruc-complexity, and use new biostrucX ASN.1 construct to communicate with server
+ *
+ * Revision 1.46 95/06/07 16:10:50 epstein
+ * add return value to SwapInEntrez()
+ *
+ * Revision 1.45 95/06/07 15:47:27 epstein
+ * make BLAST search cancellable in conjunction with Monitor
+ *
+ * Revision 1.44 95/05/17 17:53:08 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <accentr.h>
+#include <ncbinet.h>
+#include <netentr.h>
+#include <netlib.h>
+#include <netpriv.h>
+#include <objneten.h>
+
+typedef struct namedItem {
+ Boolean knownToServer;
+ CharPtr term;
+ Char tmpFileName[PATH_MAX];
+ DocType type;
+ DocField field;
+} NamedItem, PNTR NamedItemPtr;
+
+static void NEAR s_NetEntrezFini PROTO((void));
+static ByteStorePtr NEAR s_NetEntTLEvalX PROTO((ValNodePtr elst));
+static Int2 NEAR s_NetDocSumListGet PROTO((DocSumPtr PNTR result, Int2 numuid, DocType type, DocUidPtr uids, Int2 defer_count));
+static Int2 NEAR s_NetLinkUidList PROTO((LinkSetPtr PNTR result, DocType type, DocType link_to_type, Int2 numuid, DocUidPtr uids, Boolean mark_missing));
+static LinkSetPtr NEAR s_NetUidLinks PROTO((DocType type, DocUid uid, DocType link_to_type));
+static Int2 NEAR s_NetTermListByTerm PROTO((DocType type, DocField field, CharPtr term, Int2 numterms, TermListProc proc, Int2Ptr first_page));
+static Int2 NEAR s_NetTermListByPage PROTO((DocType type, DocField field, Int2 page, Int2 numpage, TermListProc proc));
+static Boolean NEAR s_NetEntrezFindTerm PROTO((DocType type, DocField field, CharPtr term, Int4Ptr spcl, Int4Ptr totl));
+static void NEAR s_NetEntrezCreateNamedUidList PROTO((CharPtr term, DocType type, DocField field, Int4 num, DocUidPtr uids));
+static Int2 NEAR s_NetEntSeqEntryListGet PROTO((SeqEntryPtr PNTR result, Int2 numuid, DocUidPtr uids, Int2 retcode, Boolean mark_missing));
+static
+Int2 NEAR s_NetEntMedlineEntryListGet PROTO((MedlineEntryPtr PNTR result, Int2 numuid, DocUidPtr uids, Boolean mark_missing));
+
+static NamedListPtr KnownNamedTerm PROTO((CharPtr term, Boolean onlyIfNotKnown, DocType type, DocField field));
+static void CleanupNamedUidLists PROTO((void));
+static AsnTypePtr NetEntReadAsn PROTO((void));
+static Boolean ReestablishNetEntrez PROTO((void));
+static Boolean SwapInEntrez PROTO((VoidPtr med));
+static void countChars PROTO((CharPtr str));
+
+static NI_HandPtr Entrez_ni = NULL;
+static AsnIoPtr Entrez_asnin = NULL;
+static AsnIoPtr Entrez_asnout = NULL;
+static EntrezInfoPtr vi = NULL;
+static CharPtr infoBuf = NULL;
+static size_t charCount = 0;
+static ValNodePtr namedTerms = NULL;
+static CharPtr netEntrezVersion = "2.02c2ASN1SPEC5 ";
+static CharPtr userApplId = NULL;
+static Boolean userWarnings;
+static EntrezExtraInfoPtr eeip = NULL;
+static Int4 serviceAttempts = 0;
+
+static AsnTypePtr ENTREZ_BACK = NULL;
+static AsnTypePtr ENTREZ_BACK_blast_bad_count = NULL;
+static AsnTypePtr ENTREZ_BACK_blast_job_progress = NULL;
+static AsnTypePtr ENTREZ_BACK_blast_job_start = NULL;
+static AsnTypePtr ENTREZ_BACK_blast_link_set = NULL;
+static AsnTypePtr ENTREZ_BACK_cluster_arts = NULL;
+static AsnTypePtr ENTREZ_BACK_docsumX = NULL;
+static AsnTypePtr ENTREZ_BACK_error = NULL;
+static AsnTypePtr ENTREZ_BACK_evalX = NULL;
+static AsnTypePtr ENTREZ_BACK_eval_count = NULL;
+static AsnTypePtr ENTREZ_BACK_extrainfo = NULL;
+static AsnTypePtr ENTREZ_BACK_get_hierarchy = NULL;
+static AsnTypePtr ENTREZ_BACK_init = NULL;
+static AsnTypePtr ENTREZ_BACK_init_e_info = NULL;
+static AsnTypePtr ENTREZ_BACK_neighbortext = NULL;
+static AsnTypePtr ENTREZ_REQUEST = NULL;
+static AsnTypePtr ENTREZ_REQUEST_blast = NULL;
+static AsnTypePtr ENTREZ_REQUEST_bypage = NULL;
+static AsnTypePtr ENTREZ_REQUEST_byterm = NULL;
+static AsnTypePtr ENTREZ_REQUEST_cluster_arts = NULL;
+static AsnTypePtr ENTREZ_REQUEST_createnamed = NULL;
+static AsnTypePtr ENTREZ_REQUEST_docsumX = NULL;
+static AsnTypePtr ENTREZ_REQUEST_evalX = NULL;
+static AsnTypePtr ENTREZ_REQUEST_eval_count = NULL;
+static AsnTypePtr ENTREZ_REQUEST_extrainfo = NULL;
+static AsnTypePtr ENTREZ_REQUEST_findseqid = NULL;
+static AsnTypePtr ENTREZ_REQUEST_findterm = NULL;
+static AsnTypePtr ENTREZ_REQUEST_fini = NULL;
+static AsnTypePtr ENTREZ_REQUEST_get_hierarchy = NULL;
+static AsnTypePtr ENTREZ_REQUEST_getbiostr = NULL;
+static AsnTypePtr ENTREZ_REQUEST_getbiostrX = NULL;
+static AsnTypePtr ENTREZ_REQUEST_getbiostrX_get = NULL;
+static AsnTypePtr REQUEST_getbiostrX_complexity = NULL;
+static AsnTypePtr REQUEST_getbiostrX_max_models = NULL;
+static AsnTypePtr ENTREZ_REQUEST_getbiostrannot = NULL;
+static AsnTypePtr REQUEST_getbiostr_feat_ids = NULL;
+static AsnTypePtr REQUEST_getbiostr_annot_by_fid = NULL;
+
+static AsnTypePtr ENTREZ_REQUEST_getmle = NULL;
+static AsnTypePtr ENTREZ_REQUEST_getseq = NULL;
+static AsnTypePtr ENTREZ_REQUEST_initX = NULL;
+static AsnTypePtr ENTREZ_REQUEST_initX_version = NULL;
+static AsnTypePtr ENTREZ_REQUEST_linkuidlist = NULL;
+static AsnTypePtr ENTREZ_REQUEST_neighbortext = NULL;
+static AsnTypePtr ENTREZ_REQUEST_seqidforgi = NULL;
+static AsnTypePtr ENTREZ_REQUEST_uidlinks = NULL;
+static AsnTypePtr ENTREZ_TERMGET_cls = NULL;
+static AsnTypePtr ENTREZ_TERMGET_terms = NULL;
+
+extern EntrezInfoPtr LIBCALL EntrezInfoAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+EntrezInfoPtr NetEntrezGetInfo PROTO((void));
+static void RemoveNonPrintingCharacters(CharPtr str);
+
+extern void MsgSetReadTimeout PROTO((MHandPtr mh, int t));
+
+
+static void NEAR FindAsnType (AsnTypePtr PNTR atp, AsnModulePtr amp, CharPtr str)
+
+{
+ if (atp != NULL && (*atp) == NULL) {
+ *atp = AsnTypeFind (amp, str);
+ }
+}
+
+
+/*****************************************************************************
+*
+* NetEntrezInit ()
+*
+*****************************************************************************/
+
+NLM_EXTERN Boolean CDECL NetEntrezInit (CharPtr appl_id, Boolean no_warnings)
+
+{
+ AsnIoPtr asnin;
+ AsnIoPtr asnout;
+ AsnTypePtr atp;
+ MediaPtr media;
+ DataVal av;
+ CharPtr versionId;
+ AsnModulePtr amp;
+
+ NetEntAsnLoad();
+ amp = AsnAllModPtr();
+
+ FindAsnType(&ENTREZ_BACK, amp, "Entrez-back");
+ FindAsnType(&ENTREZ_BACK_blast_bad_count, amp, "Entrez-back.blast.bad-count");
+ FindAsnType(&ENTREZ_BACK_blast_job_progress, amp, "Entrez-back.blast.job-progress");
+ FindAsnType(&ENTREZ_BACK_blast_job_start, amp, "Entrez-back.blast.job-start");
+ FindAsnType(&ENTREZ_BACK_blast_link_set, amp, "Entrez-back.blast.link-set");
+ FindAsnType(&ENTREZ_BACK_cluster_arts, amp, "Entrez-back.cluster-arts");
+ FindAsnType(&ENTREZ_BACK_docsumX, amp, "Entrez-back.docsumX");
+ FindAsnType(&ENTREZ_BACK_error, amp, "Entrez-back.error");
+ FindAsnType(&ENTREZ_BACK_evalX, amp, "Entrez-back.evalX");
+ FindAsnType(&ENTREZ_BACK_eval_count, amp, "Entrez-back.eval-count");
+ FindAsnType(&ENTREZ_BACK_extrainfo, amp, "Entrez-back.extrainfo");
+ FindAsnType(&ENTREZ_BACK_get_hierarchy, amp, "Entrez-back.get-hierarchy");
+ FindAsnType(&ENTREZ_BACK_init, amp, "Entrez-back.init");
+ FindAsnType(&ENTREZ_BACK_init_e_info, amp, "Entrez-back.init.e-info");
+ FindAsnType(&ENTREZ_BACK_neighbortext, amp, "Entrez-back.neighbortext");
+ FindAsnType(&ENTREZ_REQUEST, amp, "Entrez-request");
+ FindAsnType(&ENTREZ_REQUEST_blast, amp, "Entrez-request.blast");
+ FindAsnType(&ENTREZ_REQUEST_bypage, amp, "Entrez-request.bypage");
+ FindAsnType(&ENTREZ_REQUEST_byterm, amp, "Entrez-request.byterm");
+ FindAsnType(&ENTREZ_REQUEST_cluster_arts, amp, "Entrez-request.cluster-arts");
+ FindAsnType(&ENTREZ_REQUEST_createnamed, amp, "Entrez-request.createnamed");
+ FindAsnType(&ENTREZ_REQUEST_docsumX, amp, "Entrez-request.docsumX");
+ FindAsnType(&ENTREZ_REQUEST_evalX, amp, "Entrez-request.evalX");
+ FindAsnType(&ENTREZ_REQUEST_eval_count, amp, "Entrez-request.eval-count");
+ FindAsnType(&ENTREZ_REQUEST_extrainfo, amp, "Entrez-request.extrainfo");
+ FindAsnType(&ENTREZ_REQUEST_findseqid, amp, "Entrez-request.findseqid");
+ FindAsnType(&ENTREZ_REQUEST_findterm, amp, "Entrez-request.findterm");
+ FindAsnType(&ENTREZ_REQUEST_fini, amp, "Entrez-request.fini");
+ FindAsnType(&ENTREZ_REQUEST_get_hierarchy, amp, "Entrez-request.get-hierarchy");
+ FindAsnType(&ENTREZ_REQUEST_getbiostr, amp, "Entrez-request.getbiostr");
+ FindAsnType(&ENTREZ_REQUEST_getbiostrX, amp, "Entrez-request.getbiostrX");
+ FindAsnType(&REQUEST_getbiostrX_complexity, amp, "Entrez-request.getbiostrX.complexity");
+ FindAsnType(&REQUEST_getbiostrX_max_models, amp, "Entrez-request.getbiostrX.max-models");
+ FindAsnType(&ENTREZ_REQUEST_getbiostrX_get, amp, "Entrez-request.getbiostrX.get");
+ FindAsnType(&ENTREZ_REQUEST_getbiostrannot, amp, "Entrez-request.getbiostrannot");
+ FindAsnType(&REQUEST_getbiostr_feat_ids, amp, "Entrez-request.getbiostr-feat-ids");
+ FindAsnType(&REQUEST_getbiostr_annot_by_fid, amp, "Entrez-request.getbiostr-annot-by-fid");
+ FindAsnType(&ENTREZ_REQUEST_getmle, amp, "Entrez-request.getmle");
+ FindAsnType(&ENTREZ_REQUEST_getseq, amp, "Entrez-request.getseq");
+ FindAsnType(&ENTREZ_REQUEST_initX, amp, "Entrez-request.initX");
+ FindAsnType(&ENTREZ_REQUEST_initX_version, amp, "Entrez-request.initX.version");
+ FindAsnType(&ENTREZ_REQUEST_linkuidlist, amp, "Entrez-request.linkuidlist");
+ FindAsnType(&ENTREZ_REQUEST_neighbortext, amp, "Entrez-request.neighbortext");
+ FindAsnType(&ENTREZ_REQUEST_seqidforgi, amp, "Entrez-request.seqidforgi");
+ FindAsnType(&ENTREZ_REQUEST_uidlinks, amp, "Entrez-request.uidlinks");
+ FindAsnType(&ENTREZ_TERMGET_cls, amp, "Entrez-termget.cls");
+ FindAsnType(&ENTREZ_TERMGET_terms, amp, "Entrez-termget.terms");
+
+ if (! NetEInit())
+ return FALSE;
+
+ userWarnings = no_warnings;
+
+ Entrez_ni = NetServiceGet("ENTR_LINK", "Entrez", SwapInEntrez, Entrez_ni);
+ if (Entrez_ni == NULL)
+ {
+ serviceAttempts++;
+ ErrPostEx (SEV_ERROR, 0, 0, "NI_ServiceGet [%s] (%s) <%ld>",
+ ni_errlist[ni_errno], ni_errtext, (long) serviceAttempts);
+ Entrez_asnin = NULL;
+ Entrez_asnout = NULL;
+ NetEntrezFini();
+ return FALSE;
+ }
+
+ asnin = Entrez_ni->raip;
+ asnout = Entrez_ni->waip;
+
+ Entrez_asnin = asnin;
+ Entrez_asnout = asnout;
+
+ /* don't get upset if non-printing chars are encountered */
+ asnin->fix_non_print = 1;
+
+ /**********************************************************/
+
+ AsnWrite(asnout, ENTREZ_REQUEST, NULL);
+ AsnStartStruct(asnout, ENTREZ_REQUEST_initX);
+ if (netEntrezVersion != NULL) {
+ if (appl_id == NULL) {
+ av.ptrvalue = netEntrezVersion;
+ AsnWrite(asnout, ENTREZ_REQUEST_initX_version, &av);
+ } else {
+ versionId = MemNew(StrLen(netEntrezVersion) + StrLen(appl_id) + 4);
+ sprintf (versionId, "%s (%s)", netEntrezVersion, appl_id);
+ userApplId = StringSave(appl_id);
+ av.ptrvalue = versionId;
+ AsnWrite(asnout, ENTREZ_REQUEST_initX_version, &av);
+ MemFree (versionId);
+ }
+ }
+ AsnEndStruct(asnout, ENTREZ_REQUEST_initX);
+ AsnIoReset(asnout);
+
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ {
+ return FALSE;
+ }
+ else
+ {
+ AsnReadVal(asnin, atp, NULL); /* read the NULL */
+ atp = AsnReadId(asnin, amp, atp);
+ if (atp == ENTREZ_BACK_init_e_info)
+ {
+ if (vi != NULL)
+ {
+ EntrezInfoFree (vi);
+ vi = NULL;
+ }
+ vi = EntrezInfoAsnRead(asnin, atp);
+ if ((media = GetCurMedia()) != NULL &&
+ media->media_type == MEDIUM_NETWORK)
+ {
+ media->entrez_info = vi;
+ }
+ atp = AsnReadId(asnin, amp, atp);
+ }
+ if (atp != ENTREZ_BACK_init)
+ return FALSE;
+ AsnReadVal(asnin, atp, NULL); /* read the NULL */
+ ConfigInit();
+ return TRUE;
+ }
+}
+
+/*****************************************************************************
+*
+* NetEntrezFini ()
+*
+*****************************************************************************/
+
+static void NEAR s_NetEntrezFini (void)
+
+{
+ AsnTypePtr atp;
+ AsnIoPtr asnout = Entrez_asnout;
+ AsnIoPtr asnin = Entrez_asnin;
+
+ if (asnout != NULL && asnin != NULL)
+ {
+ AsnWrite(asnout, ENTREZ_REQUEST, NULL);
+ AsnWrite(asnout, ENTREZ_REQUEST_fini, NULL);
+ AsnIoReset(asnout);
+
+ if ((atp = NetEntReadAsn()) != NULL)
+ AsnReadVal(asnin, atp, NULL); /* read the NULL */
+ }
+
+ if (infoBuf != NULL)
+ {
+ MemFree(infoBuf);
+ infoBuf = NULL;
+ }
+
+ if (userApplId != NULL)
+ {
+ MemFree(userApplId);
+ userApplId = NULL;
+ }
+ if (eeip != NULL)
+ {
+ EntrezExtraInfoFree(eeip);
+ eeip = NULL;
+ }
+
+ NI_ServiceDisconnect(Entrez_ni);
+ NetFini();
+ ConfigFini();
+}
+
+/* the only thing done here is to suppress errors */
+NLM_EXTERN void CDECL NetEntrezFini (void)
+
+{
+ short erract;
+ ErrDesc err;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+
+ s_NetEntrezFini();
+
+ ErrSetOpts(erract, 0);
+ ErrFetch(&err);
+
+ CleanupNamedUidLists ();
+}
+
+/*****************************************************************************
+*
+* NetEntrezGetInfo()
+* returns global Entrez information
+*
+*****************************************************************************/
+NLM_EXTERN EntrezInfoPtr CDECL
+NetEntrezGetInfo(void)
+{
+ return vi;
+}
+
+/*****************************************************************************
+*
+* NetEntrezDetailedInfo()
+* returns NULL, or a string to some descriptive text
+*
+*****************************************************************************/
+NLM_EXTERN CharPtr CDECL
+NetEntrezDetailedInfo(void)
+{
+ charCount = 0;
+ DumpNetStats(SUBSYS_CLI_ENTREZ, countChars);
+
+ if (infoBuf != NULL)
+ MemFree(infoBuf);
+ infoBuf = MemNew(charCount + 540);
+ GetClientInfo(infoBuf);
+ return infoBuf;
+}
+
+static EntrezExtraInfoPtr
+GetEntrezExtraInfo(void)
+{
+ AsnTypePtr atp;
+ DataVal av;
+
+ if (eeip == NULL && Entrez_asnout != NULL)
+ {
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ av.intvalue = 4; /* number of currently known fields */
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST_extrainfo, &av);
+ AsnIoReset(Entrez_asnout);
+ if ((atp = NetEntReadAsn()) != NULL)
+ eeip = EntrezExtraInfoAsnRead(Entrez_asnin, ENTREZ_BACK_extrainfo);
+ }
+
+ return eeip;
+}
+
+/*****************************************************************************
+*
+* NetEntGetMaxLinks()
+* returns max links in link set allowed by system
+*
+*****************************************************************************/
+
+NLM_EXTERN Int4 NetEntGetMaxLinks(void)
+{
+ EntrezExtraInfoPtr myeeip;
+
+ if ((myeeip = GetEntrezExtraInfo()) == NULL)
+ {
+ return -1;
+ }
+
+ return myeeip->maxlinks;
+}
+
+/*****************************************************************************
+*
+* NetEntTLNew ()
+*
+*****************************************************************************/
+
+NLM_EXTERN ValNodePtr CDECL NetEntTLNew (DocType type)
+
+{
+ ValNodePtr anp;
+
+ anp = ValNodeNew(NULL);
+ anp->data.intvalue = (Int4)type;
+ return anp;
+}
+
+/*****************************************************************************
+*
+* NetEntTLAddTerm (elst, term, type, field, special)
+* Adds a term node to a boolean algebraic term query.
+*
+*****************************************************************************/
+
+NLM_EXTERN ValNodePtr CDECL NetEntTLAddTerm(ValNodePtr elst, CharPtr term, DocType type,
+ DocField field, Boolean special, CharPtr highRange)
+
+{
+ ValNodePtr anp;
+ TermDataPtr termdatp;
+ NamedListPtr nlp;
+
+ anp = NULL;
+ if (elst != NULL) {
+ if (elst->data.intvalue != (Int4)type)
+ return NULL;
+ anp = ValNodeNew (elst);
+ if (anp != NULL) {
+ if ((nlp = KnownNamedTerm(term, TRUE, type, field)) != NULL &&
+ nlp->uids != NULL) {
+ NetEntrezCreateNamedUidList (term, type, field, nlp->uids->numid,
+ nlp->uids->ids);
+ }
+
+ if (special) {
+ anp->choice = SPECIALTERM;
+ } else {
+ anp->choice = TOTALTERM;
+ }
+
+ termdatp = (TermDataPtr) MemNew(sizeof(TermData));
+ termdatp->field = field;
+ termdatp->type = type;
+ termdatp->term = StringSave(term);
+ termdatp->highRange = StringSave(highRange);
+ anp->data.ptrvalue = (Pointer) termdatp;
+ }
+ }
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Boolean terms", 1);
+ return anp;
+}
+
+/*****************************************************************************
+*
+* NetEntTLFree (elst)
+* Frees a boolean algebraic term query list.
+*
+*****************************************************************************/
+
+NLM_EXTERN ValNodePtr CDECL NetEntTLFree (ValNodePtr elst)
+
+{
+ ValNodePtr anp;
+ TermDataPtr trmp;
+
+ if (elst != NULL) {
+ elst->data.intvalue = 0; /* clear type */
+ for (anp = elst->next; anp != NULL; anp = anp->next) {
+ if (anp->choice == SPECIALTERM || anp->choice == TOTALTERM) {
+ trmp = (TermDataPtr) anp->data.ptrvalue;
+ MemFree (trmp->term);
+ trmp->term = NULL;
+ MemFree (trmp->highRange);
+ trmp->highRange = NULL;
+ }
+ }
+ ValNodeFreeData (elst);
+ }
+ return NULL;
+}
+
+/*****************************************************************************
+*
+* NetEntTLEval (elst)
+* Evaluates a boolean algebraic term query list, returning a pointer to
+* a LinkSetPtr containing the resultant unique identifiers.
+*
+*****************************************************************************/
+
+
+NLM_EXTERN LinkSetPtr CDECL NetEntTLEval (ValNodePtr elst)
+
+{
+ ByteStorePtr bsp;
+ LinkSetPtr lsp;
+ Int4 numlinks;
+
+ if ((bsp = NetEntTLEvalX(elst)) != NULL)
+ {
+ numlinks = BSLen(bsp) / sizeof(DocUid);
+ lsp = LinkSetNew();
+ lsp->num = numlinks;
+ if (numlinks <= EntrezGetUserMaxLinks())
+ {
+ lsp->uids = MemNew((size_t)(numlinks * sizeof(DocUid))); BSSeek (bsp, 0L, 0);
+ BSRead(bsp, lsp->uids, (numlinks * sizeof(DocUid)));
+ }
+ BSFree(bsp);
+ }
+ return lsp;
+
+}
+
+
+
+
+/*****************************************************************************
+*
+* NetEntTLEvalX (elst)
+* Evaluates a boolean algebraic term query list, returning a pointer to
+* a ByteStore containing the resultant unique identifiers.
+*
+*****************************************************************************/
+
+static ByteStorePtr NEAR s_NetEntTLEvalX (ValNodePtr elst)
+
+{
+ ByteStorePtr bsp = NULL;
+ AsnTypePtr atp;
+ DataVal av;
+
+ if (elst == NULL)
+ return NULL;
+ if (elst->next == NULL) /* expression without terms */
+ return NULL;
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ AsnStartStruct(Entrez_asnout, ENTREZ_REQUEST_evalX);
+ av.intvalue = elst->data.intvalue;
+ AsnWrite(Entrez_asnout, ENTREZ_TERMGET_cls, &av);
+ BoolExprAsnWrite (elst->next, Entrez_asnout, ENTREZ_TERMGET_terms);
+ AsnEndStruct(Entrez_asnout, ENTREZ_REQUEST_evalX);
+ AsnIoReset(Entrez_asnout);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return NULL;
+
+ if (atp == ENTREZ_BACK_evalX)
+ {
+ AsnReadVal(Entrez_asnin, atp, &av);
+ bsp = (ByteStorePtr) av.ptrvalue;
+#ifdef IS_LITTLE_ENDIAN
+ {
+ Int4 datum;
+ Int4 offset;
+ Int4 i;
+
+ for (i = BSLen(bsp) / sizeof(Int4), offset = 0; i > 0;
+ i--, offset += sizeof(Int4))
+ {
+ BSSeek(bsp, offset, SEEK_SET);
+ BSRead(bsp, &datum, sizeof(Int4));
+ datum = SwapUint4(datum);
+ BSSeek(bsp, offset, SEEK_SET);
+ BSWrite(bsp, &datum, sizeof(Int4));
+ }
+ }
+#endif /* IS_LITTLE_ENDIAN */
+ }
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Boolean expressions evaluated", 1);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Resulting UIDs from Boolean evaluation", bsp == NULL ? 0 : BSLen(bsp) / sizeof(DocUid));
+ return bsp;
+}
+
+NLM_EXTERN ByteStorePtr CDECL NetEntTLEvalX (ValNodePtr elst)
+
+{
+ int i;
+ ByteStorePtr retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ MsgSetReadTimeout(Entrez_ni, 1200);
+ retval = s_NetEntTLEvalX(elst);
+ MsgSetReadTimeout(Entrez_ni, 60);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ return retval; /* success */
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetEntTLEval failure");
+ return NULL;
+}
+
+/*****************************************************************************
+*
+* NetEntTLEvalCount (elst)
+* Evaluates a boolean algebraic term query list, returning a count of
+* the resultant unique identifiers.
+*
+*****************************************************************************/
+
+static Int4 NEAR s_NetEntTLEvalCount (ValNodePtr elst)
+
+{
+ Int4 retval = 0;
+ AsnTypePtr atp;
+ DataVal av;
+
+ if (elst->next == NULL) /* expression without terms */
+ return 0;
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ AsnStartStruct(Entrez_asnout, ENTREZ_REQUEST_eval_count);
+ av.intvalue = elst->data.intvalue;
+ AsnWrite(Entrez_asnout, ENTREZ_TERMGET_cls, &av);
+ BoolExprAsnWrite (elst->next, Entrez_asnout, ENTREZ_TERMGET_terms);
+ AsnEndStruct(Entrez_asnout, ENTREZ_REQUEST_eval_count);
+ AsnIoReset(Entrez_asnout);
+
+ MsgSetReadTimeout(Entrez_ni, 1200);
+ if ((atp = NetEntReadAsn()) == NULL)
+ return 0;
+ MsgSetReadTimeout(Entrez_ni, 60);
+
+ if (atp == ENTREZ_BACK_eval_count)
+ {
+ AsnReadVal(Entrez_asnin, atp, &av);
+ retval = (Int4) av.intvalue;
+ }
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Boolean expressions counted", 1);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Resulting UIDs from Boolean count-evaluation", retval);
+ return retval;
+}
+
+NLM_EXTERN Int4 CDECL NetEntTLEvalCount (ValNodePtr elst)
+
+{
+ int i;
+ Int4 retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetEntTLEvalCount(elst);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ return retval; /* success */
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetEntTLEvalCount failure");
+ return 0;
+}
+
+
+/*****************************************************************************
+*
+* NetDocSumListGet (result, numuid, type, uids)
+* returns a count of entries read
+* head of linked list is in result
+*
+*****************************************************************************/
+static Int2 NEAR s_NetDocSumListGet (DocSumPtr PNTR result, Int2 numuid,
+ DocType type, DocUidPtr uids,
+ Int2 defer_count)
+
+{
+ AsnTypePtr atp;
+ EntrezIdsPtr eip;
+ Int2 retval;
+ EntrezDocGetPtr edgp;
+ AsnModulePtr amp;
+ NewSummaryListPtr newlist;
+
+ NetEntAsnLoad();
+ amp = AsnAllModPtr();
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ edgp = EntrezDocGetNew();
+ edgp->ids = EntrezIdsNew();
+ eip = edgp->ids;
+ edgp->cls = type;
+ edgp->mark_missing = FALSE;
+ eip->numid = numuid;
+ eip->ids = uids;
+ edgp->defer_count = defer_count;
+ EntrezDocGetAsnWrite(edgp, Entrez_asnout, ENTREZ_REQUEST_docsumX);
+ eip->ids = NULL; /* for clean memory free */
+ EntrezDocGetFree(edgp);
+
+ AsnIoReset(Entrez_asnout);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return -1;
+
+ newlist = NewSummaryListAsnRead(Entrez_asnin, atp);
+ if (newlist == NULL)
+ return -1;
+ if (newlist->type != type)
+ {
+ NewSummaryListFree(newlist);
+ return -1;
+ }
+ MemCopy (result, newlist->data, (size_t) newlist->num * sizeof(DocSumPtr));
+ retval = newlist->num;
+ MemFree(newlist->data);
+ newlist->data = NULL; /* to avoid freeing actual DocSums */
+ NewSummaryListFree (newlist);
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Document summaries retrieved", retval);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Document summaries requested", numuid);
+
+ return retval;
+}
+
+NLM_EXTERN Int2 CDECL NetDocSumListGet (DocSumPtr PNTR result, Int2 numuid,
+ DocType type, DocUidPtr uids, Int2 defer_count)
+{
+ int i;
+ int retval;
+ short erract;
+ ErrDesc err;
+
+ /* default is to obtain these from the Entrez server */
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetDocSumListGet (result, numuid, type, uids, defer_count);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ goto expand_uids;
+ }
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "DocSumGet failure");
+ return -1;
+
+expand_uids:
+ if (retval < 0 || retval == numuid)
+ return retval;
+
+ {
+ Int2 i,j;
+ DocSumPtr dsp;
+#define USE_TEMP_MEMORY
+#ifdef USE_TEMP_MEMORY
+ DocSumPtr PNTR temp;
+
+ /* some UIDs are missing; we must find which ones and insert NULLs */
+ if ((temp = MemNew(sizeof(DocSumPtr) * numuid)) == NULL)
+ {
+ ErrPost(CTX_UNKNOWN, 1, "DocSumGet failure <memory allocation>");
+ return -1;
+ }
+
+ for (i = 0; i < numuid; i++)
+ {
+ temp[i] = result[i];
+ result[i] = NULL;
+ }
+
+ for (i = 0, j = 0; i < retval; i++) {
+ dsp = temp[i];
+ if (dsp != NULL) {
+ while (j < numuid && dsp->uid != uids[j]) {
+ j++;
+ }
+ if (j < numuid) {
+ result[j] = dsp;
+ j++;
+ }
+ }
+ }
+
+ MemFree (temp);
+#else
+ /* more dangerous algorithm ... operates on result in-place */
+ for (i = retval - 1, j = numuid - 1; i >= 0; i--) {
+ dsp = result[i];
+ if (dsp != NULL) {
+ while (j >= 0 && dsp->uid != uids[j]) {
+ result[j] = NULL;
+ j--;
+ }
+ if (j >= 0)
+ {
+ result[j] = dsp;
+ j--;
+ }
+ }
+ }
+
+ for (; j >= 0; j--)
+ { /* null out any unassigned bottom entries */
+ result[j] = NULL;
+ }
+#endif /* USE_TEMP_MEMORY */
+
+ return retval;
+ }
+}
+
+
+/*****************************************************************************
+*
+* DocSumPtr NetDocSum(type, uid)
+*
+*****************************************************************************/
+
+NLM_EXTERN DocSumPtr CDECL NetDocSum (DocType type, DocUid uid)
+{
+ DocSumPtr dsp = NULL;
+
+ NetDocSumListGet(&dsp, 1, type, &uid, 0);
+ return dsp;
+}
+
+/*****************************************************************************
+*
+* NetLinkUidList(type, link_to_type, numuid, uids)
+* returns count of input uids processed
+* returns -1 on error
+* if neighbors (type == link_to_type)
+* sums weights for same uids
+* if (more than EntrezUserMaxLinks() uids, frees uids and weights,
+* but leaves num set)
+*
+*****************************************************************************/
+static
+Int2 NEAR s_NetLinkUidList (LinkSetPtr PNTR result, DocType type,
+ DocType link_to_type, Int2 numuid, DocUidPtr uids,
+ Boolean mark_missing)
+
+{
+ LinkSetGetPtr lsgp;
+ MarkedLinkSetPtr mls;
+ AsnTypePtr atp;
+ Int2 retval;
+
+ lsgp = LinkSetGetNew();
+ lsgp->query_cls = type;
+ lsgp->link_to_cls = link_to_type;
+ lsgp->max = EntrezGetUserMaxLinks();
+ lsgp->mark_missing = mark_missing;
+ lsgp->query_size = numuid;
+ lsgp->query = MemNew(sizeof(DocUid) * numuid);
+
+ MemCopy (lsgp->query, uids, sizeof(DocUid) * numuid);
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ LinkSetGetAsnWrite(lsgp, Entrez_asnout, ENTREZ_REQUEST_linkuidlist);
+ AsnIoReset(Entrez_asnout);
+
+ LinkSetGetFree (lsgp);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return -1;
+ if ((mls = MarkedLinkSetAsnRead(Entrez_asnin, atp)) == NULL)
+ return -1;
+ *result = mls->link_set;
+ retval = mls->uids_processed;
+ if (mark_missing && mls->marked_missing != NULL)
+ MemCopy (uids, mls->marked_missing->ids, numuid * sizeof(DocUid));
+ mls->link_set = NULL; /* for clean memory free */
+ MarkedLinkSetFree (mls);
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "UID attempted for neighbors", numuid);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "UID processed for neighbors", retval);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "UID neighbors found", *result == NULL ? 0 : (*result)->num);
+ return retval;
+}
+
+NLM_EXTERN Int2 CDECL NetLinkUidList (LinkSetPtr PNTR result, DocType type,
+ DocType link_to_type, Int2 numuid, DocUidPtr uids,
+ Boolean mark_missing)
+{
+ int i;
+ int retval;
+ short erract;
+ ErrDesc err;
+ DocUidPtr local_uids;
+
+ /* make a local copy, to handle modifications */
+ local_uids = MemNew(sizeof(DocUid) * numuid);
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ MemCopy(local_uids, uids, sizeof(DocUid) * numuid);
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetLinkUidList(result, type, link_to_type, numuid,
+ local_uids, mark_missing);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ MemCopy(uids, local_uids, sizeof(DocUid) * numuid);
+ MemFree(local_uids);
+ return retval; /* success */
+ }
+ }
+
+ MemFree(local_uids);
+ ErrPost(CTX_UNKNOWN, 1, "NetLinkUidList failure");
+ return -1;
+}
+
+/*****************************************************************************
+*
+* NetUidLinks()
+* retrieves links to other uids
+*
+*****************************************************************************/
+static
+LinkSetPtr NEAR s_NetUidLinks(DocType type, DocUid uid, DocType link_to_type)
+
+{
+ LinkSetPtr lsp;
+ LinkSetGetPtr lsgp;
+ MarkedLinkSetPtr mls;
+ AsnTypePtr atp;
+
+ lsgp = LinkSetGetNew();
+ lsgp->query_cls = type;
+ lsgp->link_to_cls = link_to_type;
+ lsgp->max = EntrezGetUserMaxLinks();
+ lsgp->mark_missing = FALSE;
+ lsgp->query_size = 1;
+ lsgp->query = MemNew(sizeof(DocUid));
+ lsgp->query[0] = uid;
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ LinkSetGetAsnWrite(lsgp, Entrez_asnout, ENTREZ_REQUEST_uidlinks);
+ AsnIoReset(Entrez_asnout);
+
+ LinkSetGetFree (lsgp);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return NULL;
+ if ((mls = MarkedLinkSetAsnRead(Entrez_asnin, atp)) == NULL)
+ return NULL;
+ lsp = mls->link_set;
+ mls->link_set = NULL; /* for clean memory free */
+ MarkedLinkSetFree (mls);
+
+ return lsp;
+}
+
+NLM_EXTERN LinkSetPtr CDECL NetUidLinks(DocType type, DocUid uid, DocType link_to_type)
+{
+ int i;
+ LinkSetPtr retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetUidLinks(type, uid, link_to_type);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ return retval; /* success */
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetUidLinks failure");
+ return NULL;
+}
+
+
+/* The number of pages or terms to be obtain from the network in one request */
+#define NUM_NET_PAGES 4
+#define NUM_NET_TERMS 50
+
+/* The maximum number of terms to obtain in one TermListByTerm; this value */
+/* need not depend upon NUM_NET_TERMS */
+#define OBTAIN_IN_ONE_READ 100
+
+/*****************************************************************************
+*
+* NetTermListByTerm (type, field, term, numterms, proc, first_page)
+* Gets Terms starting with page near term
+* returns number of complete pages read
+* sets first_page to first page read
+*
+*****************************************************************************/
+static
+Int2 NEAR s_NetTermListByTerm (DocType type, DocField field, CharPtr term,
+ Int2 numterms, TermListProc proc,
+ Int2Ptr first_page)
+
+{
+ AsnIoPtr asnin = Entrez_asnin;
+ AsnIoPtr asnout = Entrez_asnout;
+ int i;
+ TermRespPtr p;
+ TermByTermPtr tbt;
+ TermByPagePtr tbp;
+ AsnTypePtr atp;
+ struct termresp PNTR termp;
+ int retval = 0;
+ int first_read = TRUE;
+ Boolean done = FALSE;
+ int next_page;
+ Int4 max_terms;
+ int terms_to_read;
+
+ if (numterms == 0) /* 0 ==> infinity */
+ max_terms = INT4_MAX;
+ else
+ max_terms = numterms;
+
+ while (! done) {
+ terms_to_read = MIN(max_terms, NUM_NET_TERMS);
+ if (first_read)
+ {
+ tbt = TermByTermNew();
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ tbt->type = type;
+ tbt->fld = field;
+ tbt->term = StringSave(term);
+
+ /* For efficiency, if the caller has only requested a few terms, */
+ /* then obtain them all in one shot; also note that if we're not */
+ /* going to obtain all of the requested terms in a single shot, */
+ /* then num_terms must be 0, because we need to read an integral */
+ /* number of pages. */
+ if (max_terms <= OBTAIN_IN_ONE_READ)
+ tbt->num_terms = max_terms;
+ else
+ tbt->num_terms = 0; /* bounded by # of pages, not terms */
+
+ TermByTermAsnWrite(tbt, Entrez_asnout, ENTREZ_REQUEST_byterm);
+ TermByTermFree (tbt);
+ }
+ else { /* we already know what page */
+ tbp = TermByPageNew();
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ tbp->type = type;
+ tbp->fld = field;
+ tbp->page = next_page;
+ tbp->num_pages = NUM_NET_PAGES;
+ TermByPageAsnWrite(tbp, Entrez_asnout, ENTREZ_REQUEST_bypage);
+ TermByPageFree (tbp);
+ }
+
+ AsnIoReset(Entrez_asnout);
+
+ /* now, read back response */
+ if ((atp = NetEntReadAsn()) == NULL)
+ return -1;
+ if ((p = TermRespAsnRead(asnin, atp)) == NULL)
+ return -1;
+
+ if (first_read)
+ {
+ *first_page = p->first_page;
+ next_page = p->first_page;
+ first_read = FALSE;
+ }
+
+ if (p->num_terms == 0) /* end of file */
+ done = TRUE;
+
+ termp = p->termresp;
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Terms read (by term)", p->num_terms);
+ for (i = 0; i < p->num_terms && !done; i++, termp++)
+ {
+ /* StringSave() is needed because application frees the term */
+ if (! proc(termp->term, termp->special_count, termp->total_count) )
+ done = TRUE;
+ termp->term = NULL;
+ }
+
+ retval += p->num_pages_read;
+ max_terms -= p->num_terms;
+ next_page += p->num_pages_read;
+
+ TermRespFree (p);
+
+ if (max_terms <= 0)
+ done = TRUE;
+ }
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Term pages read (by term)", retval);
+ return retval; /* page count */
+}
+
+NLM_EXTERN Int2 CDECL NetTermListByTerm (DocType type, DocField field, CharPtr term,
+ Int2 numterms, TermListProc proc,
+ Int2Ptr first_page)
+{
+ int i;
+ int retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetTermListByTerm (type, field, term, numterms,
+ proc, first_page);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ return retval; /* success */
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetTermListByTerm failure");
+ return 0;
+}
+
+/*****************************************************************************
+*
+* NetTermListByPage (type, field, page, numpage, proc)
+* Gets terms starting at page, for numpage, by calling proc
+* returns number of complete pages read
+*
+*****************************************************************************/
+
+static
+Int2 NEAR s_NetTermListByPage (DocType type, DocField field, Int2 page,
+ Int2 numpage, TermListProc proc)
+
+{
+ AsnIoPtr asnin = Entrez_asnin;
+ AsnIoPtr asnout = Entrez_asnout;
+ TermRespPtr p;
+ int i;
+ struct termresp PNTR termp;
+ TermByPagePtr tbp;
+ AsnTypePtr atp;
+ Boolean done = FALSE;
+ int retval = 0;
+ int next_page = page;
+ int pages_to_read;
+ Int4 max_pages;
+
+ if (numpage == 0) /* 0 ==> infinity */
+ max_pages = INT4_MAX;
+ else
+ max_pages = numpage;
+
+ while (! done) {
+ pages_to_read = MIN(max_pages, NUM_NET_PAGES);
+ tbp = TermByPageNew();
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ tbp->type = type;
+ tbp->fld = field;
+ tbp->page = next_page;
+ tbp->num_pages = pages_to_read;
+ TermByPageAsnWrite(tbp, Entrez_asnout, ENTREZ_REQUEST_bypage);
+ TermByPageFree(tbp);
+ AsnIoReset(Entrez_asnout);
+
+ /* now, read back response */
+ if ((atp = NetEntReadAsn()) == NULL)
+ return -1;
+ if ((p = TermRespAsnRead(asnin, atp)) == NULL)
+ return -1;
+
+ if (p->num_terms == 0) /* end of file */
+ done = TRUE;
+
+ termp = p->termresp;
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Terms read (by page)", p->num_terms);
+ for (i = 0; i < p->num_terms && !done; i++, termp++)
+ {
+ /* StringSave() is needed because application frees the term */
+ if (! proc(termp->term, termp->special_count, termp->total_count) )
+ done = TRUE;
+ termp->term = NULL;
+ }
+
+ retval += p->num_pages_read;
+ TermRespFree (p);
+
+ next_page += pages_to_read;
+ max_pages -= pages_to_read;
+
+ if (max_pages <= 0)
+ done = TRUE;
+ }
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Term pages read (by page)", retval);
+ return retval; /* page count */
+}
+
+NLM_EXTERN Int2 CDECL NetTermListByPage (DocType type, DocField field, Int2 page,
+ Int2 numpage, TermListProc proc)
+{
+ int i;
+ int retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetTermListByPage (type, field, page, numpage, proc);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ return retval; /* success */
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetTermListByPage failure");
+ return 0;
+}
+
+/*****************************************************************************
+*
+* NetEntrezFindTerm(type, field, term, spec, total)
+* returns count of special and total for a term
+* if term ends with "...", does a truncated merge of the term
+*
+*****************************************************************************/
+static
+Boolean NEAR s_NetEntrezFindTerm (DocType type, DocField field,
+ CharPtr term, Int4Ptr spcl, Int4Ptr totl)
+
+{
+ AsnIoPtr asnin = Entrez_asnin;
+ AsnIoPtr asnout = Entrez_asnout;
+ TermCountsPtr tcs;
+ TermLookupPtr tlp;
+ Boolean found;
+ AsnTypePtr atp;
+
+ tlp = TermLookupNew();
+ tlp->type = type;
+ tlp->fld = field;
+ tlp->term = StringSave(term);
+ AsnWrite(asnout, ENTREZ_REQUEST, NULL);
+ TermLookupAsnWrite(tlp, asnout, ENTREZ_REQUEST_findterm);
+ TermLookupFree(tlp);
+ AsnIoReset(asnout);
+
+ /* now, read back response */
+ if ((atp = NetEntReadAsn()) == NULL)
+ return FALSE;
+ if ((tcs = TermCountsAsnRead(asnin, atp)) == NULL)
+ return FALSE;
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Term lookup attempts", 1);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Terms found (special)", tcs->spec_count);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Terms found (total)", tcs->tot_count);
+ *spcl = tcs->spec_count;
+ *totl = tcs->tot_count;
+ found = tcs->found;
+
+ TermCountsFree(tcs);
+
+ return found;
+}
+
+NLM_EXTERN Boolean CDECL NetEntrezFindTerm (DocType type, DocField field,
+ CharPtr term, Int4Ptr spcl, Int4Ptr totl)
+
+{
+ int i;
+ int retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetEntrezFindTerm (type, field, term, spcl, totl);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ return retval; /* success */
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetEntrezFindTerm failure");
+ return FALSE;
+}
+
+
+static void CleanupNamedUidLists (void)
+{
+ ValNodePtr node;
+ NamedItemPtr nip;
+ ValNodePtr nextNode;
+
+ for (node = namedTerms; node != NULL; node = nextNode)
+ {
+ nip = (NamedItemPtr) node->data.ptrvalue;
+
+ nextNode = node->next;
+
+ if (nip != NULL) {
+ FileRemove (nip->tmpFileName);
+ MemFree (nip->term);
+ MemFree (nip);
+ }
+
+ MemFree (node);
+ }
+
+ namedTerms = NULL;
+}
+
+/**** Check to see if a term is already known to the Network server ********/
+static NamedListPtr KnownNamedTerm (CharPtr term, Boolean onlyIfNotKnown,
+ DocType type, DocField field)
+{
+ static NamedList dummy;
+ ValNodePtr node;
+ NamedItemPtr nip;
+ AsnIoPtr aip;
+ NamedListPtr nlp;
+
+
+ for (node = namedTerms; node != NULL; node = node->next)
+ {
+ nip = (NamedItemPtr) node->data.ptrvalue;
+
+ if (nip == NULL) {
+ continue;
+ }
+
+ if (StringICmp (term, nip->term) == 0 && type == nip->type &&
+ field == nip->field)
+ { /* match */
+ if (onlyIfNotKnown) {
+ if (! nip->knownToServer) {
+ /* read the file and load the data structure */
+ aip = AsnIoOpen (nip->tmpFileName, "rb");
+ nlp = NamedListAsnRead(aip, NULL);
+ AsnIoClose (aip);
+ return nlp;
+ } else {
+ return NULL;
+ }
+ } else {
+ return &dummy;
+ }
+ }
+ }
+
+ return NULL; /* not found */
+}
+
+/**** Creates a term node from the uid parameter ********/
+static void NEAR s_NetEntrezCreateNamedUidList (CharPtr term, DocType type, DocField field, Int4 num, DocUidPtr uids)
+{
+ AsnIoPtr asnin = Entrez_asnin;
+ AsnIoPtr asnout = Entrez_asnout;
+ NamedListPtr nlp;
+ AsnTypePtr atp;
+ NamedItemPtr namedItem;
+ AsnIoPtr aip;
+ ValNodePtr node;
+
+ nlp = NamedListNew();
+ nlp->type = type;
+ nlp->fld = field;
+ nlp->term = StringSave(term);
+ nlp->uids = EntrezIdsNew();
+ nlp->uids->numid = num;
+ nlp->uids->ids = (DocUidPtr) MemDup(uids, (size_t) num * sizeof(DocUid));
+ AsnWrite(asnout, ENTREZ_REQUEST, NULL);
+ NamedListAsnWrite(nlp, asnout, ENTREZ_REQUEST_createnamed);
+
+ AsnIoReset(asnout);
+
+ if (KnownNamedTerm(term, FALSE, type, field) == NULL) {
+ node = ValNodeNew (namedTerms);
+ if (namedTerms == NULL) {
+ namedTerms = node;
+ }
+ namedItem = MemNew (sizeof(NamedItem));
+ if (node != NULL && namedItem != NULL) {
+ namedItem->knownToServer = TRUE;
+ TmpNam (namedItem->tmpFileName);
+ namedItem->term = StringSave(term);
+ namedItem->type = type;
+ namedItem->field = field;
+ node->data.ptrvalue = (VoidPtr) namedItem;
+ aip = AsnIoOpen (namedItem->tmpFileName, "wb");
+ NamedListAsnWrite (nlp, aip, NULL);
+ AsnIoClose (aip);
+ }
+ }
+
+ NamedListFree(nlp);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return;
+ if (AsnReadVal(asnin, atp, NULL) < 0) /* read the NULL */
+ return;
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Named terms created", 1);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Named terms created (UID count)", num);
+}
+
+NLM_EXTERN void CDECL NetEntrezCreateNamedUidListX (CharPtr term, DocType type, DocField field, ByteStorePtr bsp)
+{}
+
+NLM_EXTERN void CDECL NetEntrezCreateNamedUidList (CharPtr term, DocType type, DocField field, Int4 num, DocUidPtr uids)
+{
+ int i;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ s_NetEntrezCreateNamedUidList (term, type, field, num, uids);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ return; /* success */
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetEntrezCreateNamedUidList failure");
+ return;
+}
+
+
+static AsnTypePtr NetEntReadAsn(void)
+{
+ AsnTypePtr atp;
+ DataVal av;
+ AsnIoPtr asnin = Entrez_asnin;
+ AsnModulePtr amp;
+
+ NetEntAsnLoad();
+ amp = AsnAllModPtr();
+
+ atp = ENTREZ_BACK;
+ if ((atp = AsnReadId(asnin, amp, atp)) != ENTREZ_BACK)
+ {
+ ErrPost(CTX_UNKNOWN, 1, "EOF on response from Entrez server");
+ return NULL;
+ }
+ AsnReadVal(asnin, atp, &av);
+ atp = AsnReadId(asnin, amp, atp); /* read the CHOICE */
+ if (atp == ENTREZ_BACK_error)
+ {
+ AsnReadVal(asnin, atp, &av);
+ return NULL;
+ }
+ else
+ return atp;
+}
+
+static Boolean ReestablishNetEntrez(void)
+{
+ Monitor *mon;
+ Boolean retval;
+ NamedItemPtr nip;
+ ValNodePtr node;
+ CharPtr uApplId = NULL;
+
+ if (userApplId != NULL)
+ { /* make a copy because this can get wiped out by NetEntrezInit() */
+ uApplId = StringSave(userApplId);
+ }
+
+ mon = MonitorStrNew("Re-establishing Entrez Service", 40);
+ MonitorStrValue(mon, "Requesting Entrez service");
+ NetFini();
+ retval = TRUE;
+
+ /* clear state information for named UID lists */
+ for (node = namedTerms; node != NULL; node = node->next)
+ {
+ nip = (NamedItemPtr) node->data.ptrvalue;
+
+ if (nip != NULL) {
+ nip->knownToServer = FALSE;
+ }
+ }
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Service Re-establishments", 1);
+
+ if (! NetEntrezInit(uApplId, userWarnings))
+ {
+ MonitorStrValue(mon, "Entrez get failed; re-contacting dispatcher");
+ retval = FALSE;
+ if (ForceNetInit())
+ { /* successfully established contact w/dispatcher */
+ MonitorStrValue(mon, "Entrez get failed; re-requesting Entrez service");
+ retval = NetEntrezInit(uApplId, userWarnings);
+ }
+ else {
+ ErrPost(CTX_UNKNOWN, 1, "Unable to re-contact dispatcher");
+ ErrShow();
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Service Re-establishments \"retries\"", 1);
+ }
+ }
+
+ MonitorFree(mon);
+
+ if (Entrez_asnin == NULL || Entrez_asnout == NULL)
+ {
+ retval = FALSE;
+ }
+
+ if (! retval )
+ {
+ ErrPost(CTX_UNKNOWN, 1, "Unable to re-establish Entrez service");
+ ErrShow();
+ } else {
+ ConfigFini(); /* to balance the extra ConfigInit() */
+ }
+
+ MemFree (uApplId);
+ return retval;
+}
+
+
+static Boolean SwapInEntrez (VoidPtr med)
+{
+ MediaPtr media = (MediaPtr) med;
+ NetMediaInfoPtr nmi;
+
+ if (media == NULL || (nmi = (NetMediaInfoPtr) media->media_info) == NULL)
+ return FALSE;
+
+ if (nmi->sessionHandle == NULL)
+ return FALSE;
+
+ Entrez_ni = nmi->sessionHandle;
+
+ Entrez_asnin = Entrez_ni->raip;
+ Entrez_asnout = Entrez_ni->waip;
+
+ return TRUE;
+}
+
+static void countChars(CharPtr str)
+{
+ charCount += StringLen(str) + 5;
+}
+
+/*****************************************************************************
+*
+* NetEntMedlineEntryListGet (result, numuid, uids, mark_missing)
+* returns a count of entries read
+* if (mark_missing) ids which could not be located are made negative
+*
+*****************************************************************************/
+static
+Int2 NEAR s_NetEntMedlineEntryListGet (MedlineEntryPtr PNTR result, Int2 numuid,
+ DocUidPtr uids, Boolean mark_missing)
+{
+ AsnTypePtr atp;
+ EntrezDocGetPtr edgp;
+ MedlineEntryListPtr mllp;
+ int count;
+
+ edgp = EntrezDocGetNew();
+
+ edgp->cls = TYP_ML; /* unused */
+ edgp->ids = EntrezIdsNew();
+ edgp->ids->numid = numuid;
+ edgp->ids->ids = uids;
+ edgp->mark_missing = mark_missing;
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ EntrezDocGetAsnWrite(edgp, Entrez_asnout, ENTREZ_REQUEST_getmle);
+ AsnIoReset(Entrez_asnout);
+ edgp->ids->ids = NULL; /* for clean memory free */
+ EntrezDocGetFree(edgp);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return 0;
+
+ if ((mllp = MedlineEntryListAsnRead(Entrez_asnin, atp)) == NULL)
+ return 0;
+
+ MemCopy (result, mllp->data, (size_t) mllp->num * sizeof(MedlineEntryPtr));
+
+ /* note that the structures underlying mllp->data are not freed; they */
+ /* are used by the caller */
+ MemFree(mllp->data);
+ mllp->data = NULL; /* for clean free */
+ if (mark_missing && mllp->marked_missing)
+ {
+ MemCopy (uids, mllp->marked_missing->ids,
+ (size_t) mllp->marked_missing->numid * sizeof(DocUid));
+ }
+ count = mllp->num;
+ MedlineEntryListFree (mllp);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Medline entries retrieved", count);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Medline entries requested", numuid);
+
+ return count;
+}
+
+NLM_EXTERN Int2 NetEntMedlineEntryListGet (MedlineEntryPtr PNTR result, Int2 numuid,
+ DocUidPtr uids, Boolean mark_missing)
+{
+ int i;
+ int retval;
+ short erract;
+ ErrDesc err;
+ DocUidPtr local_uids;
+
+ /* make a local copy, to handle modifications */
+ local_uids = MemNew(sizeof(DocUid) * numuid);
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ MemCopy(local_uids, uids, sizeof(DocUid) * numuid);
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetEntMedlineEntryListGet(result, numuid, local_uids,
+ mark_missing);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ MemCopy(uids, local_uids, sizeof(DocUid) * numuid);
+ MemFree(local_uids);
+ return retval; /* success */
+ }
+ }
+
+ MemFree(local_uids);
+ ErrPost(CTX_UNKNOWN, 1, "NetMedlineEntryListGet failure");
+ return -1;
+}
+
+/*****************************************************************************
+*
+* NetEntSeqEntryListGet (result, numuid, uids, mark_missing)
+* returns a count of entries read
+* if (mark_missing) ids which could not be located are made negative
+*
+*****************************************************************************/
+static
+Int2 NEAR s_NetEntSeqEntryListGet (SeqEntryPtr PNTR result, Int2 numuid, DocUidPtr uids, Int2 retcode, Boolean mark_missing)
+{
+ AsnTypePtr atp;
+ EntrezIdsPtr glp;
+ SeqEntryListPtr selp;
+ EntrezSeqGetPtr sgsp;
+ int count;
+
+ sgsp = EntrezSeqGetNew();
+ glp = EntrezIdsNew();
+ sgsp->ids = glp;
+
+ glp->numid = numuid;
+ glp->ids = uids;
+ sgsp->mark_missing = mark_missing;
+ sgsp->retype = retcode;
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ EntrezSeqGetAsnWrite(sgsp, Entrez_asnout, ENTREZ_REQUEST_getseq);
+ AsnIoReset(Entrez_asnout);
+ glp->ids = NULL; /* for clean memory free */
+ EntrezSeqGetFree(sgsp);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return 0;
+
+ if ((selp = SeqEntryListAsnRead(Entrez_asnin, atp)) == NULL)
+ return 0;
+
+ MemCopy (result, selp->data, (size_t) selp->num * sizeof(SeqEntryPtr));
+ /* note that the structures underlying selp->data are not freed; they */
+ /* are used by the caller */
+ MemFree(selp->data);
+ selp->data = NULL; /* for clean free */
+ if (mark_missing && selp->marked_missing)
+ {
+ MemCopy (uids, selp->marked_missing->ids,
+ (size_t) selp->marked_missing->numid * sizeof(DocUid));
+ }
+ count = selp->num;
+ SeqEntryListFree (selp);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Sequence entries retrieved", count);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Sequence entries requested", numuid);
+
+ return count;
+}
+
+NLM_EXTERN Int2 CDECL NetEntSeqEntryListGet (SeqEntryPtr PNTR result, Int2 numuid,
+ DocUidPtr uids, Int2 retcode, Boolean mark_missing)
+{
+ int i;
+ int retval;
+ short erract;
+ ErrDesc err;
+ DocUidPtr local_uids;
+
+ /* make a local copy, to handle modifications */
+ local_uids = MemNew(sizeof(DocUid) * numuid);
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ MemCopy(local_uids, uids, sizeof(DocUid) * numuid);
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetEntSeqEntryListGet(result, numuid, local_uids, retcode,
+ mark_missing);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ MemCopy(uids, local_uids, sizeof(DocUid) * numuid);
+ MemFree(local_uids);
+ return retval; /* success */
+ }
+ }
+
+ MemFree(local_uids);
+ ErrPost(CTX_UNKNOWN, 1, "NetSeqEntryListGet failure");
+ return -1;
+}
+
+
+#ifdef Biostruc_supported
+/*****************************************************************************
+*
+* NetEntrezBiostrucListGet (result, numuid, uids, mark_missing)
+* returns a count of entries read
+* if (mark_missing) ids which could not be located are made negative
+*
+*****************************************************************************/
+static
+Int2 NEAR s_NetEntrezBiostrucListGet (BiostrucPtr PNTR result, Int4 mdlLvl,
+ Int4 maxModels, Int2 numuid,
+ DocUidPtr uids, Boolean mark_missing)
+{
+ AsnTypePtr atp;
+ EntrezDocGetPtr edgp;
+ BiostrucListPtr bslp;
+ int count;
+ DataVal av;
+
+ edgp = EntrezDocGetNew();
+
+ edgp->cls = TYP_ST; /* unused */
+ edgp->ids = EntrezIdsNew();
+ edgp->ids->numid = numuid;
+ edgp->ids->ids = uids;
+ edgp->mark_missing = mark_missing;
+
+ av.intvalue = mdlLvl;
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ AsnStartStruct(Entrez_asnout, ENTREZ_REQUEST_getbiostrX);
+ AsnWrite(Entrez_asnout, REQUEST_getbiostrX_complexity, &av);
+ EntrezDocGetAsnWrite(edgp, Entrez_asnout, ENTREZ_REQUEST_getbiostrX_get);
+ av.intvalue = maxModels;
+ AsnWrite(Entrez_asnout, REQUEST_getbiostrX_max_models, &av);
+ AsnEndStruct(Entrez_asnout, ENTREZ_REQUEST_getbiostrX);
+ AsnIoReset(Entrez_asnout);
+ edgp->ids->ids = NULL; /* for clean memory free */
+ EntrezDocGetFree(edgp);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return 0;
+
+ if ((bslp = BiostrucListAsnRead(Entrez_asnin, atp)) == NULL)
+ return 0;
+
+ MemCopy (result, bslp->data, (size_t) bslp->num * sizeof(BiostrucPtr));
+
+ /* note that the structures underlying bslp->data are not freed; they */
+ /* are used by the caller */
+ MemFree(bslp->data);
+ bslp->data = NULL; /* for clean free */
+ if (mark_missing && bslp->marked_missing)
+ {
+ MemCopy (uids, bslp->marked_missing->ids,
+ (size_t) bslp->marked_missing->numid * sizeof(DocUid));
+ }
+ count = bslp->num;
+ BiostrucListFree (bslp);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Biostruc entries retrieved", count);
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Biostruc entries requested", numuid);
+
+ return count;
+}
+
+NLM_EXTERN Int2 NetEntrezBiostrucListGet (BiostrucPtr PNTR result, Int4 mdlLvl, Int4 maxModels, Int2 numuid,
+ DocUidPtr uids, Boolean mark_missing)
+{
+ int i;
+ int retval;
+ short erract;
+ ErrDesc err;
+ DocUidPtr local_uids;
+
+ /* make a local copy, to handle modifications */
+ local_uids = MemNew(sizeof(DocUid) * numuid);
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ MemCopy(local_uids, uids, sizeof(DocUid) * numuid);
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetEntrezBiostrucListGet(result, mdlLvl, maxModels, numuid, local_uids,
+ mark_missing);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ MemCopy(uids, local_uids, sizeof(DocUid) * numuid);
+ MemFree(local_uids);
+ return retval; /* success */
+ }
+ }
+
+ MemFree(local_uids);
+ ErrPost(CTX_UNKNOWN, 1, "NetBiostrucListGet failure");
+ return -1;
+}
+
+static
+BiostrucAnnotSetPtr NEAR s_NetEntrezBiostrucAnnotSetGet (DocUid gi)
+{
+ DataVal av;
+ BiostrucAnnotSetPtr retval;
+ AsnTypePtr atp;
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ av.intvalue = gi;
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST_getbiostrannot, &av);
+ AsnIoReset(Entrez_asnout);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return NULL;
+
+ retval = BiostrucAnnotSetAsnRead(Entrez_asnin, atp);
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "BiostrucAnnotSets retrieved", 1);
+
+ return retval;
+}
+
+NLM_EXTERN BiostrucAnnotSetPtr CDECL NetEntrezBiostrucAnnotSetGet (DocUid gi)
+{
+ int i;
+ BiostrucAnnotSetPtr retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetEntrezBiostrucAnnotSetGet(gi);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ return retval; /* success */
+ }
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetBiostrucAnnotSet failure");
+ return NULL;
+}
+
+static
+LinkSetPtr NEAR s_NetEntrezBiostrucFeatIds(DocUid mmdbid, Int2 feature_type, Int4 feature_set_id)
+{
+ LinkSetPtr retval;
+ GetFeatIdsPtr gfi;
+ AsnTypePtr atp;
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ gfi = GetFeatIdsNew();
+ gfi->mmdbid = mmdbid;
+ gfi->feature_type = feature_type;
+ gfi->feature_set_id = feature_set_id;
+ GetFeatIdsAsnWrite(gfi, Entrez_asnout, REQUEST_getbiostr_feat_ids);
+ AsnIoReset(Entrez_asnout);
+ GetFeatIdsFree(gfi);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return NULL;
+
+ retval = LinkSetAsnRead(Entrez_asnin, atp);
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "BiostrucAnnotFeatids retrieved", 1);
+
+ return retval;
+}
+
+NLM_EXTERN LinkSetPtr CDECL NetEntrezBiostrucFeatIds(DocUid mmdbid, Int2 feature_type, Int4 feature_set_id)
+{
+ int i;
+ LinkSetPtr retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetEntrezBiostrucFeatIds(mmdbid, feature_type, feature_set_id);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ return retval; /* success */
+ }
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetBiostrucAnnotFeatIds failure");
+ return NULL;
+}
+
+static
+BiostrucAnnotSetPtr NEAR s_NetEntrezBiostrucAnnotSetGetByFid (DocUid mmdbid, Int4 feature_id, Int4 feature_set_id)
+{
+ BiostrucAnnotSetPtr retval;
+ AsnTypePtr atp;
+ GetByFidPtr gbf;
+
+ gbf = GetByFidNew();
+ gbf->mmdbid = mmdbid;
+ gbf->feature_id = feature_id;
+ gbf->feature_set_id = feature_set_id;
+ GetByFidAsnWrite(gbf, Entrez_asnout, REQUEST_getbiostr_annot_by_fid);
+ AsnIoReset(Entrez_asnout);
+ GetByFidFree(gbf);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return NULL;
+
+ retval = BiostrucAnnotSetAsnRead(Entrez_asnin, atp);
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "BiostrucAnnotSetsByFid retrieved", 1);
+
+ return retval;
+}
+
+NLM_EXTERN BiostrucAnnotSetPtr CDECL NetEntrezBiostrucAnnotSetGetByFid (DocUid mmdbid, Int4 feature_id, Int4 feature_set_id)
+{
+ int i;
+ BiostrucAnnotSetPtr retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetEntrezBiostrucAnnotSetGetByFid (mmdbid, feature_id, feature_set_id);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ return retval; /* success */
+ }
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetBiostrucAnnotByFid failure");
+ return NULL;
+}
+#endif /* Biostruc_supported */
+
+
+static
+SeqIdPtr NEAR s_NetSeqIdForGI (DocUid gi)
+{
+ DataVal av;
+ SeqIdPtr retval;
+ AsnTypePtr atp;
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ av.intvalue = gi;
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST_seqidforgi, &av);
+ AsnIoReset(Entrez_asnout);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return NULL;
+
+ retval = SeqIdAsnRead(Entrez_asnin, atp);
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Sequence IDs looked up by GI", 1);
+
+ return retval;
+}
+
+NLM_EXTERN SeqIdPtr CDECL NetSeqIdForGI (DocUid gi)
+{
+ int i;
+ SeqIdPtr retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetSeqIdForGI(gi);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ return retval; /* success */
+ }
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetSeqIdForGI failure");
+ return NULL;
+}
+
+static
+Int4 NEAR s_NetFindSeqId (SeqIdPtr sip)
+{
+ DataVal av;
+ AsnTypePtr atp;
+
+ AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
+ SeqIdAsnWrite(sip, Entrez_asnout, ENTREZ_REQUEST_findseqid);
+ AsnIoReset(Entrez_asnout);
+
+ if ((atp = NetEntReadAsn()) == NULL)
+ return 0;
+
+ AsnReadVal(Entrez_asnin, atp, &av);
+
+ LOG_STAT(SUBSYS_CLI_ENTREZ, "Sequence GIs looked up by SeqID", 1);
+
+ return av.intvalue;
+}
+
+NLM_EXTERN Int4 CDECL NetEntrezFindSeqId (SeqIdPtr sip)
+{
+ int i;
+ Int4 retval;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ retval = s_NetFindSeqId(sip);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ return retval; /* success */
+ }
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetFindSeqId failure");
+
+ return 0;
+}
+
+static EntrezHierarchyPtr s_NetEntHierarchyGet(CharPtr term, DocType type, DocField field)
+{
+ AsnIoPtr asnin = Entrez_asnin;
+ AsnIoPtr asnout = Entrez_asnout;
+ EntrezHierarchyPtr ehp;
+ TermLookupPtr tlp;
+ AsnTypePtr atp;
+
+ tlp = TermLookupNew();
+ tlp->type = type;
+ tlp->fld = field;
+ tlp->term = StringSave(term);
+ AsnWrite(asnout, ENTREZ_REQUEST, NULL);
+ TermLookupAsnWrite(tlp, asnout, ENTREZ_REQUEST_get_hierarchy);
+ TermLookupFree(tlp);
+ AsnIoReset(asnout);
+
+ /* now, read back response */
+ if ((atp = NetEntReadAsn()) == NULL)
+ return FALSE;
+
+ if ( (ehp = EntrezHierarchyAsnRead(asnin,ENTREZ_BACK_get_hierarchy)) == NULL)
+ return NULL;
+
+ if (ehp->numInLineage == 0 && ehp->numChildren == 0)
+ {
+ EntrezHierarchyFree(ehp);
+ return NULL;
+ }
+
+ return (ehp);
+}
+
+
+NLM_EXTERN EntrezHierarchyPtr NetEntHierarchyGet (CharPtr term, DocType type, DocField field)
+{
+ int i;
+ EntrezHierarchyPtr ehp;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ ehp = s_NetEntHierarchyGet(term, type, field);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ return ehp; /* success */
+ }
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetEntMeshTreeGet failure");
+
+ return NULL;
+}
+
+static Int2 s_DatabaseFromName (CharPtr name)
+
+{
+ Int2 db;
+ EntrezInfoPtr eip;
+
+ if (name == NULL) return 0;
+ eip = EntrezGetInfo ();
+ if (eip == NULL || eip->type_info == NULL) return 0;
+ for (db = 0; db < eip->type_count; db++) {
+ if (StringICmp (eip->type_info [db].name, name) == 0) {
+ return eip->type_info [db].id;
+ }
+ }
+ return 0;
+}
+
+static Int2 s_FieldFromTag (CharPtr tag)
+
+{
+ EntrezInfoPtr eip;
+ Int2 fld;
+
+ if (tag == NULL) return 0;
+ eip = EntrezGetInfo ();
+ if (eip == NULL || eip->field_info == NULL) return 0;
+ for (fld = 0; fld < eip->field_count; fld++) {
+ if (StringICmp (eip->field_info [fld].tag, tag) == 0) {
+ return eip->field_info [fld].id;
+ }
+ }
+ return 0;
+}
+
+NLM_EXTERN EntrezHierarchyPtr NetEntMeshHierarchyGet(CharPtr term)
+{
+ Int2 fld_mesh_hier;
+ Int2 typ_ml;
+
+ typ_ml = s_DatabaseFromName ("MEDLINE");
+ fld_mesh_hier = s_FieldFromTag ("MESH");
+ return NetEntHierarchyGet (term, typ_ml, fld_mesh_hier);
+}
+
+
+static LinkSetPtr s_NetEntDoNeighborText(EntrezNeighborTextPtr entp)
+{
+ LinkSetPtr lsp = NULL;
+ AsnTypePtr atp;
+ AsnIoPtr asnin = Entrez_asnin;
+ AsnIoPtr asnout = Entrez_asnout;
+
+ RemoveNonPrintingCharacters(entp->normalText);
+ RemoveNonPrintingCharacters(entp->specialText);
+
+ if ( (*SkipSpaces(entp->normalText) == '\0')
+ && (*SkipSpaces(entp->specialText) == '\0') )
+ return (NULL);
+
+ AsnWrite(asnout, ENTREZ_REQUEST, NULL);
+ EntrezNeighborTextAsnWrite(entp,asnout,ENTREZ_REQUEST_neighbortext);
+ AsnIoReset(asnout);
+
+ if ( (atp = NetEntReadAsn()) == NULL)
+ return NULL;
+
+ if ( (lsp = LinkSetAsnRead(asnin, ENTREZ_BACK_neighbortext)) == NULL)
+ return(NULL);
+
+ return (lsp);
+}
+
+
+
+NLM_EXTERN LinkSetPtr CDECL NetEntDoNeighborText (EntrezNeighborTextPtr entp)
+{
+ int i;
+ LinkSetPtr lsp;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ lsp = s_NetEntDoNeighborText(entp);
+/* debug if (lsp == NULL)
+ fprintf(stderr,"failed to get linkset pointer. \n"); */
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ return lsp; /* success */
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetEntDoNeighborText failure");
+ return NULL;
+}
+
+
+NLM_EXTERN Boolean CDECL NetEntCanNeighborText(void)
+{
+ EntrezExtraInfoPtr myeeip;
+
+ if ((myeeip = GetEntrezExtraInfo()) == NULL)
+ {
+ return FALSE;
+ }
+
+ return myeeip->canneighbortext;
+}
+
+
+NLM_EXTERN Boolean CDECL NetEntExpandedMedlineFeatures(void)
+{
+ EntrezExtraInfoPtr myeeip;
+
+ if ((myeeip = GetEntrezExtraInfo()) == NULL)
+ {
+ return FALSE;
+ }
+
+ return myeeip->expanded_medline;
+}
+
+
+NLM_EXTERN Boolean CDECL NetEntCanBlast(void)
+{
+ EntrezExtraInfoPtr myeeip;
+
+ if ((myeeip = GetEntrezExtraInfo()) == NULL)
+ {
+ return FALSE;
+ }
+
+ return myeeip->canblast;
+}
+
+
+static void RemoveNonPrintingCharacters(CharPtr str)
+{
+ while (*str)
+ {
+ if ( (*str < ' ') || (*str > 0x7E) )
+ *str = ' ';
+ str++;
+ }
+}
+
+static Boolean
+blastProgressMonitor (Int4 value, Boolean isStart, Boolean destroyIt)
+{
+ static MonitorPtr mon = NULL;
+ Boolean retval = TRUE;
+
+ if (destroyIt)
+ {
+ if (mon != NULL)
+ {
+ MonitorFree(mon);
+ mon = NULL;
+ }
+ return TRUE;
+ }
+
+ if (isStart)
+ {
+ if (mon != NULL)
+ {
+ MonitorFree(mon);
+ mon = NULL;
+ }
+ mon = MonitorIntNew("BLAST progress", 0, value);
+ } else {
+ if (mon != NULL)
+ {
+ retval = MonitorIntValue(mon, value);
+ }
+ }
+
+ return retval;
+}
+
+static LinkSetPtr
+s_NetEntBlastBioseq(BioseqPtr bsp, DocType db, CharPtr program, CharPtr database, CharPtr options, Boolean usemonitor, BoolPtr noMoreTriesPtr)
+{
+ EntrezBlastreqPtr ebrp;
+ LinkSetPtr lsp;
+ AsnTypePtr atp;
+ DataVal av;
+ AsnModulePtr amp;
+
+ NetEntAsnLoad();
+ amp = AsnAllModPtr();
+
+ ebrp = EntrezBlastreqNew();
+ ebrp->bsp = bsp;
+ ebrp->bsp_database = db;
+ ebrp->program = StringSave(program);
+ ebrp->database = StringSave(database);
+ ebrp->options = StringSave(options);
+ ebrp->showprogress = usemonitor;
+ EntrezBlastreqAsnWrite(ebrp, Entrez_asnout, ENTREZ_REQUEST_blast);
+ ebrp->bsp = NULL; /* we don't "own" this so have no business freeing it */
+ EntrezBlastreqFree(ebrp);
+ AsnIoReset(Entrez_asnout);
+
+ while (TRUE)
+ {
+ if ( (atp = NetEntReadAsn()) == NULL)
+ return NULL;
+ AsnReadVal(Entrez_asnin, atp, NULL);
+ if ( (atp = AsnReadId(Entrez_asnin, amp, atp)) == NULL)
+ return NULL;
+ if (atp == ENTREZ_BACK_blast_bad_count)
+ {
+ AsnReadVal(Entrez_asnin, atp, NULL);
+ blastProgressMonitor(0, FALSE, TRUE);
+ return NULL;
+ } else
+ if (atp == ENTREZ_BACK_blast_link_set)
+ {
+ blastProgressMonitor(0, FALSE, TRUE);
+ lsp = LinkSetAsnRead(Entrez_asnin, atp);
+ return (lsp);
+ } else
+ if (atp == ENTREZ_BACK_blast_job_start)
+ {
+ AsnReadVal(Entrez_asnin, atp, &av);
+ if (usemonitor)
+ blastProgressMonitor(av.intvalue, TRUE, FALSE);
+ } else
+ if (atp == ENTREZ_BACK_blast_job_progress)
+ {
+ AsnReadVal(Entrez_asnin, atp, &av);
+ if (usemonitor)
+ if (! blastProgressMonitor(av.intvalue, FALSE, FALSE))
+ { /* user cancelled BLAST search */
+ blastProgressMonitor(0, FALSE, TRUE);
+ /* drop our connection since we don't know what state we're in */
+ ReestablishNetEntrez();
+ if (noMoreTriesPtr != NULL)
+ *noMoreTriesPtr = TRUE;
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+ }
+}
+
+NLM_EXTERN LinkSetPtr LIBCALL
+NetEntBlastBioseq(BioseqPtr bsp, DocType db, CharPtr program, CharPtr database, CharPtr options, Boolean usemonitor)
+{
+ int i;
+ LinkSetPtr lsp;
+ short erract;
+ ErrDesc err;
+ Boolean noMoreTries;
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ MsgSetReadTimeout(Entrez_ni, 1200);
+ noMoreTries = FALSE;
+ lsp = s_NetEntBlastBioseq(bsp, db, program, database, options, usemonitor, &noMoreTries);
+ MsgSetReadTimeout(Entrez_ni, 60);
+ ErrSetOpts(erract, 0);
+ if (noMoreTries || ! ErrFetch(&err))
+ return lsp;
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetEntBlastBioseq failure");
+ return NULL;
+}
+
+static Int4 s_NetEntClusterAnalysis(DocUidPtr uids, Int4 numuids, DocField fld, Int4 minCluster, Int4 maxCluster, Int4 maxTerms, CharPtr *terms, Int4Ptr termTotals)
+{
+ ClusterArticlesPtr clap;
+ ClusterRespPtr clrp;
+ EntrezIdsPtr eip;
+ Int4 numTerms;
+ Int4 i;
+ ValNodePtr vnpTerms;
+ ValNodePtr vnpCounts;
+ AsnTypePtr atp;
+
+ clap = ClusterArticlesNew();
+ eip = EntrezIdsNew();
+ eip->ids = uids;
+ eip->numid = numuids;
+ clap->ids = eip;
+ clap->fld = fld;
+ clap->min_cluster = minCluster;
+ clap->max_cluster = maxCluster;
+ clap->max_terms = maxTerms;
+ ClusterArticlesAsnWrite(clap, Entrez_asnout, ENTREZ_REQUEST_cluster_arts);
+ AsnIoReset(Entrez_asnout);
+ eip->ids = NULL; /* for clean free */
+ ClusterArticlesFree(clap);
+
+ if ( (atp = NetEntReadAsn()) == NULL)
+ return -1;
+ if ( (clrp = ClusterRespAsnRead(Entrez_asnin, ENTREZ_BACK_cluster_arts)) == NULL)
+ return -1;
+ numTerms = clrp->count;
+
+ for (vnpTerms = clrp->terms, vnpCounts = clrp->term_counts, i = 0;
+ vnpTerms != NULL && vnpCounts != NULL; i++, vnpTerms = vnpTerms->next,
+ vnpCounts = vnpCounts->next)
+ {
+ terms[i] = (CharPtr) vnpTerms->data.ptrvalue;
+ vnpTerms->data.ptrvalue = NULL; /* for clean free */
+ termTotals[i] = (Int4) vnpCounts->data.intvalue;
+ }
+
+ ClusterRespFree(clrp);
+ return numTerms;
+}
+
+NLM_EXTERN Int4 LIBCALL NetEntClusterAnalysis(DocUidPtr uids, Int4 numuids, DocField fld, Int4 minCluster, Int4 maxCluster, Int4 maxTerms, CharPtr *terms, Int4Ptr termTotals)
+{
+ int i;
+ Int4 retval;
+ short erract;
+ ErrDesc err;
+ extern void MsgSetReadTimeout PROTO((MHandPtr mh, int t));
+
+ for (i = 0; i < ENT_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetEntrez())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ MsgSetReadTimeout(Entrez_ni, 1200);
+ retval = s_NetEntClusterAnalysis(uids, numuids, fld, minCluster, maxCluster, maxTerms, terms, termTotals);
+ MsgSetReadTimeout(Entrez_ni, 60);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ {
+ return retval; /* success */
+ }
+ }
+
+ ErrPost(CTX_UNKNOWN, 1, "NetEntClusterAnalysis failure");
+
+ return -1;
+}
diff --git a/network/entrez/client/netentr.h b/network/entrez/client/netentr.h
new file mode 100644
index 00000000..d4fd3f63
--- /dev/null
+++ b/network/entrez/client/netentr.h
@@ -0,0 +1,234 @@
+/* netentr.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: netentr.h
+*
+* Author: Ostell, Kans, Epstein
+*
+* Version Creation Date: 10/15/91
+*
+* $Revision: 6.1 $
+*
+* File Description:
+* entrez index access library for Entrez network version
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 8-16-94 Brylawski Added declarations for on-the-fly neighboring,
+* medline explosion, and mesh tree browsing.
+*
+* 11-20-94 Brylawski Modified NetEntDoNeighborText to pass user preferences.
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: netentr.h,v $
+* Revision 6.1 1998/02/21 22:34:38 kans
+* NetEntHierarchyGet passes type and field
+*
+* Revision 6.0 1997/08/25 18:34:57 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/07/29 21:24:13 vakatov
+* [WIN32,DLL] DLL'zation of "netentr.lib"
+*
+* Revision 5.1 1996/08/14 19:47:49 epstein
+* add annot get by feat ids, and also add date filtering support
+*
+ * Revision 5.0 1996/05/28 14:10:21 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.5 1996/03/30 15:10:43 ostell
+ * changed LIBCALL to CDECL in NetEntrezBiostructAnnotSetGet
+ *
+ * Revision 4.4 1996/03/29 18:55:49 epstein
+ * add support for structure alignments
+ *
+ * Revision 4.3 1995/10/02 15:29:05 epstein
+ * support range-checking
+ *
+ * Revision 4.2 1995/08/22 19:35:27 epstein
+ * add clustering support
+ *
+ * Revision 4.1 1995/08/11 20:28:03 epstein
+ * add max-models support for biostrucs
+ *
+ * Revision 4.0 1995/07/26 13:54:59 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.18 1995/06/29 16:36:46 epstein
+ * add biostruc-complexity
+ *
+ * Revision 1.17 95/05/17 17:53:13 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NETENTREZ_
+#define _NETENTREZ_
+
+#ifndef _ENTREZ_
+#include <accentr.h>
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TERM_MAX 80
+
+struct termresp {
+ CharPtr term;
+ Int4 special_count;
+ Int4 total_count;
+};
+
+typedef struct {
+ Int4 num_terms;
+ Int4 first_page;
+ Int4 num_pages_read;
+ struct termresp PNTR termresp;
+} TermResp, PNTR TermRespPtr;
+
+typedef struct {
+ DocType type;
+ DocField field;
+ CharPtr term;
+ CharPtr highRange;
+} TermData, PNTR TermDataPtr;
+
+
+/**** Initialize and close session *********************/
+
+NLM_EXTERN Boolean CDECL NetEntrezInit PROTO((CharPtr appl_id, Boolean no_warnings));
+
+NLM_EXTERN void CDECL NetEntrezFini PROTO((void));
+
+NLM_EXTERN EntrezInfoPtr NetEntrezGetInfo PROTO((void));
+NLM_EXTERN CharPtr NetEntrezDetailedInfo PROTO((void));
+
+/**** Get Types and Terms ******************************/
+/**** prototypes are in netlib.h *********************/
+
+/**** Get Links and Neighbors **************************/
+
+NLM_EXTERN Int4 NetEntGetMaxLinks PROTO((void));
+
+NLM_EXTERN LinkSetPtr CDECL NetUidLinks PROTO((DocType type, DocUid uid, DocType link_to_type));
+NLM_EXTERN Int2 CDECL NetLinkUidList PROTO((LinkSetPtr PNTR result, DocType type,
+DocType link_to_type, Int2 numuid, DocUidPtr uids, Boolean mark_missing));
+
+/**** Get Summaries ************************************/
+
+NLM_EXTERN Int2 CDECL NetDocSumListGet PROTO((DocSumPtr PNTR result, Int2 numuid, DocType type, DocUidPtr uids, Int2 defer_count));
+NLM_EXTERN DocSumPtr CDECL NetDocSum PROTO((DocType type, DocUid uid));
+
+/**** Get Term List ************************************/
+
+NLM_EXTERN Int2 CDECL NetTermListByPage PROTO((DocType type, DocField field, Int2 page, Int2 numpage, TermListProc proc));
+NLM_EXTERN Int2 CDECL NetTermListByTerm PROTO((DocType type, DocField field, CharPtr term, Int2 numterms, TermListProc proc, Int2Ptr first_page));
+
+NLM_EXTERN Boolean CDECL NetEntrezFindTerm PROTO((DocType type, DocField field, CharPtr term, Int4Ptr spcl, Int4Ptr totl));
+
+/**** Creates a term node from the uid parameter ********/
+NLM_EXTERN void CDECL NetEntrezCreateNamedUidList PROTO((CharPtr term, DocType type, DocField field, Int4 num, DocUidPtr uids));
+NLM_EXTERN void CDECL NetEntrezCreateNamedUidListX PROTO((CharPtr term, DocType type, DocField field, ByteStorePtr bsp));
+
+
+/**** Look up terms with Boolean operations ************/
+
+NLM_EXTERN ValNodePtr CDECL NetEntTLNew PROTO((DocType type));
+NLM_EXTERN ValNodePtr CDECL NetEntTLAddTerm PROTO((ValNodePtr elst, CharPtr term, DocType type, DocField field, Boolean special, CharPtr highRange));
+NLM_EXTERN ValNodePtr CDECL NetEntTLFree PROTO((ValNodePtr elst));
+NLM_EXTERN LinkSetPtr CDECL NetEntTLEval PROTO((ValNodePtr elst));
+NLM_EXTERN ByteStorePtr CDECL NetEntTLEvalX PROTO((ValNodePtr elst));
+NLM_EXTERN Int4 CDECL NetEntTLEvalCount PROTO((ValNodePtr elst));
+
+/**** Get the Data **************************************/
+
+NLM_EXTERN Int2 CDECL NetEntMedlineEntryListGet PROTO((MedlineEntryPtr PNTR result, Int2 numuid, DocUidPtr uids, Boolean mark_missing));
+
+NLM_EXTERN Int2 CDECL NetEntSeqEntryListGet PROTO((SeqEntryPtr PNTR result, Int2 numuid,
+ DocUidPtr uids, Int2 retcode, Boolean mark_missing));
+
+NLM_EXTERN Int2 CDECL NetEntrezBiostrucListGet PROTO((BiostrucPtr PNTR result, Int4 mdlLvl, Int4 maxModels, Int2 numuid, DocUidPtr uids, Boolean mark_missing));
+NLM_EXTERN BiostrucAnnotSetPtr CDECL NetEntrezBiostrucAnnotSetGet PROTO((DocUid uid));
+NLM_EXTERN LinkSetPtr CDECL NetEntrezBiostrucFeatIds PROTO((DocUid mmdbid, Int2 feature_type, Int4 feature_set_id));
+NLM_EXTERN BiostrucAnnotSetPtr CDECL NetEntrezBiostrucAnnotSetGetByFid PROTO((DocUid mmdbid, Int4 feature_id, Int4 feature_set_id));
+
+
+
+/**** Get a SeqId for a GI ***************************/
+
+NLM_EXTERN SeqIdPtr NetSeqIdForGI PROTO((Int4 gi));
+NLM_EXTERN Int4 NetEntrezFindSeqId PROTO((SeqIdPtr sip));
+NLM_EXTERN EntrezHierarchyPtr NetEntMeshHierarchyGet PROTO((CharPtr term));
+NLM_EXTERN EntrezHierarchyPtr NetEntHierarchyGet PROTO((CharPtr term, DocType type, DocField field));
+
+/**** Neighbor some text on-the-fly ! ************/
+NLM_EXTERN LinkSetPtr CDECL NetEntDoNeighborText PROTO((EntrezNeighborTextPtr entp));
+NLM_EXTERN Boolean CDECL NetEntCanNeighborText PROTO((void));
+
+/**** BLAST a sequence on-the-fly ! ************/
+NLM_EXTERN Boolean CDECL NetEntCanBlast PROTO((void));
+NLM_EXTERN LinkSetPtr LIBCALL NetEntBlastBioseq PROTO((BioseqPtr bsp, DocType db, CharPtr program, CharPtr database, CharPtr options, Boolean usemonitor));
+
+
+
+NLM_EXTERN Boolean CDECL NetEntExpandedMedlineFeatures PROTO((void));
+NLM_EXTERN Int4 LIBCALL NetEntClusterAnalysis PROTO((DocUidPtr uids, Int4 numuids, DocField fld, Int4 minCluster, Int4 maxCluster, Int4 maxTerms, CharPtr *terms, Int4Ptr termTotals));
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+
+/* # of retries to get a server */
+#define ENT_SERV_RETRIES 2
+
+
+#ifndef _NETROMLIB_
+#include <netlib.h>
+#endif
+
+#endif
+
diff --git a/network/entrez/client/netlib.c b/network/entrez/client/netlib.c
new file mode 100644
index 00000000..d4224e6c
--- /dev/null
+++ b/network/entrez/client/netlib.c
@@ -0,0 +1,880 @@
+/* netlib.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: netlib.c
+*
+* Author: Epstein
+*
+* Version Creation Date: 06/05/92
+*
+* $Revision: 6.1 $
+*
+* File Description:
+* miscellaneous library for network Entrez
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: netlib.c,v $
+* Revision 6.1 1998/08/24 21:00:51 kans
+* fixed -v -fd warnings
+*
+* Revision 6.0 1997/08/25 18:35:01 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/07/29 21:24:15 vakatov
+* [WIN32,DLL] DLL'zation of "netentr.lib"
+*
+* Revision 5.1 1997/06/05 15:51:58 epstein
+* change name of NetInit function per Eric Hackborn's request
+*
+* Revision 5.0 1996/05/28 14:10:21 ostell
+* Set to revision 5.0
+*
+ * Revision 4.2 1995/11/27 21:48:31 epstein
+ * add information regarding outgoing connection to detailed-info
+ *
+ * Revision 4.1 1995/10/02 15:28:53 epstein
+ * support range-checking
+ *
+ * Revision 4.0 1995/07/26 13:54:59 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.22 1995/05/17 17:53:17 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <ncbi.h>
+#include <asn.h>
+#include <accentr.h>
+#include <cdconfig.h>
+#include <ncbinet.h>
+#include <netentr.h>
+#include <netpriv.h>
+#include <objmedli.h>
+#include <objsset.h>
+#include <objloc.h>
+#include <objneten.h>
+
+#define STAT_CHUNK 32
+
+static Boolean loaded = FALSE;
+
+static NetStatPtr PNTR statVector = NULL;
+static Int2 numStats = 0;
+static Boolean statsDisabled = FALSE;
+static Int2 maxCurStats;
+static Boolean reallyFinal = TRUE;
+
+static int num_attached = 0;
+static char lastDispatcher[60];
+static NI_HandPtr lastEntrezServ = NULL;
+static CharPtr statsPtr = NULL;
+static NI_DispatcherPtr dispatcher = NULL;
+
+static AsnTypePtr ENTREZ_TERM_LIST = NULL;
+static AsnTypePtr ENTREZ_TERM_LIST_E = NULL;
+static AsnTypePtr ENTREZ_TERM_LIST_E_operator = NULL;
+static AsnTypePtr ENTREZ_TERM_LIST_E_sp_operand = NULL;
+static AsnTypePtr ENTREZ_TERM_LIST_E_tot_operand = NULL;
+static AsnTypePtr ENTREZ_TERM_RESP = NULL;
+static AsnTypePtr ENTREZ_TERM_RESP_first_page = NULL;
+static AsnTypePtr ENTREZ_TERM_RESP_info = NULL;
+static AsnTypePtr ENTREZ_TERM_RESP_info_E = NULL;
+static AsnTypePtr ENTREZ_TERM_RESP_num_terms = NULL;
+static AsnTypePtr ENTREZ_TERM_RESP_pages_read = NULL;
+static AsnTypePtr SPECIAL_OPERAND_fld = NULL;
+static AsnTypePtr SPECIAL_OPERAND_term = NULL;
+static AsnTypePtr SPECIAL_OPERAND_type = NULL;
+static AsnTypePtr SPECIAL_OPERAND_high_range = NULL;
+static AsnTypePtr TOTAL_OPERAND_fld = NULL;
+static AsnTypePtr TOTAL_OPERAND_term = NULL;
+static AsnTypePtr TOTAL_OPERAND_type = NULL;
+static AsnTypePtr TOTAL_OPERAND_high_range = NULL;
+
+static void appendStats PROTO((CharPtr s));
+static Int2 NEAR statCompare PROTO((NetStatPtr s1, NetStatPtr s2));
+static void NEAR FreeNetStats PROTO((void));
+static Boolean SwapOutNet PROTO ((VoidPtr med));
+
+
+static void NEAR FindAsnType (AsnTypePtr PNTR atp, AsnModulePtr amp, CharPtr str)
+
+{
+ if (atp != NULL && (*atp) == NULL) {
+ *atp = AsnTypeFind (amp, str);
+ }
+}
+
+static Boolean InitLoad(void)
+{
+ AsnModulePtr amp;
+ static Boolean loaded = FALSE;
+
+ if (loaded)
+ return TRUE;
+ if (! NetEntAsnLoad() )
+ return FALSE;
+ amp = AsnAllModPtr();
+
+ FindAsnType(&ENTREZ_TERM_LIST, amp, "Entrez-term-list");
+ FindAsnType(&ENTREZ_TERM_LIST_E, amp, "Entrez-term-list.E");
+ FindAsnType(&ENTREZ_TERM_LIST_E_operator, amp, "Entrez-term-list.E.operator");
+ FindAsnType(&ENTREZ_TERM_LIST_E_sp_operand, amp, "Entrez-term-list.E.sp-operand");
+ FindAsnType(&ENTREZ_TERM_LIST_E_tot_operand, amp, "Entrez-term-list.E.tot-operand");
+ FindAsnType(&ENTREZ_TERM_RESP, amp, "Entrez-term-resp");
+ FindAsnType(&ENTREZ_TERM_RESP_first_page, amp, "Entrez-term-resp.first-page");
+ FindAsnType(&ENTREZ_TERM_RESP_info, amp, "Entrez-term-resp.info");
+ FindAsnType(&ENTREZ_TERM_RESP_info_E, amp, "Entrez-term-resp.info.E");
+ FindAsnType(&ENTREZ_TERM_RESP_num_terms, amp, "Entrez-term-resp.num-terms");
+ FindAsnType(&ENTREZ_TERM_RESP_pages_read, amp, "Entrez-term-resp.pages-read");
+ FindAsnType(&SPECIAL_OPERAND_fld, amp, "Special-operand.fld");
+ FindAsnType(&SPECIAL_OPERAND_term, amp, "Special-operand.term");
+ FindAsnType(&SPECIAL_OPERAND_type, amp, "Special-operand.type");
+ FindAsnType(&SPECIAL_OPERAND_high_range, amp, "Special-operand.high-range");
+ FindAsnType(&TOTAL_OPERAND_fld, amp, "Total-operand.fld");
+ FindAsnType(&TOTAL_OPERAND_term, amp, "Total-operand.term");
+ FindAsnType(&TOTAL_OPERAND_type, amp, "Total-operand.type");
+ FindAsnType(&TOTAL_OPERAND_high_range, amp, "Total-operand.high-range");
+
+ loaded = TRUE;
+ return TRUE;
+}
+
+
+NLM_EXTERN TermRespPtr CDECL TermRespNew(void)
+{
+ TermRespPtr p;
+
+ p = (TermRespPtr) MemNew(sizeof(TermResp));
+ p->num_terms = 0;
+ if (p != NULL)
+ {
+ p->termresp = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN TermRespPtr CDECL
+TermRespFree(TermRespPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ if (p->termresp != NULL)
+ {
+ if (p->termresp->term != NULL)
+ MemFree(p->termresp->term);
+ MemFree (p->termresp);
+ }
+ return ((TermRespPtr) MemFree (p));
+}
+
+NLM_EXTERN TermRespPtr CDECL TermRespAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ int i;
+ TermRespPtr tp;
+ TermPageInfoPtr tpi;
+ AsnModulePtr amp;
+
+ amp = AsnAllModPtr();
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_TERM_RESP);
+ else
+ atp = AsnLinkType(orig, ENTREZ_TERM_RESP); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ tp = TermRespNew();
+
+ if (tp == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* read the start struct */
+ goto erret;
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_num_terms)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) < 0)
+ goto erret;
+ tp->num_terms = av.intvalue;
+ tp->first_page = -1;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == ENTREZ_TERM_RESP_first_page)
+ { /* optional */
+ if (AsnReadVal(aip, atp, &av) < 0)
+ goto erret;
+ tp->first_page = av.intvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp != ENTREZ_TERM_RESP_pages_read)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ tp->num_pages_read = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_info)
+ goto erret;
+ if (AsnReadVal(aip, atp, NULL) <= 0)
+ goto erret;
+ tp->termresp = MemNew(sizeof(struct termresp) * (size_t) tp->num_terms);
+ for (i = 0; i < tp->num_terms; i++)
+ {
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_info_E)
+ goto erret;
+ if ((tpi = TermPageInfoAsnRead(aip, atp)) == NULL)
+ goto erret;
+ tp->termresp[i].special_count = tpi->spec_count;
+ tp->termresp[i].total_count = tpi->tot_count;
+ tp->termresp[i].term = tpi->term;
+ tpi->term = NULL; /* for clean free */
+ TermPageInfoFree (tpi);
+ }
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_info)
+ goto erret;
+ if (AsnReadVal(aip, atp, NULL) < 0)
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_TERM_RESP)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return tp;
+
+erret:
+ tp = TermRespFree (tp);
+ goto ret;
+}
+
+NLM_EXTERN Boolean CDECL
+BoolExprAsnWrite(ValNodePtr elst, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ static int n = 0;
+ TermDataPtr tp;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (aip == NULL)
+ return FALSE;
+ atp = AsnLinkType(orig, ENTREZ_TERM_LIST); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (elst == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ for (; elst != NULL; elst = elst->next)
+ {
+ AsnWrite (aip, ENTREZ_TERM_LIST_E, NULL);
+ switch (elst->choice) {
+ case SPECIALTERM:
+ tp = (TermDataPtr) elst->data.ptrvalue;
+
+ AsnStartStruct (aip, ENTREZ_TERM_LIST_E_sp_operand);
+ av.ptrvalue = tp->term;
+ AsnWrite (aip, SPECIAL_OPERAND_term, &av);
+ av.intvalue = tp->field;
+ AsnWrite (aip, SPECIAL_OPERAND_fld, &av);
+ av.intvalue = tp->type;
+ AsnWrite (aip, SPECIAL_OPERAND_type, &av);
+ if ((av.ptrvalue = tp->highRange) != NULL)
+ AsnWrite (aip, SPECIAL_OPERAND_high_range, &av);
+ AsnEndStruct (aip, ENTREZ_TERM_LIST_E_sp_operand);
+ break;
+ case TOTALTERM:
+ tp = (TermDataPtr) elst->data.ptrvalue;
+
+ AsnStartStruct (aip, ENTREZ_TERM_LIST_E_tot_operand);
+ av.ptrvalue = tp->term;
+ AsnWrite (aip, TOTAL_OPERAND_term, &av);
+ av.intvalue = tp->field;
+ AsnWrite (aip, TOTAL_OPERAND_fld, &av);
+ av.intvalue = tp->type;
+ AsnWrite (aip, TOTAL_OPERAND_type, &av);
+ if ((av.ptrvalue = tp->highRange) != NULL)
+ AsnWrite (aip, TOTAL_OPERAND_high_range, &av);
+ AsnEndStruct (aip, ENTREZ_TERM_LIST_E_tot_operand);
+ break;
+ case LPAREN:
+ case RPAREN:
+ case ANDSYMBL:
+ case ORSYMBL:
+ case BUTNOTSYMBL:
+ av.intvalue = elst->choice;
+ AsnWrite (aip, ENTREZ_TERM_LIST_E_operator, &av);
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig);
+ return retval;
+}
+
+NLM_EXTERN ValNodePtr CDECL
+BoolExprAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ ValNodePtr anp = NULL;
+ ValNodePtr head = NULL;
+ DataVal av;
+ TermDataPtr tp;
+ AsnTypePtr atp;
+ AsnTypePtr startsym;
+ AsnModulePtr amp;
+
+ InitLoad();
+ amp = AsnAllModPtr();
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_TERM_LIST);
+ else
+ atp = AsnLinkType(orig, ENTREZ_TERM_LIST); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ if (AsnReadVal(aip, atp, NULL) < 0)
+ goto erret;
+
+ while ((atp = AsnReadId(aip, amp, atp)) == ENTREZ_TERM_LIST_E)
+ {
+ if (AsnReadVal(aip, atp, NULL) < 0)
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+
+ if (atp == ENTREZ_TERM_LIST_E_sp_operand ||
+ atp == ENTREZ_TERM_LIST_E_tot_operand)
+ {
+ startsym = atp; /* save this, to be able to find "close" sym */
+
+ anp = ValNodeNew(anp);
+ if (head == NULL) /* keep track of head of list */
+ head = anp;
+
+ if (atp == ENTREZ_TERM_LIST_E_sp_operand)
+ anp->choice = SPECIALTERM;
+ else
+ anp->choice = TOTALTERM;
+
+ if (AsnReadVal(aip, atp, NULL) < 0)
+ goto erret;
+
+ tp = (TermDataPtr) MemNew(sizeof(TermData));
+ anp->data.ptrvalue = (Pointer) tp;
+
+ if (tp == NULL)
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* term */
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) < 0)
+ goto erret;
+ tp->term = av.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* fld */
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) < 0)
+ goto erret;
+ tp->field = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* type */
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) < 0)
+ goto erret;
+ tp->type = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == SPECIAL_OPERAND_high_range ||
+ atp == TOTAL_OPERAND_high_range)
+ {
+ if (AsnReadVal(aip, atp, &av) < 0)
+ goto erret;
+ tp->highRange = av.ptrvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+ if (atp != startsym)
+ goto erret;
+ if (AsnReadVal(aip, atp, NULL) < 0)
+ goto erret;
+ }
+ else
+ if (atp == ENTREZ_TERM_LIST_E_operator)
+ {
+ if (AsnReadVal(aip, atp, &av) < 0)
+ goto erret;
+ anp = ValNodeNew(anp);
+ if (head == NULL) /* keep track of head of list */
+ head = anp;
+ anp->choice = av.intvalue;
+ }
+ else
+ goto erret;
+ }
+
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_TERM_LIST)
+ goto erret;
+ }
+ else {
+ if (atp != orig)
+ goto erret;
+ }
+
+ /* discard last value */
+ if (AsnReadVal(aip, atp, NULL) < 0)
+ goto erret;
+
+ AsnUnlinkType(orig);
+ return head;
+
+erret:
+ ValNodeFree (head);
+ return NULL;
+}
+
+static void appendStats(CharPtr s)
+{
+ if (s != NULL)
+ {
+ StrCat(statsPtr, " ");
+ StrCat(statsPtr, s);
+ StrCat(statsPtr, "\n");
+ statsPtr += StringLen(statsPtr);
+ }
+}
+
+NLM_EXTERN void GetClientInfo (CharPtr buf)
+{
+ if (buf == NULL)
+ return;
+
+ StrCpy(buf, "NETWORK ACCESS\n Last Dispatcher Used: ");
+ StrCat(buf, lastDispatcher);
+ StrCat(buf, "\n");
+ if (dispatcher != NULL)
+ {
+ if (dispatcher->motd != NULL && dispatcher->motd[0] != NULLB)
+ {
+ StrCat(buf, "\n ");
+ StrCat(buf, dispatcher->motd);
+ StrCat(buf, "\n");
+ }
+ if (dispatcher->useOutServ)
+ {
+ StrCat(buf, "\n Using outgoing connection when communicating with server\n");
+ }
+ if (dispatcher->adminInfo != NULL && dispatcher->adminInfo[0] != NULLB)
+ {
+ StrCat(buf, "\n Your Network Entrez administrator is:\n ");
+ StrCat(buf, dispatcher->adminInfo);
+ }
+ }
+ if (lastEntrezServ != NULL)
+ {
+ StrCat(buf, "\n Entrez service currently connected to ");
+ StrCat(buf, lastEntrezServ->hostname);
+ StrCat(buf, " server\n");
+ if (NI_EncrAvailable())
+ {
+ if (lastEntrezServ->encryption != NULL)
+ {
+ StrCat (buf, " Encrypted session\n");
+ } else {
+ StrCat (buf, " Encryption available, but not in use\n");
+ }
+ }
+ statsPtr = &buf[StringLen(buf)];
+ DumpNetStats(SUBSYS_CLI_ENTREZ, appendStats);
+ }
+}
+
+static Int2 NEAR statCompare (NetStatPtr s1, NetStatPtr s2)
+{
+ if (s1 == NULL || s2 == NULL)
+ return 0;
+ if (s1->subsys < s2->subsys)
+ return -1;
+ if (s1->subsys > s2->subsys)
+ return 1;
+ return (Int2) StrCmp(s1->label, s2->label);
+}
+
+static void NEAR FreeNetStats (void)
+{
+ NetStatPtr PNTR statptr;
+ Int2 i;
+
+ for (statptr = statVector, i = 0; i < numStats; i++, statptr++)
+ {
+ MemFree((*statptr)->label);
+ MemFree((*statptr));
+ }
+
+ MemFree(statVector);
+ statVector = NULL;
+ numStats = 0;
+ statsDisabled = TRUE;
+}
+
+NLM_EXTERN void CDECL DumpNetStats (Int2 subsys, StatsCallBack callBack)
+{
+ char s[200];
+ int i;
+ NetStatPtr stat;
+ Boolean foundFirst = FALSE;
+ Boolean okSubsys;
+ Int4 total;
+ double mean;
+ double stdev;
+
+ for (i = 0; i < numStats; i++)
+ {
+ stat = statVector[i];
+ if (stat == NULL)
+ continue;
+
+ okSubsys = stat->subsys == subsys || subsys == 0;
+ if (!foundFirst)
+ {
+ if (okSubsys)
+ foundFirst = TRUE;
+ else
+ continue;
+ }
+ if (foundFirst && !okSubsys)
+ break;
+ total = (Int4) (stat->total + 0.5);
+
+ switch (stat->flags) {
+ case STAT_MEAN :
+ StrCpy (s, "{");
+ StrCat (s, stat->label);
+ if (stat->n > 0)
+ mean = stat->total / stat->n;
+ else
+ mean = 0.0;
+ sprintf (&s[strlen(s)], "} total = %ld, mean = %f", (long) total,
+ mean);
+ break;
+ case STAT_MEAN | STAT_STDEV :
+ StrCpy (s, "{");
+ StrCat (s, stat->label);
+ if (stat->n > 0)
+ mean = stat->total / stat->n;
+ else
+ mean = 0.0;
+ if (stat->n <= 1)
+ stdev = 0.0;
+ else
+ stdev = sqrt(stat->sum_of_squares / (stat->n - 1));
+ sprintf (&s[strlen(s)], "} total = %ld, mean = %f, stdev = %f",
+ (long) total, mean, stdev);
+ break;
+ default :
+ StrCpy (s, stat->label);
+ sprintf (&s[strlen(s)], " = %ld", (long) total);
+ break;
+ }
+ callBack (s);
+ }
+}
+
+
+NLM_EXTERN void CDECL LogNetStats (Int2 subsys, CharPtr label, Int4 dat,
+ NetStatPtr PNTR statHandle, Int2 flags)
+{
+ Int2 l;
+ Int2 r;
+ Int2 k;
+ Int2 compValue;
+ NetStatPtr newStat;
+ NetStatPtr Stat;
+ double mean;
+ double tempterm;
+
+ if (statsDisabled)
+ return;
+
+ if (statHandle == NULL || label == NULL)
+ return;
+
+ if (*statHandle == NULL)
+ {
+ newStat = (NetStatPtr) MemNew(sizeof(NetStat));
+ newStat->subsys = subsys;
+ newStat->label = StringSave(label);
+ newStat->total = 0;
+ newStat->n = 0;
+ newStat->flags = 0;
+ newStat->sum_of_squares = 0.0;
+ k = 0;
+ if (statVector != NULL)
+ {
+ l = 0;
+ r = numStats - 1;
+ compValue = statCompare(newStat, statVector[k]);
+ while ((l <= r) && compValue != 0)
+ {
+ k = (l + r) / 2;
+ if ((compValue = statCompare(newStat, statVector[k])) < 0)
+ r = k - 1;
+ else
+ l = k + 1;
+ }
+ if (compValue == 0)
+ { /* match */
+ *statHandle = statVector[k];
+ MemFree(newStat->label);
+ MemFree(newStat); /* not needed */
+ }
+ else {
+ while (compValue > 0 && k < numStats)
+ {
+ k++;
+ compValue = statCompare(newStat, statVector[k]);
+ }
+ }
+ }
+
+ if (*statHandle == NULL)
+ { /* not found previously */
+ if (statVector == NULL)
+ {
+ if ((statVector = (NetStatPtr PNTR) MemNew(sizeof(NetStatPtr) *
+ STAT_CHUNK)) == NULL)
+ {
+ MemFree(newStat->label);
+ MemFree(newStat);
+ return;
+ }
+ maxCurStats = STAT_CHUNK;
+ }
+
+ /* re-allocate vector if necessary */
+ if (numStats >= maxCurStats - 1)
+ {
+ maxCurStats += STAT_CHUNK;
+ if ((statVector = (NetStatPtr PNTR) Realloc(statVector,
+ sizeof(NetStatPtr) * maxCurStats)) == NULL)
+ {
+ MemFree(newStat->label);
+ MemFree(newStat);
+ return;
+ }
+ }
+
+ /* move everything else up */
+ for (r = numStats - 1; r >= k; r--)
+ {
+ statVector[r+1] = statVector[r];
+ }
+ statVector[k] = newStat;
+ *statHandle = newStat;
+ numStats++;
+ }
+ }
+
+ Stat = *statHandle;
+ Stat->n++;
+ Stat->total += dat;
+ Stat->flags |= flags;
+ mean = Stat->total / Stat->n;
+ tempterm = (mean - dat);
+ Stat->sum_of_squares += tempterm * tempterm;
+}
+
+/*******************************************************************************
+*
+* NetEInit()
+*
+* Connect to the network services dispatcher, unless already attached.
+*******************************************************************************/
+
+NLM_EXTERN Boolean NetEInit(void)
+{
+ if (! InitLoad())
+ return FALSE;
+
+ if (num_attached++ > 0)
+ return TRUE;
+
+ /* if ( there are no network-media ) then */
+ if (ParseMedia(NULL, MEDIUM_NETWORK) == 0)
+ {
+ num_attached--;
+ return FALSE;
+ }
+
+ if ((dispatcher = NI_GenericInit(NULL, NULL, TRUE, lastDispatcher, sizeof(lastDispatcher))) != NULL) {
+ return TRUE;
+ }
+
+ num_attached--;
+ return FALSE;
+}
+
+
+/*******************************************************************************
+*
+* NetFini()
+*
+* Disconnect from the network services dispatcher, if this is the last
+* service user which is detaching.
+*******************************************************************************/
+
+NLM_EXTERN Boolean CDECL NetFini(void)
+{
+ if (num_attached > 0)
+ num_attached--;
+
+ if (num_attached == 0)
+ {
+ NI_EndServices (dispatcher);
+ if (reallyFinal)
+ FreeNetStats();
+ }
+
+ return TRUE;
+}
+
+NLM_EXTERN Boolean CDECL ForceNetInit(void)
+{
+ Boolean retval;
+
+ reallyFinal = FALSE;
+ num_attached = 0; /* force re-attempt to contact dispatcher */
+ retval = NetEInit();
+ reallyFinal = TRUE;
+
+ return retval;
+}
+
+extern NI_HandPtr NetServiceGet(CharPtr channel, CharPtr def_service,
+ ConfCtlProc swapInProc, NI_HandPtr oldSessionHandle)
+{
+ MediaPtr media;
+ NetMediaInfoPtr nmi;
+ NI_HandPtr firstSessionHandle = NULL;
+ CharPtr param_section;
+
+ /* coding-trick to make current media match type "channel" */
+ if (! SelectDataSource(channel, "MEDIA", NULL))
+ {
+ return NULL;
+ }
+
+ do {
+ media = GetCurMedia();
+ if (media == NULL)
+ continue;
+ if (media->media_type != MEDIUM_NETWORK)
+ continue;
+ nmi = (NetMediaInfoPtr) media->media_info;
+
+ /* if media is already initialized, only attempt to re-obtain service */
+ /* if this media matches the media which failed or timed-out */
+ if (nmi != NULL && nmi->sessionHandle != oldSessionHandle)
+ continue;
+
+ if (nmi != NULL)
+ { /* de-allocate old resources */
+ NI_ServiceDisconnect(nmi->sessionHandle);
+ nmi->sessionHandle = NULL;
+ }
+ else { /* allocate structure */
+ nmi = (NetMediaInfoPtr) MemNew(sizeof(NetMediaInfo));
+ media->media_info = (VoidPtr) nmi;
+ }
+ nmi->sessionHandle = NULL;
+
+ media->swapOutMedia = SwapOutNet;
+ media->swapInMedia = swapInProc;
+
+ param_section = media->media_alias;
+
+ nmi->sessionHandle = NI_GenericGetService(dispatcher, NULL,
+ param_section, def_service,
+ TRUE);
+ if (firstSessionHandle == NULL)
+ firstSessionHandle = nmi->sessionHandle;
+ } while (SelectNextDataSource());
+
+ lastEntrezServ = firstSessionHandle;
+
+ return firstSessionHandle;
+}
+
+
+static Boolean SwapOutNet (VoidPtr med)
+{
+ return TRUE;
+}
diff --git a/network/entrez/client/netlib.h b/network/entrez/client/netlib.h
new file mode 100644
index 00000000..5ee342b4
--- /dev/null
+++ b/network/entrez/client/netlib.h
@@ -0,0 +1,153 @@
+/* netlib.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: netlib.h
+*
+* Author: Epstein
+*
+* Version Creation Date: 06/05/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* header file for miscellaneous library for Network Entrez
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* $Log: netlib.h,v $
+* Revision 6.0 1997/08/25 18:35:03 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/07/29 21:24:17 vakatov
+* [WIN32,DLL] DLL'zation of "netentr.lib"
+*
+* Revision 5.1 1997/06/05 15:51:42 epstein
+* change name of NetInit function per Eric Hackborn's request
+*
+* Revision 5.0 1996/05/28 14:10:21 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:54:59 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.3 1995/05/17 17:53:22 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NETLIB_
+#define _NETLIB_
+
+#ifndef _NCBI_Access_
+#include <objacces.h>
+#endif
+
+#ifndef _NETENTREZ_
+#include <netentr.h>
+#endif
+#include <cdconfig.h>
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* --- Macros --- */
+#define LOG_STAT(subsys,label,dat) { static NetStatPtr _p = NULL; LogNetStats(subsys, label, (Int4) (dat), &_p, 0); }
+#define LOG_STAT_M(subsys,label,dat) { static NetStatPtr _p = NULL; LogNetStats(subsys, label, (Int4) (dat), &_p, STAT_MEAN); }
+#define LOG_STAT_S(subsys,label,dat) { static NetStatPtr _p = NULL; LogNetStats(subsys, label, (Int4) (dat), &_p, STAT_MEAN | STAT_STDEV); }
+
+/* Subsystems for statistics management */
+#define SUBSYS_SRV_ENTREZ 1
+#define SUBSYS_SRV_ML 2
+#define SUBSYS_SRV_SEQ 3
+
+#define SUBSYS_CLI_ENTREZ 4
+#define SUBSYS_CLI_ML 5
+#define SUBSYS_CLI_SEQ 6
+
+#define STAT_MEAN 1
+#define STAT_STDEV 2
+
+typedef struct NetStat {
+ Int2 subsys;
+ CharPtr label;
+ double total;
+ double sum_of_squares;
+ Int4 n;
+ Int2 flags;
+} NetStat, PNTR NetStatPtr;
+
+typedef void (* StatsCallBack) PROTO((CharPtr s));
+
+
+/* --- Function Prototypes --- */
+
+Boolean CDECL NetInitialize PROTO((CharPtr,CharPtr,Int2Ptr));
+NLM_EXTERN Boolean CDECL NetEInit PROTO((void));
+NLM_EXTERN Boolean CDECL NetFini PROTO((void));
+
+NLM_EXTERN Boolean CDECL ForceNetInit PROTO((void));
+
+EntrezInfoPtr NetGetInfo PROTO((void));
+
+Int2 CDECL NetLinkUidGet PROTO((LinkSetPtr PNTR result, DocType type,
+DocType link_to_type, Int2 numuid, DocUidPtr uids, Boolean mark_missing,
+Int4 maxlink));
+
+NLM_EXTERN TermRespPtr CDECL TermRespNew PROTO((void));
+NLM_EXTERN TermRespPtr CDECL TermRespFree PROTO((TermRespPtr p));
+NLM_EXTERN TermRespPtr CDECL TermRespAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+
+NLM_EXTERN ValNodePtr CDECL BoolExprAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean CDECL BoolExprAsnWrite PROTO((ValNodePtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN void CDECL LogNetStats PROTO((Int2 subsys, CharPtr label, Int4 dat, NetStatPtr PNTR statHandle, Int2 flags));
+NLM_EXTERN void CDECL DumpNetStats PROTO((Int2 subsys, StatsCallBack callBack));
+NLM_EXTERN void CDECL GetClientInfo PROTO((CharPtr buf));
+
+/* The following mechanism must be re-worked after the ASN.1 tools are */
+/* modified to allow multiple includes and loads of the same include file */
+#if defined(OS_MAC) || defined(OS_DOS) /* dynamic load */
+#define NET_ENTR_DYNAMIC_LOAD 1
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif
diff --git a/network/entrez/client/netpriv.h b/network/entrez/client/netpriv.h
new file mode 100644
index 00000000..5040ae48
--- /dev/null
+++ b/network/entrez/client/netpriv.h
@@ -0,0 +1,72 @@
+/* netlib.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: netlib.h
+*
+* Author: Epstein
+*
+* Version Creation Date: 12/15/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* private header file only to be included within Network Entrez source
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* RCS Modification History:
+* $Log: netpriv.h,v $
+* Revision 6.0 1997/08/25 18:35:05 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1997/07/29 21:24:19 vakatov
+* [WIN32,DLL] DLL'zation of "netentr.lib"
+*
+* Revision 5.0 1996/05/28 14:10:21 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:54:59 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.3 1995/05/17 17:53:26 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ NI_HandPtr sessionHandle;
+} NetMediaInfo, PNTR NetMediaInfoPtr;
+
+
+extern NI_HandPtr CDECL NetServiceGet PROTO((CharPtr channel, CharPtr def_service, ConfCtlProc swapInMedia, NI_HandPtr oldSessionHandle));
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/network/entrez/client/objneten.c b/network/entrez/client/objneten.c
new file mode 100644
index 00000000..daa2f281
--- /dev/null
+++ b/network/entrez/client/objneten.c
@@ -0,0 +1,5253 @@
+/* objneten.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: objneten.c
+*
+* Author: Epstein
+*
+* Version Creation Date: 06/02/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* object loaders for Network Entrez
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 8-16-94 Brylawski Added loaders for on-the-fly text neighboring
+ (EntrezNeighborText) and EntrezHierarchy
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: objneten.c,v $
+* Revision 6.0 1997/08/25 18:35:08 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/07/29 21:24:21 vakatov
+* [WIN32,DLL] DLL'zation of "netentr.lib"
+*
+* Revision 5.1 1996/08/14 19:43:25 epstein
+* add annot get by feat ids, and also add date filtering support
+*
+ * Revision 5.0 1996/05/28 14:10:21 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.2 1995/08/29 15:40:45 epstein
+ * remove obselete ResidueGraphDictionaryLoad reference
+ *
+ * Revision 4.1 1995/08/22 19:35:11 epstein
+ * add clustering support
+ *
+ * Revision 4.0 1995/07/26 13:54:59 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.14 1995/07/11 12:30:36 epstein
+ * change CDECLs to LIBCALLs
+ *
+ * Revision 1.13 1995/07/10 19:38:23 epstein
+ * implement docsumX
+ *
+ * Revision 1.12 1995/06/23 15:58:49 kans
+ * added ResidueGraphDictionaryLoad to initialization
+ *
+ * Revision 1.11 1995/05/17 17:53:30 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <asnneten.h> /* the AsnTool header */
+#include <objacces.h>
+#include <accentr.h>
+#include <objmedli.h> /* the Medline interface */
+#include <objloc.h> /* the 'Seqloc' interface */
+#include <objsset.h> /* the 'SeqSet' interface */
+#include <objneten.h> /* the Entrez objects interface */
+#include <objall.h>
+
+
+static Boolean loaded = FALSE;
+
+/*****************************************************************************
+*
+* NetEntAsnLoad()
+*
+*****************************************************************************/
+NLM_EXTERN Boolean LIBCALL
+NetEntAsnLoad(void)
+{
+ if (loaded)
+ return TRUE;
+ loaded = TRUE;
+
+ if (! AllObjLoad()) {
+ loaded = FALSE;
+ return FALSE;
+ }
+
+#ifdef Biostruc_supported
+ objmmdb1AsnLoad ();
+ objmmdb2AsnLoad ();
+ objmmdb3AsnLoad ();
+#endif
+
+ if (! AsnLoad()) {
+ loaded = FALSE;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/************************** EntrezIds ****************************************/
+
+NLM_EXTERN EntrezIdsPtr LIBCALL
+EntrezIdsNew(void)
+{
+ EntrezIdsPtr p;
+
+ p = MemNew(sizeof(EntrezIds));
+ if (p != NULL)
+ {
+ p->numid = 0;
+ p->ids = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN EntrezIdsPtr LIBCALL
+EntrezIdsFree(EntrezIdsPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ MemFree (p->ids);
+ return MemFree(p);
+}
+
+NLM_EXTERN EntrezIdsPtr LIBCALL
+EntrezIdsAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ EntrezIdsPtr p;
+ AsnTypePtr atp;
+ Int4 num;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_IDS);
+ else
+ atp = AsnLinkType(orig, ENTREZ_IDS); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = EntrezIdsNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+ atp = AsnReadId(aip, amp, atp); /* find the num */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the num */
+ goto erret;
+ p->numid = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_IDS_ids)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ p->ids = (DocUidPtr) MemNew(sizeof(DocUid) * (size_t) p->numid);
+ atp = AsnReadId(aip, amp, atp);
+
+ for (num = 0; num < p->numid && atp == ENTREZ_IDS_ids_E; num++)
+ {
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->ids[num] = av.intvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ /* check for count mis-match */
+ if (num != p->numid || atp != ENTREZ_IDS_ids)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_IDS)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = EntrezIdsFree(p);
+ goto ret;
+}
+
+
+NLM_EXTERN Boolean LIBCALL
+EntrezIdsAsnWrite (EntrezIdsPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Int4 i;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ENTREZ_IDS); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+ av.intvalue = p->numid;
+ AsnWrite (aip, ENTREZ_IDS_numid, &av);
+
+ AsnStartStruct (aip, ENTREZ_IDS_ids);
+ for (i = 0; i < p->numid; i++)
+ {
+ av.intvalue = p->ids[i];
+ AsnWrite (aip, ENTREZ_IDS_ids_E, &av);
+ }
+ AsnEndStruct (aip, ENTREZ_IDS_ids);
+
+ if (! AsnEndStruct(aip, atp) )
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Marked-link-set **********************************/
+
+NLM_EXTERN MarkedLinkSetPtr LIBCALL
+MarkedLinkSetNew(void)
+{
+ MarkedLinkSetPtr p;
+
+ p = MemNew(sizeof(MarkedLinkSet));
+ if (p != NULL)
+ {
+ p->link_set = NULL;
+ p->marked_missing = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN MarkedLinkSetPtr LIBCALL
+MarkedLinkSetFree(MarkedLinkSetPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ LinkSetFree (p->link_set);
+ EntrezIdsFree (p->marked_missing);
+
+ return MemFree(p);
+}
+
+NLM_EXTERN MarkedLinkSetPtr LIBCALL
+MarkedLinkSetAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ MarkedLinkSetPtr p;
+ EntrezIdsPtr eip;
+ LinkSetPtr lsp;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, MARKED_LINK_SET);
+ else
+ atp = AsnLinkType(orig, MARKED_LINK_SET); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = MarkedLinkSetNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != MARKED_LINK_SET_link_set)
+ goto erret;
+
+ lsp = LinkSetAsnRead(aip, atp);
+ if (lsp == NULL)
+ goto erret;
+ p->link_set = lsp;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != MARKED_LINK_SET_uids_processed)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->uids_processed = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == MARKED_LINK_SET_marked_missing)
+ { /* optional */
+ eip = EntrezIdsAsnRead(aip, atp);
+ if (eip == NULL)
+ goto erret;
+ p->marked_missing = eip;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (orig == NULL)
+ {
+ if (atp != MARKED_LINK_SET)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = MarkedLinkSetFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+MarkedLinkSetAsnWrite (MarkedLinkSetPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, MARKED_LINK_SET); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct (aip, atp))
+ goto erret;
+
+ if (! LinkSetAsnWrite(p->link_set, aip, MARKED_LINK_SET_link_set) )
+ goto erret;
+
+ av.intvalue = p->uids_processed;
+ AsnWrite(aip, MARKED_LINK_SET_uids_processed, &av);
+
+ if (p->marked_missing != NULL) /* optional */
+ {
+ if (! EntrezIdsAsnWrite(p->marked_missing, aip, MARKED_LINK_SET_marked_missing) )
+ goto erret;
+ }
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Named-List **********************************/
+
+NLM_EXTERN NamedListPtr LIBCALL
+NamedListNew(void)
+{
+ NamedListPtr p;
+
+ p = MemNew(sizeof(NamedList));
+ p->uids = NULL;
+ return p;
+}
+
+NLM_EXTERN NamedListPtr LIBCALL
+NamedListFree(NamedListPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ EntrezIdsFree(p->uids);
+
+ return MemFree(p);
+}
+
+NLM_EXTERN NamedListPtr LIBCALL
+NamedListAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ NamedListPtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_NAMED_LIST);
+ else
+ atp = AsnLinkType(orig, ENTREZ_NAMED_LIST); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = NamedListNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_NAMED_LIST_term)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->term = av.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_NAMED_LIST_type)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->type = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_NAMED_LIST_fld)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->fld = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_NAMED_LIST_uids)
+ goto erret;
+ p->uids = EntrezIdsAsnRead(aip, atp);
+ if (p->uids == NULL)
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_NAMED_LIST)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = NamedListFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+NamedListAsnWrite (NamedListPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ENTREZ_NAMED_LIST); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ av.ptrvalue = p->term;
+ AsnWrite (aip, ENTREZ_NAMED_LIST_term, &av);
+ av.intvalue = p->type;
+ AsnWrite (aip, ENTREZ_NAMED_LIST_type, &av);
+ av.intvalue = p->fld;
+ AsnWrite (aip, ENTREZ_NAMED_LIST_fld, &av);
+ if (! EntrezIdsAsnWrite(p->uids, aip, ENTREZ_NAMED_LIST_uids) )
+ goto erret;
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Term-by-page **********************************/
+
+NLM_EXTERN TermByPagePtr LIBCALL
+TermByPageNew(void)
+{
+ TermByPagePtr p;
+
+ p = MemNew(sizeof(TermByPage));
+ return p;
+}
+
+NLM_EXTERN TermByPagePtr LIBCALL
+TermByPageFree(TermByPagePtr p)
+{
+ if (p == NULL)
+ return NULL;
+
+ return MemFree(p);
+}
+
+NLM_EXTERN TermByPagePtr LIBCALL
+TermByPageAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ TermByPagePtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_TERM_BY_PAGE);
+ else
+ atp = AsnLinkType(orig, ENTREZ_TERM_BY_PAGE); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = TermByPageNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_BY_PAGE_type)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->type = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_BY_PAGE_fld)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->fld = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_BY_PAGE_page)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->page = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_BY_PAGE_num_pages)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->num_pages = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_TERM_BY_PAGE)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = TermByPageFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+TermByPageAsnWrite (TermByPagePtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ENTREZ_TERM_BY_PAGE); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ av.intvalue = p->type;
+ AsnWrite (aip, ENTREZ_TERM_BY_PAGE_type, &av);
+ av.intvalue = p->fld;
+ AsnWrite (aip, ENTREZ_TERM_BY_PAGE_fld, &av);
+ av.intvalue = p->page;
+ AsnWrite (aip, ENTREZ_TERM_BY_PAGE_page, &av);
+ av.intvalue = p->num_pages;
+ AsnWrite (aip, ENTREZ_TERM_BY_PAGE_num_pages, &av);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Term-by-term **********************************/
+
+NLM_EXTERN TermByTermPtr LIBCALL
+TermByTermNew(void)
+{
+ TermByTermPtr p;
+
+ p = MemNew(sizeof(TermByTerm));
+ p->term = NULL;
+ return p;
+}
+
+NLM_EXTERN TermByTermPtr LIBCALL
+TermByTermFree(TermByTermPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ MemFree (p->term);
+
+ return MemFree(p);
+}
+
+NLM_EXTERN TermByTermPtr LIBCALL
+TermByTermAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ TermByTermPtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_TERM_BY_TERM);
+ else
+ atp = AsnLinkType(orig, ENTREZ_TERM_BY_TERM); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = TermByTermNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_BY_TERM_type)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->type = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_BY_TERM_fld)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->fld = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_BY_TERM_term)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->term = av.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_BY_TERM_num_terms)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->num_terms = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_TERM_BY_TERM)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = TermByTermFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+TermByTermAsnWrite (TermByTermPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ENTREZ_TERM_BY_TERM); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ av.intvalue = p->type;
+ AsnWrite (aip, ENTREZ_TERM_BY_TERM_type, &av);
+ av.intvalue = p->fld;
+ AsnWrite (aip, ENTREZ_TERM_BY_TERM_fld, &av);
+ av.ptrvalue = p->term;
+ AsnWrite (aip, ENTREZ_TERM_BY_TERM_term, &av);
+ av.intvalue = p->num_terms;
+ AsnWrite (aip, ENTREZ_TERM_BY_TERM_num_terms, &av);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Term-Lookup **********************************/
+
+NLM_EXTERN TermLookupPtr LIBCALL
+TermLookupNew(void)
+{
+ TermLookupPtr p;
+
+ p = MemNew(sizeof(TermLookup));
+ p->term = NULL;
+ return p;
+}
+
+NLM_EXTERN TermLookupPtr LIBCALL
+TermLookupFree(TermLookupPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ MemFree (p->term);
+
+ return MemFree(p);
+}
+
+NLM_EXTERN TermLookupPtr LIBCALL
+TermLookupAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ TermLookupPtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TERM_LOOKUP);
+ else
+ atp = AsnLinkType(orig, TERM_LOOKUP); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = TermLookupNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != TERM_LOOKUP_type)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->type = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != TERM_LOOKUP_fld)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->fld = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != TERM_LOOKUP_term)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->term = av.ptrvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != TERM_LOOKUP)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = TermLookupFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+TermLookupAsnWrite (TermLookupPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, TERM_LOOKUP); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ av.intvalue = p->type;
+ AsnWrite (aip, TERM_LOOKUP_type, &av);
+ av.intvalue = p->fld;
+ AsnWrite (aip, TERM_LOOKUP_fld, &av);
+ av.ptrvalue = p->term;
+ AsnWrite (aip, TERM_LOOKUP_term, &av);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Term-Page-Info **********************************/
+
+NLM_EXTERN TermPageInfoPtr LIBCALL
+TermPageInfoNew(void)
+{
+ TermPageInfoPtr p;
+
+ p = MemNew(sizeof(TermPageInfo));
+ p->term = NULL;
+ return p;
+}
+
+NLM_EXTERN TermPageInfoPtr LIBCALL
+TermPageInfoFree(TermPageInfoPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ MemFree (p->term);
+
+ return MemFree(p);
+}
+
+NLM_EXTERN TermPageInfoPtr LIBCALL
+TermPageInfoAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ TermPageInfoPtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TERM_PAGE_INFO);
+ else
+ atp = AsnLinkType(orig, TERM_PAGE_INFO); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = TermPageInfoNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != TERM_PAGE_INFO_term)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->term = av.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != TERM_PAGE_INFO_spec_count)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->spec_count = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != TERM_PAGE_INFO_tot_count)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->tot_count = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != TERM_PAGE_INFO)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = TermPageInfoFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+TermPageInfoAsnWrite (TermPageInfoPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, TERM_PAGE_INFO); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ av.ptrvalue = p->term;
+ AsnWrite (aip, TERM_PAGE_INFO_term, &av);
+ av.intvalue = p->spec_count;
+ AsnWrite (aip, TERM_PAGE_INFO_spec_count, &av);
+ av.intvalue = p->tot_count;
+ AsnWrite (aip, TERM_PAGE_INFO_tot_count, &av);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Term-Counts **********************************/
+
+NLM_EXTERN TermCountsPtr LIBCALL
+TermCountsNew(void)
+{
+ TermCountsPtr p;
+
+ p = MemNew(sizeof(TermCounts));
+ return p;
+}
+
+NLM_EXTERN TermCountsPtr LIBCALL
+TermCountsFree(TermCountsPtr p)
+{
+ if (p == NULL)
+ return NULL;
+
+ return MemFree(p);
+}
+
+NLM_EXTERN TermCountsPtr LIBCALL
+TermCountsAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ TermCountsPtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TERM_COUNTS);
+ else
+ atp = AsnLinkType(orig, TERM_COUNTS); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = TermCountsNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != TERM_COUNTS_found)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->found = av.boolvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != TERM_COUNTS_spec_count)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->spec_count = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != TERM_COUNTS_tot_count)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->tot_count = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != TERM_COUNTS)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = TermCountsFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+TermCountsAsnWrite (TermCountsPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, TERM_COUNTS); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ av.boolvalue = p->found;
+ AsnWrite (aip, TERM_COUNTS_found, &av);
+ av.intvalue = p->spec_count;
+ AsnWrite (aip, TERM_COUNTS_spec_count, &av);
+ av.intvalue = p->tot_count;
+ AsnWrite (aip, TERM_COUNTS_tot_count, &av);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** LinkSetGet ****************************************/
+
+NLM_EXTERN LinkSetGetPtr LIBCALL
+LinkSetGetNew(void)
+{
+ LinkSetGetPtr p;
+
+ p = MemNew(sizeof(LinkSetGet));
+ if (p != NULL)
+ {
+ p->query_size = 0;
+ p->query = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN LinkSetGetPtr LIBCALL
+LinkSetGetFree(LinkSetGetPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ MemFree (p->query);
+ return MemFree(p);
+}
+
+NLM_EXTERN LinkSetGetPtr LIBCALL
+LinkSetGetAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ LinkSetGetPtr p;
+ AsnTypePtr atp;
+ Int4 num;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, LINK_SETGET);
+ else
+ atp = AsnLinkType(orig, LINK_SETGET); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = LinkSetGetNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp); /* find the num */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the num */
+ goto erret;
+ p->max = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->link_to_cls = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->query_cls = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == LINK_SETGET_mark_missing)
+ {
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->mark_missing = av.boolvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp != LINK_SETGET_query_size)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->query_size = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != LINK_SETGET_query)
+ goto erret;
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ p->query = (DocUidPtr) MemNew(sizeof(DocUid) * (size_t) p->query_size);
+ atp = AsnReadId(aip, amp, atp);
+
+ for (num = 0; num < p->query_size && atp == LINK_SETGET_query_E; num++)
+ {
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->query[num] = av.intvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ /* check for count mis-match */
+ if (num != p->query_size || atp != LINK_SETGET_query)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != LINK_SETGET)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = LinkSetGetFree(p);
+ goto ret;
+}
+
+
+NLM_EXTERN Boolean LIBCALL
+LinkSetGetAsnWrite (LinkSetGetPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Int4 i;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, LINK_SETGET); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+ av.intvalue = p->max;
+ AsnWrite (aip, LINK_SETGET_max, &av);
+ av.intvalue = p->link_to_cls;
+ AsnWrite (aip, LINK_SETGET_link_to_cls, &av);
+ av.intvalue = p->query_cls;
+ AsnWrite (aip, LINK_SETGET_query_cls, &av);
+ av.boolvalue = p->mark_missing;
+ AsnWrite (aip, LINK_SETGET_mark_missing, &av);
+ av.intvalue = p->query_size;
+ AsnWrite (aip, LINK_SETGET_query_size, &av);
+
+ AsnStartStruct (aip, LINK_SETGET_query);
+ for (i = 0; i < p->query_size; i++)
+ {
+ av.intvalue = p->query[i];
+ AsnWrite (aip, LINK_SETGET_query_E, &av);
+ }
+ AsnEndStruct (aip, LINK_SETGET_query);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Medline-Summary **********************************/
+
+NLM_EXTERN DocSumPtr LIBCALL
+MlSumNew(void)
+{
+ DocSumPtr p;
+
+ p = MemNew(sizeof(DocSum));
+ p->caption = NULL;
+ p->title = NULL;
+ return p;
+}
+
+NLM_EXTERN DocSumPtr LIBCALL
+MlSumFree(DocSumPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ MemFree(p->caption);
+ MemFree(p->title);
+
+ return MemFree(p);
+}
+
+NLM_EXTERN DocSumPtr LIBCALL
+MlSumAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ DocSumPtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ML_SUMMARY);
+ else
+ atp = AsnLinkType(orig, ML_SUMMARY); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = MlSumNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ML_SUMMARY_muid)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->uid = av.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ML_SUMMARY_no_abstract)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->no_abstract = av.boolvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ML_SUMMARY_translated_title)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->translated_title = av.boolvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ML_SUMMARY_no_authors)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->no_authors = av.boolvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == ML_SUMMARY_caption)
+ {
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->caption = av.ptrvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp == ML_SUMMARY_title)
+ {
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->title = av.ptrvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (orig == NULL)
+ {
+ if (atp != ML_SUMMARY)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = DocSumFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+MlSumAsnWrite (DocSumPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ML_SUMMARY); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ av.intvalue = p->uid;
+ AsnWrite (aip, ML_SUMMARY_muid, &av);
+ av.boolvalue = p->no_abstract;
+ AsnWrite (aip, ML_SUMMARY_no_abstract, &av);
+ av.boolvalue = p->translated_title;
+ AsnWrite (aip, ML_SUMMARY_translated_title, &av);
+ av.boolvalue = p->no_authors;
+ AsnWrite (aip, ML_SUMMARY_no_authors, &av);
+ if (p->caption != NULL)
+ {
+ av.ptrvalue = p->caption;
+ AsnWrite (aip, ML_SUMMARY_caption, &av);
+ }
+ if (p->title != NULL)
+ {
+ av.ptrvalue = p->title;
+ AsnWrite (aip, ML_SUMMARY_title, &av);
+ }
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Sequence-Summary **********************************/
+
+NLM_EXTERN DocSumPtr LIBCALL
+SeqSumNew(void)
+{
+ DocSumPtr p;
+
+ p = MemNew(sizeof(DocSum));
+ p->caption = NULL;
+ p->title = NULL;
+ return p;
+}
+
+NLM_EXTERN DocSumPtr LIBCALL
+SeqSumFree(DocSumPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ MemFree(p->caption);
+ MemFree(p->title);
+
+ return MemFree(p);
+}
+
+NLM_EXTERN DocSumPtr LIBCALL
+SeqSumAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ DocSumPtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, SEQ_SUMMARY);
+ else
+ atp = AsnLinkType(orig, SEQ_SUMMARY); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = SeqSumNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != SEQ_SUMMARY_id)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->uid = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == SEQ_SUMMARY_caption)
+ {
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->caption = av.ptrvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp == SEQ_SUMMARY_title)
+ {
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->title = av.ptrvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (orig == NULL)
+ {
+ if (atp != SEQ_SUMMARY)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = DocSumFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+SeqSumAsnWrite (DocSumPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, SEQ_SUMMARY); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ av.intvalue = p->uid;
+ AsnWrite (aip, SEQ_SUMMARY_id, &av);
+ if (p->caption != NULL)
+ {
+ av.ptrvalue = p->caption;
+ AsnWrite (aip, SEQ_SUMMARY_caption, &av);
+ }
+ if (p->title != NULL)
+ {
+ av.ptrvalue = p->title;
+ AsnWrite (aip, SEQ_SUMMARY_title, &av);
+ }
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** Entrez-DocGet **********************************/
+
+NLM_EXTERN EntrezDocGetPtr LIBCALL
+EntrezDocGetNew(void)
+{
+ EntrezDocGetPtr p;
+
+ p = MemNew(sizeof(EntrezDocGet));
+ p->ids = NULL;
+ p->defer_count = 0;
+ return p;
+}
+
+NLM_EXTERN EntrezDocGetPtr LIBCALL
+EntrezDocGetFree(EntrezDocGetPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ EntrezIdsFree(p->ids);
+
+ return MemFree(p);
+}
+
+NLM_EXTERN EntrezDocGetPtr LIBCALL
+EntrezDocGetAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ EntrezDocGetPtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_DOCGET);
+ else
+ atp = AsnLinkType(orig, ENTREZ_DOCGET); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = EntrezDocGetNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_DOCGET_class)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->cls = av.intvalue;
+
+ p->mark_missing = FALSE;
+ if ((atp = AsnReadId(aip, amp, atp)) == ENTREZ_DOCGET_mark_missing)
+ {
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->mark_missing = av.boolvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp != ENTREZ_DOCGET_ids)
+ goto erret;
+ p->ids = EntrezIdsAsnRead(aip, atp);
+ if (p->ids == NULL)
+ goto erret;
+
+ p->defer_count = 0;
+ if ((atp = AsnReadId(aip, amp, atp)) == ENTREZ_DOCGET_defer_count)
+ {
+ if (AsnReadVal(aip, atp, &av) < 0)
+ goto erret;
+ p->defer_count = av.intvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_DOCGET)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = EntrezDocGetFree(p);
+ goto ret;
+}
+
+NLM_EXTERN Boolean LIBCALL
+EntrezDocGetAsnWrite (EntrezDocGetPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+ AsnTypePtr atp;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ENTREZ_DOCGET); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+
+ av.intvalue = p->cls;
+ AsnWrite (aip, ENTREZ_DOCGET_class, &av);
+ av.boolvalue = p->mark_missing;
+ AsnWrite (aip, ENTREZ_DOCGET_mark_missing, &av);
+ if (! EntrezIdsAsnWrite(p->ids, aip, ENTREZ_DOCGET_ids) )
+ goto erret;
+ av.intvalue = p->defer_count;
+ AsnWrite (aip, ENTREZ_DOCGET_defer_count, &av);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/************************** MedlineEntryList *********************************/
+
+NLM_EXTERN MedlineEntryListPtr LIBCALL
+MedlineEntryListNew(void)
+{
+ MedlineEntryListPtr p;
+
+ p = MemNew(sizeof(MedlineEntryList));
+ if (p != NULL)
+ {
+ p->num = 0;
+ p->data = NULL;
+ p->marked_missing = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN MedlineEntryListPtr LIBCALL
+MedlineEntryListFree(MedlineEntryListPtr p)
+{
+ Int4 i;
+
+ if (p == NULL)
+ return NULL;
+ if (p->data != NULL)
+ {
+ for (i = 0; i < p->num; i++)
+ MedlineEntryFree(p->data[i]);
+ }
+ MemFree (p->data);
+ EntrezIdsFree (p->marked_missing);
+ return MemFree(p);
+}
+
+NLM_EXTERN MedlineEntryListPtr LIBCALL
+MedlineEntryListAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ MedlineEntryListPtr p;
+ AsnTypePtr atp;
+ Int4 num;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_MEDLINE_ENTRY_LIST);
+ else
+ atp = AsnLinkType(orig, ENTREZ_MEDLINE_ENTRY_LIST); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = MedlineEntryListNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp); /* find the num */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the num */
+ goto erret;
+ p->num = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp); /* find the data start-struct */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the data start-struct */
+ goto erret;
+
+ p->data = (MedlineEntryPtr PNTR) MemNew(sizeof(MedlineEntryPtr) * p->num);
+ for (num = 0; num < p->num; num++)
+ p->data[num] = NULL;
+ atp = AsnReadId(aip, amp, atp);
+
+ for (num = 0; num < p->num && atp == MEDLINE_ENTRY_LIST_data_E; num++)
+ {
+ if ((p->data[num] = MedlineEntryAsnRead(aip, atp)) == NULL)
+ goto erret;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ /* check for count mis-match */
+ if (num != p->num)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+
+ if (atp == ENTRY_LIST_marked_missing)
+ {
+ p->marked_missing = EntrezIdsAsnRead(aip, atp);
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_MEDLINE_ENTRY_LIST)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = MedlineEntryListFree(p);
+ goto ret;
+}
+
+
+NLM_EXTERN Boolean LIBCALL
+MedlineEntryListAsnWrite (MedlineEntryListPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Int4 i;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ENTREZ_MEDLINE_ENTRY_LIST); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+ av.intvalue = p->num;
+ AsnWrite (aip, ENTREZ_MEDLINE_ENTRY_LIST_num, &av);
+
+ AsnStartStruct (aip, ENTREZ_MEDLINE_ENTRY_LIST_data);
+ for (i = 0; i < p->num; i++)
+ {
+ MedlineEntryAsnWrite(p->data[i], aip, MEDLINE_ENTRY_LIST_data_E);
+ }
+ AsnEndStruct (aip, ENTREZ_MEDLINE_ENTRY_LIST_data);
+
+ if (p->marked_missing != NULL) /* optional */
+ {
+ EntrezIdsAsnWrite(p->marked_missing, aip, ENTRY_LIST_marked_missing);
+ }
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/************************** MlSummaryList ****************************************/
+
+NLM_EXTERN MlSummaryListPtr LIBCALL
+MlSummaryListNew(void)
+{
+ MlSummaryListPtr p;
+
+ p = MemNew(sizeof(MlSummaryList));
+ if (p != NULL)
+ {
+ p->num = 0;
+ p->data = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN MlSummaryListPtr LIBCALL
+MlSummaryListFree(MlSummaryListPtr p)
+{
+ Int4 i;
+
+ if (p == NULL)
+ return NULL;
+ if (p->data != NULL)
+ {
+ for (i = 0; i < p->num; i++)
+ MlSumFree(p->data[i]);
+ }
+ MemFree (p->data);
+ return MemFree(p);
+}
+
+NLM_EXTERN MlSummaryListPtr LIBCALL
+MlSummaryListAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ MlSummaryListPtr p;
+ AsnTypePtr atp;
+ Int4 num;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ML_SUMMARY_LIST);
+ else
+ atp = AsnLinkType(orig, ML_SUMMARY_LIST); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = MlSummaryListNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp); /* find the num */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the num */
+ goto erret;
+ p->num = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp); /* find the data start-struct */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the data start-struct */
+ goto erret;
+
+ p->data = (DocSumPtr PNTR) MemNew(sizeof(DocSumPtr) * p->num);
+ for (num = 0; num < p->num; num++)
+ p->data[num] = NULL;
+ atp = AsnReadId(aip, amp, atp);
+
+ for (num = 0; num < p->num && atp == ML_SUMMARY_LIST_data_E; num++)
+ {
+ if ((p->data[num] = MlSumAsnRead(aip, atp)) == NULL)
+ goto erret;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ /* check for count mis-match */
+ if (num != p->num || atp != ML_SUMMARY_LIST_data)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != ML_SUMMARY_LIST)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = MlSummaryListFree(p);
+ goto ret;
+}
+
+
+NLM_EXTERN Boolean LIBCALL
+MlSummaryListAsnWrite (MlSummaryListPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Int4 i;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ML_SUMMARY_LIST); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+ av.intvalue = p->num;
+ AsnWrite (aip, ML_SUMMARY_LIST_num, &av);
+
+ AsnStartStruct (aip, ML_SUMMARY_LIST_data);
+ for (i = 0; i < p->num; i++)
+ {
+ MlSumAsnWrite(p->data[i], aip, ML_SUMMARY_LIST_data_E);
+ }
+ AsnEndStruct (aip, ML_SUMMARY_LIST_data);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** EntrezSeqGet **************************************/
+
+NLM_EXTERN EntrezSeqGetPtr LIBCALL
+EntrezSeqGetNew(void)
+{
+ EntrezSeqGetPtr p;
+
+ p = MemNew(sizeof(EntrezSeqGet));
+ if (p != NULL)
+ {
+ p->ids = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN EntrezSeqGetPtr LIBCALL
+EntrezSeqGetFree(EntrezSeqGetPtr p)
+{
+ if (p == NULL)
+ return NULL;
+ EntrezIdsFree (p->ids);
+ return MemFree(p);
+}
+
+NLM_EXTERN EntrezSeqGetPtr LIBCALL
+EntrezSeqGetAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ EntrezSeqGetPtr p;
+ AsnTypePtr atp;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_SEQGET);
+ else
+ atp = AsnLinkType(orig, ENTREZ_SEQGET); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = EntrezSeqGetNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->retype = av.intvalue;
+
+ p->mark_missing = FALSE;
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == ENTREZ_SEQGET_mark_missing) {
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ p->mark_missing = av.boolvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp == NULL)
+ goto erret;
+ p->ids = EntrezIdsAsnRead(aip, atp);
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_SEQGET)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = EntrezSeqGetFree(p);
+ goto ret;
+}
+
+
+NLM_EXTERN Boolean LIBCALL
+EntrezSeqGetAsnWrite (EntrezSeqGetPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ENTREZ_SEQGET); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+ av.intvalue = p->retype;
+ AsnWrite (aip, ENTREZ_SEQGET_retype, &av);
+ av.boolvalue = p->mark_missing;
+ AsnWrite (aip, ENTREZ_SEQGET_mark_missing, &av);
+ EntrezIdsAsnWrite(p->ids, aip, ENTREZ_SEQGET_ids);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/************************** SeqSummaryList ****************************************/
+
+NLM_EXTERN SeqSummaryListPtr LIBCALL
+SeqSummaryListNew(void)
+{
+ SeqSummaryListPtr p;
+
+ p = MemNew(sizeof(SeqSummaryList));
+ if (p != NULL)
+ {
+ p->num = 0;
+ p->data = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN SeqSummaryListPtr LIBCALL
+SeqSummaryListFree(SeqSummaryListPtr p)
+{
+ Int4 i;
+
+ if (p == NULL)
+ return NULL;
+ if (p->data != NULL)
+ {
+ for (i = 0; i < p->num; i++)
+ SeqSumFree(p->data[i]);
+ }
+ MemFree (p->data);
+ return MemFree(p);
+}
+
+NLM_EXTERN SeqSummaryListPtr LIBCALL
+SeqSummaryListAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ SeqSummaryListPtr p;
+ AsnTypePtr atp;
+ Int4 num;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, SEQ_SUMMARY_LIST);
+ else
+ atp = AsnLinkType(orig, SEQ_SUMMARY_LIST); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = SeqSummaryListNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp); /* find the num */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the num */
+ goto erret;
+ p->num = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp); /* find the data start-struct */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the data start-struct */
+ goto erret;
+
+ p->data = (DocSumPtr PNTR) MemNew(sizeof(DocSumPtr) * (size_t) p->num);
+ for (num = 0; num < p->num; num++)
+ p->data[num] = NULL;
+ atp = AsnReadId(aip, amp, atp);
+
+ for (num = 0; num < p->num && atp == SEQ_SUMMARY_LIST_data_E; num++)
+ {
+ if ((p->data[num] = SeqSumAsnRead(aip, atp)) == NULL)
+ goto erret;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ /* check for count mis-match */
+ if (num != p->num || atp != SEQ_SUMMARY_LIST_data)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != SEQ_SUMMARY_LIST)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = SeqSummaryListFree(p);
+ goto ret;
+}
+
+
+NLM_EXTERN Boolean LIBCALL
+SeqSummaryListAsnWrite (SeqSummaryListPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Int4 i;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, SEQ_SUMMARY_LIST); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+ av.intvalue = p->num;
+ AsnWrite (aip, SEQ_SUMMARY_LIST_num, &av);
+
+ AsnStartStruct (aip, SEQ_SUMMARY_LIST_data);
+ for (i = 0; i < p->num; i++)
+ {
+ SeqSumAsnWrite(p->data[i], aip, SEQ_SUMMARY_LIST_data_E);
+ }
+ AsnEndStruct (aip, SEQ_SUMMARY_LIST_data);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/************************** SeqEntryList **************************************/
+
+NLM_EXTERN SeqEntryListPtr LIBCALL
+SeqEntryListNew(void)
+{
+ SeqEntryListPtr p;
+
+ p = MemNew(sizeof(*p));
+ if (p != NULL)
+ {
+ p->num = 0;
+ p->data = NULL;
+ p->marked_missing = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN SeqEntryListPtr LIBCALL
+SeqEntryListFree(SeqEntryListPtr p)
+{
+ Int4 i;
+
+ if (p == NULL)
+ return NULL;
+ if (p->data != NULL)
+ {
+ for (i = 0; i < p->num; i++)
+ SeqEntryFree(p->data[i]);
+ }
+ MemFree (p->data);
+ EntrezIdsFree (p->marked_missing);
+ return MemFree(p);
+}
+
+NLM_EXTERN SeqEntryListPtr LIBCALL
+SeqEntryListAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ SeqEntryListPtr p;
+ AsnTypePtr atp;
+ Int4 num;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_SEQ_ENTRY_LIST);
+ else
+ atp = AsnLinkType(orig, ENTREZ_SEQ_ENTRY_LIST); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = SeqEntryListNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp); /* find the num */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the num */
+ goto erret;
+ p->num = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp); /* find the data start-struct */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the data start-struct */
+ goto erret;
+
+ p->data = (SeqEntryPtr PNTR) MemNew(sizeof(SeqEntryPtr) * p->num);
+ for (num = 0; num < p->num; num++)
+ p->data[num] = NULL;
+ atp = AsnReadId(aip, amp, atp);
+
+ for (num = 0; num < p->num && atp == ENTREZ_SEQ_ENTRY_LIST_data_E; num++)
+ {
+ if ((p->data[num] = SeqEntryAsnRead(aip, atp)) == NULL)
+ goto erret;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ /* check for count mis-match */
+ if (num != p->num)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == SEQ_ENTRY_LIST_marked_missing)
+ {
+ p->marked_missing = EntrezIdsAsnRead(aip, atp);
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_SEQ_ENTRY_LIST)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = SeqEntryListFree(p);
+ goto ret;
+}
+
+
+NLM_EXTERN Boolean LIBCALL
+SeqEntryListAsnWrite (SeqEntryListPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Int4 i;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ENTREZ_SEQ_ENTRY_LIST); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+ av.intvalue = p->num;
+ AsnWrite (aip, ENTREZ_SEQ_ENTRY_LIST_num, &av);
+
+ AsnStartStruct (aip, ENTREZ_SEQ_ENTRY_LIST_data);
+ for (i = 0; i < p->num; i++)
+ {
+ SeqEntryAsnWrite(p->data[i], aip, ENTREZ_SEQ_ENTRY_LIST_data_E);
+ }
+ AsnEndStruct (aip, ENTREZ_SEQ_ENTRY_LIST_data);
+
+ if (p->marked_missing != NULL) /* optional */
+ {
+ EntrezIdsAsnWrite(p->marked_missing, aip, SEQ_ENTRY_LIST_marked_missing);
+ }
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+#ifdef Biostruc_supported
+/************************** BiostrucList *********************************/
+
+NLM_EXTERN BiostrucListPtr LIBCALL
+BiostrucListNew(void)
+{
+ BiostrucListPtr p;
+
+ p = MemNew(sizeof(BiostrucList));
+ if (p != NULL)
+ {
+ p->num = 0;
+ p->data = NULL;
+ p->marked_missing = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN BiostrucListPtr LIBCALL
+BiostrucListFree(BiostrucListPtr p)
+{
+ Int4 i;
+
+ if (p == NULL)
+ return NULL;
+ if (p->data != NULL)
+ {
+ for (i = 0; i < p->num; i++)
+ BiostrucFree(p->data[i]);
+ }
+ MemFree (p->data);
+ EntrezIdsFree (p->marked_missing);
+ return MemFree(p);
+}
+
+NLM_EXTERN BiostrucListPtr LIBCALL
+BiostrucListAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ BiostrucListPtr p;
+ AsnTypePtr atp;
+ Int4 num;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, ENTREZ_BIOSTRUC_LIST);
+ else
+ atp = AsnLinkType(orig, ENTREZ_BIOSTRUC_LIST); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = BiostrucListNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp); /* find the num */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the num */
+ goto erret;
+ p->num = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp); /* find the data start-struct */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the data start-struct */
+ goto erret;
+
+ p->data = (BiostrucPtr PNTR) MemNew(sizeof(BiostrucPtr) * p->num);
+ for (num = 0; num < p->num; num++)
+ p->data[num] = NULL;
+ atp = AsnReadId(aip, amp, atp);
+
+ for (num = 0; num < p->num && atp == ENTREZ_BIOSTRUC_LIST_data_E; num++)
+ {
+ if ((p->data[num] = BiostrucAsnRead(aip, atp)) == NULL)
+ goto erret;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ /* check for count mis-match */
+ if (num != p->num)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+
+ if (atp == BIOSTRUC_LIST_marked_missing)
+ {
+ p->marked_missing = EntrezIdsAsnRead(aip, atp);
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (orig == NULL)
+ {
+ if (atp != ENTREZ_BIOSTRUC_LIST)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = BiostrucListFree(p);
+ goto ret;
+}
+
+
+NLM_EXTERN Boolean LIBCALL
+BiostrucListAsnWrite (BiostrucListPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Int4 i;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ENTREZ_BIOSTRUC_LIST); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+ av.intvalue = p->num;
+ AsnWrite (aip, ENTREZ_BIOSTRUC_LIST_num, &av);
+
+ AsnStartStruct (aip, ENTREZ_BIOSTRUC_LIST_data);
+ for (i = 0; i < p->num; i++)
+ {
+ BiostrucAsnWrite(p->data[i], aip, ENTREZ_BIOSTRUC_LIST_data_E);
+ }
+ AsnEndStruct (aip, ENTREZ_BIOSTRUC_LIST_data);
+
+ if (p->marked_missing != NULL) /* optional */
+ {
+ EntrezIdsAsnWrite(p->marked_missing, aip, BIOSTRUC_LIST_marked_missing);
+ }
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+#endif /* Biostruc_supported */
+
+/**************************************************
+*
+* EntrezNeighborTextAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN EntrezNeighborTextPtr LIBCALL
+EntrezNeighborTextAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ AsnReadFunc func;
+ EntrezNeighborTextPtr ptr;
+
+ if (! NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* EntrezNeighborText ::= (self contained) */
+ atp = AsnReadId(aip, amp, ENTREZ_NEIGHBOR_TEXT);
+ } else {
+ atp = AsnLinkType(orig, ENTREZ_NEIGHBOR_TEXT);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = EntrezNeighborTextNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == ENTREZ_NEIGHBOR_TEXT_fld) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> fld =av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TEXT_percent_terms_to_use) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> percent_terms_to_use =av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == NEIGHBOR_TEXT_max_neighbors) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> max_neighbors =av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_NEIGHBOR_TEXT_min_score) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> min_score =av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == NEIGHBOR_TEXT_normal_text) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> normalText =av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == NEIGHBOR_TEXT_special_text) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> specialText =av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ ptr = EntrezNeighborTextFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* EntrezNeighborTextAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+EntrezNeighborTextAsnWrite(EntrezNeighborTextPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, ENTREZ_NEIGHBOR_TEXT); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> fld;
+ retval = AsnWrite(aip, ENTREZ_NEIGHBOR_TEXT_fld, &av);
+ av.intvalue = ptr -> percent_terms_to_use;
+ retval = AsnWrite(aip, TEXT_percent_terms_to_use, &av);
+ av.intvalue = ptr -> max_neighbors;
+ retval = AsnWrite(aip, NEIGHBOR_TEXT_max_neighbors, &av);
+ av.intvalue = ptr -> min_score;
+ retval = AsnWrite(aip, ENTREZ_NEIGHBOR_TEXT_min_score, &av);
+
+ if (ptr -> normalText != NULL) {
+ av.ptrvalue = ptr -> normalText;
+ retval = AsnWrite(aip, NEIGHBOR_TEXT_normal_text, &av);
+ }
+
+ if (ptr -> specialText != NULL) {
+ av.ptrvalue = ptr -> specialText;
+ retval = AsnWrite(aip, NEIGHBOR_TEXT_special_text, &av);
+ }
+
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* ChildLinkNew()
+*
+***************************************************/
+
+static ChildLinkPtr LIBCALL ChildLinkNew(void)
+{
+ ChildLinkPtr ptr = MemNew((size_t) sizeof(ChildLink));
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* ChildLinkFree()
+*
+**************************************************/
+
+static ChildLinkPtr LIBCALL ChildLinkFree(ChildLinkPtr ptr)
+{
+
+ if(ptr == NULL)
+ {
+ return NULL;
+ }
+ MemFree(ptr -> name);
+ return MemFree(ptr);
+}
+
+/******************************************
+*
+* ChildLinkedListFree()
+*
+*******************************************/
+
+static void LIBCALL ChildLinkedListFree(ChildLinkPtr ptr)
+{
+ ChildLinkPtr next;
+ while(ptr != NULL)
+ {
+ next = ptr -> next;
+ ChildLinkFree(ptr);
+ ptr = next;
+ }
+}
+
+
+
+/**************************************************
+*
+* ChildLinkAsnRead()
+*
+**************************************************/
+
+static ChildLinkPtr LIBCALL ChildLinkAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError;
+ AsnReadFunc func;
+ ChildLinkPtr ChildPtr;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) {
+ atp = AsnReadId(aip, amp, ENTREZ_TREE_CHILD);
+ } else {
+ atp = AsnLinkType(orig, ENTREZ_TREE_CHILD);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ChildPtr = ChildLinkNew();
+ if (ChildPtr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == ENTREZ_TREE_CHILD_name) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ChildPtr -> name = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_TREE_CHILD_is_leaf_node) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ChildPtr -> isLeafNode = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_TREE_CHILD_special) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ChildPtr -> special = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_TREE_CHILD_total) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ChildPtr -> total = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ChildPtr;
+
+erret:
+ ChildLinkFree(ChildPtr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* ChildLinkAsnWrite()
+*
+**************************************************/
+static Boolean LIBCALL
+ChildLinkAsnWrite(ChildLinkPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, ENTREZ_TREE_CHILD); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> name != NULL) {
+ av.ptrvalue = ptr -> name;
+ retval = AsnWrite(aip, ENTREZ_TREE_CHILD_name, &av);
+ }
+ av.boolvalue = ptr -> isLeafNode;
+ retval = AsnWrite(aip, ENTREZ_TREE_CHILD_is_leaf_node, &av);
+ av.intvalue = ptr -> special;
+ retval = AsnWrite(aip, ENTREZ_TREE_CHILD_special, &av);
+ av.intvalue = ptr -> total;
+ retval = AsnWrite(aip, ENTREZ_TREE_CHILD_total, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+static EntrezHierarchyChildPtr ChildLinkedListToArray(ChildLinkPtr Link,
+ Int4 numChildren)
+{
+ Int4 Index = 0;
+ EntrezHierarchyChildPtr Array;
+
+ if (numChildren <= 0)
+ return NULL;
+
+ Array = MemNew(sizeof(EntrezHierarchyChild) * numChildren);
+ while (Link != NULL)
+ {
+ Array[Index].name = StringSave(Link -> name);
+ Array[Index].isLeafNode = Link -> isLeafNode;
+ Array[Index].special = Link -> special;
+ Array[Index].total = Link -> total;
+ Index++;
+ Link = Link -> next;
+ }
+
+ if (Index != numChildren)
+ {
+ fprintf(stderr,"ChildLinkedListToArray : counts do not match!\n");
+ exit (0);
+ }
+
+ return Array;
+}
+
+static ChildLinkPtr ArrayToChildLinkedList(
+ EntrezHierarchyChildPtr Array,
+ Int4 numChildren)
+{
+ Int4 Index;
+ ChildLinkPtr Link, Start;
+
+ if (numChildren <= 0)
+ return NULL;
+
+ for (Index = 0; Index < numChildren; Index++)
+ {
+ if (Index == 0)
+ Start = Link = ChildLinkNew();
+ else
+ {
+ Link -> next = ChildLinkNew();
+ Link = Link -> next;
+ }
+
+ Link -> name = StringSave(Array[Index].name);
+ Link -> isLeafNode = Array[Index].isLeafNode;
+ Link -> special = Array[Index].special;
+ Link -> total = Array[Index].total;
+ }
+
+ Link -> next = NULL;
+ return (Start);
+
+}
+
+static CharPtr PNTR LineageListToArray(ValNodePtr Lineage,
+ Int4 numInLineage)
+{
+ CharPtr PNTR start;
+ CharPtr PNTR ptr;
+
+ if (numInLineage <= 0)
+ return NULL;
+
+ start = ptr = MemNew(sizeof(CharPtr) * numInLineage);
+ while (Lineage != NULL)
+ {
+ *ptr++ = StringSave(Lineage -> data.ptrvalue);
+ Lineage = Lineage -> next;
+ }
+
+ if ((long) (ptr - start) != numInLineage)
+ {
+ fprintf(stderr,"mismatch in LineageListToArray!\n");
+ exit (0);
+ }
+
+ return start;
+}
+
+static ValNodePtr LineageArrayToList(CharPtr PNTR Lineage, Int4 numInLineage)
+{
+ ValNodePtr ptr, start;
+ Int4 index;
+
+ if (numInLineage <= 0)
+ return NULL;
+
+ for (index = 0; index < numInLineage; index++)
+ {
+ if (index == 0)
+ {
+ start = ptr = MemNew(sizeof(ValNode));
+ }
+ else
+ {
+ ptr -> next = MemNew(sizeof(ValNode));
+ ptr = ptr ->next;
+ }
+
+ ptr -> choice = 0;
+ ptr -> data.ptrvalue = StringSave(Lineage[index]);
+ }
+
+ ptr -> next = NULL;
+
+ return start;
+}
+
+static void FreeLineageList(ValNodePtr ptr)
+{
+ ValNodePtr next;
+
+ while(ptr != NULL)
+ {
+ next = ptr ->next;
+ MemFree(ptr -> data.ptrvalue);
+ MemFree(ptr);
+ ptr = next;
+ }
+}
+
+
+/**************************************************
+*
+* EntrezHierarchyNew()
+*
+**************************************************/
+
+NLM_EXTERN EntrezHierarchyPtr LIBCALL EntrezHierarchyNew(void)
+{
+ EntrezHierarchyPtr ptr = MemNew((size_t) sizeof(EntrezHierarchy));
+ return ptr;
+}
+
+
+/**************************************************
+*
+* EntrezHierarchyFree() is defined in accentr.c
+*
+**************************************************/
+
+
+
+/**************************************************
+*
+* EntrezHierarchyAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN EntrezHierarchyPtr LIBCALL EntrezHierarchyAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError;
+ AsnReadFunc func;
+ EntrezHierarchyPtr ptr;
+ ChildLinkPtr ChildLinkedList;
+ ValNodePtr LineageList;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad())
+ {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL)
+ {
+ return NULL;
+ }
+
+ if (orig == NULL)
+ { /* EntrezHierarchy ::= (self contained) */
+ atp = AsnReadId(aip, amp, ENTREZ_TREE);
+ }
+ else
+ {
+ atp = AsnLinkType(orig, ENTREZ_TREE);
+ }
+ /* link in local tree */
+ if (atp == NULL)
+ {
+ return NULL;
+ }
+
+ ptr = EntrezHierarchyNew();
+ if (ptr == NULL)
+ {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ { /* read the start struct */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == ENTREZ_TREE_num_in_lineage)
+ {
+ if ( AsnReadVal(aip, atp, &av) <= 0)
+ {
+ goto erret;
+ }
+ ptr -> numInLineage = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_TREE_num_children)
+ {
+ if ( AsnReadVal(aip, atp, &av) <= 0)
+ {
+ goto erret;
+ }
+ ptr -> numChildren = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_TREE_term)
+ {
+ if ( AsnReadVal(aip, atp, &av) <= 0)
+ {
+ goto erret;
+ }
+ ptr -> term = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_TREE_lineage)
+ {
+ LineageList = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && LineageList == NULL)
+
+ {
+ goto erret;
+ }
+ ptr -> lineage = LineageListToArray(LineageList,
+ ptr->numInLineage);
+ FreeLineageList(LineageList);
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (atp == ENTREZ_TREE_children)
+ {
+ ChildLinkedList = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError,
+ (AsnReadFunc) ChildLinkAsnRead,
+ (AsnOptFreeFunc) ChildLinkFree);
+ if (isError && ChildLinkedList == NULL)
+
+ {
+ goto erret;
+ }
+ ptr -> children = ChildLinkedListToArray(ChildLinkedList,
+ ptr ->numChildren);
+ ChildLinkedListFree(ChildLinkedList);
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_TREE_canonical_form)
+ {
+ if ( AsnReadVal(aip, atp, &av) <= 0)
+ {
+ goto erret;
+ }
+ ptr -> canonicalForm = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ {
+ goto erret;
+ }
+ /* end struct */
+
+ ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+ erret:
+ ptr = EntrezHierarchyFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* EntrezHierarchyAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+EntrezHierarchyAsnWrite(EntrezHierarchyPtr ptr, AsnIoPtr aip,
+ AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+ ValNodePtr LineageList;
+ ChildLinkPtr ChildLinkedList;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad())
+ {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL)
+ {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, ENTREZ_TREE); /* link local tree */
+ if (atp == NULL)
+ {
+ return FALSE;
+ }
+
+ if (ptr == NULL)
+ {
+ AsnNullValueMsg(aip, atp); goto erret;
+ }
+
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr))
+ {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> numInLineage;
+ retval = AsnWrite(aip, ENTREZ_TREE_num_in_lineage, &av);
+ av.intvalue = ptr -> numChildren;
+ retval = AsnWrite(aip, ENTREZ_TREE_num_children, &av);
+ if (ptr -> term != NULL)
+ {
+ av.ptrvalue = ptr -> term;
+ retval = AsnWrite(aip, ENTREZ_TREE_term, &av);
+ }
+
+ LineageList = LineageArrayToList(ptr -> lineage,ptr -> numInLineage);
+ retval = AsnGenericBaseSeqOfAsnWrite(LineageList ,ASNCODE_PTRVAL_SLOT,
+ aip,ENTREZ_TREE_lineage,
+ ENTREZ_TREE_lineage_E);
+ FreeLineageList(LineageList);
+
+ ChildLinkedList = ArrayToChildLinkedList(ptr -> children,ptr->numChildren);
+ AsnGenericUserSeqOfAsnWrite(ChildLinkedList,
+ (AsnWriteFunc) ChildLinkAsnWrite, aip,
+ ENTREZ_TREE_children, ENTREZ_TREE_children_E);
+ ChildLinkedListFree(ChildLinkedList);
+
+ if (ptr -> canonicalForm != NULL)
+ {
+ av.ptrvalue = ptr -> canonicalForm;
+ retval = AsnWrite(aip, ENTREZ_TREE_canonical_form, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr))
+ {
+ goto erret;
+ }
+ retval = TRUE;
+
+ erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* EntrezBlastreqNew()
+*
+**************************************************/
+
+NLM_EXTERN EntrezBlastreqPtr LIBCALL
+EntrezBlastreqNew(void)
+{
+ EntrezBlastreqPtr ptr = MemNew((size_t) sizeof(EntrezBlastreq));
+
+ ptr->showprogress = FALSE;
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* EntrezBlastreqFree()
+*
+**************************************************/
+
+NLM_EXTERN EntrezBlastreqPtr LIBCALL
+EntrezBlastreqFree(EntrezBlastreqPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ BioseqFree(ptr -> bsp);
+ MemFree(ptr -> program);
+ MemFree(ptr -> database);
+ MemFree(ptr -> options);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* EntrezBlastreqAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN EntrezBlastreqPtr LIBCALL
+EntrezBlastreqAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ EntrezBlastreqPtr ptr;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* EntrezBlastreq ::= (self contained) */
+ atp = AsnReadId(aip, amp, ENTREZ_BLASTREQ);
+ } else {
+ atp = AsnLinkType(orig, ENTREZ_BLASTREQ);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = EntrezBlastreqNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == ENTREZ_BLASTREQ_bsp) {
+ ptr -> bsp = BioseqAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_BLASTREQ_bsp_database) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> bsp_database = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_BLASTREQ_program) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> program = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_BLASTREQ_database) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> database = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_BLASTREQ_options) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> options = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_BLASTREQ_showprogress) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> showprogress = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = EntrezBlastreqFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* EntrezBlastreqAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+EntrezBlastreqAsnWrite(EntrezBlastreqPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, ENTREZ_BLASTREQ); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> bsp != NULL) {
+ if ( ! BioseqAsnWrite(ptr -> bsp, aip, ENTREZ_BLASTREQ_bsp)) {
+ goto erret;
+ }
+ }
+ av.intvalue = ptr -> bsp_database;
+ retval = AsnWrite(aip, ENTREZ_BLASTREQ_bsp_database, &av);
+ if (ptr -> program != NULL) {
+ av.ptrvalue = ptr -> program;
+ retval = AsnWrite(aip, ENTREZ_BLASTREQ_program, &av);
+ }
+ if (ptr -> database != NULL) {
+ av.ptrvalue = ptr -> database;
+ retval = AsnWrite(aip, ENTREZ_BLASTREQ_database, &av);
+ }
+ if (ptr -> options != NULL) {
+ av.ptrvalue = ptr -> options;
+ retval = AsnWrite(aip, ENTREZ_BLASTREQ_options, &av);
+ }
+ av.boolvalue = ptr -> bsp_database;
+ retval = AsnWrite(aip, ENTREZ_BLASTREQ_showprogress, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* EntrezExtraInfoNew()
+*
+**************************************************/
+
+NLM_EXTERN EntrezExtraInfoPtr LIBCALL
+EntrezExtraInfoNew(void)
+{
+ EntrezExtraInfoPtr ptr = MemNew((size_t) sizeof(EntrezExtraInfo));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* EntrezExtraInfoFree()
+*
+**************************************************/
+
+NLM_EXTERN EntrezExtraInfoPtr LIBCALL
+EntrezExtraInfoFree(EntrezExtraInfoPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* EntrezExtraInfoAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN EntrezExtraInfoPtr LIBCALL
+EntrezExtraInfoAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ EntrezExtraInfoPtr ptr;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* EntrezExtraInfo ::= (self contained) */
+ atp = AsnReadId(aip, amp, ENTREZ_EXTRA_INFO);
+ } else {
+ atp = AsnLinkType(orig, ENTREZ_EXTRA_INFO);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = EntrezExtraInfoNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == ENTREZ_EXTRA_INFO_maxlinks) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> maxlinks = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == EXTRA_INFO_canneighbortext) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> canneighbortext = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == EXTRA_INFO_expanded_medline) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> expanded_medline = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ENTREZ_EXTRA_INFO_canblast) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> canblast = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = EntrezExtraInfoFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* EntrezExtraInfoAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+EntrezExtraInfoAsnWrite(EntrezExtraInfoPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, ENTREZ_EXTRA_INFO); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> maxlinks;
+ retval = AsnWrite(aip, ENTREZ_EXTRA_INFO_maxlinks, &av);
+ av.boolvalue = ptr -> canneighbortext;
+ retval = AsnWrite(aip, EXTRA_INFO_canneighbortext, &av);
+ av.boolvalue = ptr -> expanded_medline;
+ retval = AsnWrite(aip, EXTRA_INFO_expanded_medline, &av);
+ av.boolvalue = ptr -> canblast;
+ retval = AsnWrite(aip, ENTREZ_EXTRA_INFO_canblast, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/************************** NewSummaryList ****************************************/
+
+NLM_EXTERN NewSummaryListPtr LIBCALL
+NewSummaryListNew(void)
+{
+ NewSummaryListPtr p;
+
+ p = MemNew(sizeof(NewSummaryList));
+ if (p != NULL)
+ {
+ p->num = 0;
+ p->data = NULL;
+ }
+ return p;
+}
+
+NLM_EXTERN NewSummaryListPtr LIBCALL
+NewSummaryListFree(NewSummaryListPtr p)
+{
+ Int4 i;
+
+ if (p == NULL)
+ return NULL;
+ if (p->data != NULL)
+ {
+ for (i = 0; i < p->num; i++)
+ DocSumFree(p->data[i]);
+ }
+ MemFree (p->data);
+ return MemFree(p);
+}
+
+NLM_EXTERN NewSummaryListPtr LIBCALL
+NewSummaryListAsnRead (AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ NewSummaryListPtr p;
+ AsnTypePtr atp;
+ Int4 num;
+
+ if (!NetEntAsnLoad())
+ return NULL;
+
+ if (aip == NULL)
+ return NULL;
+
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, NEW_SUMMARY_LIST);
+ else
+ atp = AsnLinkType(orig, NEW_SUMMARY_LIST); /* link in local tree */
+
+ if (atp == NULL)
+ return NULL;
+
+ p = NewSummaryListNew();
+ if (p == NULL)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) /* read the start struct */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp); /* find the num */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the num */
+ goto erret;
+ p->num = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp); /* find the type */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the type */
+ goto erret;
+ p->type = av.intvalue;
+
+ atp = AsnReadId(aip, amp, atp); /* find the data start-struct */
+ if (atp == NULL)
+ goto erret;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* get the data start-struct */
+ goto erret;
+
+ p->data = (DocSumPtr PNTR) MemNew(sizeof(DocSumPtr) * (size_t) p->num);
+ for (num = 0; num < p->num; num++)
+ p->data[num] = NULL;
+ atp = AsnReadId(aip, amp, atp);
+
+ for (num = 0; num < p->num && atp == NEW_SUMMARY_LIST_data_E; num++)
+ {
+ if ((p->data[num] = DocSumAsnRead(aip, atp)) == NULL)
+ goto erret;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ /* check for count mis-match */
+ if (num != p->num || atp != NEW_SUMMARY_LIST_data)
+ goto erret;
+
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ atp = AsnReadId(aip, amp, atp);
+ if (orig == NULL)
+ {
+ if (atp != NEW_SUMMARY_LIST)
+ goto erret;
+ }
+ else { /* check for "close struct" associated with "orig" */
+ if (atp != orig)
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
+ goto erret;
+
+ret:
+ AsnUnlinkType(orig);
+ return p;
+
+erret:
+ p = NewSummaryListFree(p);
+ goto ret;
+}
+
+
+NLM_EXTERN Boolean LIBCALL
+NewSummaryListAsnWrite (NewSummaryListPtr p, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ Int4 i;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! NetEntAsnLoad() )
+ return FALSE;
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, NEW_SUMMARY_LIST); /* link local tree */
+
+ if (atp == NULL)
+ return FALSE;
+
+ if (p == NULL)
+ {
+ AsnNullValueMsg(aip, atp);
+ goto erret;
+ }
+
+ if (! AsnStartStruct(aip, atp))
+ goto erret;
+ av.intvalue = p->num;
+ AsnWrite (aip, NEW_SUMMARY_LIST_num, &av);
+ av.intvalue = p->type;
+ AsnWrite (aip, NEW_SUMMARY_LIST_type, &av);
+
+ AsnStartStruct (aip, NEW_SUMMARY_LIST_data);
+ for (i = 0; i < p->num; i++)
+ {
+ DocSumAsnWrite(p->data[i], aip, NEW_SUMMARY_LIST_data_E);
+ }
+ AsnEndStruct (aip, NEW_SUMMARY_LIST_data);
+
+ if (! AsnEndStruct(aip, atp))
+ goto erret;
+
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/**************************************************
+*
+* ClusterArticlesNew()
+*
+**************************************************/
+
+NLM_EXTERN ClusterArticlesPtr LIBCALL
+ClusterArticlesNew(void)
+{
+ ClusterArticlesPtr ptr = MemNew((size_t) sizeof(ClusterArticles));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* ClusterArticlesFree()
+*
+**************************************************/
+
+NLM_EXTERN ClusterArticlesPtr LIBCALL
+ClusterArticlesFree(ClusterArticlesPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ EntrezIdsFree(ptr -> ids);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* ClusterArticlesAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN ClusterArticlesPtr LIBCALL
+ClusterArticlesAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ ClusterArticlesPtr ptr;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* ClusterArticles ::= (self contained) */
+ atp = AsnReadId(aip, amp, CLUSTER_ARTICLES);
+ } else {
+ atp = AsnLinkType(orig, CLUSTER_ARTICLES);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = ClusterArticlesNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == CLUSTER_ARTICLES_ids) {
+ ptr -> ids = EntrezIdsAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == CLUSTER_ARTICLES_fld) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> fld = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == CLUSTER_ARTICLES_min_cluster) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> min_cluster = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == CLUSTER_ARTICLES_max_cluster) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> max_cluster = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == CLUSTER_ARTICLES_max_terms) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> max_terms = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = ClusterArticlesFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* ClusterArticlesAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+ClusterArticlesAsnWrite(ClusterArticlesPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, CLUSTER_ARTICLES); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> ids != NULL) {
+ if ( ! EntrezIdsAsnWrite(ptr -> ids, aip, CLUSTER_ARTICLES_ids)) {
+ goto erret;
+ }
+ }
+ av.intvalue = ptr -> fld;
+ retval = AsnWrite(aip, CLUSTER_ARTICLES_fld, &av);
+ av.intvalue = ptr -> min_cluster;
+ retval = AsnWrite(aip, CLUSTER_ARTICLES_min_cluster, &av);
+ av.intvalue = ptr -> max_cluster;
+ retval = AsnWrite(aip, CLUSTER_ARTICLES_max_cluster, &av);
+ av.intvalue = ptr -> max_terms;
+ retval = AsnWrite(aip, CLUSTER_ARTICLES_max_terms, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* ClusterRespNew()
+*
+**************************************************/
+
+NLM_EXTERN ClusterRespPtr LIBCALL
+ClusterRespNew(void)
+{
+ ClusterRespPtr ptr = MemNew((size_t) sizeof(ClusterResp));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* ClusterRespFree()
+*
+**************************************************/
+
+NLM_EXTERN ClusterRespPtr LIBCALL
+ClusterRespFree(ClusterRespPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericBaseSeqOfFree(ptr -> terms ,ASNCODE_PTRVAL_SLOT);
+ AsnGenericBaseSeqOfFree(ptr -> term_counts ,ASNCODE_INTVAL_SLOT);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* ClusterRespAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN ClusterRespPtr LIBCALL
+ClusterRespAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ ClusterRespPtr ptr;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* ClusterResp ::= (self contained) */
+ atp = AsnReadId(aip, amp, CLUSTER_RESP);
+ } else {
+ atp = AsnLinkType(orig, CLUSTER_RESP);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = ClusterRespNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == CLUSTER_RESP_count) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> count = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == CLUSTER_RESP_terms) {
+ ptr -> terms = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_PTRVAL_SLOT, &isError);
+ if (isError && ptr -> terms == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == CLUSTER_RESP_term_counts) {
+ ptr -> term_counts = AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_INTVAL_SLOT, &isError);
+ if (isError && ptr -> term_counts == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = ClusterRespFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* ClusterRespAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+ClusterRespAsnWrite(ClusterRespPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, CLUSTER_RESP); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> count;
+ retval = AsnWrite(aip, CLUSTER_RESP_count, &av);
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> terms ,ASNCODE_PTRVAL_SLOT, aip, CLUSTER_RESP_terms, CLUSTER_RESP_terms_E);
+ retval = AsnGenericBaseSeqOfAsnWrite(ptr -> term_counts ,ASNCODE_INTVAL_SLOT, aip, CLUSTER_RESP_term_counts, CLUSTER_RESP_term_counts_E);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+/**************************************************
+*
+* DateConstraintsNew()
+*
+**************************************************/
+
+NLM_EXTERN DateConstraintsPtr LIBCALL
+DateConstraintsNew(void)
+{
+ DateConstraintsPtr ptr = MemNew((size_t) sizeof(DateConstraints));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* DateConstraintsFree()
+*
+**************************************************/
+
+NLM_EXTERN DateConstraintsPtr LIBCALL
+DateConstraintsFree(DateConstraintsPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericUserSeqOfFree(ptr -> date_vec, (AsnOptFreeFunc) DateVectorFree);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* DateConstraintsAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN DateConstraintsPtr LIBCALL
+DateConstraintsAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ DateConstraintsPtr ptr;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* DateConstraints ::= (self contained) */
+ atp = AsnReadId(aip, amp, DATE_CONSTRAINTS);
+ } else {
+ atp = AsnLinkType(orig, DATE_CONSTRAINTS);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = DateConstraintsNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == DATE_CONSTRAINTS_count) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> count = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == DATE_CONSTRAINTS_date_vec) {
+ ptr -> date_vec = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) DateVectorAsnRead, (AsnOptFreeFunc) DateVectorFree);
+ if (isError && ptr -> date_vec == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = DateConstraintsFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* DateConstraintsAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+DateConstraintsAsnWrite(DateConstraintsPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, DATE_CONSTRAINTS); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> count;
+ retval = AsnWrite(aip, DATE_CONSTRAINTS_count, &av);
+ AsnGenericUserSeqOfAsnWrite(ptr -> date_vec, (AsnWriteFunc) DateVectorAsnWrite, aip, DATE_CONSTRAINTS_date_vec, DATE_CONSTRAINTS_date_vec_E);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* DateVectorNew()
+*
+**************************************************/
+
+NLM_EXTERN DateVectorPtr LIBCALL
+DateVectorNew(void)
+{
+ DateVectorPtr ptr = MemNew((size_t) sizeof(DateVector));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* DateVectorFree()
+*
+**************************************************/
+
+NLM_EXTERN DateVectorPtr LIBCALL
+DateVectorFree(DateVectorPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ DateFree(ptr -> begin_date);
+ DateFree(ptr -> end_date);
+ MemFree(ptr -> field_abbr);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* DateVectorAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN DateVectorPtr LIBCALL
+DateVectorAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ DateVectorPtr ptr;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* DateVector ::= (self contained) */
+ atp = AsnReadId(aip, amp, DATE_VECTOR);
+ } else {
+ atp = AsnLinkType(orig, DATE_VECTOR);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = DateVectorNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == DATE_VECTOR_begin_date) {
+ ptr -> begin_date = DateAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == DATE_VECTOR_end_date) {
+ ptr -> end_date = DateAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == DATE_VECTOR_field_abbr) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> field_abbr = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = DateVectorFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* DateVectorAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+DateVectorAsnWrite(DateVectorPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, DATE_VECTOR); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> begin_date != NULL) {
+ if ( ! DateAsnWrite(ptr -> begin_date, aip, DATE_VECTOR_begin_date)) {
+ goto erret;
+ }
+ }
+ if (ptr -> end_date != NULL) {
+ if ( ! DateAsnWrite(ptr -> end_date, aip, DATE_VECTOR_end_date)) {
+ goto erret;
+ }
+ }
+ if (ptr -> field_abbr != NULL) {
+ av.ptrvalue = ptr -> field_abbr;
+ retval = AsnWrite(aip, DATE_VECTOR_field_abbr, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* GetByFidNew()
+*
+**************************************************/
+
+NLM_EXTERN GetByFidPtr LIBCALL
+GetByFidNew(void)
+{
+ GetByFidPtr ptr = MemNew((size_t) sizeof(GetByFid));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* GetByFidFree()
+*
+**************************************************/
+
+NLM_EXTERN GetByFidPtr LIBCALL
+GetByFidFree(GetByFidPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* GetByFidAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN GetByFidPtr LIBCALL
+GetByFidAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ GetByFidPtr ptr;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* GetByFid ::= (self contained) */
+ atp = AsnReadId(aip, amp, GET_BY_FID);
+ } else {
+ atp = AsnLinkType(orig, GET_BY_FID);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = GetByFidNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == GET_BY_FID_mmdbid) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> mmdbid = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == GET_BY_FID_feature_id) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> feature_id = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == GET_BY_FID_feature_set_id) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> feature_set_id = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = GetByFidFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* GetByFidAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+GetByFidAsnWrite(GetByFidPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, GET_BY_FID); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> mmdbid;
+ retval = AsnWrite(aip, GET_BY_FID_mmdbid, &av);
+ av.intvalue = ptr -> feature_id;
+ retval = AsnWrite(aip, GET_BY_FID_feature_id, &av);
+ av.intvalue = ptr -> feature_set_id;
+ retval = AsnWrite(aip, GET_BY_FID_feature_set_id, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* GetFeatIdsNew()
+*
+**************************************************/
+
+NLM_EXTERN GetFeatIdsPtr LIBCALL
+GetFeatIdsNew(void)
+{
+ GetFeatIdsPtr ptr = MemNew((size_t) sizeof(GetFeatIds));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* GetFeatIdsFree()
+*
+**************************************************/
+
+NLM_EXTERN GetFeatIdsPtr LIBCALL
+GetFeatIdsFree(GetFeatIdsPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* GetFeatIdsAsnRead()
+*
+**************************************************/
+
+NLM_EXTERN GetFeatIdsPtr LIBCALL
+GetFeatIdsAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ GetFeatIdsPtr ptr;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* GetFeatIds ::= (self contained) */
+ atp = AsnReadId(aip, amp, GET_FEAT_IDS);
+ } else {
+ atp = AsnLinkType(orig, GET_FEAT_IDS);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = GetFeatIdsNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == GET_FEAT_IDS_mmdbid) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> mmdbid = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == GET_FEAT_IDS_feature_type) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> feature_type = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == GET_FEAT_IDS_feature_set_id) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> feature_set_id = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = GetFeatIdsFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* GetFeatIdsAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+GetFeatIdsAsnWrite(GetFeatIdsPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! NetEntAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, GET_FEAT_IDS); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> mmdbid;
+ retval = AsnWrite(aip, GET_FEAT_IDS_mmdbid, &av);
+ av.intvalue = ptr -> feature_type;
+ retval = AsnWrite(aip, GET_FEAT_IDS_feature_type, &av);
+ av.intvalue = ptr -> feature_set_id;
+ retval = AsnWrite(aip, GET_FEAT_IDS_feature_set_id, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
diff --git a/network/entrez/client/objneten.h b/network/entrez/client/objneten.h
new file mode 100644
index 00000000..0945c5a5
--- /dev/null
+++ b/network/entrez/client/objneten.h
@@ -0,0 +1,646 @@
+/* objneten.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: objneten.h
+*
+* Author: Epstein
+*
+* Version Creation Date: 6/3/92
+*
+* $Revision: 6.0 $
+*
+* File Description: Object loader interface for module NCBI-Entrez
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 8-16-94 Brylawski Added declarations for EntrezNeighborText and
+* EntrezHierarchy loaders and structures.
+*
+* 11-20-94 Brylawski Moved the EntrezNeighborText structure to accentr.h
+* to permit its use in chosen.c and netentr.c .
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: objneten.h,v $
+* Revision 6.0 1997/08/25 18:35:13 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/07/29 21:24:27 vakatov
+* [WIN32,DLL] DLL'zation of "netentr.lib"
+*
+* Revision 5.1 1996/08/14 19:48:21 epstein
+* add annot get by feat ids, and also add date filtering support
+*
+ * Revision 5.0 1996/05/28 14:10:21 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.2 1995/08/22 19:35:04 epstein
+ * add clustering support
+ *
+ * Revision 4.1 1995/08/08 15:03:11 epstein
+ * fix NetEntAsnLoad prototype per J. Zhang
+ *
+ * Revision 4.0 1995/07/26 13:54:59 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.14 1995/07/11 12:30:30 epstein
+ * change CDECLs to LIBCALLs
+ *
+ * Revision 1.13 1995/07/10 19:39:04 epstein
+ * add docsumX
+ *
+ * Revision 1.12 1995/06/23 13:21:16 kans
+ * include <accentr.h> to pull in Biostruc_supported symbol
+ *
+ * Revision 1.11 1995/05/17 17:53:35 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NCBI_NetEntrez_
+#define _NCBI_NetEntrez_
+
+#ifndef _ASNTOOL_
+#include <asn.h>
+#endif
+
+/* accentr.h is included to define Biostruc_supported */
+#ifndef _ACCENTR_
+#include <accentr.h>
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************
+*
+* loader
+*
+*****************************************************************************/
+NLM_EXTERN Boolean LIBCALL NetEntAsnLoad PROTO((void));
+
+/*****************************************************************************
+*
+* internal structures for NCBI-Entrez objects
+*
+*****************************************************************************/
+
+/*****************************************************************************
+*
+* Entrez-ids
+*
+*****************************************************************************/
+
+
+typedef struct {
+ Int4 numid;
+ DocUidPtr ids;
+} EntrezIds, PNTR EntrezIdsPtr;
+
+NLM_EXTERN EntrezIdsPtr LIBCALL EntrezIdsNew PROTO((void));
+NLM_EXTERN EntrezIdsPtr LIBCALL EntrezIdsFree PROTO(( EntrezIdsPtr ufp));
+NLM_EXTERN EntrezIdsPtr LIBCALL EntrezIdsAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL EntrezIdsAsnWrite PROTO((EntrezIdsPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+/*****************************************************************************
+*
+* Marked-link-set
+*
+*****************************************************************************/
+typedef struct {
+ LinkSetPtr link_set;
+ Int4 uids_processed;
+ EntrezIdsPtr marked_missing;
+} MarkedLinkSet, PNTR MarkedLinkSetPtr;
+
+
+NLM_EXTERN MarkedLinkSetPtr LIBCALL MarkedLinkSetNew PROTO((void));
+NLM_EXTERN MarkedLinkSetPtr LIBCALL MarkedLinkSetFree PROTO(( MarkedLinkSetPtr ufp));
+NLM_EXTERN MarkedLinkSetPtr LIBCALL MarkedLinkSetAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL MarkedLinkSetAsnWrite PROTO((MarkedLinkSetPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+/*****************************************************************************
+*
+* Named-List
+*
+*****************************************************************************/
+
+typedef struct {
+ DocType type;
+ DocField fld;
+ CharPtr term;
+ EntrezIdsPtr uids;
+} NamedList, PNTR NamedListPtr;
+
+NLM_EXTERN NamedListPtr LIBCALL NamedListNew PROTO((void));
+NLM_EXTERN NamedListPtr LIBCALL NamedListFree PROTO(( NamedListPtr ufp));
+NLM_EXTERN NamedListPtr LIBCALL NamedListAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL NamedListAsnWrite PROTO((NamedListPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+/*****************************************************************************
+*
+* Term-by-Page
+*
+*****************************************************************************/
+
+typedef struct {
+ DocType type;
+ DocField fld;
+ Int4 page;
+ Int4 num_pages;
+} TermByPage, PNTR TermByPagePtr;
+
+NLM_EXTERN TermByPagePtr LIBCALL TermByPageNew PROTO((void));
+NLM_EXTERN TermByPagePtr LIBCALL TermByPageFree PROTO(( TermByPagePtr ufp));
+NLM_EXTERN TermByPagePtr LIBCALL TermByPageAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL TermByPageAsnWrite PROTO((TermByPagePtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+/*****************************************************************************
+*
+* Term-by-Term
+*
+*****************************************************************************/
+
+typedef struct {
+ DocType type;
+ DocField fld;
+ CharPtr term;
+ Int4 num_terms;
+} TermByTerm, PNTR TermByTermPtr;
+
+NLM_EXTERN TermByTermPtr LIBCALL TermByTermNew PROTO((void));
+NLM_EXTERN TermByTermPtr LIBCALL TermByTermFree PROTO(( TermByTermPtr ufp));
+NLM_EXTERN TermByTermPtr LIBCALL TermByTermAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL TermByTermAsnWrite PROTO((TermByTermPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+/*****************************************************************************
+*
+* Term-Lookup
+*
+*****************************************************************************/
+
+typedef struct {
+ DocType type;
+ DocField fld;
+ CharPtr term;
+} TermLookup, PNTR TermLookupPtr;
+
+NLM_EXTERN TermLookupPtr LIBCALL TermLookupNew PROTO((void));
+NLM_EXTERN TermLookupPtr LIBCALL TermLookupFree PROTO(( TermLookupPtr ufp));
+NLM_EXTERN TermLookupPtr LIBCALL TermLookupAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL TermLookupAsnWrite PROTO((TermLookupPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+/*****************************************************************************
+*
+* Term-Page-Info
+*
+*****************************************************************************/
+
+typedef struct {
+ CharPtr term;
+ Int4 spec_count;
+ Int4 tot_count;
+} TermPageInfo, PNTR TermPageInfoPtr;
+
+NLM_EXTERN TermPageInfoPtr LIBCALL TermPageInfoNew PROTO((void));
+NLM_EXTERN TermPageInfoPtr LIBCALL TermPageInfoFree PROTO(( TermPageInfoPtr ufp));
+NLM_EXTERN TermPageInfoPtr LIBCALL TermPageInfoAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL TermPageInfoAsnWrite PROTO((TermPageInfoPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+/*****************************************************************************
+*
+* Term-Counts
+*
+*****************************************************************************/
+
+typedef struct {
+ Boolean found;
+ Int4 spec_count;
+ Int4 tot_count;
+} TermCounts, PNTR TermCountsPtr;
+
+NLM_EXTERN TermCountsPtr LIBCALL TermCountsNew PROTO((void));
+NLM_EXTERN TermCountsPtr LIBCALL TermCountsFree PROTO(( TermCountsPtr ufp));
+NLM_EXTERN TermCountsPtr LIBCALL TermCountsAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL TermCountsAsnWrite PROTO((TermCountsPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+/*****************************************************************************
+*
+* Link-SetGet
+*
+*****************************************************************************/
+
+typedef struct {
+ Int4 max; /* maximum Ids to return */
+ DocType link_to_cls;
+ DocType query_cls;
+ Boolean mark_missing;
+ Int4 query_size;
+ DocUidPtr query;
+} LinkSetGet, PNTR LinkSetGetPtr;
+
+NLM_EXTERN LinkSetGetPtr LIBCALL LinkSetGetNew PROTO((void));
+NLM_EXTERN LinkSetGetPtr LIBCALL LinkSetGetFree PROTO(( LinkSetGetPtr ufp));
+NLM_EXTERN LinkSetGetPtr LIBCALL LinkSetGetAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL LinkSetGetAsnWrite PROTO((LinkSetGetPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+NLM_EXTERN DocSumPtr LIBCALL MlSumNew PROTO((void));
+NLM_EXTERN DocSumPtr LIBCALL MlSumFree PROTO(( DocSumPtr ufp));
+NLM_EXTERN DocSumPtr LIBCALL MlSumAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL MlSumAsnWrite PROTO((DocSumPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+NLM_EXTERN DocSumPtr LIBCALL SeqSumNew PROTO((void));
+NLM_EXTERN DocSumPtr LIBCALL SeqSumFree PROTO(( DocSumPtr ufp));
+NLM_EXTERN DocSumPtr LIBCALL SeqSumAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL SeqSumAsnWrite PROTO((DocSumPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+
+/*****************************************************************************
+*
+* EntrezDocGet
+*
+*****************************************************************************/
+
+
+typedef struct {
+ DocType cls;
+ Boolean mark_missing;
+ EntrezIdsPtr ids;
+ Int4 defer_count;
+} EntrezDocGet, PNTR EntrezDocGetPtr;
+
+NLM_EXTERN EntrezDocGetPtr LIBCALL EntrezDocGetNew PROTO((void));
+NLM_EXTERN EntrezDocGetPtr LIBCALL EntrezDocGetFree PROTO(( EntrezDocGetPtr ufp));
+NLM_EXTERN EntrezDocGetPtr LIBCALL EntrezDocGetAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL EntrezDocGetAsnWrite PROTO((EntrezDocGetPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+/*****************************************************************************
+*
+* Medline-list
+*
+*****************************************************************************/
+typedef struct {
+ Int4 num;
+ MedlineEntryPtr PNTR data; /* vector */
+ EntrezIdsPtr marked_missing; /* marked UIDs, optional */
+} MedlineEntryList, PNTR MedlineEntryListPtr;
+
+
+NLM_EXTERN MedlineEntryListPtr LIBCALL MedlineEntryListNew PROTO((void));
+NLM_EXTERN MedlineEntryListPtr LIBCALL MedlineEntryListFree PROTO(( MedlineEntryListPtr ufp));
+NLM_EXTERN MedlineEntryListPtr LIBCALL MedlineEntryListAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL MedlineEntryListAsnWrite PROTO((MedlineEntryListPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+/*****************************************************************************
+*
+* Ml-summary-list
+*
+*****************************************************************************/
+typedef struct {
+ Int4 num;
+ DocSumPtr PNTR data; /* vector */
+} MlSummaryList, PNTR MlSummaryListPtr;
+
+
+NLM_EXTERN MlSummaryListPtr LIBCALL MlSummaryListNew PROTO((void));
+NLM_EXTERN MlSummaryListPtr LIBCALL MlSummaryListFree PROTO(( MlSummaryListPtr ufp));
+NLM_EXTERN MlSummaryListPtr LIBCALL MlSummaryListAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL MlSummaryListAsnWrite PROTO((MlSummaryListPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+/*****************************************************************************
+*
+* SeqEntryGet
+*
+*****************************************************************************/
+
+typedef struct {
+ EntrezIdsPtr ids;
+ Int4 retype;
+ Boolean mark_missing;
+} EntrezSeqGet, PNTR EntrezSeqGetPtr;
+
+NLM_EXTERN EntrezSeqGetPtr LIBCALL EntrezSeqGetNew PROTO((void));
+NLM_EXTERN EntrezSeqGetPtr LIBCALL EntrezSeqGetFree PROTO(( EntrezSeqGetPtr ufp));
+NLM_EXTERN EntrezSeqGetPtr LIBCALL EntrezSeqGetAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL EntrezSeqGetAsnWrite PROTO((EntrezSeqGetPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+/*****************************************************************************
+*
+* Seq-summary-list
+*
+*****************************************************************************/
+typedef struct {
+ Int4 num;
+ DocSumPtr PNTR data; /* vector */
+} SeqSummaryList, PNTR SeqSummaryListPtr;
+
+
+NLM_EXTERN SeqSummaryListPtr LIBCALL SeqSummaryListNew PROTO((void));
+NLM_EXTERN SeqSummaryListPtr LIBCALL SeqSummaryListFree PROTO(( SeqSummaryListPtr ufp));
+NLM_EXTERN SeqSummaryListPtr LIBCALL SeqSummaryListAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL SeqSummaryListAsnWrite PROTO((SeqSummaryListPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+/*****************************************************************************
+*
+* Seq-entry-list
+*
+*****************************************************************************/
+typedef struct {
+ Int4 num;
+ SeqEntryPtr PNTR data; /* vector */
+ EntrezIdsPtr marked_missing; /* marked UIDs, optional */
+} PNTR SeqEntryListPtr;
+/* note that SeqEntryList is not provided because the name conflicted with */
+/* the name of a function on sequtil.c; the typedef was not needed anyhow */
+
+
+NLM_EXTERN SeqEntryListPtr LIBCALL SeqEntryListNew PROTO((void));
+NLM_EXTERN SeqEntryListPtr LIBCALL SeqEntryListFree PROTO(( SeqEntryListPtr ufp));
+NLM_EXTERN SeqEntryListPtr LIBCALL SeqEntryListAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL SeqEntryListAsnWrite PROTO((SeqEntryListPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+
+
+#ifdef Biostruc_supported
+
+/*****************************************************************************
+*
+* Biostruc-list
+*
+*****************************************************************************/
+typedef struct {
+ Int4 num;
+ BiostrucPtr PNTR data; /* vector */
+ EntrezIdsPtr marked_missing; /* marked UIDs, optional */
+} BiostrucList, PNTR BiostrucListPtr;
+
+
+NLM_EXTERN BiostrucListPtr LIBCALL BiostrucListNew PROTO((void));
+NLM_EXTERN BiostrucListPtr LIBCALL BiostrucListFree PROTO(( BiostrucListPtr ufp));
+NLM_EXTERN BiostrucListPtr LIBCALL BiostrucListAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
+NLM_EXTERN Boolean LIBCALL BiostrucListAsnWrite PROTO((BiostrucListPtr ufp, AsnIoPtr aip, AsnTypePtr atp));
+
+#endif /* Biostruc_supported */
+
+/**************************************************
+*
+* EntrezNeighborText
+*
+**************************************************/
+
+
+NLM_EXTERN EntrezNeighborTextPtr LIBCALL EntrezNeighborTextAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL EntrezNeighborTextAsnWrite PROTO (( EntrezNeighborTextPtr , AsnIoPtr, AsnTypePtr));
+
+
+/**************************************************
+*
+* ChildLink
+*
+*************************************************/
+typedef struct struct_Child_Link {
+ struct struct_Child_Link PNTR next;
+ CharPtr name;
+ Boolean isLeafNode;
+ Int4 special;
+ Int4 total;
+} ChildLink, PNTR ChildLinkPtr;
+
+
+
+NLM_EXTERN EntrezHierarchyChildPtr LIBCALL EntrezHierarchyChildFree PROTO ((EntrezHierarchyChildPtr ));
+NLM_EXTERN EntrezHierarchyChildPtr LIBCALL EntrezHierarchyChildNew PROTO (( void ));
+NLM_EXTERN EntrezHierarchyChildPtr LIBCALL EntrezHierarchyChildAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL EntrezHierarchyChildAsnWrite PROTO (( EntrezHierarchyChildPtr ,AsnIoPtr, AsnTypePtr));
+
+NLM_EXTERN EntrezHierarchyPtr LIBCALL EntrezHierarchyFree PROTO ((EntrezHierarchyPtr ));
+NLM_EXTERN EntrezHierarchyPtr LIBCALL EntrezHierarchyNew PROTO (( void ));
+NLM_EXTERN EntrezHierarchyPtr LIBCALL EntrezHierarchyAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL EntrezHierarchyAsnWrite PROTO (( EntrezHierarchyPtr, AsnIoPtr, AsnTypePtr));
+
+
+/**************************************************
+*
+* EntrezBlastreq
+*
+**************************************************/
+typedef struct struct_Entrez_blastreq {
+ Uint4 OBbits__;
+ BioseqPtr bsp;
+ DocType bsp_database;
+ CharPtr program;
+ CharPtr database;
+ CharPtr options;
+ Uint1 showprogress;
+} EntrezBlastreq, PNTR EntrezBlastreqPtr;
+
+
+NLM_EXTERN EntrezBlastreqPtr LIBCALL EntrezBlastreqFree PROTO ((EntrezBlastreqPtr ));
+NLM_EXTERN EntrezBlastreqPtr LIBCALL EntrezBlastreqNew PROTO (( void ));
+NLM_EXTERN EntrezBlastreqPtr LIBCALL EntrezBlastreqAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL EntrezBlastreqAsnWrite PROTO (( EntrezBlastreqPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* EntrezExtraInfo
+*
+**************************************************/
+typedef struct struct_Entrez_extra_info {
+ Uint4 OBbits__;
+ Int4 maxlinks;
+ Uint1 canneighbortext;
+ Uint1 expanded_medline;
+ Uint1 canblast;
+} EntrezExtraInfo, PNTR EntrezExtraInfoPtr;
+
+
+NLM_EXTERN EntrezExtraInfoPtr LIBCALL EntrezExtraInfoFree PROTO ((EntrezExtraInfoPtr ));
+NLM_EXTERN EntrezExtraInfoPtr LIBCALL EntrezExtraInfoNew PROTO (( void ));
+NLM_EXTERN EntrezExtraInfoPtr LIBCALL EntrezExtraInfoAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL EntrezExtraInfoAsnWrite PROTO (( EntrezExtraInfoPtr , AsnIoPtr, AsnTypePtr));
+
+typedef struct struct_New_summary_List {
+ Int4 num;
+ DocType type;
+ DocSumPtr PNTR data;
+} NewSummaryList, PNTR NewSummaryListPtr;
+
+NLM_EXTERN NewSummaryListPtr LIBCALL NewSummaryListFree PROTO ((NewSummaryListPtr ));
+NLM_EXTERN NewSummaryListPtr LIBCALL NewSummaryListNew PROTO (( void ));
+NLM_EXTERN NewSummaryListPtr LIBCALL NewSummaryListAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL NewSummaryListAsnWrite PROTO (( NewSummaryListPtr , AsnIoPtr, AsnTypePtr));
+
+
+/**************************************************
+*
+* ClusterArticles
+*
+**************************************************/
+typedef struct struct_Cluster_articles {
+ Uint4 OBbits__;
+ EntrezIdsPtr ids;
+ Int4 fld;
+ Int4 min_cluster;
+ Int4 max_cluster;
+ Int4 max_terms;
+} ClusterArticles, PNTR ClusterArticlesPtr;
+
+
+NLM_EXTERN ClusterArticlesPtr LIBCALL ClusterArticlesFree PROTO ((ClusterArticlesPtr ));
+NLM_EXTERN ClusterArticlesPtr LIBCALL ClusterArticlesNew PROTO (( void ));
+NLM_EXTERN ClusterArticlesPtr LIBCALL ClusterArticlesAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL ClusterArticlesAsnWrite PROTO (( ClusterArticlesPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+
+/**************************************************
+*
+* ClusterResp
+*
+**************************************************/
+typedef struct struct_Cluster_resp {
+ Uint4 OBbits__;
+ Int4 count;
+ ValNodePtr terms;
+ ValNodePtr term_counts;
+} ClusterResp, PNTR ClusterRespPtr;
+
+
+NLM_EXTERN ClusterRespPtr LIBCALL ClusterRespFree PROTO ((ClusterRespPtr ));
+NLM_EXTERN ClusterRespPtr LIBCALL ClusterRespNew PROTO (( void ));
+NLM_EXTERN ClusterRespPtr LIBCALL ClusterRespAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL ClusterRespAsnWrite PROTO (( ClusterRespPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* DateConstraints
+*
+**************************************************/
+typedef struct struct_Date_constraints {
+ Int4 count;
+ struct struct_Date_vector PNTR date_vec;
+} DateConstraints, PNTR DateConstraintsPtr;
+
+
+NLM_EXTERN DateConstraintsPtr LIBCALL DateConstraintsFree PROTO ((DateConstraintsPtr ));
+NLM_EXTERN DateConstraintsPtr LIBCALL DateConstraintsNew PROTO (( void ));
+NLM_EXTERN DateConstraintsPtr LIBCALL DateConstraintsAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL DateConstraintsAsnWrite PROTO (( DateConstraintsPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* DateVector
+*
+**************************************************/
+typedef struct struct_Date_vector {
+ struct struct_Date_vector PNTR next;
+ DatePtr begin_date;
+ DatePtr end_date;
+ CharPtr field_abbr;
+} DateVector, PNTR DateVectorPtr;
+
+
+NLM_EXTERN DateVectorPtr LIBCALL DateVectorFree PROTO ((DateVectorPtr ));
+NLM_EXTERN DateVectorPtr LIBCALL DateVectorNew PROTO (( void ));
+NLM_EXTERN DateVectorPtr LIBCALL DateVectorAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL DateVectorAsnWrite PROTO (( DateVectorPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* GetByFid
+*
+**************************************************/
+typedef struct struct_Get_by_fid {
+ Int4 mmdbid;
+ Int4 feature_id;
+ Int4 feature_set_id;
+} GetByFid, PNTR GetByFidPtr;
+
+
+NLM_EXTERN GetByFidPtr LIBCALL GetByFidFree PROTO ((GetByFidPtr ));
+NLM_EXTERN GetByFidPtr LIBCALL GetByFidNew PROTO (( void ));
+NLM_EXTERN GetByFidPtr LIBCALL GetByFidAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL GetByFidAsnWrite PROTO (( GetByFidPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* GetFeatIds
+*
+**************************************************/
+typedef struct struct_Get_feat_ids {
+ Int4 mmdbid;
+ Int4 feature_type;
+ Int4 feature_set_id;
+} GetFeatIds, PNTR GetFeatIdsPtr;
+
+
+NLM_EXTERN GetFeatIdsPtr LIBCALL GetFeatIdsFree PROTO ((GetFeatIdsPtr ));
+NLM_EXTERN GetFeatIdsPtr LIBCALL GetFeatIdsNew PROTO (( void ));
+NLM_EXTERN GetFeatIdsPtr LIBCALL GetFeatIdsAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL GetFeatIdsAsnWrite PROTO (( GetFeatIdsPtr , AsnIoPtr, AsnTypePtr));
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif
diff --git a/network/id1arch/accid1.c b/network/id1arch/accid1.c
new file mode 100644
index 00000000..694866e1
--- /dev/null
+++ b/network/id1arch/accid1.c
@@ -0,0 +1,312 @@
+#include <seqmgr.h>
+#include <id1arch.h>
+
+#define ID1BFS_DISABLE 0 /* ID1BioseqFetch not in use (default) */
+#define ID1BFS_INIT 1 /* ID1BioseqFetchEnable called, but not ID1Init */
+#define ID1BFS_READY 2 /* ID1Init has been called */
+
+#define ID1_NUM_RETRY 5
+
+static CharPtr procname[3] = {
+ "ID1BioseqFetch",
+ "ID1SeqIdForGI",
+ "ID1GIForSeqId" };
+static Int2 LIBCALLBACK s_ID1BioseqFetchFunc PROTO((Pointer data));
+static Int2 LIBCALLBACK s_ID1SeqIdForGIFunc PROTO((Pointer data));
+static Int2 LIBCALLBACK s_ID1GIForSeqIdFunc PROTO((Pointer data));
+
+typedef struct ID1Fetch_struct {
+ Uint1 state;
+ CharPtr app_name;
+ Uint2 ctr; /* counts iterations of enable disable */
+} ID1FetchStruct, PNTR ID1FetchStructPtr;
+
+
+Boolean
+ID1Init(void)
+{
+ return ID1ArchInit();
+}
+
+void
+ID1Fini(void)
+{
+ ID1ArchFini();
+}
+
+
+/**** Look Up a Uid from a SeqId using ID1 lookup ****/
+Int4
+ID1FindSeqId(SeqIdPtr sip)
+{
+ return ID1ArchGIGet(sip);
+}
+
+/**** Look Up the source SeqId given a GI ****************/
+SeqIdPtr
+ID1SeqIdForGI(Int4 gi)
+{
+ return ID1ArchSeqIdsGet(gi,NULL);
+}
+
+
+SeqEntryPtr
+ID1SeqEntryGet(Int4 gi, Int2 retcode)
+{
+ SeqEntryPtr sep = NULL;
+ ErrStrId errorID;
+ char errorString[32];
+ Int4 status=0,i;
+
+ if (!gi)
+ return NULL;
+ sprintf(errorString, "(ID1SeqEntryGet: %d)",gi);
+ errorID = Nlm_ErrUserInstall(errorString, 0);
+
+ for(i=0;i<ID1_NUM_RETRY;i++){
+ if((sep=ID1ArchSeqEntryGet(gi,NULL,0,&status,retcode)) != NULL){
+ break;
+ } else {
+ if(status == 1 /** override **/){
+ ErrPostEx(SEV_INFO,0,0,"Sequence is withdrawn");
+ goto DONE;
+ } else if(status == 2 /*** confidential ***/){
+ ErrPostEx(SEV_INFO,0,0,"Sequence is not yet available");
+ goto DONE;
+ } else {
+ ErrPostEx(SEV_INFO,0,0,"Network failure... Reconecting");
+ }
+ }
+ }
+ if(sep==NULL){
+ ErrPostEx(SEV_WARNING,0,0,"Unable to get the sequence ");
+ }
+
+DONE:
+ Nlm_ErrUserDelete(errorID);
+ return sep;
+}
+
+Boolean
+ID1BioseqFetchEnable(CharPtr progname, Boolean now)
+{
+ Boolean result;
+ ID1FetchStructPtr ifsp;
+ ObjMgrPtr omp;
+ ObjMgrProcPtr ompp;
+
+ /* check if already enabled ***/
+
+ omp = ObjMgrGet();
+ ompp = ObjMgrProcFind(omp, 0, procname[0], OMPROC_FETCH);
+ if(ompp != NULL){ /* already initialized */
+ ifsp = (ID1FetchStructPtr)(ompp->procdata);
+ } else {
+ ifsp = MemNew(sizeof(ID1FetchStruct));
+ ifsp->app_name = StringSave(progname);
+
+ ObjMgrProcLoad(OMPROC_FETCH,procname[0],procname[0],OBJ_SEQID,0,OBJ_BIOSEQ,0,
+ (Pointer)ifsp,s_ID1BioseqFetchFunc, PROC_PRIORITY_DEFAULT);
+
+ ObjMgrProcLoad(OMPROC_FETCH, procname[1],procname[1],OBJ_SEQID,SEQID_GI,OBJ_SEQID,0,
+ (Pointer)ifsp,s_ID1SeqIdForGIFunc,PROC_PRIORITY_DEFAULT);
+
+ ObjMgrProcLoad(OMPROC_FETCH, procname[2],procname[2],OBJ_SEQID,0,OBJ_SEQID,SEQID_GI,
+ (Pointer)ifsp,s_ID1GIForSeqIdFunc,PROC_PRIORITY_DEFAULT);
+ }
+ ifsp->ctr++; /* count number of enables */
+ if(ifsp->state == ID1BFS_READY) /* nothing more to do */
+ return TRUE;
+ if(now){
+ if ((result = ID1Init())==FALSE){
+ return result;
+ }
+ ifsp->state = ID1BFS_READY;
+ } else {
+ ifsp->state = ID1BFS_INIT;
+ }
+ return TRUE;
+}
+void
+ID1BioseqFetchDisable(void)
+{
+ ObjMgrPtr omp;
+ ObjMgrProcPtr ompp;
+ ID1FetchStructPtr ifsp;
+
+ omp = ObjMgrGet();
+ ompp = ObjMgrProcFind(omp,0,procname[0],OMPROC_FETCH);
+ if(ompp == NULL) /* not initialized */
+ return;
+
+ ifsp = (ID1FetchStructPtr)(ompp->procdata);
+ if(!ifsp || !ifsp->ctr) /* no enables active */
+ return;
+ ifsp->ctr--;
+ if(ifsp->ctr) /* connection still pending */
+ return;
+ if(ifsp->state == ID1BFS_READY)
+ ID1Fini();
+ ifsp->state = ID1BFS_DISABLE;
+ return;
+}
+/**** Static Functions *****/
+
+/*****************************************************************************
+*
+* s_ID1SeqIdForGIFunc(data)
+* callback for ID1SeqIdForGI
+*
+*****************************************************************************/
+static Int2
+s_ID1SeqIdForGIFunc(Pointer data)
+{
+ OMProcControlPtr ompcp;
+ ObjMgrProcPtr ompp;
+ ID1FetchStructPtr ifsp;
+ SeqIdPtr sip, sip2;
+
+ ompcp = (OMProcControlPtr)data;
+ ompp = ompcp->proc;
+ ifsp = ompp->procdata;
+ if(!ifsp || ifsp->state == ID1BFS_DISABLE){ /* shut off */
+ return OM_MSG_RET_OK; /* not done, go on to next */
+ } else if(ifsp->state == ID1BFS_INIT){
+ if (!ID1Init())
+ return OM_MSG_RET_ERROR;
+ ifsp->state = ID1BFS_READY;
+ }
+
+ if(ifsp->state != ID1BFS_READY)
+ return OM_MSG_RET_ERROR;
+
+ sip = (SeqIdPtr)(ompcp->input_data);
+ if(sip == NULL || sip->choice != SEQID_GI)
+ return OM_MSG_RET_ERROR;
+
+ if((sip2 = ID1SeqIdForGI(sip->data.intvalue))==NULL)
+ return OM_MSG_RET_OK;
+
+ ompcp->output_data = (Pointer)sip2; /* not registering right now */
+ return OM_MSG_RET_DONE; /* data found, don't call further functions */
+}
+
+/*****************************************************************************
+*
+* s_ID1GIForSeqIdFunc(data)
+* callback for ID1GIForSeqId
+*
+*****************************************************************************/
+static Int2
+s_ID1GIForSeqIdFunc (Pointer data)
+{
+ OMProcControlPtr ompcp;
+ ObjMgrProcPtr ompp;
+ ID1FetchStructPtr ifsp;
+ SeqIdPtr sip, sip2;
+ Int4 gi;
+
+ ompcp = (OMProcControlPtr)data;
+ ompp = ompcp->proc;
+ ifsp = ompp->procdata;
+
+ if(!ifsp || ifsp->state == ID1BFS_DISABLE){ /* shut off */
+ return OM_MSG_RET_OK; /* not done, go on to next */
+ } else if(ifsp->state == ID1BFS_INIT) {
+ if (!ID1Init())
+ return OM_MSG_RET_ERROR;
+ ifsp->state = ID1BFS_READY;
+ }
+
+ if(ifsp->state != ID1BFS_READY)
+ return OM_MSG_RET_ERROR;
+
+ if((sip = (SeqIdPtr)ompcp->input_data) == NULL)
+ return OM_MSG_RET_ERROR;
+
+ if (sip->choice == SEQID_GI)
+ return OM_MSG_RET_ERROR;
+
+ if((gi = ID1FindSeqId(sip))<=1)
+ return OM_MSG_RET_OK;
+
+ sip2 = ValNodeNew(NULL);
+ sip2->choice = SEQID_GI;
+ sip2->data.intvalue = gi;
+
+ ompcp->output_data = (Pointer)sip2; /* not registering right now */
+
+ return OM_MSG_RET_DONE; /* data found, don't call further functions */
+}
+
+/*****************************************************************************
+*
+* s_ID1BioseqFetchFunc(data)
+* callback for ID1SeqEntryGet
+*
+*****************************************************************************/
+
+static Int2
+s_ID1BioseqFetchFunc(Pointer data)
+{
+ OMProcControlPtr ompcp;
+ ObjMgrProcPtr ompp;
+ OMUserDataPtr omdp;
+ ID1FetchStructPtr ifsp;
+ SeqEntryPtr sep;
+ BioseqPtr bsp;
+ SeqIdPtr sip;
+ Int4 gi=0;
+ Int2 retcode=0;
+
+ ompcp = (OMProcControlPtr)data;
+ ompp = ompcp->proc;
+ ifsp = ompp->procdata;
+
+ if(!ifsp || ifsp->state == ID1BFS_DISABLE){ /* shut off */
+ return OM_MSG_RET_OK; /* not done, go on to next */
+ } else if(ifsp->state == ID1BFS_INIT) {
+ if (!ID1Init())
+ return OM_MSG_RET_ERROR;
+ ifsp->state = ID1BFS_READY;
+ }
+
+ if(ifsp->state != ID1BFS_READY)
+ return OM_MSG_RET_ERROR;
+
+ /* check for cached gi */
+ if (ompcp->input_entityID){
+ omdp = ObjMgrGetUserData(ompcp->input_entityID,ompp->procid, OMPROC_FETCH, 0);
+ if (omdp != NULL) {
+ gi = omdp->userdata.intvalue;
+ }
+ }
+ if(!gi){ /* not cached, try input id */
+ sip = (SeqIdPtr)(ompcp->input_data);
+ if (sip == NULL)
+ return OM_MSG_RET_ERROR;
+
+ if(sip->choice != SEQID_GI){
+ gi = ID1FindSeqId(sip);
+ } else {
+ gi = sip->data.intvalue;
+ }
+ }
+
+ if(!gi) return OM_MSG_RET_OK; /* no error but call next proc */
+
+ sep = ID1SeqEntryGet(gi,0);/*** always get a whole blob in anticipation of following requests ***/
+ if(sep == NULL)
+ return OM_MSG_RET_ERROR;
+
+ sip = (SeqIdPtr)(ompcp->input_data);
+ bsp = BioseqFindInSeqEntry(sip, sep);
+ ompcp->output_data = (Pointer)bsp;
+ ompcp->output_entityID = ObjMgrGetEntityIDForChoice(sep);
+
+ /* store the cache info */
+ omdp = ObjMgrAddUserData(ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
+ omdp->userdata.intvalue = gi;
+
+ return OM_MSG_RET_DONE; /* data found, don't call further functions */
+}
diff --git a/network/id1arch/accid1.h b/network/id1arch/accid1.h
new file mode 100644
index 00000000..3ce82df0
--- /dev/null
+++ b/network/id1arch/accid1.h
@@ -0,0 +1,61 @@
+#ifndef __ACCID1_H_
+#define __ACCID1_H_
+
+#include <id1arch.h>
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+NLM_EXTERN Boolean LIBCALL ID1Init PROTO((void));
+NLM_EXTERN void LIBCALL ID1Fini PROTO((void));
+
+/**** Look Up a Uid from a SeqId using ID1 lookup ****/
+NLM_EXTERN Int4 LIBCALL ID1FindSeqId PROTO((SeqIdPtr sip));
+
+/**** Look Up the source SeqId given a GI ****************/
+NLM_EXTERN SeqIdPtr LIBCALL ID1SeqIdForGI PROTO ((Int4 gi));
+
+NLM_EXTERN SeqEntryPtr LIBCALL ID1SeqEntryGet PROTO((Int4 uid, Int2 retcode));
+
+
+/*****************************************************************************
+*
+* The Following two functions allow access by BioseqFetch using the
+* SeqMgr. The application should call ID1BioseqFetchEnable() at the start
+* of the application and ID1BioseqFetchDisable() at the end; This
+* will make ID1BioseqFetch() the "remote" access procedure for the
+* SeqMgr. ID1Init() will only be called on the first fetch unless "now"
+* is true;
+*
+* If you add your own fetch function after calling ID1BioseqFetchEnable,
+* it will be called BEFORE ID1BioseqFetchEnable. Add yours after this
+* call, and yours will be call AFTER ID1.
+*
+*****************************************************************************/
+NLM_EXTERN Boolean LIBCALL ID1BioseqFetchEnable PROTO((CharPtr progname, Boolean now));
+NLM_EXTERN void LIBCALL ID1BioseqFetchDisable PROTO((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+
+#endif
diff --git a/network/id1arch/id1.asn b/network/id1arch/id1.asn
new file mode 100644
index 00000000..063d6895
--- /dev/null
+++ b/network/id1arch/id1.asn
@@ -0,0 +1,77 @@
+--$Revision: 1.3 $
+--********************************************************************
+--
+-- Network Id server network access
+-- Yaschenko 1996
+--
+--
+--*********************************************************************
+--
+-- ID1.asn
+--
+-- messages for id server network access
+--
+--*********************************************************************
+
+NCBI-ID1Access DEFINITIONS ::=
+BEGIN
+
+IMPORTS Seq-id FROM NCBI-Seqloc
+ -- Bioseq-set FROM NCBI-Seqset
+ Seq-entry FROM NCBI-Seqset
+ Seq-hist FROM NCBI-Sequence
+ Seq-id FROM NCBI-Seqloc;
+
+ --**********************************
+ -- requests
+ --
+
+ID1server-request ::= CHOICE {
+ init NULL , -- DlInit
+ getgi Seq-id , -- get a gi given a Seq-id
+ getsefromgi ID1server-maxcomplex , -- given a gi, get the Seq-entry
+ fini NULL, -- DlFini
+ getseqidsfromgi INTEGER, --get all Seq-ids of given gi
+ getgihist INTEGER, --get an historical list of gis
+ getgirev INTEGER, --get a revision history of gi
+ getgistate INTEGER --get a state of gi
+ }
+
+-- Complexity stuff will be for ID1
+
+ID1server-maxcomplex ::= SEQUENCE {
+ maxplex Entry-complexities ,
+ gi INTEGER ,
+ ent INTEGER OPTIONAL, -- needed when you want to retrieve a given ent
+ sat VisibleString OPTIONAL -- satellite 0-id,1-dbEST
+}
+
+Entry-complexities ::= INTEGER {
+ entry (0) , -- the "natural" entry for this (nuc-prot)
+ bioseq (1) , -- only the bioseq identified
+ bioseq-set (2) , -- any seg-set it may be part of
+ nuc-prot (3) , -- any nuc-prot it may be part of
+ pub-set (4)
+}
+
+ID1Seq-hist ::= SEQUENCE {
+ hist Seq-hist
+}
+
+
+ID1server-back ::= CHOICE {
+ init NULL , -- DlInit
+ error INTEGER ,
+ gotgi INTEGER ,
+ gotseqentry Seq-entry, -- live
+ gotdeadseqentry Seq-entry, -- dead
+ fini NULL, -- DlFini
+ gistate INTEGER,
+ ids SET OF Seq-id,
+ gihist SET OF ID1Seq-hist, -- because hand crafted Seq-hist does not follow
+ -- same conventions
+ girevhist SET OF ID1Seq-hist
+ }
+
+ID1server-debug ::= SET OF ID1server-back
+END
diff --git a/network/id1arch/id1.h b/network/id1arch/id1.h
new file mode 100644
index 00000000..b7a5977b
--- /dev/null
+++ b/network/id1arch/id1.h
@@ -0,0 +1,116 @@
+/***********************************************************************
+*
+**
+* Automatic header module from ASNTOOL
+*
+************************************************************************/
+
+#ifndef _ASNTOOL_
+#include <asn.h>
+#endif
+
+static char * asnfilename = "id1.h13";
+static AsnValxNode avnx[5] = {
+ {20,"entry" ,0,0.0,&avnx[1] } ,
+ {20,"bioseq" ,1,0.0,&avnx[2] } ,
+ {20,"bioseq-set" ,2,0.0,&avnx[3] } ,
+ {20,"nuc-prot" ,3,0.0,&avnx[4] } ,
+ {20,"pub-set" ,4,0.0,NULL } };
+
+static AsnType atx[42] = {
+ {401, "Seq-id" ,1,0,0,0,0,0,1,0,NULL,NULL,NULL,0,&atx[1]} ,
+ {402, "Seq-entry" ,1,0,0,0,0,0,1,0,NULL,NULL,NULL,0,&atx[2]} ,
+ {403, "Seq-hist" ,1,0,0,0,0,0,1,0,NULL,NULL,NULL,0,&atx[3]} ,
+ {404, "ID1server-request" ,1,0,0,0,0,0,0,0,NULL,&atx[22],&atx[4],0,&atx[8]} ,
+ {0, "init" ,128,0,0,0,0,0,0,0,NULL,&atx[5],NULL,0,&atx[6]} ,
+ {305, "NULL" ,0,5,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "getgi" ,128,1,0,0,0,0,0,0,NULL,&atx[0],NULL,0,&atx[7]} ,
+ {0, "getsefromgi" ,128,2,0,0,0,0,0,0,NULL,&atx[8],NULL,0,&atx[17]} ,
+ {405, "ID1server-maxcomplex" ,1,0,0,0,0,0,0,0,NULL,&atx[16],&atx[9],0,&atx[10]} ,
+ {0, "maxplex" ,128,0,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[12]} ,
+ {406, "Entry-complexities" ,1,0,0,0,0,0,0,0,NULL,&atx[11],&avnx[0],0,&atx[23]} ,
+ {302, "INTEGER" ,0,2,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "gi" ,128,1,0,0,0,0,0,0,NULL,&atx[11],NULL,0,&atx[13]} ,
+ {0, "ent" ,128,2,0,1,0,0,0,0,NULL,&atx[11],NULL,0,&atx[14]} ,
+ {0, "sat" ,128,3,0,1,0,0,0,0,NULL,&atx[15],NULL,0,NULL} ,
+ {323, "VisibleString" ,0,26,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {311, "SEQUENCE" ,0,16,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "fini" ,128,3,0,0,0,0,0,0,NULL,&atx[5],NULL,0,&atx[18]} ,
+ {0, "getseqidsfromgi" ,128,4,0,0,0,0,0,0,NULL,&atx[11],NULL,0,&atx[19]} ,
+ {0, "getgihist" ,128,5,0,0,0,0,0,0,NULL,&atx[11],NULL,0,&atx[20]} ,
+ {0, "getgirev" ,128,6,0,0,0,0,0,0,NULL,&atx[11],NULL,0,&atx[21]} ,
+ {0, "getgistate" ,128,7,0,0,0,0,0,0,NULL,&atx[11],NULL,0,NULL} ,
+ {315, "CHOICE" ,0,-1,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {407, "ID1Seq-hist" ,1,0,0,0,0,0,0,0,NULL,&atx[16],&atx[24],0,&atx[25]} ,
+ {0, "hist" ,128,0,0,0,0,0,0,0,NULL,&atx[2],NULL,0,NULL} ,
+ {408, "ID1server-back" ,1,0,0,0,0,0,0,0,NULL,&atx[22],&atx[26],0,&atx[40]} ,
+ {0, "init" ,128,0,0,0,0,0,0,0,NULL,&atx[5],NULL,0,&atx[27]} ,
+ {0, "error" ,128,1,0,0,0,0,0,0,NULL,&atx[11],NULL,0,&atx[28]} ,
+ {0, "gotgi" ,128,2,0,0,0,0,0,0,NULL,&atx[11],NULL,0,&atx[29]} ,
+ {0, "gotseqentry" ,128,3,0,0,0,0,0,0,NULL,&atx[1],NULL,0,&atx[30]} ,
+ {0, "gotdeadseqentry" ,128,4,0,0,0,0,0,0,NULL,&atx[1],NULL,0,&atx[31]} ,
+ {0, "fini" ,128,5,0,0,0,0,0,0,NULL,&atx[5],NULL,0,&atx[32]} ,
+ {0, "gistate" ,128,6,0,0,0,0,0,0,NULL,&atx[11],NULL,0,&atx[33]} ,
+ {0, "ids" ,128,7,0,0,0,0,0,0,NULL,&atx[35],&atx[34],0,&atx[36]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[0],NULL,0,NULL} ,
+ {314, "SET OF" ,0,17,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "gihist" ,128,8,0,0,0,0,0,0,NULL,&atx[35],&atx[37],0,&atx[38]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[23],NULL,0,NULL} ,
+ {0, "girevhist" ,128,9,0,0,0,0,0,0,NULL,&atx[35],&atx[39],0,NULL} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[23],NULL,0,NULL} ,
+ {409, "ID1server-debug" ,1,0,0,0,0,0,0,0,NULL,&atx[35],&atx[41],0,NULL} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[25],NULL,0,NULL} };
+
+static AsnModule ampx[1] = {
+ { "NCBI-ID1Access" , "id1.h13",&atx[0],NULL,NULL,0,0} };
+
+static AsnValxNodePtr avn = avnx;
+static AsnTypePtr at = atx;
+static AsnModulePtr amp = ampx;
+
+
+
+/**************************************************
+*
+* Defines for Module NCBI-ID1Access
+*
+**************************************************/
+
+#define ID1SERVER_REQUEST &at[3]
+#define ID1SERVER_REQUEST_init &at[4]
+#define ID1SERVER_REQUEST_getgi &at[6]
+#define ID1SERVER_REQUEST_getsefromgi &at[7]
+#define ID1SERVER_REQUEST_fini &at[17]
+#define REQUEST_getseqidsfromgi &at[18]
+#define ID1SERVER_REQUEST_getgihist &at[19]
+#define ID1SERVER_REQUEST_getgirev &at[20]
+#define ID1SERVER_REQUEST_getgistate &at[21]
+
+#define ID1SERVER_MAXCOMPLEX &at[8]
+#define ID1SERVER_MAXCOMPLEX_maxplex &at[9]
+#define ID1SERVER_MAXCOMPLEX_gi &at[12]
+#define ID1SERVER_MAXCOMPLEX_ent &at[13]
+#define ID1SERVER_MAXCOMPLEX_sat &at[14]
+
+#define ENTRY_COMPLEXITIES &at[10]
+
+#define ID1SEQ_HIST &at[23]
+#define ID1SEQ_HIST_hist &at[24]
+
+#define ID1SERVER_BACK &at[25]
+#define ID1SERVER_BACK_init &at[26]
+#define ID1SERVER_BACK_error &at[27]
+#define ID1SERVER_BACK_gotgi &at[28]
+#define ID1SERVER_BACK_gotseqentry &at[29]
+#define ID1SERVER_BACK_gotdeadseqentry &at[30]
+#define ID1SERVER_BACK_fini &at[31]
+#define ID1SERVER_BACK_gistate &at[32]
+#define ID1SERVER_BACK_ids &at[33]
+#define ID1SERVER_BACK_ids_E &at[34]
+#define ID1SERVER_BACK_gihist &at[36]
+#define ID1SERVER_BACK_gihist_E &at[37]
+#define ID1SERVER_BACK_girevhist &at[38]
+#define ID1SERVER_BACK_girevhist_E &at[39]
+
+#define ID1SERVER_DEBUG &at[40]
+#define ID1SERVER_DEBUG_E &at[41]
diff --git a/network/id1arch/id1arch.c b/network/id1arch/id1arch.c
new file mode 100644
index 00000000..b3c61b66
--- /dev/null
+++ b/network/id1arch/id1arch.c
@@ -0,0 +1,680 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: id1arch.c
+*
+* Author: Eugene Yaschenko
+*/
+
+#include <sequtil.h>
+#include <ncbinet.h>
+#include <objsset.h>
+#include <objsub.h>
+#include <id1gen.h>
+#include <id1arch.h>
+
+
+static ID1serverBackPtr NetID1servReadAsn PROTO((void));
+static Boolean ReestablishNetID1Arch PROTO((void));
+static Boolean NetInit PROTO((void));
+static Boolean ForceNetInit PROTO((void));
+static Boolean NetFini PROTO((void));
+static Boolean GenericReestablishNet PROTO((CharPtr svcName, Boolean showErrs));
+static SeqIdPtr s_ID1ArchSeqIdsGet PROTO((Uint4 gi,AsnIoPtr aiopr));
+static SeqEntryPtr s_ID1ArchSeqEntryGet PROTO((Int4 uid, CharPtr db, Int4 ent,Int4Ptr status, Int2 maxplex));
+static Int4 s_ID1ArcgGIStateGet PROTO((Uint4 gi));
+static ID1SeqHistPtr s_ID1ArchGIHistGet PROTO((Uint4 gi,Boolean rev,AsnIoPtr aiopr));
+
+static NI_HandPtr svcp = NULL;
+static AsnIoPtr asnin = NULL;
+static AsnIoPtr asnout = NULL;
+static Boolean num_attached = 0;
+static Boolean reallyFinal = TRUE;
+static NI_DispatcherPtr dispatcher;
+static Boolean (*myNetInit) PROTO((void));
+
+
+/*****************************************************************************
+*
+* ID1ArchInit ()
+*
+*****************************************************************************/
+
+Boolean ID1ArchInit (void)
+
+{
+
+
+ myNetInit = ID1ArchInit;
+
+ if (! NetInit())
+ return FALSE;
+
+ svcp = NI_GenericGetService(dispatcher, NULL, "ID1", "ID1", TRUE);
+ if (svcp == NULL)
+ {
+ ErrPost(CTX_UNKNOWN, 1, "NI_ServiceGet [%s] (%s)", ni_errlist[ni_errno], ni_errtext);
+ ID1ArchFini();
+ return FALSE;
+ }
+
+ asnin = svcp->raip;
+ asnout = svcp->waip;
+ return TRUE;
+}
+
+/*****************************************************************************
+*
+* ID1ArchFini ()
+*
+*****************************************************************************/
+
+static Boolean s_ID1ArchFini (void)
+
+{
+ NetFini();
+ return TRUE;
+}
+
+/* the only thing done here is to suppress errors */
+Boolean ID1ArchFini (void)
+
+{
+ short erract;
+ ErrDesc err;
+ Boolean retval;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+
+ retval = s_ID1ArchFini();
+
+ ErrSetOpts(erract, 0);
+ ErrFetch(&err);
+
+ return retval;
+}
+
+static SeqEntryPtr
+s_ID1ArchSeqEntryGet (Int4 uid, CharPtr db, Int4 ent,Int4Ptr status, Int2 maxplex)
+
+{
+ ID1serverRequestPtr id1reqp;
+ SeqEntryPtr sep;
+ ID1serverMaxcomplexPtr mcp;
+ ID1serverBackPtr id1bp;
+
+
+ if(status)
+ *status=0;
+
+ id1reqp = ValNodeNew(NULL);
+ id1reqp->choice = ID1serverRequest_getsefromgi;
+ mcp = ID1serverMaxcomplexNew();
+ id1reqp->data.ptrvalue = mcp;
+ mcp -> gi = uid;
+ mcp -> maxplex = maxplex;
+ if(ent > 0){
+ mcp->ent = ent;
+ if(db){
+ mcp->sat=StringSave(db);
+ }
+ }
+ ID1serverRequestAsnWrite (id1reqp, asnout, NULL);
+ AsnIoReset(asnout);
+ ID1serverRequestFree (id1reqp);
+
+ if ((id1bp = NetID1servReadAsn()) == NULL)
+ return NULL;
+
+ if (id1bp->choice != ID1serverBack_gotseqentry &&
+ id1bp->choice != ID1serverBack_gotdeadseqentry)
+ {
+ if(status && id1bp->choice == ID1serverBack_error){
+ *status = id1bp->data.intvalue;
+ }
+ ID1serverBackFree (id1bp);
+ return NULL;
+ }
+ if (status != NULL){
+ if (id1bp->choice == ID1serverBack_gotdeadseqentry){
+ * status = 3;
+ }else{
+ * status = 0;
+ }
+ }
+ sep = (SeqEntryPtr) (id1bp->data.ptrvalue);
+ id1bp->data.ptrvalue = NULL; /* for clean free */
+ ID1serverBackFree (id1bp);
+
+ return sep;
+}
+
+SeqEntryPtr
+ID1ArchSeqEntryGet (Int4 gi,CharPtr db, Int4 ent, Int4Ptr status, Int2 maxplex)
+{
+ Int4 i;
+ SeqEntryPtr sep=NULL;
+ short erract;
+ ErrDesc err;
+ Int4 retval = 0;
+
+ if (maxplex < 0 || maxplex > 4){
+ ErrPost(CTX_UNKNOWN, 2, "ID1ArchSeqEntryGet: maxplex(%d) out of range (0-4)", maxplex);
+ return NULL;
+ }
+ for (i = 0; i < ID_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetID1Arch())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ sep = s_ID1ArchSeqEntryGet (gi, db, ent, status, maxplex);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ break; /* success */
+ }
+ return sep;
+}
+
+static SeqIdPtr
+s_ID1ArchSeqIdsGet (Uint4 gi,AsnIoPtr aiopr)
+{
+ ID1serverRequestPtr id1reqp;
+ ID1serverBackPtr id1bp;
+
+ SeqIdPtr sip;
+
+ id1reqp = ValNodeNew(NULL);
+ id1reqp->choice = ID1serverRequest_getseqidsfromgi;
+ id1reqp->data.intvalue = gi;
+ ID1serverRequestAsnWrite (id1reqp, asnout, NULL);
+ AsnIoReset(asnout);
+ ID1serverRequestFree (id1reqp);
+
+ if ((id1bp = NetID1servReadAsn()) == NULL)
+ return NULL;
+
+ if (id1bp->choice != ID1serverBack_ids)
+ {
+ ID1serverBackFree (id1bp);
+ return NULL;
+ }
+ if(aiopr){
+ ID1serverBackAsnWrite(id1bp,aiopr,NULL);
+ AsnIoReset(aiopr);
+ }
+ sip = (id1bp->data.ptrvalue);
+ id1bp->data.ptrvalue = NULL;
+ ID1serverBackFree (id1bp);
+
+ return sip;
+}
+
+SeqIdPtr
+ID1ArchSeqIdsGet(Uint4 gi,AsnIoPtr aiopr)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ SeqIdPtr sip = NULL;
+
+ for (i = 0; i < ID_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetID1Arch())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ sip = s_ID1ArchSeqIdsGet(gi,aiopr);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ break; /* success */
+ }
+ return sip;
+}
+
+static ID1SeqHistPtr
+s_ID1ArchGIHistGet(Uint4 gi,Boolean rev,AsnIoPtr aiopr)
+{
+ ID1serverRequestPtr id1reqp;
+ ID1serverBackPtr id1bp;
+
+ ID1SeqHistPtr ishp;
+
+ id1reqp = ValNodeNew(NULL);
+ id1reqp->choice = rev? ID1serverRequest_getgirev : ID1serverRequest_getgihist;
+ id1reqp->data.intvalue = gi;
+ ID1serverRequestAsnWrite (id1reqp, asnout, NULL);
+ AsnIoReset(asnout);
+ ID1serverRequestFree (id1reqp);
+
+ if ((id1bp = NetID1servReadAsn()) == NULL)
+ return NULL;
+
+ if (id1bp->choice != ID1serverBack_girevhist && id1bp->choice != ID1serverBack_gihist)
+ {
+ ID1serverBackFree (id1bp);
+ return NULL;
+ }
+ if(aiopr){
+ ID1serverBackAsnWrite(id1bp,aiopr,NULL);
+ AsnIoReset(aiopr);
+ }
+ ishp = (id1bp->data.ptrvalue);
+ id1bp->data.ptrvalue = NULL;
+ ID1serverBackFree (id1bp);
+ return ishp;
+}
+
+ID1SeqHistPtr
+ID1ArchGIHistGet(Uint4 gi,Boolean rev,AsnIoPtr aiopr)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ ID1SeqHistPtr ishp = NULL;
+
+ for (i = 0; i < ID_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetID1Arch())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ ishp = s_ID1ArchGIHistGet(gi,rev,aiopr);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ break; /* success */
+ }
+ return ishp;
+}
+
+
+static Int4
+s_ID1ArcgGIStateGet(Uint4 gi)
+{
+ ID1serverRequestPtr id1reqp;
+ ID1serverBackPtr id1bp;
+
+ Int4 state;
+
+ id1reqp = ValNodeNew(NULL);
+ id1reqp->choice = ID1serverRequest_getgistate;
+ id1reqp->data.intvalue = gi;
+ ID1serverRequestAsnWrite (id1reqp, asnout, NULL);
+ AsnIoReset(asnout);
+ ID1serverRequestFree (id1reqp);
+
+ if ((id1bp = NetID1servReadAsn()) == NULL)
+ return 0;
+
+ if (id1bp->choice != ID1serverBack_gistate)
+ {
+ ID1serverBackFree (id1bp);
+ return 0;
+ }
+ state = id1bp->data.intvalue;
+ ID1serverBackFree (id1bp);
+ return state;
+}
+
+Int4
+ID1ArcgGIStateGet(Uint4 gi)
+{
+ Int4 state=0,i;
+ short erract;
+ ErrDesc err;
+ for (i = 0; i < ID_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetID1Arch())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ state = s_ID1ArcgGIStateGet(gi);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ break; /* success */
+ }
+ return state;
+}
+
+static ID1serverBackPtr NetID1servReadAsn(void)
+{
+ ID1serverBackPtr id1bp;
+ short erract;
+ ErrDesc err;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err); /* clear any pending error */
+
+ id1bp = ID1serverBackAsnRead(asnin, NULL);
+
+ if (ErrFetch(&err))
+ {
+ ErrPost(CTX_UNKNOWN, 1, "Null message read from server");
+ }
+ ErrSetOpts(erract, 0);
+
+ return id1bp;
+}
+
+static Boolean ReestablishNetID1Arch(void)
+{
+ return GenericReestablishNet("ID1Arch", TRUE);
+}
+
+static Boolean GenericReestablishNet(CharPtr svcName, Boolean showErrs)
+{
+ Monitor *mon = NULL;
+ Boolean retval;
+ CharPtr buf;
+
+ buf = MemNew(2 * StrLen(svcName) + 60);
+
+ if (showErrs) {
+ sprintf (buf, "Re-establishing %s Service", svcName);
+ mon = MonitorStrNew(buf, 40);
+ sprintf (buf, "Requesting %s service", svcName);
+ MonitorStrValue(mon, buf);
+ }
+ NetFini();
+ retval = TRUE;
+
+ if (! myNetInit())
+ {
+ sprintf (buf, "%s get failed; re-contacting dispatcher", svcName);
+ MonitorStrValue(mon, buf);
+ retval = FALSE;
+ if (ForceNetInit())
+ { /* successfully established contact w/dispatcher */
+ sprintf (buf, "%s get failed; re-requesting %s service",
+ svcName, svcName);
+ MonitorStrValue(mon, buf);
+ retval = myNetInit();
+ }
+ else {
+ ErrPost(CTX_UNKNOWN, 1, "Unable to re-contact dispatcher");
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+ }
+
+ MonitorFree(mon);
+
+ if (! retval )
+ {
+ sprintf (buf, "Unable to re-establish %s service", svcName);
+ ErrPost(CTX_UNKNOWN, 1, buf);
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+
+ MemFree(buf);
+ return retval;
+}
+
+static Boolean
+NetInit(void)
+{
+ if (num_attached++ > 0)
+ return TRUE;
+
+ return ((dispatcher = NI_GenericInit(NULL, NULL, TRUE, NULL, 0)) != NULL);
+}
+
+
+static Boolean ForceNetInit(void)
+{
+ Boolean retval;
+
+ reallyFinal = FALSE;
+ num_attached = 0; /* force re-attempt to contact dispatcher */
+ retval = NetInit();
+ reallyFinal = TRUE;
+
+ return retval;
+}
+
+static Boolean NetFini(void)
+{
+ if (num_attached > 0)
+ num_attached--;
+
+ if (num_attached == 0)
+ {
+ NI_ServiceDisconnect(svcp);
+ svcp = NULL;
+ NI_EndServices (dispatcher);
+ dispatcher = NULL;
+ }
+
+ return TRUE;
+}
+
+
+static Int4
+s_ID1ArchGIGet (SeqIdPtr sip)
+{
+ ID1serverRequestPtr id1reqp;
+ ID1serverBackPtr id1bp;
+ Int4 gi;
+
+ id1reqp = ValNodeNew(NULL);
+ id1reqp->choice = ID1serverRequest_getgi;
+ id1reqp->data.ptrvalue = sip;
+ ID1serverRequestAsnWrite (id1reqp, asnout, NULL);
+ AsnIoReset(asnout);
+ id1reqp->data.ptrvalue = NULL;
+ ID1serverRequestFree (id1reqp);
+
+ if ((id1bp = NetID1servReadAsn()) == NULL)
+ return 0;
+
+ if (id1bp->choice != ID1serverBack_gotgi)
+ {
+ ID1serverBackFree (id1bp);
+ return 0;
+ }
+ gi = (id1bp->data.intvalue);
+ ID1serverBackFree (id1bp);
+
+ return gi;
+}
+
+Int4
+ID1ArchGIGet (SeqIdPtr sip)
+{
+ Int4 gi=0, i;
+ short erract;
+ ErrDesc err;
+ Int4 retval = 0;
+
+ for (i = 0; i < ID_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetID1Arch())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err);
+ gi = s_ID1ArchGIGet (sip);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ break; /* success */
+ }
+ return gi;
+}
+
+
+
+void SeqHistPrintTable (ID1SeqHistPtr ishp,FILE PNTR fp)
+{
+ Char repl_date[20];
+ SeqHistPtr shp;
+ SeqIdPtr sip;
+ Uint4 old_gi=0,ent=0;
+ CharPtr sat=NULL;
+#ifdef IDFETCH_HTML_OUTPUT
+ Boolean checked=FALSE;
+ if(!ishp){
+ fprintf(fp,"<HR><h2>Gi is not found</h2>");
+ goto END;
+ }
+ fprintf(fp,"<PRE><FORM ACTION=\"http://%s:%s%s\"METHOD=POST" ">%c",
+ getenv("SERVER_NAME"),
+ getenv("SERVER_PORT"),
+ getenv("SCRIPT_NAME"),
+ 10);
+#endif
+ if(ishp){
+#ifdef IDFETCH_HTML_OUTPUT
+ fprintf(fp,"<b>");
+ fprintf(fp,"%-20s%-20s%-20s\n","GI","Loaded","Select");
+ fprintf(fp,"%-20s%-20s%-20s\n","--","------","------");
+ fprintf(fp,"</b>");
+#else
+ fprintf(fp,"%-20s%-20s%-10s%-20s\n","GI","Loaded","DB","Retrieval No.");
+ fprintf(fp,"%-20s%-20s%-10s%-20s\n","--","------","--","------------");
+
+#endif
+
+ for(;ishp;ishp=ishp->next){
+ shp=(SeqHistPtr)ishp->hist;
+ for(sip=shp->replace_ids;sip;sip=sip->next){
+ if(sip->choice == SEQID_GI ){
+ if(old_gi != sip->data.intvalue){
+ old_gi = sip->data.intvalue;
+ }
+ }else if(sip->choice == SEQID_LOCAL){
+ ent = ((ObjectIdPtr)sip->data.ptrvalue)->id;
+ sat = "ID";
+ } else if(sip->choice == SEQID_GENERAL) {
+ ent = ((DbtagPtr)sip->data.ptrvalue)->tag->id;
+ sat = ((DbtagPtr)sip->data.ptrvalue)->db;
+ }
+ }
+ if(shp->replace_date){
+ if(shp->replace_date->data[0]){
+ sprintf(repl_date,"%0.2d/%0.2d/%0.2d",
+ shp->replace_date->data[2],
+ shp->replace_date->data[3],
+ shp->replace_date->data[1]);
+ }else{
+ sprintf(repl_date,"%-20s",shp->replace_date->str);
+ }
+ }else{
+ sprintf(repl_date,"N/A");
+ }
+ fprintf(fp,"%-20d%-20s%",old_gi,repl_date);
+#ifdef IDFETCH_HTML_OUTPUT
+ fprintf(fp,"<INPUT TYPE=radio NAME=in_gientlist VALUE=\"%d|%s|%d\" %s> ",
+ old_gi,repl_date,ent,checked?"":"CHECKED");
+ fprintf(fp,"<INPUT TYPE=radio NAME=in_gientlist_2 VALUE=\"%d|%s|%d\" %s>\n",
+ old_gi,repl_date,ent,checked?"":"CHECKED");
+ checked = TRUE;
+#else
+ fprintf(fp,"%-10s%-20d\n",sat,ent);
+#endif
+ }
+ }
+#ifdef IDFETCH_HTML_OUTPUT
+ fprintf(fp,"</PRE>");
+ fprintf(fp,"<HR>\n<h3>View Sequence:</h3>\n");
+ fprintf(fp,"<b>Print Form:</b>&nbsp;&nbsp;"
+ "<select NAME=in_format> "
+ "<option> GenBank"
+ "<option> GenPept"
+ "<option> FASTA"
+ "<option> ASN.1"
+ "<option> GbDiff"
+ "</select>");
+ fprintf(fp,"<BR><INPUT TYPE=\"checkbox\" NAME=in_full VALUE=\"checked\">"
+ " &nbsp; &nbsp;<b>Get full record (including other gis</b>)"
+ "<BR><BR>");
+ fprintf(fp,"<INPUT TYPE = \"submit\" VALUE = \"Display\">");
+ fprintf(fp,"</FORM>");
+END:
+ 1==1;
+#endif
+}
+void id_print_gi_state(Int4 state,CharPtr buf,Uint1 len)
+{
+ Int4 dlen;
+ switch(state & 0xff){
+ case 0:
+ strncpy(buf,"NOT EXIST ",len-1);
+ break;
+ case 10:
+ strncpy(buf,"DELETED ",len-1);
+ break;
+ case 20:
+ strncpy(buf,"REPLACED ",len-1);
+ break;
+ case 40:
+ strncpy(buf,"LIVE ",len-1);
+ break;
+ default:
+ strncpy(buf,"UNKNOWN",len-1);
+ break;
+ }
+ dlen = strlen(buf);
+ if(state & GI_IS_SUPPRESSED){
+ strncpy(buf+dlen,"|SUPPRESSED BY RULE",len - dlen - 1);
+ }
+ dlen = strlen(buf);
+ if(state & GI_IS_OVERRIDEN){
+ strncpy(buf+dlen,"|MANUALLY SUPPRESSED",len - dlen - 1);
+ }
+ dlen = strlen(buf);
+ if(state & GI_IS_CONFIDENTIAL){
+ strncpy(buf+dlen,"|CONFIDENTIAL",len - dlen - 1);
+ }
+}
diff --git a/network/id1arch/id1arch.h b/network/id1arch/id1arch.h
new file mode 100644
index 00000000..d79e62fb
--- /dev/null
+++ b/network/id1arch/id1arch.h
@@ -0,0 +1,80 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: id1arch.h
+*
+* Authors: Eugene Yaschenko
+*/
+#ifndef __ID1ARCH_H_
+#define __ID1ARCH_H_
+#include <ncbi.h>
+#include <sequtil.h>
+#include <id1gen.h>
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define GI_IS_SUPPRESSED 0x100
+#define GI_IS_OVERRIDEN 0x200
+#define GI_IS_CONFIDENTIAL 0x400
+
+
+Boolean ID1ArchInit PROTO((void));
+Boolean ID1ArchFini PROTO((void));
+
+SeqEntryPtr ID1ArchSeqEntryGet PROTO((Int4 uid, CharPtr db, Int4 ent, Int4Ptr status, Int2 maxplex));
+Int4 ID1ArchGIGet PROTO((SeqIdPtr sip));
+SeqIdPtr ID1ArchSeqIdsGet PROTO((Uint4 gi,AsnIoPtr aiopr));
+Int4 ID1ArcgGIStateGet PROTO((Uint4 gi));
+ID1SeqHistPtr ID1ArchGIHistGet PROTO((Uint4 gi,Boolean rev,AsnIoPtr aiopr));
+void SeqHistPrintTable PROTO ((ID1SeqHistPtr ishp,FILE PNTR fp));
+void id_print_gi_state(Int4 state,CharPtr buf,Uint1 len);
+
+/* # of retries to get a server */
+#define ID_SERV_RETRIES 2
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif
diff --git a/network/id1arch/id1gen.c b/network/id1arch/id1gen.c
new file mode 100644
index 00000000..cecce98d
--- /dev/null
+++ b/network/id1arch/id1gen.c
@@ -0,0 +1,1000 @@
+#include <asn.h>
+
+#define NLM_GENERATED_CODE_PROTO
+
+#include <id1map.h>
+#include <id1gen.h>
+
+static Boolean loaded = FALSE;
+
+#include <id1.h>
+
+#ifndef NLM_EXTERN_LOADS
+#define NLM_EXTERN_LOADS {}
+#endif
+
+NLM_EXTERN Boolean LIBCALL
+id1genAsnLoad(void)
+{
+
+ if ( ! loaded) {
+ NLM_EXTERN_LOADS
+
+ if ( ! AsnLoad ())
+ return FALSE;
+ loaded = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/**************************************************
+* Generated object loaders for Module NCBI-ID1Access
+* Generated using ASNCODE Revision: 6.0 at Jul 30, 1998 4:04 PM
+*
+**************************************************/
+
+
+/**************************************************
+*
+* ID1serverRequestFree()
+*
+**************************************************/
+NLM_EXTERN
+ID1serverRequestPtr LIBCALL
+ID1serverRequestFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case ID1serverRequest_getgi:
+ SeqIdFree(anp -> data.ptrvalue);
+ break;
+ case ID1serverRequest_getsefromgi:
+ ID1serverMaxcomplexFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* ID1serverRequestAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+ID1serverRequestPtr LIBCALL
+ID1serverRequestAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* ID1serverRequest ::= (self contained) */
+ atp = AsnReadId(aip, amp, ID1SERVER_REQUEST);
+ } else {
+ atp = AsnLinkType(orig, ID1SERVER_REQUEST); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == ID1SERVER_REQUEST_init) {
+ choice = ID1serverRequest_init;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == ID1SERVER_REQUEST_getgi) {
+ choice = ID1serverRequest_getgi;
+ func = (AsnReadFunc) SeqIdAsnRead;
+ }
+ else if (atp == ID1SERVER_REQUEST_getsefromgi) {
+ choice = ID1serverRequest_getsefromgi;
+ func = (AsnReadFunc) ID1serverMaxcomplexAsnRead;
+ }
+ else if (atp == ID1SERVER_REQUEST_fini) {
+ choice = ID1serverRequest_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == REQUEST_getseqidsfromgi) {
+ choice = ID1serverRequest_getseqidsfromgi;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == ID1SERVER_REQUEST_getgihist) {
+ choice = ID1serverRequest_getgihist;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == ID1SERVER_REQUEST_getgirev) {
+ choice = ID1serverRequest_getgirev;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == ID1SERVER_REQUEST_getgistate) {
+ choice = ID1serverRequest_getgistate;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* ID1serverRequestAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+ID1serverRequestAsnWrite(ID1serverRequestPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ID1SERVER_REQUEST); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case ID1serverRequest_init:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, ID1SERVER_REQUEST_init, &av);
+ break;
+ case ID1serverRequest_getgi:
+ writetype = ID1SERVER_REQUEST_getgi;
+ func = (AsnWriteFunc) SeqIdAsnWrite;
+ break;
+ case ID1serverRequest_getsefromgi:
+ writetype = ID1SERVER_REQUEST_getsefromgi;
+ func = (AsnWriteFunc) ID1serverMaxcomplexAsnWrite;
+ break;
+ case ID1serverRequest_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, ID1SERVER_REQUEST_fini, &av);
+ break;
+ case ID1serverRequest_getseqidsfromgi:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, REQUEST_getseqidsfromgi, &av);
+ break;
+ case ID1serverRequest_getgihist:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, ID1SERVER_REQUEST_getgihist, &av);
+ break;
+ case ID1serverRequest_getgirev:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, ID1SERVER_REQUEST_getgirev, &av);
+ break;
+ case ID1serverRequest_getgistate:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, ID1SERVER_REQUEST_getgistate, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* ID1serverMaxcomplexNew()
+*
+**************************************************/
+NLM_EXTERN
+ID1serverMaxcomplexPtr LIBCALL
+ID1serverMaxcomplexNew(void)
+{
+ ID1serverMaxcomplexPtr ptr = MemNew((size_t) sizeof(ID1serverMaxcomplex));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* ID1serverMaxcomplexFree()
+*
+**************************************************/
+NLM_EXTERN
+ID1serverMaxcomplexPtr LIBCALL
+ID1serverMaxcomplexFree(ID1serverMaxcomplexPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> sat);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* ID1serverMaxcomplexAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+ID1serverMaxcomplexPtr LIBCALL
+ID1serverMaxcomplexAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ ID1serverMaxcomplexPtr ptr;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* ID1serverMaxcomplex ::= (self contained) */
+ atp = AsnReadId(aip, amp, ID1SERVER_MAXCOMPLEX);
+ } else {
+ atp = AsnLinkType(orig, ID1SERVER_MAXCOMPLEX);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = ID1serverMaxcomplexNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == ID1SERVER_MAXCOMPLEX_maxplex) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> maxplex = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ID1SERVER_MAXCOMPLEX_gi) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> gi = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ID1SERVER_MAXCOMPLEX_ent) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> ent = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == ID1SERVER_MAXCOMPLEX_sat) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> sat = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = ID1serverMaxcomplexFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* ID1serverMaxcomplexAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+ID1serverMaxcomplexAsnWrite(ID1serverMaxcomplexPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, ID1SERVER_MAXCOMPLEX); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> maxplex;
+ retval = AsnWrite(aip, ID1SERVER_MAXCOMPLEX_maxplex, &av);
+ av.intvalue = ptr -> gi;
+ retval = AsnWrite(aip, ID1SERVER_MAXCOMPLEX_gi, &av);
+ av.intvalue = ptr -> ent;
+ retval = AsnWrite(aip, ID1SERVER_MAXCOMPLEX_ent, &av);
+ if (ptr -> sat != NULL) {
+ av.ptrvalue = ptr -> sat;
+ retval = AsnWrite(aip, ID1SERVER_MAXCOMPLEX_sat, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* ID1SeqHistNew()
+*
+**************************************************/
+NLM_EXTERN
+ID1SeqHistPtr LIBCALL
+ID1SeqHistNew(void)
+{
+ ID1SeqHistPtr ptr = MemNew((size_t) sizeof(ID1SeqHist));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* ID1SeqHistFree()
+*
+**************************************************/
+NLM_EXTERN
+ID1SeqHistPtr LIBCALL
+ID1SeqHistFree(ID1SeqHistPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ SeqHistFree(ptr -> hist);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* ID1SeqHistAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+ID1SeqHistPtr LIBCALL
+ID1SeqHistAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ ID1SeqHistPtr ptr;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* ID1SeqHist ::= (self contained) */
+ atp = AsnReadId(aip, amp, ID1SEQ_HIST);
+ } else {
+ atp = AsnLinkType(orig, ID1SEQ_HIST);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = ID1SeqHistNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == ID1SEQ_HIST_hist) {
+ ptr -> hist = SeqHistAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = ID1SeqHistFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* ID1SeqHistAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+ID1SeqHistAsnWrite(ID1SeqHistPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, ID1SEQ_HIST); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> hist != NULL) {
+ if ( ! SeqHistAsnWrite(ptr -> hist, aip, ID1SEQ_HIST_hist)) {
+ goto erret;
+ }
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* ID1serverBackFree()
+*
+**************************************************/
+NLM_EXTERN
+ID1serverBackPtr LIBCALL
+ID1serverBackFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case ID1serverBack_gotseqentry:
+ SeqEntryFree(anp -> data.ptrvalue);
+ break;
+ case ID1serverBack_gotdeadseqentry:
+ SeqEntryFree(anp -> data.ptrvalue);
+ break;
+ case ID1serverBack_ids:
+ AsnGenericChoiceSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) SeqIdFree);
+ break;
+ case ID1serverBack_gihist:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) ID1SeqHistFree);
+ break;
+ case ID1serverBack_girevhist:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) ID1SeqHistFree);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* ID1serverBackAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+ID1serverBackPtr LIBCALL
+ID1serverBackAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* ID1serverBack ::= (self contained) */
+ atp = AsnReadId(aip, amp, ID1SERVER_BACK);
+ } else {
+ atp = AsnLinkType(orig, ID1SERVER_BACK); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == ID1SERVER_BACK_init) {
+ choice = ID1serverBack_init;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == ID1SERVER_BACK_error) {
+ choice = ID1serverBack_error;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == ID1SERVER_BACK_gotgi) {
+ choice = ID1serverBack_gotgi;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == ID1SERVER_BACK_gotseqentry) {
+ choice = ID1serverBack_gotseqentry;
+ func = (AsnReadFunc) SeqEntryAsnRead;
+ }
+ else if (atp == ID1SERVER_BACK_gotdeadseqentry) {
+ choice = ID1serverBack_gotdeadseqentry;
+ func = (AsnReadFunc) SeqEntryAsnRead;
+ }
+ else if (atp == ID1SERVER_BACK_fini) {
+ choice = ID1serverBack_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == ID1SERVER_BACK_gistate) {
+ choice = ID1serverBack_gistate;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == ID1SERVER_BACK_ids) {
+ choice = ID1serverBack_ids;
+ anp -> data.ptrvalue =
+ AsnGenericChoiceSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) SeqIdAsnRead, (AsnOptFreeFunc) SeqIdFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == ID1SERVER_BACK_gihist) {
+ choice = ID1serverBack_gihist;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) ID1SeqHistAsnRead, (AsnOptFreeFunc) ID1SeqHistFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == ID1SERVER_BACK_girevhist) {
+ choice = ID1serverBack_girevhist;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) ID1SeqHistAsnRead, (AsnOptFreeFunc) ID1SeqHistFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* ID1serverBackAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+ID1serverBackAsnWrite(ID1serverBackPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, ID1SERVER_BACK); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case ID1serverBack_init:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, ID1SERVER_BACK_init, &av);
+ break;
+ case ID1serverBack_error:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, ID1SERVER_BACK_error, &av);
+ break;
+ case ID1serverBack_gotgi:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, ID1SERVER_BACK_gotgi, &av);
+ break;
+ case ID1serverBack_gotseqentry:
+ writetype = ID1SERVER_BACK_gotseqentry;
+ func = (AsnWriteFunc) SeqEntryAsnWrite;
+ break;
+ case ID1serverBack_gotdeadseqentry:
+ writetype = ID1SERVER_BACK_gotdeadseqentry;
+ func = (AsnWriteFunc) SeqEntryAsnWrite;
+ break;
+ case ID1serverBack_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, ID1SERVER_BACK_fini, &av);
+ break;
+ case ID1serverBack_gistate:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, ID1SERVER_BACK_gistate, &av);
+ break;
+ case ID1serverBack_ids:
+ retval = AsnGenericChoiceSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) SeqIdAsnWrite, aip, ID1SERVER_BACK_ids, ID1SERVER_BACK_ids_E);
+ break;
+ case ID1serverBack_gihist:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) ID1SeqHistAsnWrite, aip, ID1SERVER_BACK_gihist, ID1SERVER_BACK_gihist_E);
+ break;
+ case ID1serverBack_girevhist:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) ID1SeqHistAsnWrite, aip, ID1SERVER_BACK_girevhist, ID1SERVER_BACK_girevhist_E);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* ID1serverDebugFree()
+*
+**************************************************/
+NLM_EXTERN
+ID1serverDebugPtr LIBCALL
+ID1serverDebugFree(ID1serverDebugPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericChoiceSeqOfFree(ptr, (AsnOptFreeFunc) ID1serverBackFree);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* ID1serverDebugAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+ID1serverDebugPtr LIBCALL
+ID1serverDebugAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ ID1serverDebugPtr ptr;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* ID1serverDebug ::= (self contained) */
+ atp = AsnReadId(aip, amp, ID1SERVER_DEBUG);
+ } else {
+ atp = AsnLinkType(orig, ID1SERVER_DEBUG);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ func = NULL;
+
+ ptr = AsnGenericChoiceSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) ID1serverBackAsnRead, (AsnOptFreeFunc) ID1serverBackFree);
+ if (isError && ptr == NULL) {
+ goto erret;
+ }
+
+
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = ID1serverDebugFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* ID1serverDebugAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+ID1serverDebugAsnWrite(ID1serverDebugPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! id1genAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, ID1SERVER_DEBUG); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ retval = AsnGenericChoiceSeqOfAsnWrite(ptr , (AsnWriteFunc) ID1serverBackAsnWrite, aip, atp, ID1SERVER_DEBUG_E);
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
diff --git a/network/id1arch/id1gen.h b/network/id1arch/id1gen.h
new file mode 100644
index 00000000..cb0988d2
--- /dev/null
+++ b/network/id1arch/id1gen.h
@@ -0,0 +1,130 @@
+#ifndef _id1gen_
+#define _id1gen_
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+
+#ifdef __cplusplus
+extern "C" { /* } */
+#endif
+
+
+/**************************************************
+*
+* Generated objects for Module NCBI-ID1Access
+* Generated using ASNCODE Revision: 6.0 at Jul 30, 1998 4:04 PM
+*
+**************************************************/
+
+NLM_EXTERN Boolean LIBCALL
+id1genAsnLoad PROTO((void));
+typedef ValNodePtr ID1serverRequestPtr;
+typedef ValNode ID1serverRequest;
+#define ID1serverRequest_init 1
+#define ID1serverRequest_getgi 2
+#define ID1serverRequest_getsefromgi 3
+#define ID1serverRequest_fini 4
+#define ID1serverRequest_getseqidsfromgi 5
+#define ID1serverRequest_getgihist 6
+#define ID1serverRequest_getgirev 7
+#define ID1serverRequest_getgistate 8
+
+
+NLM_EXTERN ID1serverRequestPtr LIBCALL ID1serverRequestFree PROTO ((ID1serverRequestPtr ));
+NLM_EXTERN ID1serverRequestPtr LIBCALL ID1serverRequestAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL ID1serverRequestAsnWrite PROTO (( ID1serverRequestPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* ID1serverMaxcomplex
+*
+**************************************************/
+typedef struct struct_ID1server_maxcomplex {
+ Int4 maxplex;
+ Int4 gi;
+ Int4 ent;
+ CharPtr sat;
+} ID1serverMaxcomplex, PNTR ID1serverMaxcomplexPtr;
+
+
+NLM_EXTERN ID1serverMaxcomplexPtr LIBCALL ID1serverMaxcomplexFree PROTO ((ID1serverMaxcomplexPtr ));
+NLM_EXTERN ID1serverMaxcomplexPtr LIBCALL ID1serverMaxcomplexNew PROTO (( void ));
+NLM_EXTERN ID1serverMaxcomplexPtr LIBCALL ID1serverMaxcomplexAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL ID1serverMaxcomplexAsnWrite PROTO (( ID1serverMaxcomplexPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* ID1SeqHist
+*
+**************************************************/
+typedef struct struct_ID1Seq_hist {
+ struct struct_ID1Seq_hist PNTR next;
+ struct struct_Seq_hist PNTR hist;
+} ID1SeqHist, PNTR ID1SeqHistPtr;
+
+
+NLM_EXTERN ID1SeqHistPtr LIBCALL ID1SeqHistFree PROTO ((ID1SeqHistPtr ));
+NLM_EXTERN ID1SeqHistPtr LIBCALL ID1SeqHistNew PROTO (( void ));
+NLM_EXTERN ID1SeqHistPtr LIBCALL ID1SeqHistAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL ID1SeqHistAsnWrite PROTO (( ID1SeqHistPtr , AsnIoPtr, AsnTypePtr));
+
+typedef ValNodePtr ID1serverBackPtr;
+typedef ValNode ID1serverBack;
+#define ID1serverBack_init 1
+#define ID1serverBack_error 2
+#define ID1serverBack_gotgi 3
+#define ID1serverBack_gotseqentry 4
+#define ID1serverBack_gotdeadseqentry 5
+#define ID1serverBack_fini 6
+#define ID1serverBack_gistate 7
+#define ID1serverBack_ids 8
+#define ID1serverBack_gihist 9
+#define ID1serverBack_girevhist 10
+
+
+NLM_EXTERN ID1serverBackPtr LIBCALL ID1serverBackFree PROTO ((ID1serverBackPtr ));
+NLM_EXTERN ID1serverBackPtr LIBCALL ID1serverBackAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL ID1serverBackAsnWrite PROTO (( ID1serverBackPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* ID1serverDebug
+*
+**************************************************/
+typedef ValNode ID1serverDebug;
+typedef ValNodePtr ID1serverDebugPtr;
+#define ID1serverDebugNew() ValNodeNew(NULL)
+
+#ifdef NLM_GENERATED_CODE_PROTO
+
+NLM_EXTERN ID1serverDebugPtr LIBCALL ID1serverDebugFree PROTO ((ID1serverDebugPtr ));
+NLM_EXTERN ID1serverDebugPtr LIBCALL ID1serverDebugNew PROTO (( void ));
+NLM_EXTERN ID1serverDebugPtr LIBCALL ID1serverDebugAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL ID1serverDebugAsnWrite PROTO (( ID1serverDebugPtr , AsnIoPtr, AsnTypePtr));
+
+#endif /* NLM_GENERATED_CODE_PROTO */
+
+#ifdef __cplusplus
+/* { */ }
+#endif
+
+#endif /* _id1gen_ */
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
diff --git a/network/id1arch/id1map.h b/network/id1arch/id1map.h
new file mode 100644
index 00000000..25ed425a
--- /dev/null
+++ b/network/id1arch/id1map.h
@@ -0,0 +1,6 @@
+#include <objsset.h>
+
+#define NLM_EXTERN_LOADS {if (! SeqSetAsnLoad())return FALSE; \
+ }
+#define struct_Seq_hist seqhist
+
diff --git a/network/id1arch/idfetch.c b/network/id1arch/idfetch.c
new file mode 100644
index 00000000..5c3266f8
--- /dev/null
+++ b/network/id1arch/idfetch.c
@@ -0,0 +1,506 @@
+/* idfetch.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+
+* Author Karl Sirotkin
+*
+$Log: idfetch.c,v $
+Revision 1.1 1998/12/28 17:56:29 yaschenk
+preparing idfetch to go to production
+
+Revision 1.1 1997/05/29 14:34:07 sirotkin
+syncing sampson from mutant for procs. taking source from sampson. this is now current
+
+ * Revision 4.0 1995/07/26 13:55:55 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.3 1995/06/21 14:14:29 kans
+ * replaced asn2ff_entrez with SeqEntryToFlat
+ *
+ * Revision 1.2 1995/05/17 17:59:15 epstein
+ * add RCS log revision history
+ *
+ * Revision 1.1 94/08/11 13:26:31 ostell
+ * Initial revision
+ *
+ * Revision 1.3 1993/12/02 10:12:41 kans
+ * Includes <ncbi.h> instead of <sys/types.h>
+ *
+ * Revision 1.2 93/11/24 13:25:56 sirotkin
+ * First working version
+ *
+ * Revision 1.1 93/11/23 16:01:51 sirotkin
+ * Initial revision
+ *
+ revised by OStell for public use.
+ *
+ * Modified by Eugene Yaschenko for ID1 Server
+*
+*
+* RCS Modification History:
+* $Log: idfetch.c,v $
+* Revision 1.1 1998/12/28 17:56:29 yaschenk
+* preparing idfetch to go to production
+*
+* Revision 1.1 1997/05/29 14:34:07 sirotkin
+* syncing sampson from mutant for procs. taking source from sampson. this is now current
+*
+ * Revision 4.0 1995/07/26 13:55:55 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.3 1995/06/21 14:14:29 kans
+ * replaced asn2ff_entrez with SeqEntryToFlat
+ *
+ * Revision 1.2 1995/05/17 17:59:15 epstein
+ * add RCS log revision history
+ *
+*/
+#include <ncbi.h>
+#include <objsset.h>
+#include <accid1.h>
+#include <asn2ff.h>
+#include <tofasta.h>
+#include <ni_types.h>
+
+Args myargs[] = {
+ {"Filename for output ","stdout", NULL,NULL,FALSE,'o',ARG_FILE_OUT, 0.0,0,NULL},
+ {"Output type: 1=text asn.1 2=binary asn.1 3=genbank (Seq-entry only) 4=genpept (Seq-entry only) 5=fasta (table for history)",
+ "1", "1", "5", FALSE, 't', ARG_INT, 0.0, 0, NULL } ,
+ {"Database to use",NULL,NULL,NULL,TRUE,'d',ARG_STRING,0.0,0,NULL},
+ {"Entity number ( retrieval number ) to dump" ,"0","0","99999999",TRUE,'e',ARG_INT,0.0,0,NULL},
+ {"Type of lookup:\t\
+0 - get Seq-entry\n\t\t\t\
+1 - get gi state (output to stderr)\n\t\t\t\
+2 - get SeqIds\n\t\t\t\
+3 - get gi historyn (sequence change only)\n\t\t\t\
+4 - get gi revision history (any change to asn.1)\n", "0","0","4",TRUE,'i',ARG_INT,0.0,0,NULL},
+ {"GI id for single Entity to dump" ,"0","1","99999999",TRUE,'g',ARG_INT,0.0,0,NULL},
+ {"Maximum complexity of Entity dump (only for -i 0 )" ,"0","0","4",TRUE,'c',ARG_INT,0.0,0,NULL},
+ {"flaTtened SeqId, format: \n \'type(name,accession,release,version)\'\n as \'5(HUMHBB)\' or \n type=accession, or \n type:number ",
+ NULL,NULL,NULL,TRUE,'f',ARG_STRING,0.0,0,NULL},
+ {"Fasta style SeqId ENCLOSED IN QUOTES: lcl|int or str bbs|int bbm|int gb|acc|loc emb|acc|loc pir|acc|name sp|acc|name pat|country|patent|seq gi|int dbj|acc|loc prf|acc|name pdb|entry|chain ",
+ NULL,NULL,NULL,TRUE,'s',ARG_STRING,0.0,0,NULL},
+ {"Log file for errors and feedback about IDs assigned", NULL,NULL,NULL,TRUE,'l',ARG_FILE_OUT,
+ 0.0,0,NULL}
+};
+int Numarg = sizeof(myargs)/sizeof(myargs[0]);
+
+#define MACRO_SETARG(TAG,P) \
+ {\
+ P = Nlm_WhichArg (TAG, Numarg, myargs);\
+ if ( P < 0){\
+ ErrPost(CTX_NCBIIDRETRIEVE,10,\
+ "Program error looking for arg %c\n", TAG);\
+ has_trouble = TRUE;\
+ }\
+ }
+static Nlm_Int2 Nlm_WhichArg PROTO (( Nlm_Char which, Nlm_Int2 numargs, Nlm_ArgPtr ap));
+
+DataVal Val;
+
+Int2 Main()
+{
+ AsnIoPtr aip, check_aip = NULL;
+ SeqEntryPtr sep = NULL, hold_entry;
+ Int2 fileoutarg, logarg, outtypearg,maxplexarg,
+ seqidarg, giarg, fastaarg,infotypearg,entarg,dbarg;
+ Boolean has_trouble = FALSE;
+ char * msg;
+ CharPtr outmode;
+ Int4 entity_spec_count = 0;
+ Int4 ent = 0;
+ Int4 gi = 0;
+ Int4 gi_state;
+ AsnIoPtr asnout=NULL;
+ FILE * fp = NULL;
+ Int4 status;
+ SeqIdPtr sip,sip_ret;
+ ID1SeqHistPtr ishp;
+ Char tbuf[40],buf[200];
+
+
+ /* check command line arguments */
+
+ if ( ! GetArgs("idfetch.c",Numarg, myargs))
+ return 1;
+
+
+/********************************************************************
+ **** ****
+ **** Map Args So Can be Accessed in order independent fashion ****
+ **** ****
+ *******************************************************************/
+
+ MACRO_SETARG('o', fileoutarg)
+ MACRO_SETARG('t', outtypearg)
+ MACRO_SETARG('i', infotypearg)
+ MACRO_SETARG('c', maxplexarg)
+ MACRO_SETARG('e',entarg)
+ MACRO_SETARG('d',dbarg)
+ MACRO_SETARG('g',giarg)
+ MACRO_SETARG('f',seqidarg)
+ MACRO_SETARG('l',logarg)
+ MACRO_SETARG('s',fastaarg)
+
+ if (! SeqEntryLoad())
+ ErrShow();
+
+ if (myargs[logarg].strvalue != NULL) {
+ if (! ErrSetLog (myargs[logarg].strvalue)){
+ ErrShow();
+ has_trouble = TRUE;
+ }else{
+ ErrSetOpts (ERR_TEE, ERR_LOG_ON);
+ }
+ }
+ if(myargs[infotypearg].intvalue>1 && (myargs[outtypearg].intvalue == 3 || myargs[outtypearg].intvalue == 4)){
+ ErrPostEx(SEV_FATAL,0,0,"-t 3 or -t 4 can be used only with -i 0");
+ has_trouble=TRUE;
+ goto FATAL;
+ }
+
+ if (myargs[giarg].intvalue){
+ entity_spec_count ++;
+ }
+ if (myargs[seqidarg].strvalue){
+ entity_spec_count ++;
+ }
+ if (myargs[fastaarg].strvalue)
+ entity_spec_count++;
+
+ if (entity_spec_count != 1){
+ ErrPostEx(SEV_FATAL,0,0, "One and only one of the -g, -f, -s parameters must be used");
+ has_trouble=TRUE;
+ goto FATAL;
+ }
+ if(myargs[infotypearg].intvalue != 1){
+ outmode = "w";
+ switch (myargs[outtypearg].intvalue)
+ {
+ case 2:
+ outmode = "wb";
+ case 1:
+ asnout = AsnIoOpen((CharPtr)myargs[fileoutarg].strvalue, outmode);
+ if (asnout == NULL)
+ {
+ ErrPost(CTX_NCBIIDRETRIEVE,10,
+ "Could not open %s for asn output\n",
+ myargs[fileoutarg].strvalue);
+ has_trouble = TRUE;
+ }
+ break;
+ case 3:
+ case 4:
+ case 5:
+ fp = FileOpen((CharPtr)myargs[fileoutarg].strvalue, outmode);
+ if (fp == NULL)
+ {
+ ErrPost(CTX_NCBIIDRETRIEVE,10,
+ "Could not open %s for output\n",
+ myargs[fileoutarg].strvalue);
+ has_trouble = TRUE;
+ }
+ break;
+ }
+ }
+
+ if ( has_trouble )
+ exit (1);
+ NI_SetInterface(eNII_WWWDirect);
+ if (!ID1BioseqFetchEnable("idfetch",TRUE)){
+ ErrPost(CTX_NCBIIDRETRIEVE,20,
+ "Could not open ID1 service");
+ exit(1);
+ }
+ if (myargs[giarg].intvalue){
+ gi = myargs[giarg].intvalue;
+ }
+ else if (myargs[fastaarg].strvalue != NULL)
+ {
+ sip = SeqIdParse((CharPtr)myargs[fastaarg].strvalue);
+ if (sip == NULL)
+ {
+#ifdef IDFETCH_HTML_OUTPUT
+ fprintf(fp,"<HR><h2>Couldn't parse FASTA format: <I>%s</I></h2>",myargs[fastaarg].strvalue);
+ fflush(fp);
+#endif
+ ErrPostEx(SEV_FATAL,0,0,"Couldn't parse [%s]", myargs[fastaarg].strvalue);
+ exit(1);
+ }
+ }else{
+/* "flaTtened SeqId, format:
+ type(name,accession,release,version) or type=accession",
+ */
+ static CharPtr name = NULL, accession = NULL, release = NULL, version = NULL, number = NULL;
+ CharPtr p ;
+ int type_int;
+ static CharPtr PNTR fields [] = { & name, & accession, & release, & number};
+ Boolean found_equals = FALSE, found_left = FALSE,
+ found_colon = FALSE, flat_seqid_err = FALSE,
+ dna_type = FALSE, any_type = FALSE;
+ int dex;
+ CharPtr sql_where, sql_and, temp_where, temp_and;
+ TextSeqIdPtr tsip;
+
+ sip = ValNodeNew(NULL);
+ type_int = atoi(myargs[seqidarg].strvalue);
+ for (p = myargs[seqidarg].strvalue; *p; p++ ) {
+ if ( *p == '(' || *p == '=' || *p == ':'){ /* ) match */
+
+ if ( *p == '(' ){ /* ) match */
+ found_left = TRUE;
+ if (p == myargs[seqidarg].strvalue){
+ any_type = TRUE;
+ ErrPost(CTX_NCBIIDRETRIEVE,10,
+ "Sorry, any type is not allowed for ID1service");
+ exit(1);
+ }else if ( p - myargs[seqidarg].strvalue == 1){
+ if (*myargs[seqidarg].strvalue == '0'){
+ dna_type = TRUE;
+ ErrPost(CTX_NCBIIDRETRIEVE,10,
+ "Sorry, 0== nucroe3 type is not allowed for ID1service");
+ exit(1);
+ }
+ }
+ }else if ( *p == '=') {
+ found_equals = TRUE;
+ if (p == myargs[seqidarg].strvalue){
+ any_type = TRUE;
+ }else if ( p - myargs[seqidarg].strvalue == 1){
+ if (*myargs[seqidarg].strvalue == '0'){
+ dna_type = TRUE;
+ }
+ }
+ }else if ( *p == ':'){
+ found_colon = TRUE;
+ if (p == myargs[seqidarg].strvalue){
+ any_type = TRUE;
+ }else if ( p - myargs[seqidarg].strvalue == 1){
+ if (*myargs[seqidarg].strvalue == '0'){
+ dna_type = TRUE;
+ }
+ }
+ }
+ *p = '\0';
+ p++;
+ break;
+ }
+ }
+ if ( found_left){
+ for ( * (fields[0]) = p, dex = 0; *p && dex < 4; p++){
+ if ( *p == ',' || *p == ')' ){
+ *p = '\0';
+ dex ++;
+ *(fields[dex]) = p + 1;
+ }
+ }
+ }else if (found_equals){
+ accession = p;
+ }else if (found_colon){
+ number = p;
+ }else{
+ ErrPost(CTX_NCBIIDRETRIEVE, 10,
+ "id1test: could not find \'(\' or \'=\' or \':\' in flattened seqid=%s",myargs[seqidarg].strvalue); /* ) match */
+ exit(1);
+ }
+ sip -> choice = type_int;
+ switch (type_int){
+ case SEQID_GIBBSQ :
+ case SEQID_GIBBMT :
+ case SEQID_GI :
+ sip -> data.intvalue = atoi(number);
+ break;
+ case SEQID_GENBANK : case SEQID_EMBL : case SEQID_DDBJ :
+ case SEQID_PIR : case SEQID_SWISSPROT : case SEQID_OTHER :
+ case SEQID_PRF :
+ tsip = TextSeqIdNew();
+ sip -> data.ptrvalue = tsip;
+ if (accession)
+ if (!*accession)
+ accession = NULL;
+ if (release)
+ if (!*release)
+ release = NULL;
+ if (name)
+ if (!*name)
+ name = NULL;
+ tsip -> name = StringSave(name);
+ tsip -> accession = StringSave(accession);
+ tsip -> release = StringSave(release);
+ break;
+ case SEQID_PATENT : case SEQID_GENERAL : case SEQID_PDB :
+ case SEQID_LOCAL :
+ ErrPost(CTX_NCBIIDRETRIEVE,30,
+ "Sorry, this test program does not support %d patent, general, pdb, or local, try id2asn ",
+ type_int);
+ exit(1);
+ break;
+ }
+ }
+ if (! gi){
+ gi = ID1ArchGIGet (sip);
+ if (gi <= 0){
+ SeqIdPrint(sip, tbuf, PRINTID_FASTA_SHORT);
+#ifdef IDFETCH_HTML_OUTPUT
+ fprintf(fp,"<HR><h2>Couldn't find SeqId: <I>%s</I></h2>",tbuf);
+ fflush(fp);
+#endif
+ ErrPostEx(SEV_FATAL, 0,0,"Couldn't find SeqId [%s]", tbuf);
+ exit(1);
+ }
+ }
+ switch(myargs[infotypearg].intvalue){
+ case 0:
+ sep = ID1ArchSeqEntryGet (gi, myargs[dbarg].strvalue, myargs[entarg].intvalue,
+ &status,(Int2) myargs[maxplexarg].intvalue);
+ if ( !sep){
+ switch(status){
+ case 1:
+ fprintf(stderr,"Sequence has been withdrawn\n");
+ break;
+ case 2:
+ fprintf(stderr,"Sequence is not yet available\n");
+ break;
+ default:
+ fprintf(stderr," Unable to read ASN.1 message\n");
+ }
+#ifdef IDFETCH_HTML_OUTPUT
+ printf("<HR><h2>Sorry, Sequence is not available</h2>");
+ fflush(stdout);
+#endif
+ goto FATAL;
+ }
+ if (status==3)
+ fprintf(stderr," IS DEAD!\n");
+ break;
+ case 1:
+ gi_state = ID1ArcgGIStateGet(gi);
+ break;
+ case 2:
+ sip_ret = ID1ArchSeqIdsGet(gi,asnout);
+ break;
+ case 3:
+ ishp = ID1ArchGIHistGet(gi,FALSE,asnout);
+ break;
+ case 4:
+ ishp = ID1ArchGIHistGet(gi,TRUE,asnout);
+ break;
+ }
+ if(myargs[infotypearg].intvalue == 1){
+ Char buf[200];
+ id_print_gi_state(gi_state,buf,sizeof(buf));
+ printf("gi= %d, states: %s\n",gi,buf);
+ } else {
+ switch (myargs[outtypearg].intvalue)
+ {
+ case 1:
+ case 2:
+ switch(myargs[infotypearg].intvalue){
+ case 0:
+ SeqEntryAsnWrite(sep, asnout, NULL);
+ break;
+ }
+ break;
+ case 3:
+ if(!SeqEntryToFlat(sep, fp, GENBANK_FMT, RELEASE_MODE)){
+ ErrPostEx(SEV_WARNING,0,0,
+ "GenBank Format does not exist for this sequence");
+ has_trouble=TRUE;
+#ifdef IDFETCH_HTML_OUTPUT
+ fprintf(fp,
+ "<HR><h2>GenBank Format does not exist for this sequence</h2>");
+ fflush(fp);
+#endif
+ }
+ break;
+ case 4:
+ if(!SeqEntryToFlat(sep, fp, GENPEPT_FMT, RELEASE_MODE)){
+ ErrPostEx(SEV_WARNING,0,0,
+ "GenPept Format does not exist for this sequence");
+ has_trouble=TRUE;
+#ifdef IDFETCH_HTML_OUTPUT
+ fprintf(fp,
+ "<HR><h2>GenPept Format does not exist for this sequence</h2>");
+ fflush(fp);
+#endif
+ }
+ break;
+ case 5:
+ switch(myargs[infotypearg].intvalue){
+ case 0:
+ SeqEntryToFasta(sep, fp, TRUE); /* nuc acids */
+ SeqEntryToFasta(sep, fp, FALSE); /* proteins */
+ break;
+ case 2:
+ SeqIdWrite(sip_ret,buf,PRINTID_FASTA_LONG,sizeof(buf) - 1);
+ fprintf(fp,"%s\n",buf);
+ break;
+ case 3:
+ case 4:
+ SeqHistPrintTable(ishp,fp);
+ break;
+ }
+ break;
+ }
+ }
+ SeqEntryFree(sep);
+FATAL:
+ if(asnout)
+ AsnIoClose(asnout);
+ if(fp)
+ FileClose(fp);
+ ID1ArchFini();
+
+ return(has_trouble?1:0);
+}
+
+/*****************************************************************************
+*
+* Nlm_WhichArg(ap)
+* returns array position for a tag
+*
+*****************************************************************************/
+static Nlm_Int2 Nlm_WhichArg( Nlm_Char which, Nlm_Int2 numargs, Nlm_ArgPtr ap)
+{
+ Nlm_Boolean okay = FALSE;
+ Nlm_Int2 i;
+ Nlm_ArgPtr curarg;
+ Nlm_Int2 retval = -1;
+
+ if ((ap == NULL) || (numargs == 0) )
+ return okay;
+
+ curarg = ap; /* set defaults */
+
+ for (i = 0; i < numargs; i++, curarg++)
+ {
+ if (curarg->tag == which)
+ {
+ retval = i;
+ break;
+ }
+ }
+
+ return retval;
+}
diff --git a/network/medarch/client/mapmla.h b/network/medarch/client/mapmla.h
new file mode 100644
index 00000000..a8fe6ddd
--- /dev/null
+++ b/network/medarch/client/mapmla.h
@@ -0,0 +1,92 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: mapmla.h
+*
+* Author: Epstein
+*
+* Version Creation Date: 03/31/93
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Mappings file used to work around incompleteness of automatic ASN.1
+* code generation for Medline Archive object loaders
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 031596 grisha delete warning: Attemp to redefine NLM_EXTERN_LOADS
+* without using #undef
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: mapmla.h,v $
+* Revision 6.0 1997/08/25 18:35:36 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/02/06 21:42:48 grisha
+* Add new functionality for support Medlars entry transfer
+*
+ * Revision 5.1 1996/12/16 20:18:23 grisha
+ * grisha add definition for support PubMed entry definition
+ *
+ * Revision 5.0 1996/05/28 14:11:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.1 1996/03/15 18:49:17 grisha
+ * Fix warning: Attempt to redefine NLM_EXTERN_LOADS without using #undef
+ * I add undef if NLM_EXTERN_LOADS already defined
+ *
+ * Revision 4.0 1995/07/26 13:55:12 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.2 1995/05/17 17:53:51 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <mappubme.h>
+#include <objmedli.h>
+#include <objpubme.h>
+#include <objmdrs.h>
+#include <objpub.h>
+
+/* legitimate substitutions to handle differences between existing object */
+/* loaders and symbol names generated for automatically-generated object */
+/* loaders (for imported types) */
+#define TitlePtr ValNodePtr
+
+#if defined(NLM_EXTERN_LOADS)
+#undef NLM_EXTERN_LOADS
+#endif
+#define NLM_EXTERN_LOADS { if (! objpubmeAsnLoad()) return FALSE; \
+ if (! objmdrsAsnLoad()) return FALSE; \
+ if (! MedlineAsnLoad()) return FALSE; \
+ if (! PubAsnLoad()) return FALSE; \
+ if (! BiblioAsnLoad()) return FALSE; }
diff --git a/network/medarch/client/mdrcherr.h b/network/medarch/client/mdrcherr.h
new file mode 100644
index 00000000..22a24985
--- /dev/null
+++ b/network/medarch/client/mdrcherr.h
@@ -0,0 +1,35 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: mdrcherr.h,v $
+* Revision 6.0 1997/08/25 18:35:37 madden
+* Revision changed to 6.0
+*
+* Revision 5.0 1996/05/28 14:11:11 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:55:12 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.5 1995/05/17 17:54:01 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef __MODULE_medarch__
+#define __MODULE_medarch__
+
+#define ERR_REFERENCE 1,0
+#define ERR_REFERENCE_MuidNotFound 1,1
+#define ERR_REFERENCE_SuccessfulMuidLookup 1,2
+#define ERR_REFERENCE_OldInPress 1,3
+#define ERR_REFERENCE_No_reference 1,4
+#define ERR_REFERENCE_Multiple_ref 1,5
+#define ERR_REFERENCE_Multiple_muid 1,6
+#define ERR_REFERENCE_MedlineMatchIgnored 1,7
+#define ERR_REFERENCE_MuidMissmatch 1,8
+#define ERR_PRINT 2,0
+#define ERR_PRINT_Failed 2,1
+
+#endif
diff --git a/network/medarch/client/medarch.c b/network/medarch/client/medarch.c
new file mode 100644
index 00000000..7a683bc8
--- /dev/null
+++ b/network/medarch/client/medarch.c
@@ -0,0 +1,2194 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: medarch.c
+*
+* Author: Epstein
+*
+* Version Creation Date: 03/31/93
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* API for Medline Archive service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 6/15/93 Epstein Changed Message() to ErrPost() in init function
+* 6/24/93 Epstein Remember to load Pub object loaders in
+* MedArchPubSetCreate().
+* 8/04/93 Epstein Fix Fini() logic to correctly disconnect the service,
+* and fix erroneously-typed returned value.
+* 2/28/96 Grisha Add new function for MRI look up
+* 5/08/96 Grisha Add new functions for PubMed support
+* 3/06/97 volodya Has implemented global functions MedArchGetAccUids(),
+ MedArchGetAccPmids()
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: medarch.c,v $
+* Revision 6.0 1997/08/25 18:35:40 madden
+* Revision changed to 6.0
+*
+* Revision 5.6 1997/06/05 21:34:05 volodya
+* volodya added more comments to MedArchGetAccPmids(), MedArchGetAccUids() description
+*
+* Revision 5.5 1997/06/03 22:07:08 volodya
+* volodya has implemented MedArchGetAccPmids(), MedArchGetAccUids()
+*
+* Revision 5.4 1997/06/03 21:31:22 volodya
+* volodyas has implemented MedArchGetAccUids(), MedArchGetAccPmids() functionality
+*
+* Revision 5.3 1997/04/18 18:27:19 grisha
+* Fixed bug with ASN.1 I/O streams initializations
+*
+ * Revision 5.2 1997/02/11 22:41:47 grisha
+ * Add code and prototypes for support MEDLARS entry
+ *
+ * Revision 5.1 1996/12/17 20:32:30 grisha
+ * update interface to support PubmedEntry
+ *
+ * Revision 5.0 1996/05/28 14:11:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.6 1996/05/10 16:17:15 grisha
+ * Fixed bug with check: MlaBack_error
+ *
+ * Revision 4.5 1996/05/08 22:09:27 grisha
+ * implement Medline Id, PubMed Id conversion functions
+ *
+ * Revision 4.4 1996/05/08 20:58:36 grisha
+ * implement new set of functions for PubMed support
+ *
+ * Revision 4.3 1996/02/28 22:13:51 kans
+ * trivial codewarrior warnings
+ *
+ * Revision 4.2 1996/02/28 21:41:46 grisha
+ * implement function MedArchGetMriUids(), now this function
+ * will call MedArch server for MRI lookup
+ *
+ * Revision 4.1 1996/01/05 21:40:44 grisha
+ * Add prototypes for new functions. MedArchGetMriUids for
+ * MRI lookup and MedArchGetAccUids for accession lookup
+ *
+ * Revision 4.0 1995/07/26 13:55:12 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.15 1995/05/17 17:53:55 epstein
+ * add RCS log revision history
+ *
+*/
+#ifndef __MEDARCHC__
+#define __MEDARCHC__ medarchc
+
+/******************************************************************************/
+/* INCLUDES */
+/******************************************************************************/
+#include <ncbinet.h>
+#include <objmedli.h>
+#include <objpub.h>
+#include <objall.h>
+#include "mapmla.h"
+#include <objmla.h>
+#include <medarch.h>
+
+/******************************************************************************/
+/* DEFINES */
+/******************************************************************************/
+
+/******************************************************************************/
+/* GLOBAL VARIABLES */
+/******************************************************************************/
+MlaRequestPtr mlarp;
+MlaBackPtr mlabp;
+
+/******************************************************************************/
+/* LOCAL VARIABLES */
+/******************************************************************************/
+static NI_HandPtr svcp = NULL;
+static AsnIoPtr asnin = NULL;
+static AsnIoPtr asnout = NULL;
+static Boolean num_attached = 0;
+static Boolean reallyFinal = TRUE;
+static NI_DispatcherPtr dispatcher;
+static Boolean (*myNetInit) PROTO((void));
+
+/******************************************************************************/
+/* LOCAL FUNCTIONS PROTOTYPES */
+/******************************************************************************/
+static MlaBackPtr NetMedArchReadAsn PROTO((
+ void
+ ));
+static Boolean ReestablishNetMedArch PROTO((
+ void
+ ));
+static Boolean GenericReestablishNet PROTO((
+ CharPtr,
+ Boolean
+ ));
+static Boolean NetInit PROTO((
+ void
+ ));
+static Boolean ForceNetInit PROTO((
+ void
+ ));
+static Boolean NetFini PROTO((
+ void
+ ));
+static MedlineEntryPtr s_MedArchMedlineEntryGet PROTO((
+ Int4 /* Medline Id */
+ ));
+static PubmedEntryPtr s_MedArchPubmedEntryGetUid PROTO((
+ Int4 /* PubMed Id */
+ ));
+static PubmedEntryPtr s_MedArchPubmedEntryGetPmId PROTO((
+ Int4 /* PubMed Id */
+ ));
+static MedlarsEntryPtr s_MedArchMedlarsEntryGetUid PROTO((
+ Int4 /* PubMed Id */
+ ));
+static MedlarsEntryPtr s_MedArchMedlarsEntryGetPmId PROTO((
+ Int4 /* PubMed Id */
+ ));
+static MedlineEntryPtr s_MedArchPubSetEntryGet PROTO((
+ Int4, /* Medline Id */
+ MedlineEntryPtr, /* Last Medline entry */
+ AsnIoPtr, /* Client ASN.1 stream */
+ AsnTypePtr /* ASN.1 types */
+ ));
+static PubmedEntryPtr s_MedArchPubSetEntryGetPmId PROTO((
+ Int4, /* PubMed Id */
+ PubmedEntryPtr, /* Last PubMed entry */
+ AsnIoPtr, /* Client ASN.1 stream */
+ AsnTypePtr /* ASN.1 types */
+ ));
+static PubmedEntryPtr s_MedArchPubSetEntryGetUid PROTO((
+ Int4, /* PubMed Id */
+ PubmedEntryPtr, /* Last PubMed entry */
+ AsnIoPtr, /* Client ASN.1 stream */
+ AsnTypePtr /* ASN.1 types */
+ ));
+static ValNodePtr s_MedArchGetPub PROTO((
+ Int4 /* Medline Id */
+ ));
+static ValNodePtr s_MedArchGetPubPmId PROTO((
+ Int4 /* Medline Id */
+ ));
+static Int4 s_MedArchGetTitles PROTO((
+ CharPtr PNTR,
+ Int1Ptr,
+ CharPtr,
+ Int1,
+ Int1,
+ Int4
+ ));
+static Int4 s_MedArchCitMatch PROTO((
+ ValNodePtr
+ ));
+static Int4 s_MedArchCitMatchPmId PROTO((
+ ValNodePtr
+ ));
+static ValNodePtr s_MedArchCitMatchList PROTO((
+ ValNodePtr,
+ Int4Ptr
+ ));
+static ValNodePtr s_MedArchGetMriUids PROTO((
+ Int4
+ ));
+static ValNodePtr s_MedArchGetMriPmids PROTO((
+ Int4
+ ));
+static ValNodePtr s_MedArchGetAccPmids PROTO((
+ Int4 iCode,
+ CharPtr lpAccNum
+ ));
+static ValNodePtr s_MedArchGetAccUids PROTO((
+ Int4 iCode,
+ CharPtr lpAccNum
+ ));
+static Int4 s_MedArchMu2Pm PROTO((
+ Int4
+ ));
+static Int4 s_MedArchPm2Mu PROTO((
+ Int4
+ ));
+
+/******************************************************************************/
+/* LOCAL FUNCTIONS */
+/******************************************************************************/
+
+/******************************************************************************/
+/*.doc NetMedArchReadAsn(internal) */
+/*+
+-*/
+/******************************************************************************/
+static MlaBackPtr
+/*FCN*/NetMedArchReadAsn (void)
+{
+ MlaBackPtr mlabp;
+ short erract;
+ ErrDesc err;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err); /* clear any pending error */
+
+ mlabp = MlaBackAsnRead(asnin, NULL);
+
+ if ( mlabp == NULL ) {
+ ErrPost(CTX_UNKNOWN, 1, "Null message read from server");
+ }
+ ErrSetOpts(erract, 0);
+
+ return mlabp;
+} /* NetMedArchReadAsn() */
+
+/******************************************************************************/
+/*.doc ReestablishNetMedArch(internal) */
+/*+
+-*/
+/******************************************************************************/
+static Boolean
+/*FCN*/ReestablishNetMedArch (void)
+{
+ return GenericReestablishNet("MedArch", TRUE);
+} /* ReestablishNetMedArch() */
+
+/******************************************************************************/
+/*.doc GenericReestablishNet(internal) */
+/*+
+-*/
+/******************************************************************************/
+static Boolean
+/*FCN*/GenericReestablishNet (
+ CharPtr svcName,
+ Boolean showErrs
+){
+ Monitor *mon = NULL;
+ Boolean retval;
+ CharPtr buf;
+
+ buf = (CharPtr)MemNew(2 * StrLen(svcName) + 60);
+
+ if ( showErrs ) {
+ sprintf (buf, "Re-establishing %s Service", svcName);
+ mon = MonitorStrNew(buf, 40);
+ sprintf (buf, "Requesting %s service", svcName);
+ MonitorStrValue(mon, buf);
+ }
+ NetFini();
+ retval = TRUE;
+
+ if ( !myNetInit() ) {
+ sprintf (buf, "%s get failed; re-contacting dispatcher", svcName);
+ MonitorStrValue(mon, buf);
+ retval = FALSE;
+ if ( ForceNetInit() ) {
+ /* successfully established contact w/dispatcher */
+ sprintf (
+ buf,
+ "%s get failed; re-requesting %s service",
+ svcName,
+ svcName
+ );
+ MonitorStrValue(mon, buf);
+ retval = myNetInit();
+ } else {
+ ErrPost(CTX_UNKNOWN, 1, "Unable to re-contact dispatcher");
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+ }
+
+ MonitorFree(mon);
+
+ if ( !retval ) {
+ sprintf (
+ buf,
+ "Unable to re-establish %s service",
+ svcName
+ );
+ ErrPost(CTX_UNKNOWN, 1, buf);
+ if ( showErrs ) {
+ ErrShow();
+ }
+ }
+
+ MemFree((VoidPtr)buf);
+ return retval;
+} /* GenericReestablishNet() */
+
+/******************************************************************************/
+/*.doc (internal) */
+/*+
+-*/
+/******************************************************************************/
+static Boolean
+/*FCN*/NetInit(void)
+{
+ if ( num_attached++ > 0 ) {
+ return TRUE;
+ }
+
+ if ( (dispatcher = NI_GenericInit (
+ NULL,
+ NULL,
+ TRUE,
+ NULL,
+ 0
+ )) != NULL ) {
+ return TRUE;
+ }
+
+ return FALSE;
+} /* NetInit() */
+
+/******************************************************************************/
+/*.doc ForceNetInit(internal) */
+/*+
+-*/
+/******************************************************************************/
+static Boolean
+/*FCN*/ForceNetInit (void)
+{
+ Boolean retval;
+
+ reallyFinal = FALSE;
+ num_attached = 0; /* force re-attempt to contact dispatcher */
+ retval = NetInit();
+ reallyFinal = TRUE;
+
+ return retval;
+} /* ForceNetInit() */
+
+/******************************************************************************/
+/*.doc NetFini(internal) */
+/*+
+-*/
+/******************************************************************************/
+static Boolean
+/*FCN*/NetFini (void)
+{
+ if ( num_attached > 0 ) {
+ num_attached--;
+ }
+
+ if ( num_attached == 0 ) {
+ NI_ServiceDisconnect (svcp);
+ svcp = NULL;
+ NI_EndServices (dispatcher);
+ dispatcher = NULL;
+ }
+
+ return TRUE;
+} /* NetFini() */
+
+/******************************************************************************/
+/*.doc s_MedArchFini(internal) */
+/*+
+ Create FINI request and send to MedArch server, terminate
+ network connection.
+-*/
+/******************************************************************************/
+static Boolean
+/*FCN*/s_MedArchFini (void)
+{
+ Boolean retval = TRUE;
+
+ if ( asnout != NULL && asnin != NULL ) {
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_fini;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset(asnout);
+ MlaRequestFree (mlarp);
+
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ retval = FALSE;
+ } else {
+ mlabp->data.ptrvalue = NULL;
+ MlaBackFree (mlabp);
+ }
+ }
+
+ NetFini();
+
+ return retval;
+} /* s_MedArchFini() */
+
+/******************************************************************************/
+/*.doc s_MedArchMedlineEntryGet(internal) */
+/*+
+ Generate request: Get Medline Article using Medline Id, return
+ pointer to Medline entry. Return NULL if article not found or
+ some errors found.
+-*/
+/******************************************************************************/
+static MedlineEntryPtr
+/*FCN*/s_MedArchMedlineEntryGet (
+ Int4 uid
+){
+ MlaRequestPtr mlarp;
+ MedlineEntryPtr mep;
+
+ /* create request object */
+ mlarp = ValNodeNew(NULL); /* allocate node */
+ mlarp->choice = MlaRequest_getmle; /* request type */
+ mlarp->data.intvalue = uid; /* Medline id */
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to MedArch */
+ AsnIoReset(asnout); /* fush output stream */
+ MlaRequestFree (mlarp); /* free request */
+
+ /* result processing */
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return NULL;
+ }
+
+ if ( mlabp->choice != MlaBack_getmle ) {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+
+ mep = (MedlineEntryPtr) (mlabp->data.ptrvalue);
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return mep;
+} /* s_MedArchMedlineEntryGet() */
+
+/******************************************************************************/
+/*.doc s_MedArchPubmedEntryGetPmId(internal) */
+/*+
+ Generate request: Get Medline Article using PubMed Id, return
+ pointer to PubMed entry. Return NULL if article not found or
+ some errors found.
+-*/
+/******************************************************************************/
+static PubmedEntryPtr
+/*FCN*/s_MedArchPubmedEntryGetPmId (
+ Int4 pmid
+){
+ MlaRequestPtr mlarp;
+ PubmedEntryPtr mep;
+
+ /* create request object */
+ mlarp = ValNodeNew(NULL); /* allocate node */
+ mlarp->choice = MlaRequest_getmlepmid; /* request type */
+ mlarp->data.intvalue = pmid; /* PubMed id */
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to MedArch */
+ AsnIoReset(asnout); /* fush output stream */
+ MlaRequestFree (mlarp); /* free request */
+
+ /* result processing */
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return NULL;
+ }
+
+ if ( mlabp->choice != MlaBack_getpme ) {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+
+ mep = (PubmedEntryPtr) (mlabp->data.ptrvalue);
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return mep;
+} /* s_MedArchPubmedEntryGetPmId() */
+
+/******************************************************************************/
+/*.doc s_MedArchPubmedEntryGetUid(internal) */
+/*+
+ Generate request: Get Medline Article using PubMed Id, return
+ pointer to PubMed entry. Return NULL if article not found or
+ some errors found.
+-*/
+/******************************************************************************/
+static PubmedEntryPtr
+/*FCN*/s_MedArchPubmedEntryGetUid (
+ Int4 pmid
+){
+ MlaRequestPtr mlarp;
+ PubmedEntryPtr mep;
+
+ /* create request object */
+ mlarp = ValNodeNew(NULL); /* allocate node */
+ mlarp->choice = MlaRequest_getmleuid; /* request type */
+ mlarp->data.intvalue = pmid; /* PubMed id */
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to MedArch */
+ AsnIoReset(asnout); /* fush output stream */
+ MlaRequestFree (mlarp); /* free request */
+
+ /* result processing */
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return NULL;
+ }
+
+ if ( mlabp->choice != MlaBack_getpme ) {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+
+ mep = (PubmedEntryPtr) (mlabp->data.ptrvalue);
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return mep;
+} /* s_MedArchPubmedEntryGetUid() */
+
+/******************************************************************************/
+/*.doc s_MedArchMedlarsEntryGetPmId(internal) */
+/*+
+ Generate request: Get MEDLARS entry using PubMed Id, return
+ pointer to Medlars entry. Return NULL if article not found or
+ some errors found.
+-*/
+/******************************************************************************/
+static MedlarsEntryPtr
+/*FCN*/s_MedArchMedlarsEntryGetPmId (
+ Int4 pmid
+){
+ MlaRequestPtr mlarp;
+ MedlarsEntryPtr mep;
+
+ /* create request object */
+ mlarp = ValNodeNew(NULL); /* allocate node */
+ mlarp->choice = MlaRequest_getmlrpmid; /* request type */
+ mlarp->data.intvalue = pmid; /* PubMed id */
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to MedArch */
+ AsnIoReset(asnout); /* fush output stream */
+ MlaRequestFree (mlarp); /* free request */
+
+ /* result processing */
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return NULL;
+ }
+
+ if ( mlabp->choice != MlaBack_getmlr ) {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+
+ mep = (MedlarsEntryPtr) (mlabp->data.ptrvalue);
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return mep;
+} /* s_MedArchMedlarsEntryGetPmId() */
+
+/******************************************************************************/
+/*.doc s_MedArchMedlarsEntryGetUid(internal) */
+/*+
+ Generate request: Get MEDLARS entry using PubMed Id, return
+ pointer to Medlars entry. Return NULL if article not found or
+ some errors found.
+-*/
+/******************************************************************************/
+static MedlarsEntryPtr
+/*FCN*/s_MedArchMedlarsEntryGetUid (
+ Int4 pmid
+){
+ MlaRequestPtr mlarp;
+ MedlarsEntryPtr mep;
+
+ /* create request object */
+ mlarp = ValNodeNew(NULL); /* allocate node */
+ mlarp->choice = MlaRequest_getmlruid; /* request type */
+ mlarp->data.intvalue = pmid; /* PubMed id */
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to MedArch */
+ AsnIoReset(asnout); /* fush output stream */
+ MlaRequestFree (mlarp); /* free request */
+
+ /* result processing */
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return NULL;
+ }
+
+ if ( mlabp->choice != MlaBack_getmlr ) {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+
+ mep = (MedlarsEntryPtr) (mlabp->data.ptrvalue);
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return mep;
+} /* s_MedArchMedlarsEntryGetUid() */
+
+/******************************************************************************/
+/*.doc s_MedArchPubSetEntryGet(internal) */
+/*+
+ This function read Medline entry from MedArch and write
+ last entry while waiting for MedArch answer.
+-*/
+/******************************************************************************/
+static MedlineEntryPtr
+/*FCN*/s_MedArchPubSetEntryGet (
+ Int4 uid,
+ MedlineEntryPtr lastmep,
+ AsnIoPtr aip,
+ AsnTypePtr atp
+){
+ MlaRequestPtr mlarp;
+ MedlineEntryPtr mep;
+
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_getmle;
+ mlarp->data.intvalue = uid;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset (asnout);
+ MlaRequestFree (mlarp);
+
+ /* write the caller's last entry to a file while waiting
+ for the server to compute and send the answer for the
+ current entry
+ */
+ if ( lastmep != NULL && aip != NULL ) {
+ MedlineEntryAsnWrite (lastmep, aip, atp);
+ }
+
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return NULL;
+ }
+
+ if ( mlabp->choice != MlaBack_getmle ) {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+
+ mep = (MedlineEntryPtr) (mlabp->data.ptrvalue);
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return mep;
+} /* s_MedArchPubSetEntryGet() */
+
+/******************************************************************************/
+/*.doc s_MedArchPubSetEntryGetPmId(internal) */
+/*+
+ This function read Medline entry from MedArch and write
+ last entry while waiting for MedArch answer.
+-*/
+/******************************************************************************/
+static PubmedEntryPtr
+/*FCN*/s_MedArchPubSetEntryGetPmId (
+ Int4 pmid,
+ PubmedEntryPtr lastmep,
+ AsnIoPtr aip,
+ AsnTypePtr atp
+){
+ MlaRequestPtr mlarp;
+ PubmedEntryPtr mep;
+
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_getmlepmid;
+ mlarp->data.intvalue = pmid;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset (asnout);
+ MlaRequestFree (mlarp);
+
+ /* write the caller's last entry to a file while waiting
+ for the server to compute and send the answer for the
+ current entry
+ */
+ if ( lastmep != NULL && aip != NULL ) {
+ PubmedEntryAsnWrite (lastmep, aip, atp);
+ }
+
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return NULL;
+ }
+
+ if ( mlabp->choice != MlaBack_getpme ) {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+
+ mep = (PubmedEntryPtr) (mlabp->data.ptrvalue);
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return mep;
+} /* s_MedArchPubSetEntryGetPmId() */
+
+/******************************************************************************/
+/*.doc s_MedArchPubSetEntryGetUid(internal) */
+/*+
+ This function read Medline entry from MedArch and write
+ last entry while waiting for MedArch answer.
+-*/
+/******************************************************************************/
+static PubmedEntryPtr
+/*FCN*/s_MedArchPubSetEntryGetUid (
+ Int4 pmid,
+ PubmedEntryPtr lastmep,
+ AsnIoPtr aip,
+ AsnTypePtr atp
+){
+ MlaRequestPtr mlarp;
+ PubmedEntryPtr mep;
+
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_getmleuid;
+ mlarp->data.intvalue = pmid;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset (asnout);
+ MlaRequestFree (mlarp);
+
+ /* write the caller's last entry to a file while waiting
+ for the server to compute and send the answer for the
+ current entry
+ */
+ if ( lastmep != NULL && aip != NULL ) {
+ PubmedEntryAsnWrite (lastmep, aip, atp);
+ }
+
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return NULL;
+ }
+
+ if ( mlabp->choice != MlaBack_getpme ) {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+
+ mep = (PubmedEntryPtr) (mlabp->data.ptrvalue);
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return mep;
+} /* s_MedArchPubSetEntryGetUid() */
+
+/******************************************************************************/
+/*.doc s_MedArchGetPub(internal) */
+/*+
+ This function read Citation definition for selected entry using
+ Medline Id.
+-*/
+/******************************************************************************/
+static ValNodePtr
+/*FCN*/s_MedArchGetPub (
+ Int4 uid /* Medline Id */
+){
+ MlaRequestPtr mlarp;
+ ValNodePtr pub;
+
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_getpub;
+ mlarp->data.intvalue = uid;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset(asnout);
+ MlaRequestFree (mlarp);
+
+ if ((mlabp = NetMedArchReadAsn()) == NULL)
+ return NULL;
+
+ if (mlabp->choice != MlaBack_getpub)
+ {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+ pub = (ValNodePtr)mlabp->data.ptrvalue;
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return pub;
+} /* s_MedArchGetPub() */
+
+/******************************************************************************/
+/*.doc s_MedArchGetPubPmId(internal) */
+/*+
+ This function read Citation definition for selected entry using
+ PubMed Id.
+-*/
+/******************************************************************************/
+static ValNodePtr
+/*FCN*/s_MedArchGetPubPmId (
+ Int4 pmid /* PubMed Id */
+){
+ MlaRequestPtr mlarp;
+ ValNodePtr pub;
+
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_getpubpmid;
+ mlarp->data.intvalue = pmid;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset(asnout);
+ MlaRequestFree (mlarp);
+
+ if ((mlabp = NetMedArchReadAsn()) == NULL)
+ return NULL;
+
+ if (mlabp->choice != MlaBack_getpub)
+ {
+ MlaBackFree (mlabp);
+ return NULL;
+ }
+ pub = (ValNodePtr)mlabp->data.ptrvalue;
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp);
+
+ return pub;
+} /* s_MedArchGetPubPmId() */
+
+/******************************************************************************/
+/*.doc s_MedArchGetTitles(internal) */
+/*+
+-*/
+/******************************************************************************/
+static Int4
+/*FCN*/s_MedArchGetTitles (
+ CharPtr PNTR titles_found,
+ Int1Ptr title_types_found,
+ CharPtr title_to_lookup,
+ Int1 request_type,
+ Int1 response_type,
+ Int4 max_titles_to_find
+){
+ MlaRequestPtr mlarp;
+ TitleMsgPtr tmsgp;
+ TitleMsgListPtr tmlp;
+ Int4 i;
+
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_gettitle;
+ tmsgp = TitleMsgNew();
+ tmsgp->type = response_type;
+ tmsgp->title = ValNodeNew(NULL);
+ tmsgp->title->choice = request_type;
+ tmsgp->title->data.ptrvalue = (Pointer) StringSave(title_to_lookup);
+ mlarp->data.ptrvalue = (Pointer) tmsgp;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset(asnout);
+ MlaRequestFree (mlarp);
+
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return 0;
+ }
+
+ if ( mlabp->choice != MlaBack_gettitle ) {
+ MlaBackFree (mlabp);
+ return 0;
+ }
+
+ if ( (tmlp = (TitleMsgListPtr)mlabp->data.ptrvalue) == NULL ) {
+ MlaBackFree (mlabp);
+ return 0;
+ }
+
+ for ( i = 0, tmsgp = tmlp->titles;
+ i < max_titles_to_find
+ && tmlp != NULL
+ && i < tmlp->num;
+ i++, tmsgp = tmsgp->next ) {
+ titles_found[i] = (CharPtr) tmsgp->title->data.ptrvalue;
+ tmsgp->title->data.ptrvalue = NULL; /* for clean free */
+ title_types_found[i] = (Int1) tmsgp->type;
+ }
+ MlaBackFree (mlabp);
+
+ return i;
+} /* s_MedArchGetTitles() */
+
+/******************************************************************************/
+/*.doc s_MedArchCitMatch(internal) */
+/*+
+-*/
+/******************************************************************************/
+static Int4
+/*FCN*/s_MedArchCitMatch (
+ ValNodePtr pub
+){
+ MlaRequestPtr mlarp;
+ Int4 uid;
+
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_citmatch;
+ mlarp->data.ptrvalue = pub;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset(asnout);
+ mlarp->data.ptrvalue = NULL; /* for clean free */
+ MlaRequestFree (mlarp);
+
+ if ((mlabp = NetMedArchReadAsn()) == NULL)
+ return 0;
+
+ if (mlabp->choice != MlaBack_citmatch)
+ {
+ MlaBackFree (mlabp);
+ return 0;
+ }
+ uid = mlabp->data.intvalue;
+ MlaBackFree (mlabp);
+
+ return uid;
+} /* s_MedArchCitMatch() */
+
+/******************************************************************************/
+/*.doc s_MedArchCitMatchPmId(internal) */
+/*+
+-*/
+/******************************************************************************/
+static Int4
+/*FCN*/s_MedArchCitMatchPmId (
+ ValNodePtr pub
+){
+ MlaRequestPtr mlarp;
+ Int4 pmid;
+
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_citmatchpmid;
+ mlarp->data.ptrvalue = pub;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset(asnout);
+ mlarp->data.ptrvalue = NULL; /* for clean free */
+ MlaRequestFree (mlarp);
+
+ if ((mlabp = NetMedArchReadAsn()) == NULL)
+ return 0;
+
+ if (mlabp->choice != MlaBack_citmatch)
+ {
+ MlaBackFree (mlabp);
+ return 0;
+ }
+ pmid = mlabp->data.intvalue;
+ MlaBackFree (mlabp);
+
+ return pmid;
+} /* s_MedArchCitMatchPmId() */
+
+/******************************************************************************/
+/*.doc s_MedArchCitMatchList(internal) */
+/*+
+ This function send request '' to MedArch server and recive result
+ list. It set up error code in case some error found.
+-*/
+/******************************************************************************/
+static ValNodePtr
+/*FCN*/s_MedArchCitMatchList (
+ ValNodePtr pub,
+ Int4Ptr pErrCode
+){
+ MlaRequestPtr mlarp;
+ register ValNodePtr pPmIdList = NULL; /* result PubMed ID list */
+
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_citlstpmids;
+ mlarp->data.ptrvalue = pub;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset(asnout);
+ mlarp->data.ptrvalue = NULL; /* for clean free */
+ MlaRequestFree (mlarp);
+
+ if ((mlabp = NetMedArchReadAsn()) == NULL) {
+ *pErrCode = Error_val_operational_error;
+ return NULL;
+ }
+
+ if ( mlabp->choice == MlaBack_getpmids ) { /* must be PubMed ID list */
+ pPmIdList = (ValNodePtr)mlabp->data.ptrvalue; /* get Medline list */
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ *pErrCode = 0;
+ } else if ( mlabp->choice == MlaBack_error ) {
+ *pErrCode = mlabp->data.intvalue;
+ } else {
+ *pErrCode = Error_val_operational_error;
+ }
+
+ MlaBackFree (mlabp); /* free result */
+
+ return pPmIdList;
+} /* s_MedArchCitMatchList() */
+
+/******************************************************************************/
+/*.doc s_MedArchGetMriUids(internal) */
+/*+
+ This function call MedArch server and send MRI code, it recive
+ list of Medline ID. Return NULL if where are no articles in
+ selected MRI or if some error found.
+-*/
+/******************************************************************************/
+static
+ValNodePtr s_MedArchGetMriUids (
+ Int4 mri /* Journal MRI code (I) */
+){
+ MlaRequestPtr mlarp; /* to build request object */
+ ValNodePtr pub = NULL; /* result */
+
+ mlarp = ValNodeNew(NULL); /* create request node */
+ mlarp->choice = MlaRequest_getmriuids; /* request code MRI lookup */
+ mlarp->data.intvalue = mri; /* journal MRI code */
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to request server */
+ AsnIoReset(asnout); /* reset ASN out buffer */
+ MlaRequestFree (mlarp); /* do not need request node */
+
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) { /* try to read result */
+ return NULL; /* error */
+ }
+
+ if ( mlabp->choice != MlaBack_getuids ) { /* must be Medline ID list */
+ MlaBackFree (mlabp); /* free result */
+ return NULL; /* error */
+ }
+
+ pub = (ValNodePtr)mlabp->data.ptrvalue; /* get Medline list */
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp); /* free result */
+
+ return pub;
+} /* s_MedArchGetMriUids() */
+
+/******************************************************************************/
+/*.doc s_MedArchGetMriPmids(internal) */
+/*+
+ This function call MedArch server and send MRI code, it recive
+ list of Medline ID. Return NULL if where are no articles in
+ selected MRI or if some error found.
+-*/
+/******************************************************************************/
+static
+ValNodePtr s_MedArchGetMriPmids (
+ Int4 mri /* Journal MRI code (I) */
+){
+ MlaRequestPtr mlarp; /* to build request object */
+ ValNodePtr pub = NULL; /* result */
+
+ mlarp = ValNodeNew(NULL); /* create request node */
+ mlarp->choice = MlaRequest_getmripmids; /* request code MRI lookup */
+ mlarp->data.intvalue = mri; /* journal MRI code */
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to request server */
+ AsnIoReset(asnout); /* reset ASN out buffer */
+ MlaRequestFree (mlarp); /* do not need request node */
+
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) { /* try to read result */
+ return NULL; /* error */
+ }
+
+ if ( mlabp->choice != MlaBack_getuids ) { /* must be Medline ID list */
+ MlaBackFree (mlabp); /* free result */
+ return NULL; /* error */
+ }
+
+ pub = (ValNodePtr)mlabp->data.ptrvalue; /* get Medline list */
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp); /* free result */
+
+ return pub;
+} /* s_MedArchGetMriPmids() */
+
+/******************************************************************************/
+/*.doc s_MedArchGetAccUids(internal) */
+/*+
+ This function call MedArch server and sends accession/xref code, it recives
+ list of Medline IDs. plAccNum is an optional argument in accordance with
+ Medline-si definition. Set it to NULL if accession code is unknown.
+ It returns NULL if there are no entries found or if some error occured.
+-*/
+/******************************************************************************/
+static
+ValNodePtr s_MedArchGetAccUids (
+ Int4 iCode, /* Type of xref (I) */
+ CharPtr lpAccNum /* The citation/accession number (I) */
+){
+ MlaRequestPtr mlarp; /* to build request object */
+ ValNodePtr pub = NULL; /* result */
+
+ mlarp = ValNodeNew(NULL); /* create request node */
+ mlarp->choice = MlaRequest_getaccuids; /* request code MRI lookup */
+ mlarp->data.ptrvalue = ValNodeNew(NULL); /* Medline-si structure */
+ ((ValNodePtr)mlarp->data.ptrvalue)->choice = iCode;
+ ((ValNodePtr)mlarp->data.ptrvalue)->data.ptrvalue =
+ (Nlm_VoidPtr)(lpAccNum == NULL ? NULL : StringSave(lpAccNum));
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to request server */
+ AsnIoReset(asnout); /* reset ASN out buffer */
+ MlaRequestFree (mlarp); /* do not need request node */
+
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) { /* try to read result */
+ return NULL; /* error */
+ }
+
+ if ( mlabp->choice != MlaBack_getuids ) { /* must be Medline ID list */
+ MlaBackFree (mlabp); /* free result */
+ return NULL; /* error */
+ }
+
+ pub = (ValNodePtr)mlabp->data.ptrvalue; /* get Medline list */
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp); /* free result */
+
+ return pub;
+} /* s_MedArchGetAccUids() */
+
+/******************************************************************************/
+/*.doc s_MedArchGetAccPmids(internal) */
+/*+
+ This function call MedArch server and sends accession/xref code, it recives
+ list of PubMed IDs.
+ plAccNum is an optional argument in accordance with
+ Medline-si definition. Set it to NULL if accession code is unknown.
+ It returns NULL if there are no entries found or if some error occured.
+ -*/
+/******************************************************************************/
+static
+ValNodePtr s_MedArchGetAccPmids (
+ Int4 iCode, /* Type of xref (I) */
+ CharPtr lpAccNum /* The citation/accession number (I) */
+){
+ MlaRequestPtr mlarp; /* to build request object */
+ ValNodePtr pub = NULL; /* result */
+
+ mlarp = ValNodeNew(NULL); /* create request node */
+ mlarp->choice = MlaRequest_getaccpmids; /* request code PmId lookup */
+ mlarp->data.ptrvalue = ValNodeNew(NULL); /* Medline-si structure */
+ ((ValNodePtr)mlarp->data.ptrvalue)->choice = iCode;
+ ((ValNodePtr)mlarp->data.ptrvalue)->data.ptrvalue =
+ (Nlm_VoidPtr)(lpAccNum == NULL ? NULL : StringSave(lpAccNum));
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to request server */
+ AsnIoReset(asnout); /* reset ASN out buffer */
+ MlaRequestFree (mlarp); /* do not need request node */
+
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) { /* try to read result */
+ return NULL; /* error */
+ }
+
+ if ( mlabp->choice != MlaBack_getpmids ) { /* must be Pm ID list */
+ MlaBackFree (mlabp); /* free result */
+ return NULL; /* error */
+ }
+
+ pub = (ValNodePtr)mlabp->data.ptrvalue; /* get Medline list */
+ mlabp->data.ptrvalue = NULL; /* for clean free */
+ MlaBackFree (mlabp); /* free result */
+
+ return pub;
+} /* s_MedArchGetAccPmids() */
+
+/******************************************************************************/
+/*.doc s_MedArchMu2Pm(internal) */
+/*+
+ This function generate request to MedArch server for
+ convert Medline Id to PubMed Id
+-*/
+/******************************************************************************/
+static Int4
+/*FCN*/s_MedArchMu2Pm (
+ Int4 uid
+){
+ MlaRequestPtr mlarp;
+ Int4 pmid;
+
+ /* create request object */
+ mlarp = ValNodeNew(NULL); /* allocate node */
+ mlarp->choice = MlaRequest_uidtopmid; /* request type */
+ mlarp->data.intvalue = uid; /* Medline id */
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to MedArch */
+ AsnIoReset(asnout); /* fush output stream */
+ MlaRequestFree (mlarp); /* free request */
+
+ /* result processing */
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return 0;
+ }
+
+ if ( mlabp->choice != MlaBack_outpmid ) {
+ MlaBackFree (mlabp);
+ return 0;
+ }
+ pmid = mlabp->data.intvalue;
+ MlaBackFree (mlabp);
+
+ return pmid;
+} /* s_MedArchMu2Pm() */
+
+/******************************************************************************/
+/*.doc s_MedArchMu2Pm(internal) */
+/*+
+ This function generate request to MedArch server for
+ convert PubMed Id to Medline Id
+-*/
+/******************************************************************************/
+static Int4
+/*FCN*/s_MedArchPm2Mu (
+ Int4 pmid
+){
+ MlaRequestPtr mlarp;
+ Int4 uid;
+
+ /* create request object */
+ mlarp = ValNodeNew(NULL); /* allocate node */
+ mlarp->choice = MlaRequest_pmidtouid; /* request type */
+ mlarp->data.intvalue = pmid; /* Medline id */
+ MlaRequestAsnWrite (mlarp, asnout, NULL); /* send to MedArch */
+ AsnIoReset(asnout); /* fush output stream */
+ MlaRequestFree (mlarp); /* free request */
+
+ /* result processing */
+ if ( (mlabp = NetMedArchReadAsn()) == NULL ) {
+ return 0;
+ }
+
+ if ( mlabp->choice != MlaBack_outuid ) {
+ MlaBackFree (mlabp);
+ return 0;
+ }
+ uid = mlabp->data.intvalue;
+ MlaBackFree (mlabp);
+
+ return uid;
+} /* s_MedArchPm2Mu() */
+
+/******************************************************************************/
+/* GLOBAL FUNCTIONS */
+/******************************************************************************/
+
+/******************************************************************************/
+/*.doc MedArchInit(external) */
+/*+
+ Create INIT request and send to MedArch server
+-*/
+/******************************************************************************/
+Boolean
+/*FCN*/MedArchInit (void)
+{
+ myNetInit = MedArchInit;
+
+ asnin = NULL; /* reset I/O streams */
+ asnout = NULL;
+
+ if ( !NetInit() ) { /* try init network */
+ return FALSE;
+ }
+
+ /* make connection with MedArch */
+ if ( (svcp = NI_GenericGetService (
+ dispatcher,
+ NULL,
+ "MED_ARCH",
+ "MedArch",
+ TRUE
+ )) == NULL ) {
+ ErrPostEx ( /* report error */
+ SEV_ERROR,
+ 0,
+ 0,
+ "NI_ServiceGet [%s] (%s)",
+ ni_errlist[ni_errno],
+ ni_errtext
+ );
+ MedArchFini();
+ return FALSE;
+ }
+
+ asnin = svcp->raip;
+ asnout = svcp->waip;
+
+ /* generate INIT request and send to MedArch server */
+ mlarp = ValNodeNew(NULL);
+ mlarp->choice = MlaRequest_init;
+ MlaRequestAsnWrite (mlarp, asnout, NULL);
+ AsnIoReset(asnout);
+ MlaRequestFree (mlarp);
+
+ if ( (mlabp = NetMedArchReadAsn()) != NULL ) {
+ mlabp->data.ptrvalue = NULL;
+ MlaBackFree (mlabp);
+ return TRUE;
+ }
+
+ return FALSE;
+} /* MedArchInit() */
+
+/******************************************************************************/
+/*.doc MedArchFini(external) */
+/*+
+ The only thing done here is to suppress errors, plus call
+ function s_MedArchFini() to real discoonnect.
+-*/
+/******************************************************************************/
+Boolean
+/*FCN*/MedArchFini (void)
+{
+ short erract;
+ ErrDesc err;
+ Boolean retval;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ retval = s_MedArchFini();
+
+ ErrSetOpts(erract, 0);
+ ErrFetch(&err);
+
+ return retval;
+} /* MedArchFini() */
+
+/******************************************************************************/
+/*.doc MedArchMedlineEntryListGet(external) */
+/*+
+ This function generate list of Medline entries using Medline Id,
+ return number of result entries.
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchMedlineEntryListGet (
+ MedlineEntryPtr PNTR result,
+ Int4 numuid,
+ Int4Ptr uids,
+ Boolean mark_missing
+){
+ Int4 i;
+ Int4 j;
+ MedlineEntryPtr mep;
+ short erract;
+ ErrDesc err;
+ Int4 retval = 0;
+
+ for (j = 0; j < numuid; j++) {
+ for ( i = 0; i < MEDARCH_SERV_RETRIES; i++ ) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ mep = s_MedArchMedlineEntryGet (uids[j]);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ break; /* success */
+ }
+ result[j] = mep;
+ if ( mep != NULL ) {
+ retval++;
+ } else {
+ if ( mark_missing ) {
+ uids[j] *= -1;
+ }
+ }
+ }
+
+ return retval;
+} /* MedArchMedlineEntryListGet() */
+
+/******************************************************************************/
+/*.doc MedArchMedlineEntryGet(external) */
+/*+
+ This function generate single Medline entry using Medline Id,
+ return pointer to Medline entry and NULL if some errors found.
+-*/
+/******************************************************************************/
+MedlineEntryPtr
+/*FCN*/MedArchMedlineEntryGet (
+ Int4 uid
+){
+ MedlineEntryPtr mep = NULL;
+
+ MedArchMedlineEntryListGet (&mep, 1, &uid, FALSE);
+
+ return mep;
+} /* MedArchMedlineEntryGet() */
+
+/******************************************************************************/
+/*.doc MedArchPubmedEntryListGetPmId(external) */
+/*+
+ This function generate list of PubMed entries using PubMed Id,
+ return number of result entries.
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchPubmedEntryListGetPmId (
+ PubmedEntryPtr PNTR result,
+ Int4 numpmid,
+ Int4Ptr pmids,
+ Boolean mark_missing
+){
+ Int4 i;
+ Int4 j;
+ PubmedEntryPtr mep;
+ short erract;
+ ErrDesc err;
+ Int4 retval = 0;
+
+ for (j = 0; j < numpmid; j++) {
+ for ( i = 0; i < MEDARCH_SERV_RETRIES; i++ ) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ mep = s_MedArchPubmedEntryGetPmId (pmids[j]);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ break; /* success */
+ }
+ result[j] = mep;
+ if ( mep != NULL ) {
+ retval++;
+ } else {
+ if ( mark_missing ) {
+ pmids[j] *= -1;
+ }
+ }
+ }
+
+ return retval;
+} /* MedArchPubmedEntryListGetPmId() */
+
+/******************************************************************************/
+/*.doc MedArchPubmedEntryGetPmId(external) */
+/*+
+ This function generate single PubMed entry using Medline Id,
+ return pointer to PubMed entry and NULL if some errors found.
+-*/
+/******************************************************************************/
+PubmedEntryPtr
+/*FCN*/MedArchPubmedEntryGetPmId (
+ Int4 pmid
+){
+ PubmedEntryPtr mep = NULL;
+
+ MedArchPubmedEntryListGetPmId (&mep, 1, &pmid, FALSE);
+
+ return mep;
+} /* MedArchPubmedEntryGetPmId() */
+
+/******************************************************************************/
+/*.doc MedArchPubmedEntryListGetUid(external) */
+/*+
+ This function generate list of PubMed entries using PubMed Id,
+ return number of result entries.
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchPubmedEntryListGetUid (
+ PubmedEntryPtr PNTR result,
+ Int4 numpmid,
+ Int4Ptr pmids,
+ Boolean mark_missing
+){
+ Int4 i;
+ Int4 j;
+ PubmedEntryPtr mep;
+ short erract;
+ ErrDesc err;
+ Int4 retval = 0;
+
+ for (j = 0; j < numpmid; j++) {
+ for ( i = 0; i < MEDARCH_SERV_RETRIES; i++ ) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ mep = s_MedArchPubmedEntryGetUid (pmids[j]);
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ break; /* success */
+ }
+ result[j] = mep;
+ if ( mep != NULL ) {
+ retval++;
+ } else {
+ if ( mark_missing ) {
+ pmids[j] *= -1;
+ }
+ }
+ }
+
+ return retval;
+} /* MedArchPubmedEntryListGetUid() */
+
+/******************************************************************************/
+/*.doc MedArchPubmedEntryGetUid(external) */
+/*+
+ This function generate single PubMed entry using Medline Id,
+ return pointer to PubMed entry and NULL if some errors found.
+-*/
+/******************************************************************************/
+PubmedEntryPtr
+/*FCN*/MedArchPubmedEntryGetUid (
+ Int4 pmid
+){
+ PubmedEntryPtr mep = NULL;
+
+ MedArchPubmedEntryListGetUid (&mep, 1, &pmid, FALSE);
+
+ return mep;
+} /* MedArchPubmedEntryGetUid() */
+
+/******************************************************************************/
+/*.doc MedArchPubSetCreate(external) */
+/*+
+ This function generate PubSet using list of Medline Id
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchPubSetCreate (
+ AsnIoPtr aip,
+ Int4 numuid,
+ Int4Ptr uids,
+ Boolean mark_missing
+){
+ static Boolean alreadyInited = FALSE;
+ AsnTypePtr startAtp;
+ AsnTypePtr pubSetAtp;
+ AsnTypePtr pubSetEAtp;
+ AsnModulePtr amp;
+ Int4 j;
+ Int4 i;
+ MedlineEntryPtr mep;
+ MedlineEntryPtr lastmep = NULL;
+ Int4 retval = 0;
+ short erract;
+ ErrDesc err;
+
+ if ( !alreadyInited ) {
+ if ( !PubAsnLoad() ) {
+ return 0;
+ }
+ amp = AsnAllModPtr();
+ if ( amp == NULL ) {
+ return 0;
+ }
+ alreadyInited = TRUE;
+ startAtp = AsnTypeFind(amp, "Pub-set");
+ pubSetAtp = AsnTypeFind(amp, "Pub-set.medline");
+ pubSetEAtp = AsnTypeFind(amp, "Pub-set.medline.E");
+ if ( startAtp == NULL
+ || pubSetAtp == NULL
+ || pubSetEAtp == NULL ) {
+ return 0;
+ }
+ }
+
+ AsnWrite (aip, startAtp, NULL);
+ AsnStartStruct (aip, pubSetAtp);
+
+ for (j = 0; j < numuid; j++) {
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ mep = s_MedArchPubSetEntryGet (
+ uids[j],
+ lastmep,
+ aip,
+ pubSetEAtp
+ );
+ MedlineEntryFree (lastmep); /* do not need any more */
+ lastmep = NULL;
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+ lastmep = mep;
+ if ( mep != NULL ) {
+ retval++;
+ } else {
+ if ( mark_missing ) {
+ uids[j] *= -1;
+ }
+ }
+ }
+
+ if ( lastmep != NULL ) { /* write final entry */
+ MedlineEntryAsnWrite (lastmep, aip, pubSetEAtp);
+ MedlineEntryFree (lastmep);
+ }
+
+ AsnEndStruct (aip, pubSetAtp);
+
+ return retval;
+} /* MedArchPubSetCreate() */
+
+/******************************************************************************/
+/*.doc MedArchPubSetCreatePmId(external) */
+/*+
+ This function generate PubSet using list of PubMed Id
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchPubSetCreatePmId (
+ AsnIoPtr aip,
+ Int4 numpmid,
+ Int4Ptr pmids,
+ Boolean mark_missing
+){
+ return 0;
+} /* MedArchPubSetCreatePmId() */
+
+/******************************************************************************/
+/*.doc MedArchPubSetCreateUid(external) */
+/*+
+ This function generate PubSet using list of PubMed Id
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchPubSetCreateUid (
+ AsnIoPtr aip,
+ Int4 numpmid,
+ Int4Ptr pmids,
+ Boolean mark_missing
+){
+ return 0;
+} /* MedArchPubSetCreateUid() */
+
+/******************************************************************************/
+/*.doc MedArchGetPub(external) */
+/*+
+ This function generate single citation using Medline Id
+-*/
+/******************************************************************************/
+ValNodePtr
+/*FCN*/MedArchGetPub (
+ Int4 uid
+){
+ ValNodePtr retval = NULL;
+ Int4 i;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ retval = s_MedArchGetPub(uid);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return retval;
+} /* MedArchGetPub() */
+
+/******************************************************************************/
+/*.doc MedArchGetPubPmId(external) */
+/*+
+ This function generate single citation using PubMed Id
+-*/
+/******************************************************************************/
+ValNodePtr
+/*FCN*/MedArchGetPubPmId (
+ Int4 pmid
+){
+ ValNodePtr retval = NULL;
+ Int4 i;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ retval = s_MedArchGetPubPmId(pmid);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return retval;
+} /* MedArchGetPubPmId() */
+
+/******************************************************************************/
+/*.doc MedArchGetTitles(external) */
+/*+
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchGetTitles (
+ CharPtr PNTR titles_found,
+ Int1Ptr title_types_found,
+ CharPtr title_to_lookup,
+ Int1 request_type,
+ Int1 response_type,
+ Int4 max_titles_to_find
+){
+ Int4 retval = 0;
+ Int4 i;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if (i > 0) {
+ if ( !ReestablishNetMedArch() )
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ retval = s_MedArchGetTitles (
+ titles_found,
+ title_types_found,
+ title_to_lookup,
+ request_type,
+ response_type,
+ max_titles_to_find
+ );
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return retval;
+} /* MedArchGetTitles() */
+
+/******************************************************************************/
+/*.doc MedArchCitMatch(external) */
+/*+
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchCitMatch (
+ ValNodePtr pub
+){
+ Int4 retval = 0;
+ Int4 i;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ retval = s_MedArchCitMatch(pub);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return retval;
+} /* MedArchCitMatch() */
+
+/******************************************************************************/
+/*.doc MedArchCitMatchPmId(external) */
+/*+
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchCitMatchPmId (
+ ValNodePtr pub
+){
+ Int4 retval = 0;
+ Int4 i;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ retval = s_MedArchCitMatchPmId(pub);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return retval;
+} /* MedArchCitMatchPmId() */
+
+
+/******************************************************************************/
+/*.doc MedArchCitMatchList(internal) */
+/*+
+ This function send request '' to MedArch server and recive result
+ list. It set up error code in case some error found.
+-*/
+/******************************************************************************/
+ValNodePtr
+/*FCN*/MedArchCitMatchList (
+ ValNodePtr pub,
+ Int4Ptr pErrCode
+){
+ register ValNodePtr pPmIdList = NULL; /* result PubMed ID list */
+ Int4 i;
+ short erract;
+ ErrDesc err;
+
+ for ( i = 0; i < MEDARCH_SERV_RETRIES; i++ ) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ pPmIdList = s_MedArchCitMatchList(pub,pErrCode);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return pPmIdList;
+} /* MedArchCitMatchList() */
+
+/******************************************************************************/
+/*.doc MedArchGetMriUids(external) */
+/*+
+ This function call MedArch server and send MRI code. Server will return
+ list of articles(MuId's) that are present in this issue. This function
+ will return NULL if MRI not found or some errors found. Caller must
+ free list of medline id's.
+-*/
+/******************************************************************************/
+ValNodePtr
+/*FCN*/MedArchGetMriUids (
+ Int4 mri /* MRI code (I) */
+){
+ register ValNodePtr pMuIdList = NULL; /* result Medline ID list */
+ Int4 i; /* temp count */
+ short erract; /* values for save error code */
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ pMuIdList = s_MedArchGetMriUids (mri);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return pMuIdList;
+} /* MedArchGetMriUids() */
+
+/******************************************************************************/
+/*.doc MedArchGetMriPmids(external) */
+/*+
+ This function call MedArch server and send MRI code. Server will return
+ list of articles(MuId's) that are present in this issue. This function
+ will return NULL if MRI not found or some errors found. Caller must
+ free list of PubMed id's.
+-*/
+/******************************************************************************/
+ValNodePtr
+/*FCN*/MedArchGetMriPmids (
+ Int4 mri /* MRI code (I) */
+){
+ register ValNodePtr pMuIdList = NULL; /* result Medline ID list */
+ Int4 i; /* temp count */
+ short erract; /* values for save error code */
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ pMuIdList = s_MedArchGetMriPmids (mri);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return pMuIdList;
+} /* MedArchGetMriPmids() */
+
+/******************************************************************************/
+/*.doc MedArchGetAccUids(external) */
+/*+
+ This function call MedArch server and send Xref and Accession.
+ Server will return list of articles(MuId's) that are present in this issue.
+ plAccNum is an optional argument in accordance with
+ Medline-si definition. Set it to NULL if accession code is unknown.
+ It returns NULL if there are no entries found or if some error occured.-*/
+/******************************************************************************/
+ValNodePtr
+/*FCN*/MedArchGetAccUids (
+ Int4 iCode, /* Medline-si.type, */
+ /* type of xref (I) */
+ CharPtr lpAccNum /* Medline.si.cit, */
+ /* the citation/accession number (I) */
+){
+ register ValNodePtr pMuIdList = NULL; /* result Medline ID list */
+ Int4 i; /* temp count */
+ short erract; /* values for save error code */
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ pMuIdList = s_MedArchGetAccUids (iCode, lpAccNum);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return pMuIdList;
+} /* MedArchGetAccUids() */
+
+/******************************************************************************/
+/*.doc MedArchGetAccPmids(external) */
+/*+
+ This function call MedArch server and send Xref and Accession.
+ Server will return list of PmIds that are present in this issue.
+ plAccNum is an optional argument in accordance with
+ Medline-si definition. Set it to NULL if accession code is unknown.
+ It returns NULL if there are no entries found or if some error occured.-*/
+/******************************************************************************/
+ValNodePtr
+/*FCN*/MedArchGetAccPmids (
+ Int4 iCode, /* Medline-si.type, */
+ /* type of xref (I) */
+ CharPtr lpAccNum /* Medline.si.cit, */
+ /* the citation/accession number (I) */
+){
+ register ValNodePtr pmIdList = NULL; /* result Medline ID list */
+ Int4 i; /* temp count */
+ short erract; /* values for save error code */
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ pmIdList = s_MedArchGetAccPmids (iCode, lpAccNum);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return pmIdList;
+} /* MedArchGetAccPmids() */
+
+/******************************************************************************/
+/*.doc MedArchPm2Mu(external) */
+/*+
+ Convert PubMed id to Medline id
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchPm2Mu (
+ Int4 pmid /* PubMed id (I) */
+){
+ Int4 muid = 0;
+ Int4 i; /* temp count */
+ short erract; /* values for save error code */
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ muid = s_MedArchPm2Mu (pmid);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return muid;
+} /* MedArchPm2Mu() */
+
+/******************************************************************************/
+/*.doc MedArchMu2Pm(external) */
+/*+
+ Convert Medline id to PubMed id
+-*/
+/******************************************************************************/
+Int4
+/*FCN*/MedArchMu2Pm (
+ Int4 uid /* Medline id (I) */
+){
+ Int4 pmid = 0;
+ Int4 i; /* temp count */
+ short erract; /* values for save error code */
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ pmid = s_MedArchMu2Pm (uid);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return pmid;
+} /* MedArchMu2Pm() */
+
+/******************************************************************************/
+/*.doc MedArchMedlarsEntryGetUid(external) */
+/*+
+ Retrive single MEDLARS entry from database
+-*/
+/******************************************************************************/
+MedlarsEntryPtr
+/*FCN*/MedArchMedlarsEntryGetUid (
+ Int4 uid
+){
+ MedlarsEntryPtr retval = NULL;
+ Int4 i;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ retval = s_MedArchMedlarsEntryGetUid(uid);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return retval;
+} /* MedArchMedlarsEntryGetUid() */
+
+/******************************************************************************/
+/*.doc MedArchMedlarsEntryGetPmId(external) */
+/*+
+ Retrive single MEDLARS entry from database
+-*/
+/******************************************************************************/
+MedlarsEntryPtr
+/*FCN*/MedArchMedlarsEntryGetPmId (
+ Int4 uid
+){
+ MedlarsEntryPtr retval = NULL;
+ Int4 i;
+ short erract;
+ ErrDesc err;
+
+ for (i = 0; i < MEDARCH_SERV_RETRIES; i++) {
+ if ( i > 0 ) {
+ if ( !ReestablishNetMedArch() ) {
+ break;
+ }
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+ retval = s_MedArchMedlarsEntryGetPmId(uid);
+ ErrSetOpts(erract, 0);
+ if ( !ErrFetch(&err) ) {
+ break; /* success */
+ }
+ }
+
+ return retval;
+} /* MedArchMedlarsEntryGetPmId() */
+
+#endif /* __MEDARCHC__ */
+/*EOF*/
diff --git a/network/medarch/client/medarch.h b/network/medarch/client/medarch.h
new file mode 100644
index 00000000..fab33653
--- /dev/null
+++ b/network/medarch/client/medarch.h
@@ -0,0 +1,247 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: medarch.h
+*
+* Author: Epstein
+*
+* Version Creation Date: 04/12/93
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* API for Medline Archive service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 010296 grisha Add prototypes for MRI and Accessions lookup
+* 050896 grisha Add prototypes for PubMed support
+* 021196 grisha Add prototypes for MEDLARS entry support
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: medarch.h,v $
+* Revision 6.0 1997/08/25 18:35:44 madden
+* Revision changed to 6.0
+*
+* Revision 5.3 1997/02/11 22:41:47 grisha
+* Add code and prototypes for support MEDLARS entry
+*
+ * Revision 5.2 1996/12/17 20:32:30 grisha
+ * update interface to support PubmedEntry
+ *
+ * Revision 5.1 1996/07/23 19:36:18 grisha
+ * Add new function to return Medline entry in new format
+ *
+ * Revision 5.0 1996/05/28 14:11:11 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.3 1996/05/08 20:58:36 grisha
+ * implement new set of functions for PubMed support
+ *
+ * Revision 4.2 1996/05/03 14:35:19 grisha
+ * Add new functions and error codes for PubMed support
+ *
+ * Revision 4.1 1996/01/05 21:40:44 grisha
+ * Add two new function for MRI and Accession lookup. Now
+ * this function do not call MedArch server.
+ *
+ * Revision 4.0 1995/07/26 13:55:12 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.2 1995/05/17 17:53:58 epstein
+ * add RCS log revision history
+ *
+*/
+#ifndef __MEDARCHH__
+#define __MEDARCHH__ medarchh
+
+/***************************************************************************/
+/* INCLUDES */
+/***************************************************************************/
+#include <mapmla.h>
+
+/***************************************************************************/
+/* TYPEDEFS */
+/***************************************************************************/
+typedef enum {
+ kMedArchDdbj = 1, /* DNA Data Bank of Japan */
+ kMedArchCarbBank = 2, /* Carbohydrate Structure Database */
+ kMedArchEmbl = 3, /* EMBL Data Library */
+ kMedArchHdb = 4, /* Hybridoma Data Bank */
+ kMedArchGenBank = 5, /* GenBank */
+ kMedArchHgml = 6, /* Human Gene Map Library */
+ kMedArchMim = 7, /* Mendelian Inheritance in Man */
+ kMedArchMsd = 8, /* Microbial Strains Database */
+ kMedArchPdb = 9, /* Protein Data Bank (Brookhaven) */
+ kMedArchPir = 10, /* Protein Identification Resource */
+ kMedArchPrfseqdb = 11, /* Protein Research Foundation (Japan) */
+ kMedArchPsd = 12, /* Protein Sequence Database (Japan) */
+ kMedArchSwissprot = 13 /* SwissProt */
+} EMedArchTypeOfXref;
+
+/***************************************************************************/
+/* DEFINES */
+/***************************************************************************/
+#define MEDARCH_SERV_RETRIES 2 /* The number of retries to get a server */
+
+/***************************************************************************/
+/* FUNCTION PROTOTYPES */
+/***************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Initialization/Termination */
+Boolean MedArchInit PROTO(( /* Initialize MedArch interface */
+ void
+ ));
+Boolean MedArchFini PROTO(( /* Close MedArch interface */
+ void
+ ));
+
+/* Generate list of articles using Medline id(uids) or PubMed id(pmid) */
+Int4 MedArchPubmedEntryListGetPmId PROTO(( /* Create list of Med. Ent. */
+ PubmedEntryPtr PNTR result, /* To store data list (O) */
+ Int4 nupmid, /* Number if pmids (I) */
+ Int4Ptr pmids, /* Array of pmids (I/O) */
+ Boolean mark_missing /* Mark missing flag (I) */
+ ));
+Int4 MedArchPubmedEntryListGetUid PROTO(( /* Create list of Med. Ent.*/
+ PubmedEntryPtr PNTR result, /* To store data list (O) */
+ Int4 numuid, /* Number if ids (I) */
+ Int4Ptr uids, /* Array of ids (I/O) */
+ Boolean mark_missing /* Mark missing flag (I) */
+ ));
+Int4 MedArchMedlineEntryListGet PROTO(( /* Create list of Med. Ent.*/
+ MedlineEntryPtr PNTR result, /* To store data list (O) */
+ Int4 numuid, /* Number if ids (I) */
+ Int4Ptr uids, /* Array of ids (I/O) */
+ Boolean mark_missing /* Mark missing flag (I) */
+ ));
+
+/* Generate single article entry using Medline id(uid) or PubMed id(pmid) */
+PubmedEntryPtr MedArchPubmedEntryGetPmId PROTO(( /* Get entry by PubMed id */
+ Int4 pmid /* PubMed unique id */
+ ));
+PubmedEntryPtr MedArchPubmedEntryGetUid PROTO(( /* Get entry by Medline id */
+ Int4 uid /* Medline unique id */
+ ));
+MedlineEntryPtr MedArchMedlineEntryGet PROTO(( /* Get entry by Medline id */
+ Int4 uid /* Medline unique id */
+ ));
+MedlarsEntryPtr MedArchMedlarsEntryGetPmId PROTO(( /* Get entry by PubMed id */
+ Int4 pmid /* PubMed unique id */
+ ));
+MedlarsEntryPtr MedArchMedlarsEntryGetUid PROTO(( /* Get entry by Medline id */
+ Int4 uid /* Medline unique id */
+ ));
+
+/* Generate ASN.1 Publication Set using list of PubMed or Medline ids */
+Int4 MedArchPubSetCreatePmId PROTO(( /* Create PubSet using PubMed ids */
+ AsnIoPtr aip, /* Output ASN.1 stream (I/O) */
+ Int4 numpmid, /* Number of ids (I) */
+ Int4Ptr pmids, /* Array of pmids (I/O) */
+ Boolean mark_missing /* Mark missing flag (I) */
+ ));
+Int4 MedArchPubSetCreateUid PROTO(( /* Create PubSet using Medline ids */
+ AsnIoPtr aip, /* Output ASN.1 stream (I/O) */
+ Int4 numuid, /* Number of ids (I) */
+ Int4Ptr uids, /* Array of muids (I/O) */
+ Boolean mark_missing /* Mark missing flag (I) */
+ ));
+Int4 MedArchPubSetCreate PROTO(( /* Create PubSet using Medline ids */
+ AsnIoPtr aip, /* Output ASN.1 stream (I/O) */
+ Int4 numuid, /* Number of ids (I) */
+ Int4Ptr uids, /* Array of muids (I/O) */
+ Boolean mark_missing /* Mark missing flag (I) */
+ ));
+
+/* Journal database titles lookup */
+Int4 MedArchGetTitles PROTO((
+ CharPtr PNTR titles_found,
+ Int1Ptr title_types_found,
+ CharPtr title_to_lookup,
+ Int1 request_type,
+ Int1 response_type,
+ Int4 max_titles_to_find
+ ));
+
+/* Generate citation information for id */
+ValNodePtr MedArchGetPubPmId PROTO(( /* Create citation for PubMed id */
+ Int4 pmid /* Article PubMed id (I) */
+ ));
+ValNodePtr MedArchGetPub PROTO(( /* Create citation for Medline id */
+ Int4 uid /* Article Medline id (I) */
+ ));
+
+/* Citation matching functions */
+ValNodePtr MedArchCitMatchList PROTO(( /* Find PubMed ids are match */
+ ValNodePtr pub, /* Citation (I) */
+ Int4Ptr /* Error code (O) */
+ ));
+Int4 MedArchCitMatchPmId PROTO(( /* Find article PubMed id */
+ ValNodePtr pub /* Citation (I) */
+ ));
+Int4 MedArchCitMatch PROTO(( /* Find article Medline id */
+ ValNodePtr pub /* Citation (I) */
+ ));
+
+/* Generate list of PubMed or Medline id for selected MRI */
+ValNodePtr MedArchGetMriPmids PROTO(( /* Generate list of PubMed ids */
+ Int4 mri /* Machine-readable id (I) */
+ ));
+ValNodePtr MedArchGetMriUids PROTO(( /* Generate list of Medline ids */
+ Int4 mri /* Machine-readable id (I) */
+ ));
+
+/* Generate list of PubMed or Medline id for selected accession */
+ValNodePtr MedArchGetAccPmids PROTO(( /* Generate list of PubMed ids */
+ Int4 iCode, /* Type of xref (I) */
+ CharPtr lpAccNum /* The citation/accession number (I) */
+ ));
+ValNodePtr MedArchGetAccUids PROTO(( /* Generate list of Medline ids */
+ Int4 iCode, /* Type of xref (I) */
+ CharPtr lpAccNum /* The citation/accession number (I) */
+ ));
+
+/* Medline to PubMed identifier convertor */
+Int4 MedArchPm2Mu PROTO(( /* Convert PubMed id to Medline id */
+ Int4 pmid /* PubMed id (I) */
+ ));
+Int4 MedArchMu2Pm PROTO(( /* Convert Medline id to PubMed id */
+ Int4 uid /* Medline id (I) */
+ ));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MEDARCHH__ */
+/*END*/
diff --git a/network/medarch/client/medarch.msg b/network/medarch/client/medarch.msg
new file mode 100644
index 00000000..7cfa0d27
--- /dev/null
+++ b/network/medarch/client/medarch.msg
@@ -0,0 +1,13 @@
+MODULE medarch
+$$ REFERENCE, 1
+$^ MuidNotFound, 1, SEV_WARNING
+$^ SuccessfulMuidLookup, 2, SEV_INFO
+$^ OldInPress, 3, SEV_WARNING
+$^ No_reference, 4, SEV_WARNING
+$^ Multiple_ref, 5, SEV_WARNING
+$^ Multiple_muid, 6, SEV_WARNING
+$^ MedlineMatchIgnored, 7, SEV_WARNING
+$^ MuidMissmatch, 8, SEV_WARNING
+
+$$ PRINT, 2
+$^ Failed, 1, SEV_WARNING
diff --git a/network/medarch/client/medutil.c b/network/medarch/client/medutil.c
new file mode 100644
index 00000000..d6bc98af
--- /dev/null
+++ b/network/medarch/client/medutil.c
@@ -0,0 +1,1095 @@
+/* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: medutil.c
+*
+* Author: James Ostell
+*
+* Version Creation Date: 8/31/93
+*
+* $Revision: 6.1 $
+*
+* File Description: Medline Utilities for MedArch
+* Assumes user calls MedArchInit and Fini
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: medutil.c,v $
+* Revision 6.1 1998/09/14 20:54:51 bazhin
+* Changes in "ten_authors()" : if successful medline lookup has returned
+* no authors, then will use input ones.
+*
+* Revision 6.0 1997/08/25 18:35:48 madden
+* Revision changed to 6.0
+*
+* Revision 5.0 1996/05/28 14:11:11 ostell
+* Set to revision 5.0
+*
+ * Revision 4.4 1996/05/22 17:30:09 kans
+ * changed name of error file, initialize muid in lookup procedure
+ *
+ * Revision 4.3 1996/03/12 22:21:07 tatiana
+ * add bullet proof to MedlineToISO function
+ *
+ * Revision 4.2 1995/11/02 23:39:28 tatiana
+ * do not accept Medline article with 0 authors
+ *
+ * Revision 4.1 1995/08/16 14:28:21 tatiana
+ * modified get_std_auth to handle spaces between initials
+ *
+ * Revision 4.0 1995/07/26 13:55:12 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.32 1995/06/06 14:34:39 tatiana
+ * bug fixed in print_pub()
+ *
+ * Revision 1.30 1995/05/25 22:17:14 kans
+ * fixed FixPubEquiv
+ *
+ * Revision 1.29 1995/05/25 18:14:35 kans
+ * additional long and int casts in ErrPostEx
+ *
+ * Revision 1.28 1995/05/24 16:13:47 tatiana
+ * add in_press() to avoid lookup for in press articles
+ *
+ * Revision 1.24 1995/05/17 17:54:05 epstein
+ * add RCS log revision history
+ *
+*/
+
+/** for ErrPostEx() ****/
+
+static char *this_module = "medarch";
+#ifdef THIS_MODULE
+#undef THIS_MODULE
+#endif
+
+#define THIS_MODULE this_module
+static char *this_file = __FILE__;
+#define THIS_FILE this_file
+
+/**********************/
+#include <medutil.h> /* the interface */
+#include <medarch.h> /* the medarch interface */
+#include <mdrcherr.h> /* the errors interface */
+
+/*--------------------------- print_pub() ---------------------------*/
+
+/****************************************************************************
+* print_pub
+*
+****************************************************************************/
+void print_pub(ValNodePtr pub, Boolean found, Boolean auth, Int4 muid)
+{
+ ValNodePtr v, title = NULL;
+ CitArtPtr art;
+ CitJourPtr jour;
+ CitBookPtr book;
+ NameStdPtr namestd;
+ AuthorPtr aup;
+ CharPtr s_title=NULL, page=NULL, vol=NULL, last=NULL, first=NULL;
+ Int2 year = 0;
+ ImprintPtr imp = NULL;
+ DatePtr dp;
+
+ if (pub == NULL) {
+ ErrPostEx(SEV_WARNING, ERR_PRINT_Failed, "Citation NULL");
+ return;
+ }
+ if (pub->data.ptrvalue == NULL) {
+ ErrPostEx(SEV_WARNING, ERR_PRINT_Failed, "Citation NULL");
+ return;
+ }
+ if (pub->choice != PUB_Article)
+ return;
+
+ art = pub->data.ptrvalue;
+ first = "";
+ last = "";
+ if (art->authors == NULL) {
+ ErrPostEx(SEV_WARNING, ERR_PRINT_Failed, "Authors NULL");
+ } else {
+ v = art->authors->names;
+ if (v == NULL) {
+ ErrPostEx(SEV_WARNING, ERR_PRINT_Failed, "Authors NULL");
+ } else {
+
+ /* warning! processing only the first of the author name valnodes */
+ /* should loop through them all in case first is uninformative */
+
+ if (art->authors->choice == 1) {
+ aup = v->data.ptrvalue;
+ if (aup != NULL) {
+ namestd = aup->name->data;
+ if (namestd->names[0]) {
+ last = namestd->names[0];
+ }
+ if (namestd->names[4]) {
+ first = namestd->names[4];
+ }
+ }
+ } else {
+ first = "";
+ last = v->data.ptrvalue;
+ }
+ }
+ }
+ if (art->from == 1) {
+ jour = art->fromptr;
+ if (jour != NULL) {
+ title = jour->title;
+ imp = jour->imp;
+ }
+ } else if (art->from == 2) {
+ book = art->fromptr;
+ if (book != NULL) {
+ title = book->title;
+ imp = book->imp;
+ }
+ }
+ if (title != NULL) {
+ s_title = title->data.ptrvalue;
+ }
+ if (s_title == NULL) {
+ s_title = "journal unknown";
+ }
+ if (imp != NULL) {
+ vol = imp->volume;
+ page = imp->pages;
+ if (imp->date != NULL) {
+ year = imp->date->data[1]+1900;
+ }
+ }
+ if (page == NULL) {
+ page = "no page number";
+ }
+ if (vol == NULL) {
+ vol = "no volume number";
+ }
+ if (auth) {
+ ErrPostEx(SEV_WARNING, ERR_REFERENCE_MedlineMatchIgnored,
+ "Too many author name differences: %ld|%s %s|%s|(%d)|%s|%s",
+ (long) muid, last, first, s_title, (int) year, vol, page);
+ return;
+ }
+ if (imp != NULL && imp->prepub == 2) { /* in-press */
+ dp = DateCurr();
+ if (year && (Int2) (dp->data[1]) + 1900 - year > 2) {
+ ErrPostEx(SEV_WARNING, ERR_REFERENCE_OldInPress,
+ "encountered in-press article more than 2 years old: %s %s|%s|(%d)|%s|%s",
+ last, first, s_title, (int) year, vol, page);
+ }
+ DateFree(dp);
+ } else {
+ if (found) {
+ ErrPostEx(SEV_INFO, ERR_REFERENCE_SuccessfulMuidLookup,
+ "%ld|%s %s|%s|(%d)|%s|%s", (long) muid, last, first, s_title, (int) year, vol, page);
+ } else if (muid == 0) {
+ ErrPostEx(SEV_WARNING, ERR_REFERENCE_MuidNotFound,
+ "%s %s|%s|(%d)|%s|%s", last, first, s_title, (int) year, vol, page);
+ }
+ else {
+ ErrPostEx(SEV_WARNING, ERR_REFERENCE_MuidNotFound,
+ ">>%ld<<|%s %s|%s|(%d)|%s|%s", (long) muid, last, first, s_title, (int) year, vol, page);
+ }
+ }
+ return;
+}
+
+/*--------------------------- ten_authors() ---------------------------*/
+
+/****************************************************************************
+* ten_authors
+*
+****************************************************************************/
+static Boolean ten_authors(CitArtPtr art, CitArtPtr art_tmp)
+{
+ Int2 num, numnew, i, match, n;
+ ValNodePtr v, pub;
+ CharPtr ptr, mu[10];
+ AuthorPtr aup;
+ NameStdPtr namestd;
+ Boolean no_compare = TRUE, ret = TRUE;
+
+ if (art == NULL || art_tmp == NULL) {
+ return TRUE;
+ }
+ numnew = 0;
+ num = 0;
+ match = 0;
+ if (art->authors != NULL)
+ {
+ for (v = art->authors->names; v != NULL;
+ v = v->next, num++);
+ }
+ if (art_tmp->authors != NULL)
+ {
+ for (v = art_tmp->authors->names; v != NULL && numnew < 10;
+ v = v->next, numnew++) {
+ aup = v->data.ptrvalue;
+ namestd = aup->name->data;
+ mu[numnew] = namestd->names[0];
+ }
+ }
+
+ if (art->authors != NULL && art_tmp->authors != NULL) {
+ if (art->authors->choice == 1 && art_tmp->authors->choice == 1) {
+ no_compare = FALSE;
+ for (v = art->authors->names; v != NULL; v = v->next) {
+ aup = v->data.ptrvalue;
+ namestd = aup->name->data;
+ ptr = namestd->names[0];
+ for (i = 0; i < numnew; i++) {
+ if (StringICmp(ptr, mu[i]) == 0) {
+ match++;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (no_compare) {
+ ret = TRUE; /* replace */
+ if (num == 0 && numnew == 0) {
+ ret = TRUE; /* replace */
+ } else if (num == 0) { /* no original authors - replace*/
+ ret = TRUE;
+ } else if (numnew == 0) { /* no Medline authors - don't replace*/
+ ret = FALSE;
+ }
+ } else {
+ n = num < numnew?num:numnew;
+ if (n > 3*match) {
+ ret = FALSE;
+ }
+ }
+ if (ret && (num > 10 || numnew == 0)) /* original article has > 10 authors */
+ {
+ AuthListFree(art_tmp->authors); /* keep original authors */
+ art_tmp->authors = art->authors;
+ art->authors = NULL;
+ }
+ return ret;
+}
+/*****************************************************************************
+*
+* FindPub
+* SeqEntryExplore to process all pubs
+*
+*****************************************************************************/
+
+
+void FindPub(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
+{
+ BioseqPtr bsp;
+ BioseqSetPtr bssp;
+ ValNodePtr vnp, pub, newpub, prev, next, head;
+ SeqAnnotPtr sap;
+ SeqFeatPtr sfp;
+ PubdescPtr pdp;
+ FindPubOptionPtr fpop;
+
+ fpop = (FindPubOptionPtr)data;
+
+ if (IS_Bioseq(sep))
+ {
+ bsp = (BioseqPtr)(sep->data.ptrvalue);
+ vnp = bsp->descr;
+ sap = bsp->annot;
+ }
+ else
+ {
+ bssp = (BioseqSetPtr)(sep->data.ptrvalue);
+ vnp = bssp->descr;
+ sap = bssp->annot;
+ }
+
+ for (vnp; vnp != NULL; vnp = vnp->next)
+ {
+ if (vnp->choice == Seq_descr_pub)
+ {
+ pdp = (PubdescPtr)(vnp->data.ptrvalue);
+ newpub = FixPubEquiv(pdp->pub, fpop);
+ pdp->pub = newpub;
+ }
+ }
+
+ for (sap; sap != NULL; sap = sap->next)
+ {
+ if (sap->type == 1) /* feature table */
+ {
+ for (sfp = (SeqFeatPtr)(sap->data); sfp != NULL; sfp = sfp->next)
+ {
+ if (sfp->data.choice == 6) /* pub feature */
+ {
+ pdp = (PubdescPtr)(sfp->data.value.ptrvalue);
+ newpub = FixPubEquiv(pdp->pub, fpop);
+ pdp->pub = newpub;
+ }
+
+ if (sfp->cit != NULL)
+ {
+ head = sfp->cit;
+ prev = NULL;
+ for (pub = (ValNodePtr)(head->data.ptrvalue);
+ pub != NULL; pub = next)
+ {
+ next = pub->next;
+ newpub = FixPub(pub, fpop);
+ if (prev == NULL)
+ head->data.ptrvalue = newpub;
+ else
+ prev->next = newpub;
+ prev = newpub;
+ }
+ head->choice = 1; /* set to Pub-set.pub */
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+/*****************************************************************************
+*
+* FixPub(pub, fpop)
+* Tries to make any Pub into muid/cit-art
+*
+*****************************************************************************/
+ValNodePtr FixPub (ValNodePtr pub, FindPubOptionPtr fpop)
+{
+ ValNodePtr newpub, tmp, v;
+ Int4 muid;
+ Int2 num, numnew;
+ CitArtPtr cit;
+
+
+ if (pub == NULL) return NULL;
+
+ pub->next = NULL; /* ready for return */
+ newpub = pub;
+ switch (pub->choice)
+ {
+ case PUB_Medline: /* medline, just split to pubequiv */
+ tmp = SplitMedlineEntry((MedlineEntryPtr)(pub->data.ptrvalue));
+ newpub->choice = PUB_Equiv;
+ newpub->data.ptrvalue = tmp;
+ break;
+ case PUB_Article:
+ cit = pub->data.ptrvalue;
+ if (cit->from == 2 || in_press(cit)) {
+ /* article from book or in press*/
+ return pub;
+ }
+ fpop->lookups_attempted++;
+ muid = MedArchCitMatch(pub);
+ if (muid) /* matched it */
+ {
+ print_pub(pub, TRUE, FALSE, muid);
+ fpop->lookups_succeeded++;
+ if (fpop->replace_cit)
+ {
+ fpop->fetches_attempted++;
+ tmp = FetchPub(muid);
+
+ if (tmp != NULL)
+ {
+ if (ten_authors(pub->data.ptrvalue,
+ tmp->data.ptrvalue))
+ {
+
+ fpop->fetches_succeeded++;
+ PubFree(pub);
+ pub = ValNodeNew(tmp);
+ pub->choice = PUB_Muid;
+ pub->data.intvalue = muid;
+ newpub = ValNodeNew(NULL);
+ newpub->choice = PUB_Equiv;
+ newpub->data.ptrvalue = tmp;
+ }
+ else
+ {
+ print_pub(pub, FALSE, TRUE, muid);
+ newpub = pub;
+ MedlineToISO(pub);
+ }
+ }
+ }
+ else
+ {
+ print_pub(pub, FALSE, FALSE, muid);
+ newpub = pub;
+ MedlineToISO(pub);
+ }
+ }
+ break;
+ case PUB_Equiv:
+ tmp = FixPubEquiv((ValNodePtr)(pub->data.ptrvalue), fpop);
+ pub->data.ptrvalue = tmp;
+ newpub = pub;
+ break;
+ default:
+ break;
+ }
+ return newpub;
+}
+
+/*****************************************************************************
+*
+* SplitMedlineEntry(mep)
+* splits a medline entry into 2 pubs (1 muid, 1 Cit-art)
+* converts Cit-art to ISO/GenBank style
+* returns pointer to first (chained) pub
+* deletes original medline entry
+*
+*****************************************************************************/
+ValNodePtr SplitMedlineEntry(MedlineEntryPtr mep)
+{
+ ValNodePtr uid, cit;
+
+ uid = ValNodeNew(NULL);
+ uid->choice = PUB_Muid;
+ uid->data.intvalue = mep->uid;
+
+ cit = ValNodeNew(uid);
+ cit->choice = PUB_Article;
+ cit->data.ptrvalue = mep->cit;
+ mep->cit = NULL;
+ MedlineToISO(cit);
+
+ MedlineEntryFree(mep);
+
+ return uid;
+}
+
+/*****************************************************************************
+*
+* FixPubEquiv()
+*
+*****************************************************************************/
+ValNodePtr FixPubEquiv(ValNodePtr pube, FindPubOptionPtr fpop)
+{
+ ValNodePtr tmp, newpub, muidptr=NULL, citartptr=NULL, mepptr = NULL,
+ otherptr = NULL, tmp2, next, new;
+ Int2 muidctr = 0, citartctr = 0, mepctr = 0, otherctr = 0;
+ Int4 muid = 0, oldmuid=0;
+ Int2 num, numnew;
+ ValNodePtr v;
+ CitArtPtr cit;
+
+ if (pube == NULL) return NULL;
+
+ for (tmp = pube; tmp != NULL; tmp = next)
+ {
+ next = tmp->next;
+ tmp->next = NULL;
+ switch (tmp->choice)
+ {
+ case PUB_Muid:
+ muidctr++;
+ if (muidptr == NULL)
+ muidptr = tmp;
+ else
+ {
+ for (tmp2 = muidptr; tmp2->next != NULL; tmp2 = tmp2->next)
+ continue;
+ tmp2->next = tmp;
+ }
+ break;
+ case PUB_Article:
+ cit = tmp->data.ptrvalue;
+ if (cit->from == 2 || in_press(cit)) {
+ otherctr++;
+ if (otherptr == NULL)
+ otherptr = tmp;
+ else
+ {
+ for (tmp2 = otherptr; tmp2->next != NULL; tmp2 = tmp2->next)
+ continue;
+ tmp2->next = tmp;
+ }
+ } else {
+ citartctr++;
+ if (citartptr == NULL)
+ citartptr = tmp;
+ else
+ {
+ for (tmp2 = citartptr; tmp2->next != NULL;
+ tmp2 = tmp2->next)
+ continue;
+ tmp2->next = tmp;
+ }
+ }
+ break;
+ case PUB_Medline:
+ mepctr++;
+ if (mepptr == NULL)
+ mepptr = tmp;
+ else
+ {
+ for (tmp2 = mepptr; tmp2->next != NULL; tmp2 = tmp2->next)
+ continue;
+ tmp2->next = tmp;
+ }
+ break;
+ default:
+ otherctr++;
+ if (otherptr == NULL)
+ otherptr = tmp;
+ else
+ {
+ for (tmp2 = otherptr; tmp2->next != NULL; tmp2 = tmp2->next)
+ continue;
+ tmp2->next = tmp;
+ }
+ break;
+ }
+ }
+
+ pube = otherptr; /* put back others */
+ tmp2 = otherptr;
+ if (tmp2 != NULL)
+ {
+ for (tmp2 = otherptr; tmp2->next != NULL; tmp2 = tmp2->next)
+ continue;
+ }
+
+ if ((muidctr != 0) && (! fpop->always_look)) /* got an muid */
+ {
+ if (mepptr != NULL)
+ {
+ if (tmp2 == NULL)
+ {
+ tmp2 = mepptr;
+ pube = tmp2;
+ }
+ else
+ tmp2->next = mepptr;
+
+ while (tmp2->next != NULL)
+ tmp2 = tmp2->next;
+ }
+ if (muidptr != NULL)
+ {
+ if (tmp2 == NULL)
+ {
+ tmp2 = muidptr;
+ pube = tmp2;
+ }
+ else
+ tmp2->next = muidptr;
+
+ while (tmp2->next != NULL)
+ tmp2 = tmp2->next;
+ }
+ if (citartptr != NULL)
+ {
+ if (tmp2 == NULL)
+ {
+ tmp2 = citartptr;
+ pube = tmp2;
+ }
+ else
+ tmp2->next = citartptr;
+ }
+ return pube; /* no changes */
+ }
+
+ if (mepctr != 0) /* have a medline entry, take it first */
+ {
+ if (mepctr > 1)
+ {
+ ErrPostEx(SEV_WARNING, ERR_REFERENCE_Multiple_ref, "More than one Medline entry in Pub-equiv");
+ mepptr->next = PubEquivFree(mepptr->next);
+ }
+ PubEquivFree(muidptr); /* ditch others */
+ PubEquivFree(citartptr);
+ tmp = SplitMedlineEntry((MedlineEntryPtr)(mepptr->data.ptrvalue));
+ ValNodeFree(mepptr);
+ if (tmp2 == NULL)
+ pube = tmp;
+ else
+ tmp2->next = tmp;
+ return pube;
+ }
+
+ if (muidctr != 0) /* have an muid */
+ {
+ oldmuid = muidptr->data.intvalue;
+ if (muidctr > 1) /* more than one, just take the first */
+ {
+ for (tmp = muidptr->next; tmp != NULL; tmp = tmp->next)
+ {
+ if (tmp->data.intvalue != muid)
+ {
+ ErrPostEx(SEV_WARNING, ERR_REFERENCE_Multiple_muid, "Two different muids in Pub-equiv [%ld] [%ld]\n",
+ (long) oldmuid, (long) (tmp->data.intvalue));
+ }
+ }
+ muidptr->next = PubEquivFree(muidptr->next);
+ }
+ }
+
+ if (citartctr > 0)
+ {
+ if (citartctr > 1) /* ditch extras */
+ {
+ ErrPostEx(SEV_WARNING, ERR_REFERENCE_Multiple_ref, "More than one Cit-art in Pub-equiv");
+ citartptr->next = PubEquivFree(citartptr->next);
+ }
+
+ fpop->lookups_attempted++;
+ muid = MedArchCitMatch(citartptr);
+ if (muid != 0) /* success */
+ {
+ print_pub(citartptr, TRUE, FALSE, muid);
+ fpop->lookups_succeeded++;
+ if (oldmuid) /* already had an muid */
+ {
+ if (oldmuid != muid)
+ {
+ ErrPostEx(SEV_ERROR, ERR_REFERENCE_MuidMissmatch, "OldMUID=%ld doesn't match lookup (%ld). Keeping lookup.",
+ (long)oldmuid, (long)muid);
+ }
+ }
+ if (fpop->replace_cit)
+ {
+ fpop->fetches_attempted++;
+ new = FetchPub(muid);
+ if (new != NULL)
+ {
+ fpop->fetches_succeeded++;
+
+ if (ten_authors(citartptr->data.ptrvalue,
+ new->data.ptrvalue))
+ {
+ if (muidptr != NULL)
+ tmp = muidptr;
+ else
+ {
+ tmp = ValNodeNew(tmp2);
+ tmp->choice = PUB_Muid;
+ }
+ if (tmp2 == NULL) {
+ pube = tmp;
+ } else {
+ tmp2->next = tmp;
+ }
+ tmp->data.intvalue = muid;
+ tmp->next = new;
+
+ PubFree(citartptr);
+ } else {
+ print_pub(citartptr, FALSE, TRUE, muid);
+ PubFree(new);
+ if (tmp2 == NULL) {
+ pube = citartptr;
+ } else {
+ tmp2->next = citartptr;
+ }
+ if (muidptr != NULL)
+ citartptr->next = muidptr;
+ }
+ }
+ }
+ else
+ {
+ if (muidptr != NULL)
+ tmp = muidptr;
+ else
+ {
+ tmp = ValNodeNew(tmp2);
+ tmp->choice = PUB_Muid;
+ }
+ if (tmp2 == NULL)
+ pube = tmp;
+ tmp->data.intvalue = muid;
+ tmp2 = tmp;
+ tmp->next = citartptr;
+ MedlineToISO(citartptr);
+ }
+ return pube;
+ }
+ print_pub(citartptr, FALSE, FALSE, oldmuid);
+ if (tmp2 == NULL)
+ pube = citartptr;
+ else
+ tmp2->next = citartptr;
+ if (muidptr != NULL) /* ditch the mismatched muid */
+ PubFree(muidptr);
+ return pube;
+
+ }
+
+ if (oldmuid != 0) /* have an muid but no cit-art */
+ {
+ fpop->fetches_attempted++;
+ tmp = MedArchGetPub(oldmuid);
+ if (tmp == NULL)
+ {
+ ErrPostEx(SEV_WARNING, ERR_REFERENCE_No_reference, "Cant find article for muid [%ld]", (long) oldmuid);
+ }
+ else
+ {
+ fpop->fetches_succeeded++;
+ if (fpop->replace_cit)
+ {
+ tmp = MedlineToISO(tmp);
+ if (tmp2 == NULL)
+ pube = tmp;
+ else
+ tmp2->next = tmp;
+ tmp2 = tmp;
+ } else {
+ PubFree(tmp);
+ }
+ }
+ if (tmp2 == NULL)
+ pube = muidptr;
+ else
+ tmp2->next = muidptr;
+ }
+
+ return pube;
+}
+
+
+/*****************************************************************************
+*
+* FetchPub(muid)
+* get a pub given a uid
+* convert to ISO/GenBank Style
+*
+*****************************************************************************/
+ValNodePtr FetchPub (Int4 muid)
+{
+ ValNodePtr tmp;
+
+ tmp = MedArchGetPub(muid);
+ if (tmp == NULL) return NULL;
+ tmp = MedlineToISO(tmp);
+ return tmp;
+}
+
+/*****************************************************************************
+*
+* MedlineToISO(tmp)
+* converts a MEDLINE citation to ISO/GenBank style
+*
+*****************************************************************************/
+ValNodePtr MedlineToISO (ValNodePtr tmp)
+{
+ ValNodePtr titlenode, oldnames, curr, tmp2, v;
+ AuthListPtr alp;
+ AuthorPtr ap;
+ PersonIdPtr pip;
+ NameStdPtr nsp;
+ CitArtPtr cap;
+ CitJourPtr cjp;
+ Int4 titlenum;
+ CharPtr titles[1], title;
+ Int1 types[1];
+ ImprintPtr ip;
+ Boolean is_iso;
+
+ if (tmp == NULL) return NULL;
+
+ if (tmp->choice != PUB_Article) return tmp;
+
+ cap = (CitArtPtr)(tmp->data.ptrvalue);
+ alp = cap->authors;
+ if (alp && alp->choice == 2) /* ml style names */
+ {
+ oldnames = alp->names;
+ alp->names = NULL;
+ curr = NULL;
+ alp->choice = 1; /* make std names */
+ for (tmp2 = oldnames; tmp2 != NULL; tmp2 = tmp2->next)
+ {
+ curr = get_std_auth((CharPtr)(tmp2->data.ptrvalue), ML_REF);
+ if (alp->names == NULL) {
+ alp->names = curr;
+ } else {
+ for (v = alp->names; v->next != NULL; v = v->next);
+ v->next = curr;
+ }
+ }
+ ValNodeFreeData(oldnames);
+ }
+ if (cap->from == 1) /* from a journal - get iso_jta */
+ {
+ if ((cjp = (CitJourPtr)(cap->fromptr)) != NULL)
+ {
+ is_iso = FALSE;
+ for (titlenode = cjp->title; titlenode != NULL; titlenode = titlenode->next)
+ {
+ if (titlenode->choice == Cit_title_iso_jta) /* have it */
+ {
+ is_iso = TRUE;
+ break;
+ }
+ }
+ if (! is_iso)
+ {
+ titlenode = cjp->title;
+ title = (CharPtr)(titlenode->data.ptrvalue);
+ titlenum = MedArchGetTitles(titles, types, title, (Int1)titlenode->choice,
+ Cit_title_iso_jta, 1);
+ if (titlenum)
+ {
+ MemFree(title);
+ titlenode->choice = types[0];
+ titlenode->data.ptrvalue = titles[0];
+ }
+ }
+ ip = cjp->imp; /* remove Eng language */
+ if (! StringCmp(ip->language, "Eng"))
+ {
+ ip->language = MemFree(ip->language);
+ }
+ }
+ }
+ return tmp;
+}
+
+Boolean AllUpperCase(CharPtr p )
+{
+ if (p == NULL) return FALSE;
+ while( *p != '\0' )
+ {
+ if( ! IS_UPPER( *p ) )
+ return FALSE;
+ p++;
+ }
+ return TRUE;
+}
+
+
+void SplitMlAuthorName( CharPtr name, CharPtr last, CharPtr initials, CharPtr suffix )
+{
+ CharPtr p, p2;
+ Int2 i;
+ Char sbuf[20], ibuf[20];
+
+ /* Clear the ibuf field and transfer the entire name to 'last',
+ excluding leading and trailing spaces */
+
+ if (name == NULL) return;
+
+ ibuf[0] = '\0';
+ sbuf[0] = '\0';
+ last[0] = '\0';
+ initials[0] = '\0';
+ suffix[0] = '\0';
+ while(*name <= ' ')
+ {
+ name++;
+ if (*name == '\0')
+ return;
+ }
+ StringCpy( last, name );
+
+ for(i=StringLen(last)-1;((i >= 0) && (last[i] <= ' ')); i--)
+ last[i] = '\0';
+
+ /* Strip off the last token (initials or name suffix (Jr, Sr, suffix.) */
+
+ p = StringRChr(last, (int)' ');
+ if (p != NULL) /* more than just last name */
+ {
+ /* Separate the token from the last name */
+
+ p2 = p + 1;
+ while((p > last) && (*p == ' '))
+ {
+ *p = '\0';
+ *p--;
+ }
+
+ /* If the last token is not all upper case, and there are more than
+ two tokens, see if the next to the last are initials (upper case) */
+
+ if ( ! AllUpperCase(p2) && (p = StringRChr( last, (int)' ' )) != NULL )
+ {
+ /* We have at least three tokens, is the next to last initials? */
+
+ if( AllUpperCase( p + 1 ) )
+ {
+ /* Yes - concatenate the last two tokens as initials */
+
+ StringCpy( ibuf, p + 1 );
+ StringCpy( sbuf, p2 );
+ while( p > last && (*p == ' ') )
+ {
+ *p = '\0';
+ p--;
+ }
+ }
+ }
+
+ if (ibuf[0] == '\0') /* Only the last token goes in ibuf */
+ StringCpy( ibuf, p2 );
+ }
+
+ /* now add periods to ibuf and convert suffix */
+
+ for (p = initials, p2 = ibuf; *p2 != '\0'; p2++, p++)
+ {
+ *p = *p2;
+ if (! IS_LOWER(*(p2 + 1))) /* watch out for foreign names */
+ {
+ p++;
+ *p = '.';
+ }
+ }
+ *p = '\0';
+
+ if (sbuf[0])
+ {
+ if ( StringCmp(sbuf, "1d")==0)
+ p = StringMove (suffix, "I.");
+ else if ( StringCmp(sbuf, "2d")==0)
+ p = StringMove (suffix, "II.");
+ else if ( StringCmp(sbuf, "3d")==0)
+ p = StringMove (suffix, "III.");
+ else if ( StringCmp(sbuf, "4th")==0)
+ p = StringMove (suffix, "IV.");
+ else if ( StringCmp(sbuf, "5th")==0)
+ p = StringMove (suffix, "V.");
+ else if ( StringCmp(sbuf, "6th")==0)
+ p = StringMove (suffix, "VI.");
+ else if ( StringCmp(sbuf, "Sr")==0)
+ p = StringMove (suffix, "Sr.");
+ else if ( StringCmp(sbuf, "Jr")==0)
+ p = StringMove (suffix, "Jr.");
+ else
+ p = StringMove (suffix, sbuf);
+ }
+
+ return;
+}
+
+ValNodePtr get_std_auth(CharPtr token, Uint1 format)
+{
+ static CharPtr auth, eptr;
+ Char last[80], initials[20], suffix[20];
+ ValNodePtr tmp;
+ NameStdPtr namestd = NULL;
+ AuthorPtr aup;
+ PersonIdPtr pid;
+
+ if (token == NULL) {
+ return NULL;
+ }
+ eptr = token + StringLen(token) - 1;
+ for (; eptr > token && *eptr == ' '; eptr--);
+ namestd = NameStdNew();
+ if (format == PIR_REF || format == GB_REF) {
+ for(auth = token; *auth != ',' && *auth != '\0'; auth++);
+ if (*auth == ',') {
+ *auth = '\0';
+ if (*(auth+1) != '\0') {
+ namestd->names[4] = StringSave(auth + 1);
+ }
+ }
+ namestd->names[0] = StringSave(token);
+ } else if (format == PDB_REF) {
+ for (auth = eptr; auth > token && *auth != '.'; auth--);
+ if (*auth == '.') {
+ if (*(auth+1) != '\0' && *(auth+1) != '.') {
+ namestd->names[0] = StringSave(auth+1);
+ }
+ *(auth+1) = '\0';
+ namestd->names[4] = StringSave(token);
+ } else {
+ namestd->names[0] = StringSave(token);
+ }
+ } else if (format == EMBL_REF || format == SP_REF) {
+ for(auth = eptr; *auth != ' ' && auth > token; auth--);
+ if (*auth == ' ') {
+ if (*(auth-1) == '.') {
+ for(auth--; *auth != ' ' && auth > token; auth--);
+ }
+ if (*auth == ' ') {
+ *auth = '\0';
+ namestd->names[0] = StringSave(token);
+ if (*(auth+1) != '\0') {
+ namestd->names[4] = StringSave(auth+1);
+ }
+ } else {
+ namestd->names[0] = StringSave(token);
+ }
+ } else {
+ namestd->names[0] = StringSave(token);
+ }
+ } else if (format == ML_REF) {
+ SplitMlAuthorName(token, last, initials, suffix);
+ namestd->names[0] = StringSave(last);
+ if (initials[0] != '\0')
+ namestd->names[4] = StringSave(initials);
+ if (suffix[0] != '\0')
+ namestd->names[5] = StringSave(suffix);
+ }
+ if (namestd != NULL && namestd->names[0] != NULL) {
+ pid = PersonIdNew();
+ pid->choice = 2; /*name*/
+ pid->data = namestd;
+ aup = AuthorNew();
+ aup->name = pid;
+ tmp = ValNodeNew(NULL);
+ tmp->data.ptrvalue = aup;
+ }
+
+ return tmp;
+}
+
+Boolean in_press(CitArtPtr cit)
+{
+ ImprintPtr imp;
+ CitJourPtr jour;
+
+ if (cit == NULL) {
+ return TRUE;
+ }
+ if ((jour = cit->fromptr) == NULL || jour->title == NULL) {
+ return TRUE;
+ }
+ if ((imp = jour->imp) == NULL) {
+ return TRUE;
+ }
+ if (imp->volume == NULL || imp->pages == NULL || imp->date == NULL) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/network/medarch/client/medutil.h b/network/medarch/client/medutil.h
new file mode 100644
index 00000000..182ca3aa
--- /dev/null
+++ b/network/medarch/client/medutil.h
@@ -0,0 +1,129 @@
+/* medutil.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: medutil.h
+*
+* Author: James Ostell
+*
+* Version Creation Date: 8/31/93
+*
+* $Revision: 6.0 $
+*
+* File Description: * File Description: Medline Utilities for MedArch
+* Assumes user calls MedArchInit and Fini
+* Uses MedArch to match citations, lookup Medline uids, and ISO jta's
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: medutil.h,v $
+* Revision 6.0 1997/08/25 18:35:50 madden
+* Revision changed to 6.0
+*
+* Revision 5.0 1996/05/28 14:11:11 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:55:12 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.6 1995/05/24 16:14:56 tatiana
+ * add in_press() to avoid lookup for in press articles
+ *
+ * Revision 1.4 1995/05/17 17:54:08 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NCBI_MedUtil_
+#define _NCBI_MedUtil_
+
+#ifndef _NCBI_SeqUtil_
+#include <sequtil.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GB_REF 0
+#define EMBL_REF 1
+#define SP_REF 2
+#define PIR_REF 3
+#define PDB_REF 4
+#define ML_REF 5
+
+typedef struct findpubstr {
+ Boolean always_look; /* if TRUE, look up even if muid in Pub-equiv */
+ Boolean replace_cit; /* if TRUE, replace Cit-art w/ replace from MEDLINE */
+ Int4 lookups_attempted, /* citartmatch tries */
+ lookups_succeeded, /* citartmatch worked */
+ fetches_attempted, /* FetchPubs tried */
+ fetches_succeeded; /* FetchPubs that worked */
+} FindPubOption, PNTR FindPubOptionPtr;
+
+ /* SeqEntryExplore callback to fix all Pubs */
+ /* "data" is a FindPubOptionPtr */
+
+void print_pub(ValNodePtr pub, Boolean found, Boolean auth, Int4 muid);
+
+void FindPub PROTO((SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent));
+
+ /* Converts any Pub to ISO/GenBank style */
+ValNodePtr FixPub PROTO((ValNodePtr pub, FindPubOptionPtr fpop));
+
+ /* Converts MedlineEntry to Pub-equiv */
+ValNodePtr SplitMedlineEntry PROTO((MedlineEntryPtr mep));
+
+ /* Process PubEquiv to ISO/GenBank style */
+ValNodePtr FixPubEquiv PROTO((ValNodePtr pube, FindPubOptionPtr fpop));
+
+ /* gets Cit-art in ISO/GenBank style given Muid */
+ValNodePtr FetchPub PROTO((Int4 muid));
+
+ /* check if a string all upper case */
+Boolean AllUpperCase PROTO((CharPtr p ));
+
+ /* splits ML name into parts */
+void SplitMlAuthorName PROTO(( CharPtr name, CharPtr last, CharPtr initials, CharPtr suffix ));
+
+ /* makes ML Cit-art to ISO/GenBank style */
+ValNodePtr MedlineToISO PROTO((ValNodePtr tmp));
+
+ /* makes std Author name from string */
+ValNodePtr get_std_auth PROTO((CharPtr token, Uint1 format));
+
+Boolean in_press PROTO ((CitArtPtr cit));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/network/medarch/client/mla.asn b/network/medarch/client/mla.asn
new file mode 100644
index 00000000..005a728e
--- /dev/null
+++ b/network/medarch/client/mla.asn
@@ -0,0 +1,121 @@
+--$Revision: 6.0 $
+--********************************************************************
+--
+-- Network MEDLINE Archive message formats
+-- Ostell 1993
+--
+--
+--*********************************************************************
+--
+-- mla.asn
+--
+-- messages for medline archive data access
+--
+--*********************************************************************
+
+NCBI-MedArchive DEFINITIONS ::=
+BEGIN
+
+IMPORTS Medline-entry, PubMedId FROM NCBI-Medline
+ Medlars-entry FROM NCBI-Medlars
+ Pubmed-entry FROM NCBI-PubMed
+ Medline-si FROM NCBI-Medline
+ Pub FROM NCBI-Pub
+ Title FROM NCBI-Biblio;
+
+ --**********************************
+ -- requests
+ --
+
+Mla-request ::= CHOICE {
+ init [0] NULL, -- DlInit
+ getmle [1] INTEGER, -- get MedlineEntry
+ getpub [2] INTEGER, -- get citation by muid
+ gettitle [3] Title-msg, -- match titles
+ citmatch [4] Pub, --
+ fini [5] NULL, -- DlFini
+ getmriuids [6] INTEGER, -- Get MUIDs for an MRI
+ getaccuids [7] Medline-si, -- Get MUIDs for an Accessions
+ uidtopmid [8] INTEGER, -- get PMID for MUID
+ pmidtouid [9] PubMedId, -- get MUID for PMID
+ getmlepmid [10] PubMedId, -- get MedlineEntry by PubMed id
+ getpubpmid [11] PubMedId, -- get citation by PubMed id
+ citmatchpmid [12] Pub, -- citation match, PMID on out
+ getmripmids [13] INTEGER, -- get PMIDs for an MRI
+ getaccpmids [14] Medline-si,-- get PMIDs for an Accessions
+ citlstpmids [15] Pub, -- generate list of PMID for Pub
+ getmleuid [16] INTEGER, -- get MedlineEntry by Medline id
+ getmlrpmid [17] PubMedId, -- get MedlarsEntry by PubMed id
+ getmlruid [18] INTEGER -- get MedlarsEntry by Medline id
+ }
+
+--**********************************************************************
+--
+-- if request = all
+-- if one row returned
+-- reply=all, return every column
+-- else
+-- reply=ml-jta for each row
+--
+-- if request = not-set, reply=ml-jta
+--
+-- otherwise,
+-- if request != ml-jta
+-- if column exist, reply=column, else reply=ml-jta
+--
+--**********************************************************************
+
+Title-type ::= ENUMERATED {
+ not-set (0), -- request=ml-jta (default), reply=not-found
+ name (1),
+ tsub (2),
+ trans (3),
+ jta (4),
+ iso-jta (5),
+ ml-jta (6),
+ coden (7),
+ issn (8),
+ abr (9),
+ isbn (10),
+ all (255)
+ }
+
+Title-msg ::= SEQUENCE { -- Title match request/response
+ type Title-type, -- type to get, or type returned
+ title Title -- title(s) to look up, or title(s) found
+ }
+
+Title-msg-list ::= SEQUENCE {
+ num INTEGER, -- number of titles
+ titles SEQUENCE OF Title-msg
+ }
+
+Error-val ::= ENUMERATED {
+ not-found (0), -- Entry was not found
+ operational-error (1), -- A run-time operation error was occurred
+ cannot-connect-jrsrv (2), -- Cannot connect to Journal server
+ cannot-connect-pmdb (3), -- Cannot connect to PubMed
+ journal-not-found (4), -- Journal title not found
+ citation-not-found (5), -- Volume, Page and Author do not match any
+ -- article
+ citation-ambiguous (6), -- More than one article found
+ citation-too-many (7) -- Too many article was found
+ }
+
+Mla-back ::= CHOICE {
+ init [0] NULL, -- DlInit
+ error [1] Error-val, -- not found for getmle/getpub/citmatch
+ getmle [2] Medline-entry, -- got Medline Entry
+ getpub [3] Pub,
+ gettitle [4] Title-msg-list, -- match titles
+ citmatch [5] INTEGER, -- citation lookup muid or 0
+ fini [6] NULL, -- DlFini
+ getuids [7] SEQUENCE OF INTEGER, -- got a set of MUIDs
+ getpmids [8] SEQUENCE OF INTEGER,-- got a set of PMIDs
+ outuid [9] INTEGER, -- result muid or 0 if not found
+ outpmid [10] PubMedId, -- result pmid or 0 if not found
+ getpme [11] Pubmed-entry, -- got Pubmed Entry
+ getmlr [12] Medlars-entry -- got Medlars Entry
+ }
+
+END
diff --git a/network/medarch/client/objmla.c b/network/medarch/client/objmla.c
new file mode 100644
index 00000000..efefc3ee
--- /dev/null
+++ b/network/medarch/client/objmla.c
@@ -0,0 +1,1023 @@
+#include <asn.h>
+
+#define NLM_GENERATED_CODE_PROTO
+
+#include <mapmla.h>
+#include <objmla.h>
+
+static Boolean loaded = FALSE;
+
+#include <asnmla.h>
+
+#ifndef NLM_EXTERN_LOADS
+#define NLM_EXTERN_LOADS {}
+#endif
+
+NLM_EXTERN Boolean LIBCALL
+objmlaAsnLoad(void)
+{
+
+ if ( ! loaded) {
+ NLM_EXTERN_LOADS
+
+ if ( ! AsnLoad ())
+ return FALSE;
+ loaded = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/**************************************************
+* Generated object loaders for Module NCBI-MedArchive
+* Generated using ASNCODE Revision: 5.2 at Feb 6, 1997 4:41 PM
+*
+**************************************************/
+
+
+/**************************************************
+*
+* MlaRequestFree()
+*
+**************************************************/
+NLM_EXTERN
+MlaRequestPtr LIBCALL
+MlaRequestFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case MlaRequest_gettitle:
+ TitleMsgFree(anp -> data.ptrvalue);
+ break;
+ case MlaRequest_citmatch:
+ PubFree(anp -> data.ptrvalue);
+ break;
+ case MlaRequest_getaccuids:
+ MedlineSiFree(anp -> data.ptrvalue);
+ break;
+ case MlaRequest_citmatchpmid:
+ PubFree(anp -> data.ptrvalue);
+ break;
+ case MlaRequest_getaccpmids:
+ MedlineSiFree(anp -> data.ptrvalue);
+ break;
+ case MlaRequest_citlstpmids:
+ PubFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* MlaRequestAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+MlaRequestPtr LIBCALL
+MlaRequestAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objmlaAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* MlaRequest ::= (self contained) */
+ atp = AsnReadId(aip, amp, MLA_REQUEST);
+ } else {
+ atp = AsnLinkType(orig, MLA_REQUEST); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == MLA_REQUEST_init) {
+ choice = MlaRequest_init;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == MLA_REQUEST_getmle) {
+ choice = MlaRequest_getmle;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_getpub) {
+ choice = MlaRequest_getpub;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_gettitle) {
+ choice = MlaRequest_gettitle;
+ func = (AsnReadFunc) TitleMsgAsnRead;
+ }
+ else if (atp == MLA_REQUEST_citmatch) {
+ choice = MlaRequest_citmatch;
+ func = (AsnReadFunc) PubAsnRead;
+ }
+ else if (atp == MLA_REQUEST_fini) {
+ choice = MlaRequest_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == MLA_REQUEST_getmriuids) {
+ choice = MlaRequest_getmriuids;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_getaccuids) {
+ choice = MlaRequest_getaccuids;
+ func = (AsnReadFunc) MedlineSiAsnRead;
+ }
+ else if (atp == MLA_REQUEST_uidtopmid) {
+ choice = MlaRequest_uidtopmid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_pmidtouid) {
+ choice = MlaRequest_pmidtouid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_getmlepmid) {
+ choice = MlaRequest_getmlepmid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_getpubpmid) {
+ choice = MlaRequest_getpubpmid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_citmatchpmid) {
+ choice = MlaRequest_citmatchpmid;
+ func = (AsnReadFunc) PubAsnRead;
+ }
+ else if (atp == MLA_REQUEST_getmripmids) {
+ choice = MlaRequest_getmripmids;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_getaccpmids) {
+ choice = MlaRequest_getaccpmids;
+ func = (AsnReadFunc) MedlineSiAsnRead;
+ }
+ else if (atp == MLA_REQUEST_citlstpmids) {
+ choice = MlaRequest_citlstpmids;
+ func = (AsnReadFunc) PubAsnRead;
+ }
+ else if (atp == MLA_REQUEST_getmleuid) {
+ choice = MlaRequest_getmleuid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_getmlrpmid) {
+ choice = MlaRequest_getmlrpmid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_REQUEST_getmlruid) {
+ choice = MlaRequest_getmlruid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* MlaRequestAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+MlaRequestAsnWrite(MlaRequestPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objmlaAsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, MLA_REQUEST); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case MlaRequest_init:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_init, &av);
+ break;
+ case MlaRequest_getmle:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_getmle, &av);
+ break;
+ case MlaRequest_getpub:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_getpub, &av);
+ break;
+ case MlaRequest_gettitle:
+ writetype = MLA_REQUEST_gettitle;
+ func = (AsnWriteFunc) TitleMsgAsnWrite;
+ break;
+ case MlaRequest_citmatch:
+ writetype = MLA_REQUEST_citmatch;
+ func = (AsnWriteFunc) PubAsnWrite;
+ break;
+ case MlaRequest_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_fini, &av);
+ break;
+ case MlaRequest_getmriuids:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_getmriuids, &av);
+ break;
+ case MlaRequest_getaccuids:
+ writetype = MLA_REQUEST_getaccuids;
+ func = (AsnWriteFunc) MedlineSiAsnWrite;
+ break;
+ case MlaRequest_uidtopmid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_uidtopmid, &av);
+ break;
+ case MlaRequest_pmidtouid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_pmidtouid, &av);
+ break;
+ case MlaRequest_getmlepmid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_getmlepmid, &av);
+ break;
+ case MlaRequest_getpubpmid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_getpubpmid, &av);
+ break;
+ case MlaRequest_citmatchpmid:
+ writetype = MLA_REQUEST_citmatchpmid;
+ func = (AsnWriteFunc) PubAsnWrite;
+ break;
+ case MlaRequest_getmripmids:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_getmripmids, &av);
+ break;
+ case MlaRequest_getaccpmids:
+ writetype = MLA_REQUEST_getaccpmids;
+ func = (AsnWriteFunc) MedlineSiAsnWrite;
+ break;
+ case MlaRequest_citlstpmids:
+ writetype = MLA_REQUEST_citlstpmids;
+ func = (AsnWriteFunc) PubAsnWrite;
+ break;
+ case MlaRequest_getmleuid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_getmleuid, &av);
+ break;
+ case MlaRequest_getmlrpmid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_getmlrpmid, &av);
+ break;
+ case MlaRequest_getmlruid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_REQUEST_getmlruid, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* TitleMsgNew()
+*
+**************************************************/
+NLM_EXTERN
+TitleMsgPtr LIBCALL
+TitleMsgNew(void)
+{
+ TitleMsgPtr ptr = MemNew((size_t) sizeof(TitleMsg));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* TitleMsgFree()
+*
+**************************************************/
+NLM_EXTERN
+TitleMsgPtr LIBCALL
+TitleMsgFree(TitleMsgPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ TitleFree(ptr -> title);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* TitleMsgAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+TitleMsgPtr LIBCALL
+TitleMsgAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ TitleMsgPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objmlaAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* TitleMsg ::= (self contained) */
+ atp = AsnReadId(aip, amp, TITLE_MSG);
+ } else {
+ atp = AsnLinkType(orig, TITLE_MSG);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = TitleMsgNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == TITLE_MSG_type) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> type = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TITLE_MSG_title) {
+ ptr -> title = TitleAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = TitleMsgFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* TitleMsgAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+TitleMsgAsnWrite(TitleMsgPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objmlaAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, TITLE_MSG); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> type;
+ retval = AsnWrite(aip, TITLE_MSG_type, &av);
+ if (ptr -> title != NULL) {
+ if ( ! TitleAsnWrite(ptr -> title, aip, TITLE_MSG_title)) {
+ goto erret;
+ }
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* TitleMsgListNew()
+*
+**************************************************/
+NLM_EXTERN
+TitleMsgListPtr LIBCALL
+TitleMsgListNew(void)
+{
+ TitleMsgListPtr ptr = MemNew((size_t) sizeof(TitleMsgList));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* TitleMsgListFree()
+*
+**************************************************/
+NLM_EXTERN
+TitleMsgListPtr LIBCALL
+TitleMsgListFree(TitleMsgListPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ AsnGenericUserSeqOfFree(ptr -> titles, (AsnOptFreeFunc) TitleMsgFree);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* TitleMsgListAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+TitleMsgListPtr LIBCALL
+TitleMsgListAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ TitleMsgListPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objmlaAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* TitleMsgList ::= (self contained) */
+ atp = AsnReadId(aip, amp, TITLE_MSG_LIST);
+ } else {
+ atp = AsnLinkType(orig, TITLE_MSG_LIST);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = TitleMsgListNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == TITLE_MSG_LIST_num) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> num = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TITLE_MSG_LIST_titles) {
+ ptr -> titles = AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) TitleMsgAsnRead, (AsnOptFreeFunc) TitleMsgFree);
+ if (isError && ptr -> titles == NULL) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = TitleMsgListFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* TitleMsgListAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+TitleMsgListAsnWrite(TitleMsgListPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objmlaAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, TITLE_MSG_LIST); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> num;
+ retval = AsnWrite(aip, TITLE_MSG_LIST_num, &av);
+ AsnGenericUserSeqOfAsnWrite(ptr -> titles, (AsnWriteFunc) TitleMsgAsnWrite, aip, TITLE_MSG_LIST_titles, TITLE_MSG_LIST_titles_E);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* MlaBackFree()
+*
+**************************************************/
+NLM_EXTERN
+MlaBackPtr LIBCALL
+MlaBackFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case MlaBack_getmle:
+ MedlineEntryFree(anp -> data.ptrvalue);
+ break;
+ case MlaBack_getpub:
+ PubFree(anp -> data.ptrvalue);
+ break;
+ case MlaBack_gettitle:
+ TitleMsgListFree(anp -> data.ptrvalue);
+ break;
+ case MlaBack_getuids:
+ AsnGenericBaseSeqOfFree((ValNodePtr) pnt,ASNCODE_INTVAL_SLOT);
+ break;
+ case MlaBack_getpmids:
+ AsnGenericBaseSeqOfFree((ValNodePtr) pnt,ASNCODE_INTVAL_SLOT);
+ break;
+ case MlaBack_getpme:
+ PubmedEntryFree(anp -> data.ptrvalue);
+ break;
+ case MlaBack_getmlr:
+ MedlarsEntryFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* MlaBackAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+MlaBackPtr LIBCALL
+MlaBackAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objmlaAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* MlaBack ::= (self contained) */
+ atp = AsnReadId(aip, amp, MLA_BACK);
+ } else {
+ atp = AsnLinkType(orig, MLA_BACK); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == MLA_BACK_init) {
+ choice = MlaBack_init;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == MLA_BACK_error) {
+ choice = MlaBack_error;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_BACK_getmle) {
+ choice = MlaBack_getmle;
+ func = (AsnReadFunc) MedlineEntryAsnRead;
+ }
+ else if (atp == MLA_BACK_getpub) {
+ choice = MlaBack_getpub;
+ func = (AsnReadFunc) PubAsnRead;
+ }
+ else if (atp == MLA_BACK_gettitle) {
+ choice = MlaBack_gettitle;
+ func = (AsnReadFunc) TitleMsgListAsnRead;
+ }
+ else if (atp == MLA_BACK_citmatch) {
+ choice = MlaBack_citmatch;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_BACK_fini) {
+ choice = MlaBack_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == MLA_BACK_getuids) {
+ choice = MlaBack_getuids;
+ anp -> data.ptrvalue =
+ AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_INTVAL_SLOT, &isError);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == MLA_BACK_getpmids) {
+ choice = MlaBack_getpmids;
+ anp -> data.ptrvalue =
+ AsnGenericBaseSeqOfAsnRead(aip, amp, atp, ASNCODE_INTVAL_SLOT, &isError);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == MLA_BACK_outuid) {
+ choice = MlaBack_outuid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_BACK_outpmid) {
+ choice = MlaBack_outpmid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == MLA_BACK_getpme) {
+ choice = MlaBack_getpme;
+ func = (AsnReadFunc) PubmedEntryAsnRead;
+ }
+ else if (atp == MLA_BACK_getmlr) {
+ choice = MlaBack_getmlr;
+ func = (AsnReadFunc) MedlarsEntryAsnRead;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* MlaBackAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+MlaBackAsnWrite(MlaBackPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objmlaAsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, MLA_BACK); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case MlaBack_init:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, MLA_BACK_init, &av);
+ break;
+ case MlaBack_error:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_BACK_error, &av);
+ break;
+ case MlaBack_getmle:
+ writetype = MLA_BACK_getmle;
+ func = (AsnWriteFunc) MedlineEntryAsnWrite;
+ break;
+ case MlaBack_getpub:
+ writetype = MLA_BACK_getpub;
+ func = (AsnWriteFunc) PubAsnWrite;
+ break;
+ case MlaBack_gettitle:
+ writetype = MLA_BACK_gettitle;
+ func = (AsnWriteFunc) TitleMsgListAsnWrite;
+ break;
+ case MlaBack_citmatch:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_BACK_citmatch, &av);
+ break;
+ case MlaBack_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, MLA_BACK_fini, &av);
+ break;
+ case MlaBack_getuids:
+ retval = AsnGenericBaseSeqOfAsnWrite((Pointer) pnt,ASNCODE_INTVAL_SLOT, aip, MLA_BACK_getuids, MLA_BACK_getuids_E); break;
+ case MlaBack_getpmids:
+ retval = AsnGenericBaseSeqOfAsnWrite((Pointer) pnt,ASNCODE_INTVAL_SLOT, aip, MLA_BACK_getpmids, MLA_BACK_getpmids_E); break;
+ case MlaBack_outuid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_BACK_outuid, &av);
+ break;
+ case MlaBack_outpmid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, MLA_BACK_outpmid, &av);
+ break;
+ case MlaBack_getpme:
+ writetype = MLA_BACK_getpme;
+ func = (AsnWriteFunc) PubmedEntryAsnWrite;
+ break;
+ case MlaBack_getmlr:
+ writetype = MLA_BACK_getmlr;
+ func = (AsnWriteFunc) MedlarsEntryAsnWrite;
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
diff --git a/network/medarch/client/objmla.h b/network/medarch/client/objmla.h
new file mode 100644
index 00000000..63ac601b
--- /dev/null
+++ b/network/medarch/client/objmla.h
@@ -0,0 +1,147 @@
+#ifndef _objmla_
+#define _objmla_
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+
+#ifdef __cplusplus
+extern "C" { /* } */
+#endif
+
+
+/**************************************************
+*
+* Generated objects for Module NCBI-MedArchive
+* Generated using ASNCODE Revision: 5.2 at Feb 6, 1997 4:41 PM
+*
+**************************************************/
+
+NLM_EXTERN Boolean LIBCALL
+objmlaAsnLoad PROTO((void));
+typedef ValNodePtr MlaRequestPtr;
+typedef ValNode MlaRequest;
+#define MlaRequest_init 1
+#define MlaRequest_getmle 2
+#define MlaRequest_getpub 3
+#define MlaRequest_gettitle 4
+#define MlaRequest_citmatch 5
+#define MlaRequest_fini 6
+#define MlaRequest_getmriuids 7
+#define MlaRequest_getaccuids 8
+#define MlaRequest_uidtopmid 9
+#define MlaRequest_pmidtouid 10
+#define MlaRequest_getmlepmid 11
+#define MlaRequest_getpubpmid 12
+#define MlaRequest_citmatchpmid 13
+#define MlaRequest_getmripmids 14
+#define MlaRequest_getaccpmids 15
+#define MlaRequest_citlstpmids 16
+#define MlaRequest_getmleuid 17
+#define MlaRequest_getmlrpmid 18
+#define MlaRequest_getmlruid 19
+
+
+NLM_EXTERN MlaRequestPtr LIBCALL MlaRequestFree PROTO ((MlaRequestPtr ));
+NLM_EXTERN MlaRequestPtr LIBCALL MlaRequestAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL MlaRequestAsnWrite PROTO (( MlaRequestPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TitleMsg
+*
+**************************************************/
+typedef struct struct_Title_msg {
+ struct struct_Title_msg PNTR next;
+ Uint2 type;
+ ValNodePtr title;
+} TitleMsg, PNTR TitleMsgPtr;
+
+
+NLM_EXTERN TitleMsgPtr LIBCALL TitleMsgFree PROTO ((TitleMsgPtr ));
+NLM_EXTERN TitleMsgPtr LIBCALL TitleMsgNew PROTO (( void ));
+NLM_EXTERN TitleMsgPtr LIBCALL TitleMsgAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL TitleMsgAsnWrite PROTO (( TitleMsgPtr , AsnIoPtr, AsnTypePtr));
+
+/* following #defines are for enumerated type, not used by object loaders */
+#define Title_type_not_set 0
+#define Title_type_name 1
+#define Title_type_tsub 2
+#define Title_type_trans 3
+#define Title_type_jta 4
+#define Title_type_iso_jta 5
+#define Title_type_ml_jta 6
+#define Title_type_coden 7
+#define Title_type_issn 8
+#define Title_type_abr 9
+#define Title_type_isbn 10
+#define Title_type_all 255
+
+
+
+/**************************************************
+*
+* TitleMsgList
+*
+**************************************************/
+typedef struct struct_Title_msg_list {
+ Int4 num;
+ struct struct_Title_msg PNTR titles;
+} TitleMsgList, PNTR TitleMsgListPtr;
+
+
+NLM_EXTERN TitleMsgListPtr LIBCALL TitleMsgListFree PROTO ((TitleMsgListPtr ));
+NLM_EXTERN TitleMsgListPtr LIBCALL TitleMsgListNew PROTO (( void ));
+NLM_EXTERN TitleMsgListPtr LIBCALL TitleMsgListAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL TitleMsgListAsnWrite PROTO (( TitleMsgListPtr , AsnIoPtr, AsnTypePtr));
+
+/* following #defines are for enumerated type, not used by object loaders */
+#define Error_val_not_found 0
+#define Error_val_operational_error 1
+#define Error_val_cannot_connect_jrsrv 2
+#define Error_val_cannot_connect_pmdb 3
+#define Error_val_journal_not_found 4
+#define Error_val_citation_not_found 5
+#define Error_val_citation_ambiguous 6
+#define Error_val_citation_too_many 7
+
+typedef ValNodePtr MlaBackPtr;
+typedef ValNode MlaBack;
+#define MlaBack_init 1
+#define MlaBack_error 2
+#define MlaBack_getmle 3
+#define MlaBack_getpub 4
+#define MlaBack_gettitle 5
+#define MlaBack_citmatch 6
+#define MlaBack_fini 7
+#define MlaBack_getuids 8
+#define MlaBack_getpmids 9
+#define MlaBack_outuid 10
+#define MlaBack_outpmid 11
+#define MlaBack_getpme 12
+#define MlaBack_getmlr 13
+
+
+NLM_EXTERN MlaBackPtr LIBCALL MlaBackFree PROTO ((MlaBackPtr ));
+NLM_EXTERN MlaBackPtr LIBCALL MlaBackAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL MlaBackAsnWrite PROTO (( MlaBackPtr , AsnIoPtr, AsnTypePtr));
+
+#ifdef __cplusplus
+/* { */ }
+#endif
+
+#endif /* _objmla_ */
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
diff --git a/network/medarch/client/sybmed.c b/network/medarch/client/sybmed.c
new file mode 100644
index 00000000..a97e8d63
--- /dev/null
+++ b/network/medarch/client/sybmed.c
@@ -0,0 +1,275 @@
+/* fakemedarch.c
+* ===========================================================================
+*
+* File Name: fakemedarch.c
+*
+* Author: Chung
+*
+* Version Creation Date: 04/01/94
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Fake API for Medline Archive service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*/
+
+#include <objmedli.h>
+#include <objpub.h>
+#include <objall.h>
+#include <medarch.h>
+#include <objbibli.h>
+#include "mapmedarch.h"
+#include <objmla.h>
+
+extern CloseDatabaseConnection();
+extern InitMedlineDB();
+extern MedlineEntryPtr SybaseMedlineEntryGet( Int4 ui );
+extern CitArtPtr SybaseMedlinePubGet( Int4 ui );
+extern TitleMsgListPtr SybaseMedlineGetTitle( TitleMsgPtr tmsg );
+extern int SybaseMedlineCitMatch( CitArtPtr citation );
+
+/*****************************************************************************
+*
+* MedArchInit ()
+*
+*****************************************************************************/
+
+Boolean MedArchInit (void)
+
+{
+ return( InitMedlineDB() );
+}
+
+/*****************************************************************************
+*
+* MedArchFini ()
+*
+*****************************************************************************/
+
+Boolean MedArchFini (void)
+
+{
+ CloseMedlineDB();
+}
+
+
+/*****************************************************************************
+*
+* MedArchMedlineEntryListGet
+*
+*****************************************************************************/
+
+Int4
+MedArchMedlineEntryListGet (MedlineEntryPtr PNTR result, Int4 numuid,
+ Int4Ptr uids, Boolean mark_missing)
+{
+ Int4 j;
+ MedlineEntryPtr mep;
+ Int4 retval = 0;
+
+ for (j = 0; j < numuid; j++)
+ {
+ mep = SybaseMedlineEntryGet (uids[j]);
+
+ result[j] = mep;
+ if (mep != NULL)
+ {
+ retval++;
+ } else {
+ if (mark_missing)
+ {
+ uids[j] *= -1;
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+*
+* MedArchMedlineEntryGet
+*
+*****************************************************************************/
+
+MedlineEntryPtr
+MedArchMedlineEntryGet (Int4 uid)
+{
+ MedlineEntryPtr mep = NULL;
+
+ MedArchMedlineEntryListGet (&mep, 1, &uid, FALSE);
+ return mep;
+}
+
+/*****************************************************************************
+*
+* s_MedArchPubSetEntryGet
+*
+*****************************************************************************/
+
+static MedlineEntryPtr
+s_MedArchPubSetEntryGet (Int4 uid, MedlineEntryPtr lastmep, AsnIoPtr aip,
+ AsnTypePtr atp )
+{
+ MedlineEntryPtr mep;
+
+
+ /* write the caller's last entry to a file while waiting for the server */
+ /* to compute and send the answer for the current entry */
+
+ if (lastmep != NULL && aip != NULL) {
+ MedlineEntryAsnWrite (lastmep, aip, atp);
+ }
+
+ mep = SybaseMedlineEntryGet (uid);
+
+ return mep;
+}
+
+
+/*****************************************************************************
+*
+* MedArchPubSetEntryGet
+*
+*****************************************************************************/
+
+Int4 MedArchPubSetCreate (AsnIoPtr aip, Int4 numuid, Int4Ptr uids,
+ Boolean mark_missing)
+{
+ static Boolean alreadyInited = FALSE;
+ AsnTypePtr startAtp;
+ AsnTypePtr pubSetAtp;
+ AsnTypePtr pubSetEAtp;
+ AsnModulePtr amp;
+ DataVal av;
+ Int4 j;
+ Int4 i;
+ MedlineEntryPtr mep;
+ MedlineEntryPtr lastmep = NULL;
+ Int4 retval = 0;
+
+ if (! alreadyInited) {
+ amp = AsnAllModPtr();
+ if (amp == NULL) {
+ return 0;
+ }
+ alreadyInited = TRUE;
+ startAtp = AsnTypeFind(amp, "Pub-set");
+ pubSetAtp = AsnTypeFind(amp, "Pub-set.medline");
+ pubSetEAtp = AsnTypeFind(amp, "Pub-set.medline.E");
+ }
+
+ AsnWrite (aip, startAtp, NULL);
+ AsnStartStruct (aip, pubSetAtp);
+
+ mep = s_MedArchPubSetEntryGet (uids[j], lastmep, aip, pubSetEAtp);
+ MedlineEntryFree (lastmep);
+ lastmep = NULL;
+
+ lastmep = mep;
+ if (mep != NULL)
+ retval++;
+ else
+ if (mark_missing)
+ uids[j] *= -1;
+
+ if (lastmep != NULL)
+ {
+ MedlineEntryAsnWrite (lastmep, aip, pubSetEAtp);
+ MedlineEntryFree (lastmep);
+ }
+
+ AsnEndStruct (aip, pubSetAtp);
+
+ return retval;
+}
+
+
+/*****************************************************************************
+*
+* MedArchGetPub
+* changed by Tatiana 04-14-94
+*****************************************************************************/
+
+ValNodePtr MedArchGetPub (Int4 uid)
+{
+ ValNodePtr pub;
+ CitArtPtr art, tmp;
+
+ if ((tmp = SybaseMedlinePubGet(uid)) != NULL) {
+ pub = ValNodeNew(NULL);
+ art = AsnIoMemCopy(tmp, (AsnReadFunc) CitArtAsnRead,
+ (AsnWriteFunc) CitArtAsnWrite);
+ pub->choice = PUB_Article;
+ pub->data.ptrvalue = art;
+ return pub;
+ } else {
+ /* may be an error message here? Tatiana*/
+ return NULL;
+ }
+}
+
+
+/*****************************************************************************
+*
+* MedArchGetTitles
+*
+*****************************************************************************/
+
+static Int4
+s_MedArchGetTitles (CharPtr PNTR titles_found, Int1Ptr title_types_found, CharPtr title_to_lookup, Int1 request_type, Int1 response_type, Int4 max_titles_to_find)
+
+{
+ TitleMsgPtr tmsgp;
+ TitleMsgListPtr tmlp;
+ Int4 i;
+
+ tmsgp = TitleMsgNew();
+ tmsgp->type = response_type;
+ tmsgp->title = ValNodeNew(NULL);
+ tmsgp->title->choice = request_type;
+ tmsgp->title->data.ptrvalue = (Pointer) StringSave(title_to_lookup);
+
+ tmlp = SybaseMedlineGetTitle( tmsgp );
+
+ MemFree( tmsgp->title->data.ptrvalue );
+ tmsgp->title->data.ptrvalue = NULL;
+
+ for (i = 0, tmsgp = tmlp->titles; i < max_titles_to_find && i < tmlp->num &&
+ tmlp != NULL; i++, tmsgp = tmsgp->next)
+ {
+ titles_found[i] = (CharPtr) tmsgp->title->data.ptrvalue;
+ tmsgp->title->data.ptrvalue = NULL; /* for clean free */
+ title_types_found[i] = (Int1) tmsgp->type;
+ }
+
+ return i;
+}
+
+Int4
+MedArchGetTitles (CharPtr PNTR titles_found, Int1Ptr title_types_found, CharPtr title_to_lookup, Int1 request_type, Int1 response_type, Int4 max_titles_to_find)
+{
+ Int4 retval = 0;
+
+ retval = s_MedArchGetTitles(titles_found, title_types_found,
+ title_to_lookup, request_type,
+ response_type, max_titles_to_find);
+ return retval;
+}
+
+
+/*****************************************************************************
+*
+* MedArchCitMatch
+*
+*****************************************************************************/
+
+Int4 MedArchCitMatch (ValNodePtr pub)
+{
+ return( SybaseMedlineCitMatch( (CitArtPtr)pub->data.ptrvalue ) );
+}
diff --git a/network/medarch/server/bulkgetmed.h b/network/medarch/server/bulkgetmed.h
new file mode 100644
index 00000000..3f398dfa
--- /dev/null
+++ b/network/medarch/server/bulkgetmed.h
@@ -0,0 +1,77 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: bulkgetmed.h,v $
+* Revision 6.0 1997/08/25 18:36:00 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:23 epstein
+* add RCS log revision history
+*
+*/
+
+
+#ifndef DEFS_MODULE_BULKGETMED_H
+#define DEFS_MODULE_BULKGETMED_H
+
+#include "database.h"
+#include "getmedart.h"
+
+/* This is the maximum number of bulk access channels */
+/* The current version only uses 10, but we may want to add
+ more later. They don't cost much. */
+
+#define MAX_BULK_CHANNELS 15
+
+typedef char BaseHandle[20];
+typedef char BulkHandle[32];
+
+typedef enum
+ { inactive, idle, query_sent, query_ok, have_results, have_data, at_end }
+DbState;
+
+typedef enum {
+ SyncHandler, ArticleHandler, AuthorHandler,
+ AbstractHandler, MeshHandler, QualifierHandler,
+ SubstanceHandler, XrefHandler, SupportHandler,
+ GeneSymbolHandler, IsoHandler, DoneHandler
+} Handler;
+
+
+typedef struct Channel {
+ BaseHandle base_handle;
+ long flag_mask;
+ long flag_value;
+ char *query_format;
+ Handler handler;
+ RETCODE (*load)();
+ int (*store)();
+ DBINT (*get_ui)();
+} Channel;
+
+typedef struct BChan {
+ BulkHandle name;
+ DBPROCESS *db;
+ RETCODE rc;
+ DbState state;
+ Channel *channel;
+ void *data;
+ int errors;
+} BChan;
+
+typedef struct BulkDb {
+ int flags;
+ int bulk_id;
+ BChan *iso_channel;
+ int n_channels;
+ DBINT last_ui;
+ int articles;
+ BChan channel[MAX_BULK_CHANNELS];
+} BulkDb;
+
+extern BulkDb *BulkOpenMedline( char *, const char *, const int );
+extern void BulkCloseMedline( BulkDb * );
+extern int BulkGetMedline( BulkDb *, MedArt * );
+
+#endif /* DEFS_MODULE_BULKGETMED_H */
diff --git a/network/medarch/server/charset.h b/network/medarch/server/charset.h
new file mode 100644
index 00000000..8df9ca32
--- /dev/null
+++ b/network/medarch/server/charset.h
@@ -0,0 +1,132 @@
+/*
+ PROJECT: Medline database.
+ MODULE: charset
+ FILES: charset.c, charset.h (this one)
+
+ This module contains the procedures needed to map from the Medline
+ EBCDIC character set to the domestic (no accented characters) and
+ internationalized ASCII character sets used in the Sybase database.
+
+ Work started: 10 June 1991, Rand Huntzinger
+ Original version completed: 24 July 1991, Rand S. Huntzinger
+*
+*
+* RCS Modification History:
+* $Log: charset.h,v $
+* Revision 6.0 1997/08/25 18:36:01 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:26 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEF_MODULE_CHARSET
+#define DEF_MODULE_CHARSET
+
+/* The CHARSET_SIZE parameter gives the maximum number of characters in
+ the input character set. It is used to allocate conversion tables. */
+
+#define CHARSET_SIZE 256
+
+/* The following declarations give the basic conversion types for the
+ characters in the character set. They indicate how to interpret the
+ source character in teh conversion process. */
+
+#define CHAR_OMIT (0) /* Omit this character - pad, etc. */
+#define CHAR_SIMPLE (1) /* EBCDIC -> ASCII = ISO-8859 */
+#define CHAR_INTERNATIONAL (2) /* ASCII char != ISO-8859 character */
+#define CHAR_DIACRITIC (3) /* Two byte source, mark + character */
+#define CHAR_SPECIAL (4) /* Generates a control character */
+#define CHAR_INVALID (5) /* The input character is not valid */
+
+/* These codes are used to separate sections of the MeSH heading
+ records. They correspond to EBCDIC codes 0x51->0x53 respectively.
+ They are coded in the conversion table as type CHAR_SPECIAL. */
+
+#define CHAR_SV '\001'
+#define CHAR_EV '\002'
+#define CHAR_SS '\003'
+
+/* These codes appear in the CvtChar cs_error field and determine how
+ character set errors are to be handled. */
+
+#define CHAR_BAD_ERROR 'E' /* Invalid character is an ERROR! */
+#define CHAR_BAD_WARN 'W' /* Invalid character is a warning */
+#define CHAR_BAD_COUNT 'C' /* Only count errors - don't flag */
+#define CHAR_BAD_SKIP 'S' /* Simply skip bad characters */
+
+
+/* The ConvTable structure describes the CvtChar cv_table rows. Each
+ character in the character set has one row of this type which gives
+ the type of conversion to take place plus a datum, which may be used
+ in the conversion. How the datum is used depends upon the type field. */
+
+typedef struct ConvTable {
+ char type; /* Type of the conversion */
+ char datum; /* Value is character */
+} ConvTable;
+
+
+/* The CharGroup structure is insed in the CvtChar in_table and diacritics
+ fields. It is used where the ASCII and ISO-8859 equivalents differ. The
+ CharGroup table has three tables, one which contains source tables, one
+ with the ascii and one with the ISO-8859 equivalents. The source character
+ is matched in the source string and the offset into that table is the
+ offset of the corresponding character in the ascii and iso tables.
+
+ This structure is used for handling types CHAR_INTERNATIONAL and
+ CHAR_DIACRITIC. */
+
+typedef struct CharGroup {
+ int n_set; /* Number of characters in set */
+ unsigned char *source; /* Source character (EBCDIC) */
+ char *ascii; /* Ascii conversion equivalents */
+ char *iso; /* ISO (international) equivalents */
+} CharGroup;
+
+
+/* The CvtChar structure describes how to convert the source character set
+ (a form of EBCDIC) into both ASCII and ISO-8859. It contains the
+ conversion table (cv_table) with associated tables for handling the
+ international tables (in_table and diacritics), the source character
+ set name, and information on how to handle errors. */
+
+typedef struct CvtChar {
+ char *name; /* Character set name */
+ int cs_size; /* # rows in cv_table */
+ char cs_error; /* Character set error level */
+ char mark_bad; /* True => mark bad characters */
+ char bad_ascii; /* ASCII bad character mark */
+ char bad_iso; /* ISO bad character mark */
+ ConvTable *cv_table; /* Base table */
+ CharGroup *in_table; /* ISO/ASCII diffs */
+ int n_diacritics; /* # diacritic tables */
+ CharGroup *diacritics; /* Diacritic tables */
+} CvtChar;
+
+
+/* The CvtCode structure is filled out by the ConvertChar() function to
+ translate a single character in the source character set into both it's
+ ASCII and ISO-8859 equivalents. */
+
+typedef struct CvtCode {
+ short in_bytes; /* Number of source character bytes */
+ short type; /* Conversion type (cvtable.type) */
+ char ascii; /* The ASCII equivalent */
+ char iso; /* The ISO equivalent */
+ short valid; /* True if character is to be used */
+} CvtCode;
+
+/* The following declarations are externally available routines defined
+ in the charset.c portion of this module */
+
+void InitializeCharacterSet( /* CvtChar *cs */ );
+CvtChar *GetCharacterSet();
+char *CharacterSetName();
+int ConvertCharacter();
+int ConvertString( /* char *in, int n, char *out, int size, int iso */ );
+int ConvertPatchedString( /* char *in, char *out, int out_size,
+ char *patch, int patch_size */ );
+
+#endif /* DEF_MODULE_CHARSET */
diff --git a/network/medarch/server/cmdline.c b/network/medarch/server/cmdline.c
new file mode 100644
index 00000000..fee88e3d
--- /dev/null
+++ b/network/medarch/server/cmdline.c
@@ -0,0 +1,630 @@
+/*
+ PROJECT: Medline database.
+ MODULE: cmdline
+ FILES: cmdline.c, (this one) cmdline.h
+
+ This module contains the ProcessCommandLine procedure which parses
+ the contents of the command line and stores the results in global
+ variables (global module).
+
+ Work started: 8 May 1991, Rand Huntzinger
+ Original version completed: 24 July 1991, Rand S. Huntzinger
+*
+*
+* RCS Modification History:
+* $Log: cmdline.c,v $
+* Revision 6.0 1997/08/25 18:36:03 madden
+* Revision changed to 6.0
+*
+* Revision 1.3 1995/05/17 17:54:29 epstein
+* add RCS log revision history
+*
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "ma_global.h"
+
+
+#define rindex(s,c) strrchr(s,c)
+
+/* The flagHelp field is made true if the -help flag is seen. It means that
+ the user wants us to print extensive help information and then exit without
+ actually processing any input files. */
+
+static short flagHelp = FALSE; /* TRUE => print help and exit */
+
+
+/* This table can be used to initialize string variables from the
+ environment. The env field contains the name of the environment
+ variable, the default field contains a default to be used if the
+ environment variable is non-null, and var contains the address
+ where the string pointer of the default is to be placed. These
+ defaults can be overriddent by command line options. */
+
+static struct env_default {
+ char *env;
+ char *def_value;
+ char **var;
+} init_env_table[] = {
+
+ /* These variables define the defaults to be used for logging
+ into the Medline database under Sybase. They include the
+ database name, server and Sybase user name and password */
+
+ ENV_DATABASE, DEF_DATABASE, &flagDatabase,
+ ENV_USER, DEF_USER, &flagUser,
+ ENV_SERVER, DEF_SERVER, &flagServer,
+ ENV_PASSWORD, DEF_PASSWORD, &flagPassword,
+ ENV_CONFIGFILE, DEF_CONFIGFILE, &flagConfigFile,
+
+};
+static int init_env_count = (sizeof(init_env_table)/sizeof(struct env_default));
+
+
+/* The FlagType enumerated type defines the various kinds of flags we
+ need to be able to interpret. They are used in the flag_options
+ table to get us to the proper flag handling routine for a given flag */
+
+typedef enum
+ { FtypeFormat, FtypeString, FtypeFlag, FtypeInt, FtypeWrite } FlagType;
+
+
+/* The flag_options table contains data describing all of the valid flag
+ options. It includes the text of the flag (ie. -update), text for the
+ generation of the help message (arg_note, help_message), data for
+ processing the flag (type, seen, option) and an address where the result
+ of flag processing is to be placed (address) */
+
+static struct flag_record {
+ char *flag; /* The name of the flag */
+ char *arg_note; /* The argument notation */
+ char *help_message; /* The associated help message */
+ FlagType type; /* The type of the flag */
+ short seen; /* Mark here if we've seen one. */
+ short option; /* Select options */
+ void *address; /* Where to store the result */
+} flag_options[] = {
+ { "-database", "name", "Sybase database to be used",
+ FtypeString, 0, 0, &flagDatabase },
+
+ { "-server", "name", "Sybase server to be used",
+ FtypeString, 0, 0, &flagServer },
+
+ { "-user", "name", "Sybase login name (default is Unix login)",
+ FtypeString, 0, 0, &flagUser },
+
+ { "-password", "string", "Password for Sybase login (prompt if omitted)",
+ FtypeString, 0, 0, &flagPassword },
+
+ { "-iso", "", "Output articles in ISO Latin 1 character set",
+ FtypeFlag, 0, 0, &flagISO },
+
+ { "-write", "format file", "Write a given format to a given file",
+ FtypeWrite, 0, 0, NULL },
+
+ { "-format", "name object symbol",
+ "Define how to write a given format",
+ FtypeFormat, 0, 0, NULL },
+
+ { "-config", "file", "Override default configuration file",
+ FtypeString, 0, 0, &flagConfigFile },
+
+ { "-verbose", "", "Print out job status information",
+ FtypeFlag, 0, 0, &flagVerbose },
+
+ { "-debug", "", "Verbose output & rollback changes (debugging)",
+ FtypeFlag, 0, 0, &flagDebug },
+
+ { "-trace", "", "Print out queries executed (debugging)",
+ FtypeFlag, 0, 1, &flagTrace },
+
+ { "-help", "", "Print usage message and runtime parameters",
+ FtypeFlag, 0, 0, &flagHelp },
+};
+static int flag_option_count =
+ (sizeof(flag_options)/sizeof(struct flag_record));
+
+
+/*
+ isint Is a string an integer value?
+
+ This procedure returns TRUE if the string is an integer value or
+ FALSE if not. A leading + or - is permitted.
+
+ Parameters:
+
+ s A pointer to the string to be tested.
+
+ Returns:
+
+ TRUE if a string representation of an integer, FALSE
+ otherwise.
+*/
+
+/*
+* isint(s)
+*/
+int isint( s )
+ char *s;
+{
+ /* NULL's ain't numeric! */
+
+ if( s == NULL ) return( FALSE );
+
+ /* Leading + or - followed by at least one digit */
+
+ if( *s == '+' || *s == '-' ) s++;
+ if( ! isdigit( *s ) ) return( FALSE );
+
+ /* Everything else must be a digit */
+
+ while( isdigit( *s ) ) s++;
+ return( (*s == NULL) ? TRUE : FALSE );
+}
+
+
+/*
+ init_command_globals Internal procedure to initialize defaults.
+
+ This procedure uses the init_env_table table to establish default
+ values for certain string variables using environment variables
+ which may override certain hard-wired defaults. These defaults
+ can then be overridden by switch options as well.
+
+ This procedure also initializes the programName global variable.
+
+ Parameters:
+
+ argv0 The name of the program (possibly with a
+ directory path). Used to initialize the
+ programName variable.
+
+ Returns: nothing
+*/
+
+static
+/*
+* init_command_globals(argv0)
+*/
+void init_command_globals( argv0 )
+ char *argv0;
+{
+ register int i;
+
+ /* Set the programName global variable */
+
+ programName = rindex( argv0, '/' );
+ programName = ( programName == NULL ) ? argv0 : programName + 1;
+
+ /* Initialize some variables from the environment */
+
+ for( i = 0; i < init_env_count; i++ ) {
+ char *v = getenv( init_env_table[i].env );
+ *init_env_table[i].var = (v == NULL) ? init_env_table[i].def_value : v;
+ }
+}
+
+
+/* The ARGUMENT_CHECK macro checks to see if the argument at index I in
+ the argv vector (V argument) has an argument (not at the end as
+ determined by argc (C argument) and the next item does not start with
+ a "-" indicating another flag. */
+
+#define ARGUMENT_CHECK2(C,V,F,I) if((I) >= (C) || ((V)[I][0] == '-' \
+ && (V)[I][1] != (char) 0)) { \
+ fprintf(stderr, "%s: missing or invalid arguments for option %s\n", \
+ programName, (V)[F] ); error_noted = TRUE; break; }
+#define ARGUMENT_CHECK(C,V,I) ARGUMENT_CHECK2(C,V,I,I+1)
+#if 0
+#define ARGUMENT_CHECK(C,V,I) if(((I)+1) >= (C) || (V)[(I)+1][0] == '-' ) { \
+ fprintf(stderr, "%s: option %s requires an argument\n", \
+ programName, (V)[I] ); error_noted = TRUE; break; }
+#endif
+
+/*
+ process_flag_options Internal routine to process flag arguments.
+
+ This procedure interprets the flag arguments passed in argc and
+ argv and decodes them into the variables to receive their values.
+
+ Parameters:
+
+ argc The number of arguments in argv.
+
+ argv An array of strings containing the arguments.
+
+ argument_label Label for non-option arguments.
+
+ Returns:
+ The index of the first non-flag argument (file name) if there
+ was no error, or the negative of this value if there was an
+ error.
+*/
+
+static
+/*
+* process_flag_options(argc,argv,argument_label)
+*/
+int process_flag_options( argc, argv, argument_label )
+ int argc;
+ char **argv;
+ char *argument_label;
+{
+ register int a;
+ short error_noted = FALSE;
+ short mode_option = 0;
+
+ /* Loop over the command line extracting the command options. The
+ first unprotected token (ie. not a flag argument) which does not
+ start with "-" is treated as the start of the input file list. */
+
+ for( a = 1; a < argc && argv[a][0] == '-'; a++ ) {
+ register int i;
+
+ /* Look the flag up in the argument list */
+
+ for( i = 0; i < flag_option_count; i++ )
+ if( strcmp( flag_options[i].flag, argv[a] ) == 0 )
+ break;
+
+ /* Process the flag */
+
+ if( i < flag_option_count ) {
+ switch( flag_options[i].type ) {
+ case FtypeString: /* Character string arguments */
+ ARGUMENT_CHECK(argc,argv,a);
+ *((char **) flag_options[i].address) = argv[++a];
+ break;
+ case FtypeFlag: /* Simple Boolean flag arguments */
+ *((short *) flag_options[i].address) = 1;
+ break;
+ case FtypeInt: /* Integer (long) value arguments */
+ ARGUMENT_CHECK(argc,argv,a);
+ ++a;
+ if(flag_options[i].option && strcmp(argv[a], "all") == 0) {
+ *((long *) flag_options[i].address) = -1L;
+ break;
+ }
+ if( ! isint( argv[a] ) || atol( argv[a] ) < 0) {
+ fprintf(stderr,
+ "%s: %s argument not an positive integer value.\n",
+ programName, argv[a-1] );
+ break;
+ }
+ *((long *) flag_options[i].address) = atol(argv[a]);
+ break;
+ case FtypeWrite: /* Add an output stream option */
+ ARGUMENT_CHECK(argc, argv, a);
+ ARGUMENT_CHECK2(argc, argv, a, (a+2));
+ if( outputStreamCount >= MAX_OUTPUT_STREAMS ) {
+ fprintf( stderr,
+ "%s: Only %d output streams are allowed, %s flag ignored!\n",
+ MAX_OUTPUT_STREAMS, argv[a] );
+ error_noted = TRUE;
+ } else {
+ outputStreams[outputStreamCount].format = argv[a+1];
+ outputStreams[outputStreamCount].file = argv[a+2];
+ outputStreams[outputStreamCount].handle = NULL;
+ outputStreamCount++;
+ }
+ a += 2;
+ break;
+ default: /* This shouldn't happen */
+ fprintf(stderr,
+ "%s: program error: bad flag_options[%d].type for %s\n",
+ programName, i, argv[a] );
+ }
+
+ /* Flag an error on duplicates */
+
+ if( flag_options[i].seen == 1) {
+ fprintf(stderr, "%s: option %s seen more than once\n",
+ programName, argv[a] );
+ error_noted = TRUE;
+ flag_options[i].seen++; /* We've seen this one! */
+ }
+ } else {
+ /* Invalid flag, issue diagnostic and skip protected argument */
+
+ fprintf(stderr, "%s: invalid option (%s)\n", programName, argv[a] );
+ if( argc > (a+2) && argv[a+1][0] != '-' && argv[a+2][0] == '-' )
+ a++; /* allow one protected argument */
+ error_noted = TRUE;
+ }
+ }
+
+ /* Final argument is start of file list */
+
+ return( error_noted ? -a : a );
+}
+
+
+/*
+ process_arguments Internal procedure to check file arguments
+
+ This procedure checks the non-option arguments. It makes sure that
+ each file exists and is readable. When done, it stores a pointer
+ to the input file list in argumentList and the number of input
+ files in argumentCount.
+
+ Parameters:
+
+ arg_index Index into argv pointing to the first
+ putative input file name.
+
+ argc The number of command line arguments.
+
+ argv The list of command line arguments.
+
+ Returns:
+ TRUE if the input list was OK, FALSE if there were errors.
+*/
+/*
+ * process_arguments( arg_index, argc, argv, check_procedure)
+ */
+static
+int process_arguments( arg_index, argc, argv, check_procedure )
+ int arg_index;
+ int argc;
+ char **argv;
+ int (*check_procedure)();
+{
+ register int i;
+ int error_noted = FALSE;
+
+ /* Check all of the input arguments */
+
+ for(i = arg_index; i < argc; i++ )
+ error_noted |= (! check_procedure( i - arg_index, argv[i] ) );
+
+ /* Set the input file count and list */
+
+ argumentCount = argc - arg_index;
+ argumentList = &argv[arg_index];
+
+ /* Done */
+
+ return( ! error_noted );
+}
+
+
+/*
+ usage_line Internal procedure to print an option help line
+
+ This procedure prints out the output line describing the option
+ flag with index 'i' in the flag_options table.
+
+ Parameters:
+
+ i The index into the flag_options table giving
+ the line to be printed.
+
+ Returns: nothing
+*/
+
+static
+/*
+* usage_line(i)
+*/
+void usage_line( i )
+ int i;
+{
+ char option[100];
+
+ /* Generate the full option and argument string */
+
+ sprintf( option, "%.40s %.40s", flag_options[i].flag,
+ flag_options[i].arg_note );
+
+ /* Now print out the usage line using this */
+
+ fprintf( stderr, " %-20.20s %.50s\n", option,
+ flag_options[i].help_message );
+}
+
+
+/*
+ output_command_summary Internal procedure to output parameters.
+
+ This procedure scans the flag_options table to produce a list of
+ the run parameters for this program as determined from the hard-
+ wired defaults, environment variables and command line arguments.
+ It is part of the extensive output generated by the -help command.
+
+ Parameters:
+
+ argument_label Label for non-option arguments
+
+ check_procedure Procedure to validate non-option
+ arguments.
+
+ Returns nothing.
+*/
+
+/*
+ * output_command_summary()
+*/
+static
+void output_command_summary( argument_label, check_procedure )
+ char *argument_label;
+ int (*check_procedure)();
+{
+ register int i;
+
+ fprintf(stderr, "\nParameters after command line processing:\n\n" );
+ for(i = 0; i < flag_option_count; i++ ) {
+ char *arg;
+
+ if( flag_options[i].type != FtypeFormat ) {
+ fprintf(stderr, " %10.10s: ", flag_options[i].flag );
+ switch( flag_options[i].type ) {
+ case FtypeString:
+ arg = *((char **) flag_options[i].address);
+ fprintf(stderr, "%s\n", (arg == NULL) ? "(default)" : arg );
+ break;
+ case FtypeInt:
+ fprintf(stderr, "%ld\n",
+ *((long *) flag_options[i].address) );
+ break;
+ case FtypeWrite:
+ fprintf(stderr, "(see output conversion table below)\n" );
+ break;
+ case FtypeFlag:
+ fprintf(stderr, "%s\n",
+ *((short *) flag_options[i].address) ? "on" : "off" );
+ break;
+ default:
+ fprintf(stderr, "<<ERROR>>\n" );
+ }
+ }
+ }
+
+ fprintf(stderr, "\nOutput conversions (specified by -write options)\n");
+ if( outputStreamCount > 0 ) {
+ for(i = 0; i < outputStreamCount; i++)
+ fprintf(stderr, "%4d) %s to %s\n", i+1, outputStreams[i].format,
+ strcmp(outputStreams[i].file, "-") == 0 ? "standard output" :
+ outputStreams[i].file );
+ } else {
+ fprintf( stderr, " 1) %s to standard output (default)\n",
+ DEFAULT_OUTPUT_FORMAT );
+ }
+
+ if( argumentCount > 0 ) {
+ fprintf(stderr, "\n%s: (n = %d)\n\n", argument_label, argumentCount );
+ for( i = 0; i < argumentCount; i++ ) {
+ fprintf(stderr, "%5d) %s [%sok]\n", i+1,
+ argumentList[i],
+ check_procedure( i, argumentList[i] ) ? "" : "not " );
+ }
+ }
+}
+
+
+/*
+ usage_error Internal procedure to output the entire usage message
+
+ This procedure prints out the entire usage message and then
+ exits from the program. The error_noted flag indicates whether
+ the program exits with a normal status (no error noted) or a
+ usage error status (if an error was noted). The normal status
+ exit occurs when the -help flag was used and there were no
+ command line errors.
+
+ Parameters:
+
+ error_noted If true, exit with usage error
+ status; otherwise, exit with
+ normal status.
+
+ argument_label Label to use on on-option arguments.
+
+ Returns:
+
+ This procedure does not return to the calling program, it
+ exits from the program with either EXIT_STATUS_OK (normal
+ exit status) or EXIT_STATUS_USAGE (usage error status)
+*/
+
+/*
+ * usage_error()
+*/
+static
+void usage_error( error_noted, argument_label, check_procedure )
+ int error_noted;
+ char *argument_label;
+ int (*check_procedure)();
+{
+ register int i;
+
+ /* Print out the basic usage error message */
+
+ fprintf(stderr, "\nUsage: %s [ options ] [ input_file ... ]\n\n",
+ programName );
+
+ /* Print out the mode options */
+
+ fprintf(stderr, "Usage mode options: (exclusive)\n" );
+ for(i = 0; i < flag_option_count; i++ )
+ if( flag_options[i].type == FtypeFormat )
+ usage_line( i );
+
+ /* Print out the other options */
+
+ fprintf(stderr, "\nOther options:\n" );
+ for(i = 0; i < flag_option_count; i++ )
+ if( flag_options[i].type != FtypeFormat )
+ usage_line( i );
+
+ /* Print out the analysis of the command line options */
+
+ if( flagHelp ) output_command_summary( argument_label, check_procedure );
+
+ /* Exit with the appropriate error status */
+
+ exit( error_noted ? EXIT_STATUS_USAGE : EXIT_STATUS_OK );
+}
+
+
+/*
+ ProcessCommandLine: Parse the Unix style command line.
+
+ This procedure parses the Unix command line and stores the results
+ of the parse in a set of global areas defined above. If an error
+ occurs, this procedure will generate a usage error diagnostic and
+ continue exit.
+
+ Parameters:
+
+ argc The number of command line arguments.
+
+ argv The list of command line arguments.
+
+ Return value: none.
+*/
+/*
+ * ProcessCommandLine()
+*/
+void ProcessCommandLine( argc, argv, argument_label, check_procedure )
+ int argc;
+ char **argv;
+ char *argument_label;
+ int (*check_procedure)();
+{
+ int arg_index;
+
+ /* Initialize the command line global variables */
+
+ init_command_globals( *argv );
+
+ /* Process the command line flag arguments */
+
+ arg_index = process_flag_options( argc, argv, argument_label );
+ if( flagDebug ) {
+ flagVerbose = TRUE; /* Debug => verbose too */
+ }
+
+ /* Check the input file names */
+
+ if( ! process_arguments( abs(arg_index), argc, argv, check_procedure ) ||
+ arg_index < 0 )
+ usage_error( TRUE, argument_label, check_procedure );
+
+ /* If this is a -help run, just print the diagnostics */
+
+ if( flagHelp ) usage_error( FALSE, argument_label, check_procedure );
+
+ /* Setup a few things */
+
+ /*if( flagTrace ) SybaseQueryPrintCount = -1;*/
+ if( outputStreamCount < 1 ) {
+ /* Default the output if necessary */
+ outputStreamCount = 1;
+ outputStreams[0].format = DEFAULT_OUTPUT_FORMAT;
+ outputStreams[0].file = DEFAULT_OUTPUT_FILE;
+ outputStreams[0].handle;
+ }
+
+ /* Done */
+}
diff --git a/network/medarch/server/cmdline.h b/network/medarch/server/cmdline.h
new file mode 100644
index 00000000..b2c30594
--- /dev/null
+++ b/network/medarch/server/cmdline.h
@@ -0,0 +1,32 @@
+/*
+ PROJECT: Medline database.
+ MODULE: cmdline
+ FILES: cmdline.c, cmdline.h (this one)
+
+ This file contains the definitions related to the command line
+ processor for the medline_load program.
+
+ Work started: 8 May 1991, Rand Huntzinger
+ Original version completed: 8 May 1991, Rand S. Huntzinger
+*
+*
+* RCS Modification History:
+* $Log: cmdline.h,v $
+* Revision 6.0 1997/08/25 18:36:05 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:32 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_CMDLINE
+#define DEFS_MODULE_CMDLINE
+
+/* ProcessComandLine - Parse the tokens on the command line and
+ store the results in various variables in the global area. */
+
+void ProcessCommandLine( /* int argc, char *argv[] */ );
+
+
+#endif /* DEFS_MODULE_CMDLINE */
diff --git a/network/medarch/server/config.h b/network/medarch/server/config.h
new file mode 100644
index 00000000..e91e2b21
--- /dev/null
+++ b/network/medarch/server/config.h
@@ -0,0 +1,65 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: config.h,v $
+* Revision 6.0 1997/08/25 18:36:06 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:34 epstein
+* add RCS log revision history
+*
+*/
+
+
+#define ENV_DATABASE "MEDLINE_DATABASE"
+#define ENV_USER "MEDLINE_USER"
+#define ENV_SERVER "MEDLINE_SERVER"
+#define ENV_PASSWORD "MEDLINE_PASSWORD"
+#define ENV_CONFIGFILE "MEDLINE_RETRIEVAL_CONFIG"
+
+#define DEF_SERVER "MEDLINE"
+#define DEF_DATABASE "medline"
+#define DEF_PASSWORD NULL
+#define DEF_USER NULL
+#ifdef MEDLINE_CONFIG_FILE
+#define DEF_CONFIGFILE MEDLINE_CONFIG_FILE
+#else
+#define DEF_CONFIGFILE "/sun/lib/medline.cfg"
+#endif
+
+#ifndef MAX_OUTPUT_STREAMS
+#define MAX_OUTPUT_STREAMS 15
+#endif
+
+#ifndef DEFAULT_OUTPUT_FORMAT
+#define DEFAULT_OUTPUT_FORMAT "asn1"
+#endif
+#ifndef DEFAULT_OUTPUT_FILE
+#define DEFAULT_OUTPUT_FILE "-"
+#endif
+
+extern char *programName;
+extern char *flagDatabase;
+extern char *flagServer;
+extern char *flagUser;
+extern char *flagPassword;
+extern char *flagConfigFile;
+extern short flagISO;
+extern short flagVerbose;
+extern short flagDebug;
+extern short flagTrace;
+extern short flagReload;
+extern int argumentCount;
+extern char **argumentList;
+
+#ifndef FALSE
+#define FALSE (1==0)
+#endif
+#ifndef TRUE
+#define TRUE (1==1)
+#endif
+
+#define EXIT_STATUS_OK 0
+#define EXIT_STATUS_USAGE 1
+#define EXIT_STATUS_ERROR 2
diff --git a/network/medarch/server/error.h b/network/medarch/server/error.h
new file mode 100644
index 00000000..7c62bae8
--- /dev/null
+++ b/network/medarch/server/error.h
@@ -0,0 +1,86 @@
+/*
+ PROJECT: Medline database.
+ MODULE: error
+ FILES error.c and error.h (this one).
+
+ This file contains defintions which pertain to the medline_load
+ error module, which handles all error messages (except for usage
+ errors) for the program.
+
+ Work started: 22 May 1991
+ Original version completed: 24 May 1991, Rand S. Huntzinger
+*
+*
+* RCS Modification History:
+* $Log: error.h,v $
+* Revision 6.0 1997/08/25 18:36:08 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:37 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_ERROR
+#define DEFS_MODULE_ERROR
+
+#include <stdio.h>
+#include "message.h"
+
+/* Define the various error handling options - these are basically issue
+ an error, issue a warning or just ignore it altogether */
+
+typedef enum { issue_error, issue_warning, ignore_error } ErrorOption;
+
+
+/* Define error message flags to be passed to the error handler. These
+ flags are used by the error handler to control how the error message
+ is handled. Programmer errors will get a reassuring "this isn't your
+ fault" message added, database errors will get query dumps, fatal errors
+ will cause the program to die, process errors will get logged to the
+ database, etc. */
+
+#define ERR_PROGRAMMER (1 << 9) /* Program logic error */
+#define ERR_DATABASE (1 << 10) /* Database access error */
+#define ERR_FATAL (1 << 11) /* Fatal error */
+#define ERR_SYSTEM (1 << 12) /* Non-database system error */
+#define ERR_PROCESS (1 << 13) /* Error in processing */
+#define ERR_USAGE (1 << 14) /* Error from command line */
+#define ERR_FILE_FORMAT (1 << 15) /* Error in input format */
+#define ERR_NO_QUERY_DUMP (1 << 16) /* Don't dump query */
+#define ERR_CHARSET (1 << 17) /* Character set error */
+#define ERR_LOG_TO_DATABASE (1 << 18) /* Log the error in database */
+
+/* This mask is used to extract the error type value for the LogMessage
+ flags word so it can be written into the BBErrors table. */
+
+#define ERR_TYPE_MASK 0xff /* Low 8 bits - error type */
+
+/* Define the error classes. These are the values which you will get when
+ you mask out the flag bits (above) using ERR_TYPE_MASK. */
+
+#define ERR_MESSAGE (0) /* A message */
+#define ERR_REQUEST (1) /* Request user intervention */
+#define ERR_WARNING (2) /* A warning message */
+#define ERR_ERROR (3) /* Error - abort entry */
+#define ERR_TYPE_COUNT (4) /* Number of error types */
+
+/* Define names for specific error types (groups of flags). These are
+ convenience definitions, so you don't have to or in everything on each
+ LogMessage call. */
+
+#define PROGRAM_ERROR ( ERR_PROGRAMMER | ERR_ERROR | ERR_FATAL )
+#define UNIX_IO_ERROR ( ERR_SYSTEM | ERR_ERROR | ERR_FATAL )
+#define DB_ERROR ( ERR_DATABASE | ERR_ERROR | ERR_FATAL )
+#define DB_WARNING ( ERR_DATABASE | ERR_WARNING | ERR_LOG_TO_DATABASE )
+#define PROCESS_ERROR ( ERR_PROCESS | ERR_LOG_TO_DATABASE | ERR_ERROR )
+#define PROCESS_WARNING ( ERR_PROCESS | ERR_LOG_TO_DATABASE | ERR_WARNING )
+#define PROCESS_MESSAGE ( ERR_PROCESS | ERR_LOG_TO_DATABASE | ERR_MESSAGE )
+#define USAGE_ERROR ( ERR_USAGE | ERR_ERROR | ERR_FATAL )
+#define INPUT_ERROR ( ERR_FILE_FORMAT | ERR_ERROR | ERR_FATAL )
+#define INPUT_WARNING ( ERR_FILE_FORMAT | ERR_LOG_TO_DATABASE | ERR_WARNING )
+#define CHARSET_ERROR ( ERR_CHARSET | ERR_LOG_TO_DATABASE | ERR_ERROR )
+#define CHARSET_WARNING ( ERR_CHARSET | ERR_LOG_TO_DATABASE | ERR_WARNING )
+
+
+#endif /* DEFS_MODULE_ERROR */
diff --git a/network/medarch/server/get_medline.h b/network/medarch/server/get_medline.h
new file mode 100644
index 00000000..fa0f53e1
--- /dev/null
+++ b/network/medarch/server/get_medline.h
@@ -0,0 +1,21 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: get_medline.h,v $
+* Revision 6.0 1997/08/25 18:36:10 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:39 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_GET_MEDLINE_H
+#define DEFS_MODULE_GET_MEDLINE_H
+
+#include "error.h"
+
+extern ErrContext errorContext;
+
+#endif /* DEFS_MODULE_GET_MEDLINE_H */
diff --git a/network/medarch/server/getmedart.c b/network/medarch/server/getmedart.c
new file mode 100644
index 00000000..1bd719c1
--- /dev/null
+++ b/network/medarch/server/getmedart.c
@@ -0,0 +1,848 @@
+#include "getmedart.h"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <string.h>
+
+#define bzero(b,length) memset(b,0,length)
+#define bcopy(b1,b2,length) memmove(b2,b1,length)
+
+/* NOTE: The mr_get_article script will return sections is numerical order! */
+
+#define MR_STATE_ARTICLE 0 /* Basic article data */
+#define MR_STATE_ISO_VTITLE 1
+#define MR_STATE_ISO_ADDRESS 2
+#define MR_STATE_AUTHOR 3
+#define MR_STATE_ISO_AUTHOR 4
+#define MR_STATE_ISO_ABSTRACT 5 /* We send ISO first for the */
+#define MR_STATE_ABSTRACT 6 /* abstract only */
+#define MR_STATE_MESH 7
+#define MR_STATE_SUBHEADING 8
+#define MR_STATE_SUBSTANCE 9
+#define MR_STATE_CROSSREFERENCE 10
+#define MR_STATE_SUPPORT 11
+#define MR_STATE_GENESYMBOL 12
+#define MR_STATE_DONE 255
+
+#define PATCH_BUFFER_SIZE 8192
+#define TEXT_BUFFER_SIZE 8192
+#define MAX_ABSTRACT_PATCHES 64
+
+extern FILE * Id_timing_file;
+
+#ifdef SYSV
+hrtime_t Time_start, Time_back;
+#define MACRO_before_exec \
+ if (Id_timing_file) \
+ Time_start = gethrtime();
+
+#define MACRO_after_exec(type) \
+ if (Id_timing_file) {\
+ Time_back = gethrtime();\
+ fprintf(Id_timing_file,"%s %ld %ld\n", #type, (long) (Time_start/1000000.), (long) (( Time_back- Time_start)/ 1000000. )); fflush(Id_timing_file);}
+#else
+struct timeb Time_start, Time_back;
+#define MACRO_before_exec \
+ if (Id_timing_file) \
+ ftime(&Time_start);
+
+#define MACRO_after_exec(type) \
+ if (Id_timing_file) {\
+ ftime (&Time_back);\
+ fprintf(Id_timing_file,"%s %ld %ld\n", #type, (long) Time_start.time, (long) (( Time_back.time - Time_start.time)* 1000 + (Time_back.millitm - Time_start.millitm))); fflush(Id_timing_file);}
+#endif
+
+typedef struct AbPatch {
+ DBINT line_no;
+ DBINT length;
+ DBBINARY *start;
+} AbPatch;
+
+typedef struct AbPList {
+ int n_patches;
+ AbPatch patches[MAX_ABSTRACT_PATCHES];
+ int used;
+ DBBINARY buffer[PATCH_BUFFER_SIZE];
+} AbPList;
+
+
+char *strstr();
+static
+/*
+* skip_undefined_section(DBPROCESSdb)
+* RCS Modification History:
+* $Log: getmedart.c,v $
+* Revision 6.0 1997/08/25 18:36:12 madden
+* Revision changed to 6.0
+*
+* Revision 1.3 1995/05/30 18:00:10 tatiana
+* cleanup title
+*
+* Revision 1.2 1995/05/17 17:54:43 epstein
+* add RCS log revision history
+*
+*/
+int skip_undefined_section( DBPROCESS *db )
+{
+ RETCODE rc;
+
+ /* This simply skips to the end of the data */
+
+ while( (rc = dbnextrow( db )) != NO_MORE_ROWS && rc != FAIL );
+ return( (rc == FAIL) ? Error : True );
+}
+
+
+static
+/*
+* title_append(DbTitle(title),charrest)
+*/
+void title_append( DbTitle(title), char *rest )
+{
+ int len;
+
+ if( *rest == 0 ) return;
+ for( len = strlen( title ); len < DBSIZE_Article_title; len++ )
+ title[len] = ' ';
+ strcpy( &title[len], rest );
+}
+
+static void check_title(char *title)
+{
+ char *s;
+
+ if ((s = strstr(title, "[see comments]")) != NULL) {
+ s--;
+ while( s >= title && (*s == ' ') ) {
+ *s = '\0';
+ s--;
+ }
+ }
+}
+
+void check_pages(char *pages)
+{
+ char *s;
+
+ for (; isspace(*pages); pages++);
+ if ((s = strchr(pages, ' ')) != NULL) {
+ *s = '\0';
+ }
+}
+
+static
+/*
+* process_article(DBPROCESSdb,MedArtrec)
+*/
+int process_article( DBPROCESS *db, MedArt *rec )
+{
+ RETCODE rc;
+ DbColumn (Article,title1);
+ DbColumn (Article,vtitle1);
+ char *chr;
+
+ /* Load the article row from the database */
+ /* TODO - CHECK THE FIELDS IN THE BIND! */
+ rc = SybaseLoad( db,
+ 1, INTBIND, sizeof(rec->ui), &rec->ui,
+ 2, INTBIND, sizeof(rec->mri), &rec->mri,
+ 3, NTBSTRINGBIND, sizeof(rec->title), rec->title,
+ 4, NTBSTRINGBIND, sizeof(title1), title1,
+ 5, NTBSTRINGBIND, sizeof(rec->vtitle), rec->vtitle,
+ 6, NTBSTRINGBIND, sizeof(vtitle1), vtitle1,
+ 7, NTBSTRINGBIND, sizeof(rec->address), rec->address,
+ 8, NTBSTRINGBIND, sizeof(rec->pages), rec->pages,
+ 9, SMALLBIND, 0, &rec->entry_month,
+ 10, NTBSTRINGBIND, sizeof(rec->volume), rec->volume,
+ 11, NTBSTRINGBIND, sizeof(rec->issue), rec->issue,
+ 12, NTBSTRINGBIND, sizeof(rec->pubdate), rec->pubdate,
+ 13, NTBSTRINGBIND, sizeof(rec->med_abbr), rec->med_abbr,
+ 14, NTBSTRINGBIND, sizeof(rec->language_code), rec->language_code,
+ 0 );
+ if( rc != REG_ROW ) return( False );
+
+ /* Add the extension columns to the title and vtitle fields */
+
+ rec->title_type = 6; /* ml-jta */
+ title_append( rec->title, title1 );
+ title_append( rec->vtitle, vtitle1 );
+
+ check_title(rec->title);
+ check_title(rec->vtitle);
+
+ if (strncmp(rec->pages, "Suppl", 5) == 0) {
+ if ((chr = strchr(rec->pages, ':')) != NULL) {
+ *chr = '\0';
+ if (rec->issue[0] != '\0') {
+ strncat(rec->issue, rec->pages,
+ DBSIZE_Issue_issue - strlen(rec->issue));
+ } else {
+ strncat(rec->volume, rec->pages,
+ DBSIZE_Issue_volume - strlen(rec->volume));
+ }
+ strcpy(rec->pages, chr + 1);
+ }
+ }
+ check_pages(rec->pages);
+
+ /* Done */
+
+ return( True );
+}
+
+
+static
+/*
+* process_pub_article(DBPROCESSdb,MedArtrec)
+*/
+int process_pub_article( DBPROCESS *db, MedArt *rec )
+{
+ RETCODE rc;
+ DbColumn (Article,title1);
+ DbColumn (Article,vtitle1);
+ char *chr;
+
+ /* Load the article row from the database */
+ /* TODO - CHECK THE FIELDS IN THE BIND! */
+ rc = SybaseLoad( db,
+ 1, INTBIND, sizeof(rec->ui), &rec->ui,
+ 2, INTBIND, sizeof(rec->mri), &rec->mri,
+ 3, NTBSTRINGBIND, sizeof(rec->title), rec->title,
+ 4, NTBSTRINGBIND, sizeof(title1), title1,
+ 5, NTBSTRINGBIND, sizeof(rec->vtitle), rec->vtitle,
+ 6, NTBSTRINGBIND, sizeof(vtitle1), vtitle1,
+ 7, NTBSTRINGBIND, sizeof(rec->address), rec->address,
+ 8, NTBSTRINGBIND, sizeof(rec->pages), rec->pages,
+ 9, SMALLBIND, 0, &rec->entry_month,
+ 10, NTBSTRINGBIND, sizeof(rec->volume), rec->volume,
+ 11, NTBSTRINGBIND, sizeof(rec->issue), rec->issue,
+ 12, NTBSTRINGBIND, sizeof(rec->pubdate), rec->pubdate,
+ 13, NTBSTRINGBIND, sizeof(rec->med_abbr), rec->med_abbr,
+ 14, NTBSTRINGBIND, sizeof(rec->language_code), rec->language_code,
+ 15, INTBIND, sizeof(rec->title_type),&rec->title_type,
+ 0 );
+ if( rc != REG_ROW ) return( False );
+
+ /* Add the extension columns to the title and vtitle fields */
+
+ title_append( rec->title, title1 );
+ title_append( rec->vtitle, vtitle1 );
+
+ check_title(rec->title);
+ check_title(rec->vtitle);
+
+ if (strncmp(rec->pages, "Suppl", 5) == 0) {
+ if ((chr = strchr(rec->pages, ':')) != NULL) {
+ *chr = '\0';
+ if (rec->issue[0] != '\0') {
+ strncat(rec->issue, rec->pages,
+ DBSIZE_Issue_issue - strlen(rec->issue));
+ } else {
+ strncat(rec->volume, rec->pages,
+ DBSIZE_Issue_volume - strlen(rec->volume));
+ }
+ strcpy(rec->pages, chr + 1);
+ }
+ }
+ check_pages(rec->pages);
+
+ /* Done */
+
+ return( True );
+}
+
+
+static DBINT patch_sequence = 0;
+static DBINT patch_item = 0;
+static DBINT patch_length;
+static MaxBinary patch_line;
+
+static
+/*
+* load_patch(DBPROCESSdb,DBBINARYpatches,intsize,
+*/
+int load_patch( DBPROCESS *db, DBBINARY *patches, int size,
+ DBINT *item, DBINT *length, int first )
+{
+ RETCODE rc;
+ DBINT sequence;
+
+ /* If we have buffered a line - get it */
+
+ if( ! first && patch_sequence == 1 ) {
+ *item = patch_item;
+ bcopy( patch_line, patches, patch_length );
+ *length = patch_length;
+ sequence = 1;
+ } else {
+ *length = patch_length = patch_item = sequence = 0;
+ }
+
+ while ( (rc = SybaseLoad( db,
+ 1, INTBIND, 0, &patch_item,
+ 2, INTBIND, 0, &patch_sequence,
+ 3, INTBIND, 0, &patch_length,
+ 4, BINARYBIND, sizeof(patch_line), patch_line,
+ 0)) == REG_ROW )
+ {
+ /* If this is the first line - init the setup */
+
+ if( sequence == 0 ) {
+ if( patch_sequence != 1 ) continue; /* Skip junk */
+ *item = patch_item;
+ }
+
+ /* If we get this far, test for a continuation line */
+
+ if( patch_sequence == (sequence + 1) && patch_item == *item ) {
+ if( ( patch_length + *length ) > size )
+ goto error; /* Overflow */
+ bcopy( patch_line, patches + *length, patch_length );
+ *length += patch_length;
+ continue;
+ } else if( patch_sequence != 1 )
+ goto error; /* Patch sequence error */
+
+ /* If we get here - we're at the start of the next patch */
+
+ break;
+ }
+ if( rc == FAIL ) goto error;
+ if( rc != REG_ROW ) patch_sequence = 0; /* Reset on end */
+
+ /* Normal exit */
+
+ return( (*length == 0) ? False : True );
+
+ /* Error exit */
+
+error:
+ patch_sequence = 0;
+ return( Error );
+}
+
+
+/*ARGSUSED*/
+static
+/*
+* patch_string(DBPROCESSdb,charstr,intsize)
+*/
+int patch_string( DBPROCESS *db, char *str, int size )
+{
+ DBBINARY patches[PATCH_BUFFER_SIZE];
+ DBINT patch_length = 0, item = 0;
+ DBCHAR buffer[TEXT_BUFFER_SIZE];
+ int rv;
+ char *ptr;
+
+ /* Get the title patches from the input string */
+
+ if( ! DBROWS( db ) ) return( False );
+ rv = load_patch( db, patches, sizeof(patches), &item, &patch_length, True );
+ if( rv != True ) return( rv );
+
+ /* We have the patches, apply them */
+
+ if( ApplyIsoPatches( str, size, buffer, sizeof(buffer),
+ patches, patch_length ) > 0 )
+ {
+ return( Error );
+ }
+
+ /* Done - put the stuff back */
+ strcpy( str, buffer );
+ return( True );
+}
+
+
+static
+/*
+* process_author(DBPROCESSdb,MedArtrec)
+*/
+int process_author( DBPROCESS *db, MedArt *rec )
+{
+ DbColumn(Name,name);
+ RETCODE rc;
+ DBINT seq;
+
+ /* Read the author list */
+
+ while( (rc = SybaseLoad( db,
+ 1, INTBIND, 0, &seq,
+ 2, NTBSTRINGBIND, sizeof(name), name,
+ 0 )) == REG_ROW )
+ {
+ if( seq > MAX_AUTHOR_COUNT )
+ continue; /* Author index too large */
+ strcpy( rec->authors[seq], name );
+ if( (seq+1) > rec->n_authors ) rec->n_authors = seq+1;
+ }
+
+ return((rc == NO_MORE_ROWS) ? ((rec->n_authors == 0) ? False: True): Error);
+}
+
+
+/*ARGSUSED*/
+static
+/*
+* patch_author(DBPROCESSdb,MedArtrec)
+*/
+int patch_author( DBPROCESS *db, MedArt *rec )
+{
+ DBBINARY patches[PATCH_BUFFER_SIZE];
+ DBINT patch_length = 0, item = 0;
+ DBCHAR buffer[TEXT_BUFFER_SIZE];
+ int rv = False;
+ int first;
+
+ for( first = 1;; first = 0 ) {
+ switch( load_patch( db, patches, sizeof(patches), &item,
+ &patch_length, first ) )
+ {
+ case True: /* We found a patch */
+ if( ApplyIsoPatches( rec->authors[item-1],
+ sizeof(rec->authors[0]), buffer, sizeof(buffer),
+ patches, patch_length ) == 0 )
+ {
+ strcpy( rec->authors[item-1], buffer );
+ rv = True;
+ }
+ break;
+ case False: /* No patch found */
+ return( rv );
+ case Error: /* Oops - */
+ return( Error );
+ }
+ }
+}
+
+
+/*ARGSUSED*/
+static
+/*
+* process_abstract(DBPROCESSdb,MedArtrec,AbPListplist)
+*/
+int process_abstract( DBPROCESS *db, MedArt *rec, AbPList *plist )
+{
+ DbNColumn(Abstract,abstract,line); /* Line buffer */
+ int pi = 0; /* Index to next patch */
+ int ti = 0; /* Index to next text line */
+ int next_line = 1; /* Expect this line next */
+ int rv = False;
+ RETCODE rc;
+ DBINT line_no;
+
+ while( (sizeof(rec->abstract) - ti) >= sizeof(line) ) {
+
+ /* Skip patches to lines alsready passed */
+
+ while(pi < plist->n_patches && next_line > plist->patches[pi].line_no)
+ pi++;
+ /* If a patch is expected, prepare for it */
+
+ if( pi < plist->n_patches && next_line == plist->patches[pi].line_no ) {
+
+ /* The next line should be a patch line */
+ rc = SybaseLoad( db,
+ 1, INTBIND, sizeof(line_no), &line_no,
+ 2, NTBSTRINGBIND, sizeof(line), line,
+ 0 );
+
+ /* Apply the patch */
+
+ if( rc == REG_ROW && line_no == next_line ) {
+ (void) ApplyIsoPatches( line, strlen(line), &rec->abstract[ti],
+ sizeof(rec->abstract) - ti, plist->patches[pi].start,
+ plist->patches[pi].length );
+ }
+ } else {
+ rc = SybaseLoad( db,
+ 1, INTBIND, sizeof(line_no), &line_no,
+ 2, NTBSTRINGBIND, sizeof(line), &rec->abstract[ti],
+ 0 );
+ if( rc != REG_ROW ) break;
+ }
+ ti += strlen( &rec->abstract[ti] ); /* New abstract length */
+ next_line = line_no + 1;
+
+ /* Exit */
+ }
+
+ /* Return the status */
+
+ return( (rv == Error) ? rv : ((ti > 0) ? True : False) );
+}
+
+
+/*ARGSUSED*/
+static
+/*
+* patch_abstract(DBPROCESSdb,MedArtrec,AbPListplist)
+*/
+int patch_abstract( DBPROCESS *db, MedArt *rec, AbPList *plist )
+{
+ int first = 1;
+ int rv;
+
+ /* Load the patches */
+
+ for( plist->n_patches = 0; plist->n_patches < MAX_ABSTRACT_PATCHES &&
+ (rv = load_patch( db, &plist->buffer[plist->used],
+ sizeof(plist->buffer) - plist->used,
+ &plist->patches[plist->n_patches].line_no,
+ &plist->patches[plist->n_patches].length,
+ first )) == True;
+ plist->n_patches++ )
+ {
+ /* A patch was loaded - record it */
+ plist->used += plist->patches[plist->n_patches].length;
+ first = 0;
+ }
+
+ /* Done */
+
+ return( (rv == Error) ? Error : ((plist->n_patches > 0) ? True : False) );
+}
+
+
+static
+int mesh_compare( const void *m1, const void *m2 )
+{
+ return( strcmp( ((Mesh *) m1)->heading, ((Mesh *) m2)->heading ) );
+}
+
+static
+/*
+* process_mesh(DBPROCESSdb,MedArtrec)
+*/
+int process_mesh( DBPROCESS *db, MedArt *rec )
+{
+ DBINT id_mesh;
+ DbColumn (Mesh,main_point);
+ DbColumn (Mesh,heading);
+ RETCODE rc;
+
+
+ /* Read the main mesh headings into the table */
+
+ rec->n_mesh = 0;
+
+ while( (rc = SybaseLoad( db,
+ 1, INTBIND, 0, &id_mesh,
+ 2, NTBSTRINGBIND, sizeof(main_point), main_point,
+ 3, NTBSTRINGBIND, sizeof(heading), heading,
+ 0 )) == REG_ROW )
+ {
+ /* Load the MeSH heading into the table. */
+ if( rec->n_mesh >= MAX_MESH_COUNT ) continue; /* Too many */
+ rec->mesh[rec->n_mesh].id_mesh = id_mesh;
+ strcpy( rec->mesh[rec->n_mesh].main_point, main_point );
+ strcpy( rec->mesh[rec->n_mesh].heading, heading );
+ ( rec->n_mesh )++;
+ }
+
+ /* Done */
+
+ if ( rec->n_mesh > 0 )
+ qsort( rec->mesh, rec->n_mesh, sizeof(Mesh), mesh_compare );
+
+ return( rec->n_mesh == 0 ? False : True );
+}
+
+
+/*ARGSUSED*/
+static
+/*
+* process_subheading(DBPROCESSdb,MedArtrec)
+*/
+int process_subheading( DBPROCESS *db, MedArt *rec )
+{
+ RETCODE rc;
+ DbColumn (Subheading,main_point);
+ DbColumn (Subheading,code);
+ DbColumn (Subheading,name);
+ DbColumn (Subheading,description);
+ int id_mesh, i, seq;
+
+ while( (rc = SybaseLoad( db,
+ 1, INTBIND, 0, &id_mesh,
+ 2, NTBSTRINGBIND, sizeof(main_point), main_point,
+ 3, NTBSTRINGBIND, sizeof(code), code,
+ 4, NTBSTRINGBIND, sizeof(name), name,
+ 5, NTBSTRINGBIND, sizeof(description), description,
+ 0 )) == REG_ROW )
+ {
+ Qual *q;
+ Mesh *m;
+
+ for ( i = 0, seq = -1; i< rec->n_mesh; i++ )
+ if ( id_mesh == rec->mesh[i].id_mesh )
+ {
+ seq = i; break;
+ }
+
+ if( seq == -1 ) continue;
+ m = &rec->mesh[seq];
+
+ if( m->n_qual >= MAX_QUALIFIER_COUNT ) continue;
+ q = &m->qualifiers[m->n_qual++];
+ strcpy(q->main_point, main_point);
+ strcpy(q->code, code);
+ strcpy(q->name, name);
+ strcpy(q->description, description);
+ }
+ return( True );
+}
+
+
+/*ARGSUSED*/
+static
+/*
+* process_substance(DBPROCESSdb,MedArtrec)
+*/
+int process_substance( DBPROCESS *db, MedArt *rec )
+{
+ int i;
+ RETCODE rc;
+
+ /* Read the subsances from the database */
+
+ for( i = 0; i < MAX_SUBSTANCE_COUNT; i++ ) {
+ rc = SybaseLoad( db,
+ 1, NTBSTRINGBIND, sizeof(rec->substances[0].number),
+ rec->substances[i].number,
+ 2, NTBSTRINGBIND, sizeof(rec->substances[0].name),
+ rec->substances[i].name,
+ 0 );
+ if( rc != REG_ROW ) break;
+ }
+ rec->n_substances = i;
+
+ return( (rc == FAIL) ? Error : ( (i==0) ? False : True ) );
+}
+
+
+/*ARGSUSED*/
+static
+/*
+* process_xref(DBPROCESSdb,MedArtrec)
+*/
+int process_xref( DBPROCESS *db, MedArt *rec )
+{
+ int i;
+ RETCODE rc;
+
+ /* Read the subsances from the database */
+
+ for( i = 0; i < MAX_XREF_COUNT; i++ ) {
+ rc = SybaseLoad( db,
+ 1, NTBSTRINGBIND, sizeof(rec->xrefs[0].database),
+ rec->xrefs[i].database,
+ 2, NTBSTRINGBIND, sizeof(rec->xrefs[0].accession),
+ rec->xrefs[i].accession,
+ 0 );
+ if( rc != REG_ROW ) break;
+ }
+
+ /* Make sure that + is last */
+
+ rec->n_xrefs = i;
+
+ return( (rc == FAIL) ? Error : ( (i==0) ? False : True ) );
+}
+
+
+/*ARGSUSED*/
+static
+/*
+* process_support(DBPROCESSdb,MedArtrec)
+*/
+int process_support( DBPROCESS *db, MedArt *rec )
+{
+ int i;
+ RETCODE rc;
+ int have_plus = 0;
+
+ /* Read the subsances from the database */
+
+ for( i = 0; i < MAX_IDNUM_COUNT; i++ ) {
+ rc = SybaseLoad( db,
+ 1, NTBSTRINGBIND, sizeof(SupportId), rec->idnums[i],
+ 0 );
+ if( rc != REG_ROW ) break;
+
+ /* If we get a +, just remeber that we saw it. We'll put it last */
+
+ if( strcmp( rec->idnums[i], "+" ) == 0 ) {
+ i--;
+ have_plus++;
+ }
+ }
+
+ /* Add the plus back in */
+
+ if( i < MAX_IDNUM_COUNT && have_plus > 0 ) {
+ strcpy( rec->idnums[i], "+" );
+ i++;
+ }
+ rec->n_idnum = i;
+
+ return( (rc == FAIL) ? Error : ( (i==0) ? False : True ) );
+}
+
+
+/*ARGSUSED*/
+static
+/*
+* process_genesymbol(DBPROCESSdb,MedArtrec)
+*/
+int process_genesymbol( DBPROCESS *db, MedArt *rec )
+{
+ int i;
+ RETCODE rc;
+
+ /* Read the subsances from the database */
+
+ for( i = 0; i < MAX_GENESYM_COUNT; i++ ) {
+ rc = SybaseLoad( db,
+ 1, NTBSTRINGBIND, sizeof(GeneSymbol), rec->gene_symbols[i],
+ 0 );
+ if( rc != REG_ROW ) break;
+ }
+ rec->n_gene_symbols = i;
+
+ return( (rc == FAIL) ? Error : ( (i==0) ? False : True ) );
+}
+
+
+/*
+* ProcessMedlineArticle(DBPROCESS *db, MedArt *rec)
+*/
+
+int ProcessMedlineArticle( DBPROCESS *db, MedArt *rec, int is_pub )
+{
+ AbPList plist;
+ RETCODE rc;
+ DBCHAR state_msg[40]; /* Text description of state */
+ DBINT state;
+ int status;
+
+ /* Clear out the input record */
+
+ bzero( rec, sizeof(MedArt) );
+ bzero( &plist, sizeof(plist) ); /* Get rid of all patches */
+
+ /* Collect the data from the database */
+
+ for(status = True; status != Error; rc = dbresults( db )) {
+
+ /* Get the next header row from the batch and then skip to
+ the results batch associated with the header (dbresults call) */
+
+ rc = SybaseLoad( db,
+ 1, INTBIND, 0, &state,
+ 2, NTBSTRINGBIND, sizeof(state_msg), state_msg,
+ 0 );
+ if( rc == REG_ROW ) {
+ /* EOF marked with MR_STATE_DONE as the state */
+ if( state == MR_STATE_DONE )
+ return( True );
+
+ /* Prepare to read the results section */
+ rc = dbresults(db);
+ }
+ if( rc != SUCCEED ) return( Error );
+
+ /* Dispatch to the handler for this block of input */
+
+ switch( state ) {
+ case MR_STATE_ARTICLE: /* This one should be first */
+ if ( is_pub )
+ status = process_pub_article( db, rec );
+ else
+ status = process_article( db, rec );
+ if( status != True ) return( status );
+ break;
+ case MR_STATE_ISO_VTITLE:
+ status = patch_string(db, rec->vtitle, sizeof(rec->vtitle));
+ break;
+ case MR_STATE_ISO_ADDRESS:
+ status = patch_string(db, rec->address, sizeof(rec->address));
+ break;
+ case MR_STATE_AUTHOR:
+ status = process_author( db, rec );
+ break;
+ case MR_STATE_ISO_AUTHOR:
+ status = patch_author( db, rec );
+ break;
+ case MR_STATE_ISO_ABSTRACT:
+ if( plist.n_patches > 0 )
+ bzero( &plist, sizeof(plist) );
+ status = patch_abstract( db, rec, &plist );
+ break;
+ case MR_STATE_ABSTRACT:
+ status = process_abstract( db, rec, &plist );
+ break;
+ case MR_STATE_MESH:
+ status = process_mesh( db, rec );
+ break;
+ case MR_STATE_SUBHEADING:
+ status = process_subheading( db, rec );
+ break;
+ case MR_STATE_SUBSTANCE:
+ status = process_substance( db, rec );
+ break;
+ case MR_STATE_CROSSREFERENCE:
+ status = process_xref( db, rec );
+ break;
+ case MR_STATE_SUPPORT:
+ status = process_support( db, rec );
+ break;
+ case MR_STATE_GENESYMBOL:
+ status = process_genesymbol( db, rec );
+ break;
+ default: /* Unknown state - ignore it */
+ status = skip_undefined_section( db );
+ break;
+ }
+ }
+
+ /* Return the proper status */
+
+ return( Error );
+}
+
+
+/*
+* GetMedlineArticle(DBPROCESSdb,intui,intflags,MedArtrec)
+*/
+int GetMedlineArticle( DBPROCESS *db, int ui, int flags, MedArt *rec )
+{
+ RETCODE rc;
+
+ dbfreebuf( db );
+MACRO_before_exec
+ rc = RunSybase( db, "execute mr_get_article %d, %d", ui, flags );
+MACRO_after_exec(GetMedlineArticle)
+ if( rc != SUCCEED ) return( Error );
+
+ return( ProcessMedlineArticle( db, rec, 0 ) );
+}
+
+/*
+* GetMedlinePub(DBPROCESSdb,intui,intflags,MedArtrec)
+*/
+int GetMedlinePub( DBPROCESS *db, int ui, int flags, MedArt *rec )
+{
+ RETCODE rc;
+
+
+ dbfreebuf( db );
+MACRO_before_exec
+ rc = RunSybase( db, "execute mr_get_pub %d, %d", ui, flags );
+MACRO_after_exec(GetMedlinePub)
+ if( rc != SUCCEED ) return( Error );
+
+ return( ProcessMedlineArticle( db, rec, 1 ) );
+}
diff --git a/network/medarch/server/getmedart.h b/network/medarch/server/getmedart.h
new file mode 100644
index 00000000..634f57b4
--- /dev/null
+++ b/network/medarch/server/getmedart.h
@@ -0,0 +1,119 @@
+/*
+ Edit History:
+
+ 27 February 1992 Rand S. Huntzinger
+ Changed typedef of Author to be AuthName to avoid a naming
+ conflict the the ASN1 code.
+*
+*
+* RCS Modification History:
+* $Log: getmedart.h,v $
+* Revision 6.0 1997/08/25 18:36:14 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:45 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_GETMEDART_H
+#define DEFS_MODULE_GETMEDART_H
+
+#include "medschema.h"
+
+#define True (1)
+#define False (0)
+#define Error (-1)
+
+/* These flags can be or'ed together to control the data obtained from
+ the database using either the mr_get_article SQL procedure (used int
+ the GetMedlineArticle() procedure) or via the bulk access mechanism. */
+
+#define MED_ISO8859_FLAG (1 << 0)
+#define MED_ABSTRACT_FLAG (1 << 1)
+#define MED_MESH_FLAG (1 << 2)
+#define MED_QUALIFIER_FLAG (1 << 3)
+#define MED_SUBSTANCE_FLAG (1 << 4)
+#define MED_CROSSREF_FLAG (1 << 5)
+#define MED_SUPPORT_FLAG (1 << 6)
+#define MED_GENESYMBOL_FLAG (1 << 7)
+
+typedef DbNColumn(Name,name,AuthName);
+
+typedef DbNColumn(ResearchSupport,id,SupportId);
+
+typedef DbNColumn(GeneSymbol,symbol,GeneSymbol);
+
+typedef struct Qual {
+ DbColumn (Subheading,main_point);
+ DbColumn (Subheading,code);
+ DbColumn (Subheading,name);
+ DbColumn (Subheading,description);
+} Qual;
+
+typedef struct Mesh {
+ DBINT id_mesh;
+ DbColumn (Mesh,main_point);
+ DbColumn (Mesh,heading);
+ int n_qual;
+ Qual qualifiers[MAX_QUALIFIER_COUNT];
+} Mesh;
+
+typedef struct Substance {
+ DbColumn (Substance,number);
+ DbColumn (Substance,name);
+
+} Substance;
+
+typedef struct Xref {
+ DbNColumn (Databases,database_name,database);
+ DbColumn (CrossReference,accession);
+} Xref;
+
+typedef struct MedlineArticle {
+ /* Basic data */
+ DBINT ui;
+ DBINT mri;
+ DBINT title_type;
+ DbTitle (title);
+ DbTitle (vtitle);
+ DbColumn (Article,address);
+ DbColumn (Article,pages);
+ DBSMALLINT entry_month;
+ DbColumn (Issue,volume);
+ DbColumn (Issue,issue);
+ DbColumn (Issue,pubdate);
+ DbColumn (Journal,med_abbr);
+ DbColumn (Language,language_code);
+ /* Abstract */
+ DBCHAR abstract[MAX_ABSTRACT_SIZE];
+ /* Authors */
+ int n_authors;
+ AuthName authors[MAX_AUTHOR_COUNT];
+ /* Substances */
+ int n_substances;
+ Substance substances[MAX_SUBSTANCE_COUNT];
+ /* CrossReferences */
+ int n_xrefs;
+ Xref xrefs[MAX_XREF_COUNT];
+ /* MeSH terms */
+ int n_mesh;
+ Mesh mesh[MAX_MESH_COUNT];
+ /* Research grant/contract id's */
+ int n_idnum;
+ SupportId idnums[MAX_IDNUM_COUNT];
+ /* Gene Symbols */
+ int n_gene_symbols;
+ GeneSymbol gene_symbols[MAX_GENESYM_COUNT];
+ char part_sup[25]; /* part/sup of volume */
+ char part_supi[25]; /* part/sup of issue */
+} MedArt;
+
+
+#ifdef __STDC_
+extern int GetMedlineArticle( DBPROCESS *db, int ui, int flags, MedArt *rec );
+#else
+extern int GetMedlineArticle();
+#endif
+
+#endif /* DEFS_MODULE_GETMEDART_H */
diff --git a/network/medarch/server/ma_global.c b/network/medarch/server/ma_global.c
new file mode 100644
index 00000000..5a584bb5
--- /dev/null
+++ b/network/medarch/server/ma_global.c
@@ -0,0 +1,65 @@
+/*
+ PROJECT: Medline database.
+ MODULE: ma_global
+ FILES: ma_global.c (this one), ma_global.h
+
+ This file contains the global variable definitions for the
+ medline retrieval programs.
+
+ Original version completed: 24 February 1992, Rand S. Huntzinger
+
+*
+*
+* RCS Modification History:
+* $Log: ma_global.c,v $
+* Revision 6.0 1997/08/25 18:36:15 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:48 epstein
+* add RCS log revision history
+*
+*/
+
+#define COMPILING_GLOBAL_C
+
+#include "ma_global.h"
+
+/******************************************************************************
+ COMMAND LINE PARSING
+
+ The following variables receive the results of compiling the
+ medline_load command line. The cmdline module is used to fill
+ in the data and other modules (particularly at the top level)
+ have access to it.
+
+******************************************************************************/
+
+char *programName = NULL; /* This program's name (from argv[0]) */
+
+char *flagDatabase = NULL; /* Database name from command line */
+
+char *flagUser = NULL; /* Sybase user name from command line */
+
+char *flagServer = NULL; /* Sybase server from command line */
+
+char *flagPassword = NULL; /* Sybase password from command line */
+
+char *flagConfigFile=NULL; /* Configuration file for formats */
+
+short flagVerbose = FALSE; /* State of the -verbose flag */
+
+short flagDebug = FALSE; /* State of the -debug flag */
+
+short flagISO = FALSE; /* State of the -iso flag */
+
+short flagTrace = 0; /* -trace flag, default = no trace */
+
+int argumentCount = 0; /* Number of command line arguments */
+
+char **argumentList = (char **) NULL;
+ /* Pointer to vector of arguments. */
+
+int outputStreamCount = 0; /* # of output streams */
+
+OutStream outputStreams[ MAX_OUTPUT_STREAMS ]; /* Stream table */
+
diff --git a/network/medarch/server/ma_global.h b/network/medarch/server/ma_global.h
new file mode 100644
index 00000000..34f3dd96
--- /dev/null
+++ b/network/medarch/server/ma_global.h
@@ -0,0 +1,101 @@
+/*
+ PROJECT: Medline database.
+ MODULE: ma_global
+ FILES: ma_global.c, ma_global.h (this one)
+
+ This file contains the global variable definitions for the
+ medline retrieval programs. It is used to reference the global
+ variables as externs. This file also contains type definitions
+ which are limited to the global name space.
+
+ Original version completed: 24 February 1992, Rand S. Huntzinger
+*
+*
+* RCS Modification History:
+* $Log: ma_global.h,v $
+* Revision 6.0 1997/08/25 18:36:17 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:51 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_GLOBAL
+#define DEFS_MODULE_GLOBAL
+
+#include <unistd.h>
+#include <stdlib.h>
+#include "config.h"
+
+/******************************************************************************
+
+ MACRO DECLARATIONS
+
+******************************************************************************/
+
+/* The GLOBAL macro is set to nothing if we are compiling the global.c
+ option (as noted by the COMPILING_GLOBAL_C flag) or to extern if
+ compiling any other module. Therefore, the declaration acts either
+ as a forward of an extern declaration, depending upon the module. */
+
+#ifdef COMPILING_GLOBAL_C
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif /* COMPILING_GLOBAL_C */
+
+
+/******************************************************************************
+
+ TYPE DECLARATIONS
+
+******************************************************************************/
+
+typedef struct OutStream {
+ char *format; /* The name of the output format */
+ char *file; /* The output file name (- => stdout) */
+ void *handle; /* Output file handle (null=>none) */
+} OutStream;
+
+/******************************************************************************
+
+ GLOBAL VARIABLE DECLARATIONS
+
+******************************************************************************/
+
+/* COMMAND LINE PARSING - The following variables are set by the cmdline
+ as the command line is parsed. The may be used by other modules in the
+ medline_load program. */
+
+GLOBAL char *programName; /* This program's name (from argv[0]) */
+
+GLOBAL char *flagDatabase; /* Database name from command line */
+
+GLOBAL char *flagUser; /* Sybase user name from command line */
+
+GLOBAL char *flagServer; /* Sybase server from command line */
+
+GLOBAL char *flagPassword; /* Sybase password from command line */
+
+GLOBAL char *flagConfigFile; /* Configuration file for formats */
+
+GLOBAL short flagVerbose; /* State of the -verbose flag */
+
+GLOBAL short flagDebug; /* State of the -debug flag */
+
+GLOBAL short flagISO; /* State of the -iso flag */
+
+GLOBAL short flagTrace; /* -trace flag, default = no trace */
+
+GLOBAL int argumentCount; /* Number of command line arguments */
+
+GLOBAL char **argumentList; /* Pointer to vector of arguments.
+ Loaded only if inputFileCount > 0 */
+
+GLOBAL int outputStreamCount; /* Number of output streams given */
+
+GLOBAL OutStream outputStreams[ MAX_OUTPUT_STREAMS];
+ /* Table of output stream arguments */
+
+#endif /* DEFS_MODULE_GLOBAL */
diff --git a/network/medarch/server/ma_intfc.c b/network/medarch/server/ma_intfc.c
new file mode 100644
index 00000000..dc471cf6
--- /dev/null
+++ b/network/medarch/server/ma_intfc.c
@@ -0,0 +1,405 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: ma_intfc.c,v $
+* Revision 6.0 1997/08/25 18:36:18 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:55 epstein
+* add RCS log revision history
+*
+*/
+
+#include <stdlib.h>
+#include "xalloc.h"
+#include "ma_intfc.h"
+
+extern ma_Obj mfmt_ASN1_text, mfmt_ASN1_binary;
+
+typedef struct ma_Hand {
+ char *cmd_flag;
+ char *handler_name;
+ char *load_path;
+ char *loadob_sym;
+ ma_Obj *object;
+ void *handle;
+ void *data;
+ int unusable;
+} ma_Hand;
+
+ma_Hand default_handler_table[] = {
+
+ { /* Handle the ASN1 text interface */
+ "asn1",
+ "ASN1 Text",
+ NULL,
+ "_mfmt_ASN1_text",
+ &mfmt_ASN1_text,
+ (void *) NULL,
+ (void *) NULL,
+ FALSE
+ },
+
+ { /* Handle the ASN1 binary interface */
+ "asn1b",
+ "ASN1 Binary",
+ NULL,
+ "_mfmt_ASN1_binary",
+ &mfmt_ASN1_binary,
+ (void *) NULL,
+ (void *) NULL,
+ FALSE
+ }
+};
+static int n_default_handlers =
+ sizeof(default_handler_table)/sizeof(ma_Hand);
+
+
+static
+ma_Hand handler_table[ MAX_FORMAT_HANDLERS ];
+static int n_handlers = 0;
+
+
+static
+char *strdup( char *s ) {
+ char *r;
+
+ if( s == NULL ) return( NULL );
+
+ r = xalloc( strlen(s) + 1 );
+ strcpy(r, s );
+ return( r );
+}
+
+static
+int install_format( char *file_name, char *cmd_flag, char *load_path,
+ ma_Obj *object, char *load_symbol, char *handler_name )
+{
+ char *config_file;
+
+ /* Check the arguments */
+
+ config_file = (file_name == NULL) ? "built-in's" : file_name;
+ if( cmd_flag != NULL && handler_name == NULL ) handler_name = cmd_flag;
+ if( handler_name == NULL ) handler_name = "<<Unknown handler>>";
+ if( cmd_flag == NULL ) {
+ fprintf(stderr, "%s: No format name flag specified for %s handler\n",
+ config_file, handler_name );
+ return( FALSE );
+ }
+ if( load_path == NULL && file_name != NULL ) {
+ fprintf(stderr, "%s: No load path given for %s handler\n",
+ config_file, handler_name );
+ return( FALSE );
+ }
+ if( load_symbol == NULL ) {
+ fprintf(stderr, "%s: No load symbol given for %s handler\n",
+ config_file, handler_name );
+ return( FALSE );
+ }
+
+ /* Install the entry */
+
+ if( n_handlers >= MAX_FORMAT_HANDLERS ) {
+ fprintf(stderr, "%s: Too many handlers at handler %s (%d MAX)\n",
+ config_file, handler_name, MAX_FORMAT_HANDLERS );
+ return( FALSE );
+ }
+ handler_table[n_handlers].cmd_flag = cmd_flag;
+ handler_table[n_handlers].handler_name = handler_name;
+ handler_table[n_handlers].load_path = load_path;
+ handler_table[n_handlers].object = object;
+ handler_table[n_handlers].loadob_sym = load_symbol;
+ n_handlers++;
+
+ return( TRUE );
+}
+
+typedef enum { begin_scan, in_token, quoted_char, quoted_string, end_scan }
+ State;
+
+static
+char *get_token( char *s, char **next )
+{
+ static char token[MAX_TOKEN_SIZE];
+ char *t = &token[0];
+ State state, old_state;
+ char mark;
+
+ /* Scan out the token */
+
+ if( s != NULL ) {
+ for( state = begin_scan; state != end_scan; ) {
+
+ /* White space is all equivalent */
+
+ if( isspace( *s ) || *s == '\r' || *s == '\n' )
+ *s = ' ';
+
+ switch( state ) {
+ case begin_scan:
+ switch( *s ) {
+ case '"':
+ case '\'': /* Quoted strings */
+ mark = *s;
+ state = quoted_string;
+ break;
+ case 0: /* End of string */
+ state = end_scan;
+ /* DROP THROUGH */
+ case ' ': /* Spaces - ignore */
+ break;
+ default: /* Standard token */
+ state = in_token;
+ continue; /* We'll retest this char */
+ }
+ break;
+ case in_token: /* Standard token */
+ switch( *s ) {
+ case ' ': /* Space - terminate the token */
+ case 0: /* End of input */
+ state = end_scan;
+ break;
+ case '\\': /* Quoted character? */
+ old_state = state;
+ state = quoted_char;
+ break;
+ default:
+ *t++ = *s;
+ break; /* Continue collecting */
+ }
+ break;
+ case quoted_string: /* String inside quotes */
+ if( *s == 0 )
+ state == end_scan;
+ else if( *s == mark ) {
+ state = old_state;
+ break;
+ } else if( *s == '\\' ) {
+ old_state = state;
+ state = quoted_char;
+ } else {
+ *t++ = *s;
+ }
+ break;
+ case quoted_char: /* Quoted char (\x) */
+ if( *s == 0 )
+ state = end_scan;
+ else {
+ state = old_state;
+ *t++ = *s;
+ }
+ break;
+ }
+ if( *s != (char) 0 ) s++;
+ }
+ }
+ *t++ = (char) 0; /* Terminate token */
+
+ /* Figure out where the next token is */
+
+ if( next != (char **) NULL ) {
+ *next = ( s == NULL || *s == (char) 0 ) ? NULL : s;
+ }
+
+ /* Done */
+
+ return( (*token == (char) 0) ? NULL : token );
+}
+
+
+static
+int get_handlers( char *file_name )
+{
+ FILE *fd;
+ char buffer[MAX_FORMAT_LINE];
+ int rv = TRUE;
+ char *token;
+
+ /* Open the configuration file */
+
+ fd = fopen( file_name, "r" );
+ if( fd == NULL ) {
+ perror( file_name );
+ return( FALSE );
+ }
+
+ /* Read the file and extract the handler lines */
+
+ while( fgets( buffer, sizeof(buffer), fd ) != NULL ) {
+ char *next;
+ char *label = get_token( buffer, &next );
+ if( label == NULL || *label == '#' )
+ continue; /* Ignore me type lines */
+ if( strcmp( label, "format" ) == 0 ) {
+ char *cmd_flag, *load_path, *load_symbol, *handler_name;
+
+ cmd_flag = strdup( get_token( next, &next ) );
+ load_path = strdup( get_token( next, &next ) );
+ load_symbol = strdup( get_token( next, &next ) );
+ handler_name = strdup( get_token( next, &next ) );
+ rv &= install_format( file_name, cmd_flag, load_path,
+ (ma_Obj *) NULL, load_symbol, handler_name);
+
+ } else if( strcmp( label, "include" ) == 0 ) {
+ while( (token = get_token( next, &next )) != NULL ) {
+ char file_name[MAX_TOKEN_SIZE];
+
+ strcpy( file_name, token );
+ rv &= get_handlers( file_name );
+ }
+ }
+ }
+
+ /* Return the status */
+
+ return( rv );
+}
+
+
+/*ARGSUSED*/
+int ma_GetHandlers( char *file_name )
+{
+#ifdef DEBUG
+ /* DEBUG VERSION - Uses hard coded table */
+
+ n_handlers = sizeof(handler_table)/sizeof(ma_Hand);
+ return( TRUE );
+#else
+ int rv = TRUE; /* Assume everything OK */
+ int i;
+
+ /* Open the configuration file and read the data */
+
+ if( file_name != NULL ) rv = get_handlers( file_name );
+
+ /* Install the default handlers */
+
+ for( i = 0; i < n_default_handlers; i++ ) {
+ ma_Hand *h = &default_handler_table[i];
+ rv &= install_format( NULL, h->cmd_flag, h->load_path,
+ h->object, h->loadob_sym, h->handler_name );
+ }
+#endif
+}
+
+
+void *ma_ValidHandler( char *cmd_flag )
+{
+ register int i;
+
+ /* Search the handler table for a key. Only one file can be open
+ on a channel, so we'll look only at closed channels */
+
+ for( i = 0; i < n_handlers; i++ )
+ if( handler_table[i].data == NULL &&
+ strcmp( handler_table[i].cmd_flag, cmd_flag ) == 0 )
+ return( &handler_table[i] );
+
+ /* If we didn't find one - we didn't have a slot for it. */
+
+ return( NULL );
+}
+
+
+int ma_OpenHandler( void *x_handler, char *file_name, FILE *fd )
+{
+ ma_Hand *handler = x_handler;
+ int rv;
+
+ /* Open the library */
+
+ if( handler->load_path != NULL ) {
+ handler->handle = dlopen( handler->load_path, RTLD_LAZY );
+ if( handler->handle == NULL ) goto err;
+
+ /* Get the object from the module */
+
+ handler->object = dlsym( handler->handle, handler->loadob_sym );
+ }
+ if( handler->object == NULL )
+ goto err;
+
+ /* Initialize the channel */
+
+ handler->data = handler->object->initialize( handler->handler_name,
+ handler->object->data );
+ if( handler->data == NULL )
+ goto err;
+
+ /* If the file pointer is NULL - we'll open it; otherwise, we assume
+ that the file is already open (usually stdout) */
+
+ if( fd != NULL)
+ rv = handler->object->setup_file( handler->data, file_name, fd );
+ else
+ rv = handler->object->open_file( handler->data, file_name );
+
+ /* Successful exit */
+
+ if( rv ) return( True );
+
+ /* Come here on an error */
+err:
+ handler->unusable = TRUE;
+ return( FALSE );
+}
+
+
+int ma_WriteArticle( void *x_handler, MedArt *article )
+{
+ ma_Hand *handler = x_handler;
+ /* If the handler is usable - use it */
+
+ if( handler->unusable )
+ return( FALSE );
+
+ return( handler->object->process( handler->data, article ) );
+}
+
+
+int ma_CloseHandler( void *x_handler )
+{
+ ma_Hand *handler = x_handler;
+
+ /* We don't have to do anything if it was never opened */
+
+ if( handler->object != NULL && handler->data != NULL ) {
+ (void) handler->object->close( handler->data );
+ handler->data = NULL;
+ }
+
+ /* Close the object module */
+
+ if( handler->handle != NULL ) {
+ dlclose( handler->handle );
+ handler->handle = NULL;
+ handler->object = NULL;
+ }
+
+ /* Finished */
+
+ return( TRUE );
+}
+
+
+char *ma_GetErrorString( void *x_handler )
+{
+ ma_Hand *handler = x_handler;
+
+ /* Make sure that the handler is open */
+
+ if( handler->handle == NULL || handler->object == NULL ||
+ handler->data == NULL )
+ {
+ static char message[512];
+ sprintf( message, "MEDLINE %s output handler is not open",
+ handler->handler_name );
+ return( message );
+ }
+
+ /* We have the handler - get the error string */
+
+ return( handler->object->get_error( handler->data ) );
+}
diff --git a/network/medarch/server/ma_intfc.h b/network/medarch/server/ma_intfc.h
new file mode 100644
index 00000000..a5febeed
--- /dev/null
+++ b/network/medarch/server/ma_intfc.h
@@ -0,0 +1,50 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: ma_intfc.h,v $
+* Revision 6.0 1997/08/25 18:36:20 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:57 epstein
+* add RCS log revision history
+*
+*/
+
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include "getmedart.h"
+
+#ifndef MODULE_MA_INTFC_H
+#define MODULE_MA_INTFC_H
+
+#ifndef MAX_FORMAT_HANDLERS
+#define MAX_FORMAT_HANDLERS 512
+#endif
+#ifndef MAX_TOKEN_SIZE
+#define MAX_TOKEN_SIZE 2048
+#endif
+#ifndef MAX_FORMAT_LINE
+#define MAX_FORMAT_LINE 4096
+#endif
+
+
+typedef struct ma_Obj {
+ void *(*initialize)(char *, void *); /* Initialize */
+ int (*open_file)(void *, char *file_name );
+ int (*setup_file)(void *, char *file_name, FILE *fd );
+ int (*process)(void *, MedArt *); /* Convert format */
+ int (*close)(void *); /* Finish up */
+ char *(*get_error)(void *); /* Get error text */
+ void *data; /* Other data */
+} ma_Obj;
+
+int ma_GetHandlers( char *file_name );
+void *ma_ValidHandler( char *cmd_flag );
+int ma_OpenHandler( void *handler, char *file, FILE *fd );
+int ma_WriteArticle( void *handler, MedArt *article );
+int ma_CloseHandler( void *handler );
+char *ma_GetErrorString( void *handler );
+
+#endif /* MODULE_MA_INTFC_H */
diff --git a/network/medarch/server/makeserver.old b/network/medarch/server/makeserver.old
new file mode 100644
index 00000000..4fe5103c
--- /dev/null
+++ b/network/medarch/server/makeserver.old
@@ -0,0 +1,87 @@
+#
+# Makefile for medsmain program
+#
+include $(NCBI)/ncbi.mk
+
+CODEGEN=asncode
+ASNTOOL=asntool
+
+CC= $(NCBI_CC)
+
+INCLUDES=-I$(NCBI_SYBASE)/include -I$(NCBI_INCDIR)
+
+LIBS1=-lncbimla -lncbiobj -lnetcli -lncbi -lm $(NCBI_OTHERLIBS)
+LIBS=$(NCBI_SYBLIBS) -lncbimla -lncbiobj -lnetcli -lncbi -ldl $(NCBI_OTHERLIBS)
+LIBDIRS=-L$(NCBI_ALTLIB) -L$(NCBI_SYBASE)/lib
+
+CFLAGS=-g $(INCLUDES)
+
+# sources and objects for medline retrieval
+
+MED_OBJ= medretrieve.o getmedart.o voutf.o password.o sybbind.o \
+ sybintfc.o sqlstring.o message.o patchtoiso.o \
+ ma_global.o cmdline.o ma_intfc.o mfmt_medasn.o outmedart.o \
+ medart2asn.o xalloc.o
+
+MED_SRC= medretrieve.c getmedart.c voutf.c password.c sybbind.c \
+ sybintfc.c sqlstring.c message.c patchtoiso.c \
+ ma_global.c cmdline.c ma_intfc.c mfmt_medasn.c outmedart.c \
+ medart2asn.c xalloc.c
+
+OBJECTS= medsmain.o $(MED_OBJ)
+
+SOURCES= medsmain.c $(MED_SRC)
+
+TEST_OBJ= medarchtest.o
+
+TEST_SRC= medarchtest.c
+
+TEST1_OBJ= test.o
+
+TEST1_SRC= test.c
+
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
+medretrieve.o : medretrieve.c
+ $(CC) $(CFLAGS) -c -o $@ -DSYSV medretrieve.c
+
+getmedart.o : getmedart.c
+ $(CC) $(CFLAGS) -c -o $@ -DSYSV getmedart.c
+
+medserv: $(OBJECTS)
+ $(CC) -o medserv $(OBJECTS) $(LIBDIRS) $(LIBS)
+
+medserv.purify: $(OBJECTS)
+ purify $(CC) -o medserv.purify $(OBJECTS) $(LIBDIRS) $(LIBS)
+
+medarchtest: $(TEST_OBJ)
+ $(CC) -o medarchtest $(TEST_OBJ) $(LIBDIRS) $(LIBS1)
+
+test1: $(TEST1_OBJ)
+ $(CC) -o test1 $(TEST1_OBJ) $(LIBDIRS) $(LIBS1)
+
+objmla.o: objmla.c asnmla.h mappings.h
+ $(CC) -c -g -DNLM_OBJ_INCL=\"mappings.h\" -I$(INC) objmla.c
+
+objmla.c: asnmla.l $(CODEGEN)
+ rm -f objmlaerr objmlaout
+ $(CODEGEN) -l asnmla.l -o objmla >objmlaout 2>objmlaerr
+
+medarch.o: medarch.c asnmla.h objmla.h medarch.h
+ $(CC) -c -g -I$(INC) -I. medarch.c
+
+medarchtest.o: medarchtest.c asnmla.h medarch.h
+ $(CC) -c -g -I$(INC) -I. medarchtest.c
+
+asnmla.l: mla.asn
+ rm -f asnmla.l*
+ $(ASNTOOL) -m mla.asn -l asnmla.h
+ -mv asnmla.l* asnmla.l
+ mv asnmla.h asnmlastat.h
+
+asnmla.h: mla.asn
+ $(ASNTOOL) -m mla.asn -o asnmla.h
+
+clean:
+ rm -f objmla.c objmla.h asnmla.l asnmla.h *.o medserv objmlaerr objmlaout
diff --git a/network/medarch/server/makesybmla.unx b/network/medarch/server/makesybmla.unx
new file mode 100644
index 00000000..3ab659c2
--- /dev/null
+++ b/network/medarch/server/makesybmla.unx
@@ -0,0 +1,108 @@
+# makefile for medserv
+# Sun with unbundled ANSI compiler [ make LCL=acc RAN=ranlib CC=acc ]
+# Sun with Gnu C [ make LCL=gcc RAN=ranlib CC=gcc ]
+# Sun with Solaris 2.x OS [ make LCL=sol CC="cc -Xa" ]
+# Silicon Graphics [ make LCL=sgi OTHERLIBS="-lm -lPW -lsun" ]
+# IBM 3090 with AIX [ make LCL=370 ]
+# ULTRIX [ make LCL=ult RAN=ranlib ]
+# Apple AUX [ make LCL=aux SHELL=\usr\bin ]
+# NeXt [ make LCL=nxt CFLAGS1="-c -ansi" RAN=ranlib ]
+# DEC Alpha under OSF/1 [ make LCL=alf CC=cc RAN=ranlib ]
+#
+# see README for other supported systems
+#
+# Subsequent makes should make ... nocopy instead of make ... all
+# to avoid recopying the include files
+#
+#
+# NOTE: some make utilities (like SGI and IBM 3090) do not like a target
+# which is undefined. This would be $(LIB4) if you are not making a
+# vibrant version. Thus, this library target must be deleted on those
+# systems. The section to be deleted is marked below with DELETE
+#
+
+# default flags for compiling and loading
+
+include $(NCBI)/ncbi.mk
+SUFFIXLCL = $(LCL)
+CCOPT = -g
+CC = $(NCBI_CC)
+RAN = ls
+AR=ar
+LIBS=$(NCBI_SYBLIBS) -lncbimla -lncbiobj -lncbi -lnetcli -ldl $(NCBI_OTHERLIBS)
+LIBDIRS=-L$(NCBI_ALTLIB) -L$(NCBI_SYBASE)/lib
+
+INCLUDES=-I../include -I$(NCBI_SYBASE)/include -I$(NCBI_INCDIR)
+
+CFLAGS=-g $(INCLUDES)
+
+SUFFIXENV = unx
+ASNDIR = asnstat
+LIBMLA = libsybmla.a
+
+
+##
+## some things to make
+##
+
+# sources and objects for medline retrieval
+
+MED_OBJ= cmdline.o getmedart.o ma_global.o ma_intfc.o medart2asn.o \
+ medretrieve.o mfmt_medasn.o message.o outmedart.o \
+ password.o patchtoiso.o sqlstring.o sybbind.o sybintfc.o \
+ voutf.o xalloc.o
+
+MED_SRC= cmdline.c getmedart.c ma_global.c ma_intfc.c medart2asn.c \
+ medretrieve.c mfmt_medasn.c message.c outmedart.c \
+ password.c patchtoiso.c sqlstring.c sybbind.c sybintfc.c \
+ voutf.c xalloc.c
+
+## All things to make
+##
+all : copy nocopy medserv
+
+nocopy : sources $(LIBMLA)
+
+sources : $(MED_SRC)
+
+## To clean out the directory without removing make
+##
+clean :
+ - rm -f *.[acho]
+
+## Implicit actions
+##
+
+
+## get all the source files
+##
+
+copy :
+ - chmod +w ../include/*
+ - chmod +w *
+ cp ../network/medarch/server/*.h ../include
+ cp ../network/medarch/server/*.c .
+ - chmod +w *.c
+ - chmod +w ../include/*
+ - chmod +w *
+
+## make libraries
+##
+
+medretrieve.o : medretrieve.c
+ $(CC) $(CFLAGS) -c -o $@ -DSYSV medretrieve.c
+
+getmedart.o : getmedart.c
+ $(CC) $(CFLAGS) -c -o $@ -DSYSV getmedart.c
+
+$(LIBMLA) : $(MED_OBJ)
+ - rm -f $(LIBMLA)
+ $(AR) cru $(LIBMLA) $(MED_OBJ)
+ cp $(LIBMLA) ../lib
+ $(RAN) ../lib/$(LIBMLA)
+
+# medserv
+
+medserv: medsmain.o $(LIBMLA)
+ $(CC) -g -o medserv medsmain.o ../lib/$(LIBMLA) $(LIBDIRS) $(LIBS)
+
diff --git a/network/medarch/server/mapmedarch.h b/network/medarch/server/mapmedarch.h
new file mode 100644
index 00000000..08529e96
--- /dev/null
+++ b/network/medarch/server/mapmedarch.h
@@ -0,0 +1,24 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: mapmedarch.h,v $
+* Revision 6.0 1997/08/25 18:36:24 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:54:59 epstein
+* add RCS log revision history
+*
+*/
+
+#include <objmedli.h>
+#include <objpub.h>
+
+/* legitimate substitutions to handle differences between existing object */
+/* loaders and symbol names generated for automatically-generated object */
+/* loaders (for imported types) */
+#define TitlePtr ValNodePtr
+
+#define NLM_EXTERN_LOADS { if (! MedlineAsnLoad()) return FALSE; \
+ if (! PubAsnLoad()) return FALSE; \
+ if (! BiblioAsnLoad()) return FALSE; }
diff --git a/network/medarch/server/mappings.h b/network/medarch/server/mappings.h
new file mode 100644
index 00000000..2153f0e1
--- /dev/null
+++ b/network/medarch/server/mappings.h
@@ -0,0 +1,25 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: mappings.h,v $
+* Revision 6.0 1997/08/25 18:36:25 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:02 epstein
+* add RCS log revision history
+*
+*/
+
+#include <objmedli.h>
+#include <objpub.h>
+#include <objfeat.h>
+
+/* legitimate substitutions to handle differences between existing object */
+/* loaders and symbol names generated for automatically-generated object */
+/* loaders (for imported types) */
+#define TitlePtr ValNodePtr
+
+#define NLM_EXTERN_LOADS { if (! MedlineAsnLoad()) return FALSE; \
+ if (! PubAsnLoad()) return FALSE; \
+ if (! BiblioAsnLoad()) return FALSE; }
diff --git a/network/medarch/server/medart2asn.c b/network/medarch/server/medart2asn.c
new file mode 100644
index 00000000..efcc846b
--- /dev/null
+++ b/network/medarch/server/medart2asn.c
@@ -0,0 +1,1117 @@
+/* medart2asn.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: getasnmed.c
+*
+* Author: Karl Sirotkin
+*
+* Version Creation Date: 2/26/92
+*
+* $Revision: 6.0 $
+*
+* File Description: interface between getmedart.h and ncbi asn objects
+*
+* RCS Modification History:
+* $Log: medart2asn.c,v $
+* Revision 6.0 1997/08/25 18:36:27 madden
+* Revision changed to 6.0
+*
+* Revision 1.5 1995/07/12 14:47:47 tatiana
+* memset 0 for volume, issue arrays
+*
+ * Revision 1.4 1995/07/07 19:09:49 tatiana
+ * a bug fixed in ma_get_parts() issue wasn't populated
+ *
+ * Revision 1.3 1995/05/30 17:58:28 tatiana
+ * fix memory leaks
+ *
+ * Revision 1.2 1995/05/17 17:55:05 epstein
+ * add RCS log revision history
+ *
+*/
+
+
+#ifndef DEFS_MODULE_GETMEDART_H
+#include "getmedart.h"
+#endif
+
+
+#ifndef _NCBI_Medline_
+#include <objmedli.h>
+#endif
+
+#define Med2Asn_RESTART -1
+#define Med2Asn_CONTINUE 0
+
+#define ERR_OUT_OF_SPACE 1
+/*------
+ * These structures will not be ..New() ed or ...Free()ed.
+ *-----*/
+static Affil MedAffil;
+static AuthList MedAsnAuthList;
+static MedlineEntry asnmedline_article;
+static AsnIoPtr aip = NULL;
+static NCBI_Date entry_month, journal_date;
+static CitArt asn_article;
+static ValNode asn_title, asn_journal_title;
+static CitJour asn_journal;
+static Imprint asn_imprint;
+static Char datebuf[81];
+static DBINT article_ui;
+extern Char * NCBI_months[12];
+
+/* added 08/02/94 for pages */
+
+typedef struct token_boundary {
+ int start_pos;
+ int end_pos;
+ char data[20];
+} TokenBound, *TokenBoundPtr;
+
+/* added 10/10/94 for parts. Tatiana */
+CharPtr TextSave();
+
+static InitStaticVariables()
+{
+ asnmedline_article.uid = 0;
+ asnmedline_article.em = NULL;
+ asnmedline_article.cit = NULL;
+ asnmedline_article.abstract = NULL;
+ asnmedline_article.mesh = NULL;
+ asnmedline_article.substance = NULL;
+ asnmedline_article.xref = NULL;
+ asnmedline_article.idnum = NULL;
+ asnmedline_article.gene = NULL;
+
+ asn_article.title = NULL;
+ asn_article.authors = NULL;
+ asn_article.fromptr = NULL;
+ asn_article.from = 0;
+
+ asn_journal.title = NULL;
+ asn_journal.imp = NULL;
+
+ asn_imprint.date = NULL;
+ asn_imprint.volume = NULL;
+ asn_imprint.issue = NULL;
+ asn_imprint.pages = NULL;
+ asn_imprint.section = NULL;
+ asn_imprint.part_sup = NULL;
+ asn_imprint.language = NULL;
+ asn_imprint.cprt = NULL;
+ asn_imprint.part_supi= NULL;
+ asn_imprint.retract = NULL;
+ asn_imprint.pub = NULL;
+ asn_imprint.prepub = 0;
+
+ MedAsnAuthList.names = NULL;
+ MedAsnAuthList.affil = NULL;
+
+ MedAffil.affil = NULL;
+ MedAffil.div = NULL;
+ MedAffil.city = NULL;
+ MedAffil.sub = NULL;
+ MedAffil.country = NULL;
+ MedAffil.street = NULL;
+ MedAffil.email = NULL;
+ MedAffil.fax = NULL;
+ MedAffil.phone = NULL;
+}
+
+Boolean all_space(CharPtr beg, CharPtr end)
+{
+ Int2 i;
+ CharPtr s;
+ Boolean ret = FALSE;
+
+ if (beg == NULL) {
+ return ret;
+ }
+ for (s = beg; s < end && IS_WHITESP(*s); s++);
+ if (s >= end) {
+ ret = TRUE;
+ }
+ return ret;
+}
+
+/**************************************************************************
+* get_parts:
+* return a PARTS
+**************************************************************************/
+Boolean ma_get_parts(CharPtr bptr, CharPtr eptr, ImprintPtr imp)
+{
+ static Char vv[255], vp[255], vi[255], vs[255];
+ CharPtr s;
+ CharPtr volume = NULL, end_vol, issue = NULL, end_issue;
+ CharPtr sup_i = NULL, end_sup_i;
+ CharPtr sup = NULL, end_sup;
+
+ memset(vv, 0, 255);
+ memset(vp, 0, 255);
+ memset(vi, 0, 255);
+ memset(vs, 0, 255);
+ s = eptr;
+ volume = bptr;
+ for (end_vol = volume; IS_DIGIT(*end_vol); end_vol++);
+ if (volume == end_vol) {
+ sup = volume;
+ volume = NULL;
+ } else {
+ sup = end_vol;
+ }
+ end_sup = eptr;
+ if (*(s-1) == ')') {
+ end_sup_i = s-1;
+ for (s--; s >= bptr && *s != '('; s--);
+ if (*s != '(') {
+ return FALSE;
+ }
+ end_sup = s;
+ while (*end_sup == ' ')
+ end_sup--;
+ issue = s+1;
+ if (*issue == ')') {
+ issue = NULL;
+ sup_i = NULL;
+ } else {
+ for (end_issue = issue; IS_DIGIT(*end_issue) ||
+ *end_issue == '-'; end_issue++);
+ if (issue == end_issue) {
+ sup_i = issue;
+ issue = NULL;
+ } else {
+ sup_i = end_issue;
+ }
+ }
+ }
+ if (volume != NULL && *volume != '0' && !all_space(volume, end_vol)) {
+ strncpy(vv, volume, end_vol-volume);
+ imp->volume = vv;
+ }
+ if (sup != NULL && !all_space(sup, end_sup)) {
+ strncpy(vp, sup, end_sup-sup);
+ imp->part_sup = vp;
+ }
+ if (issue != NULL && !all_space(issue, end_issue)) {
+ strncpy(vi, issue, end_issue-issue);
+ imp->issue = vi;
+ }
+ if (sup_i != NULL && !all_space(sup_i, end_sup_i)) {
+ strncpy(vs, sup_i, end_sup_i-sup_i);
+ imp->part_supi = vs;
+ }
+ return TRUE;
+}
+
+/*-----Med2AsnAuthNew()--------*/
+
+ValNodePtr
+Med2AsnAuthNew(restart)
+ int * restart;
+{
+ static dex=0;
+ static ValNode MedAsnAuth[MAX_AUTHOR_COUNT];
+ ValNodePtr retval = NULL;
+
+ if ( * restart == Med2Asn_RESTART){
+ dex = 0;
+ * restart = Med2Asn_CONTINUE;
+ }
+ if ( dex >= MAX_AUTHOR_COUNT){
+ char msg[80];
+ sprintf( msg, "NO MORE AUTHOR SPACE FOR UI=%d", article_ui );
+ ErrPost( CTX_NCBIMED2ASN, ERR_OUT_OF_SPACE, msg );
+ }else {
+ retval = & MedAsnAuth[dex ++ ];
+ }
+
+ return retval;
+}
+
+/*-----Med2AsnSubNew()--------*/
+
+MedlineRnPtr
+Med2AsnSubNew(restart)
+ int * restart;
+{
+ static dex=0;
+ static MedlineRn asnmedline_substance [MAX_SUBSTANCE_COUNT];
+ MedlineRnPtr retval = NULL;
+
+ if ( * restart == Med2Asn_RESTART){
+ * restart = Med2Asn_CONTINUE;
+ dex = 0;
+ }
+ if ( dex >= MAX_SUBSTANCE_COUNT){
+ char msg[80];
+ sprintf( msg, "NO MORE SUBSTANCE SPACE FOR UI=%d", article_ui );
+ ErrPost( CTX_NCBIMED2ASN, ERR_OUT_OF_SPACE, msg );
+ }else {
+ retval = & asnmedline_substance[dex ++ ];
+ }
+
+ return retval;
+}
+
+
+/*-----Med2AsnXrefNew()--------*/
+
+ValNodePtr
+Med2AsnXrefNew(restart)
+ int * restart;
+{
+ static dex=0;
+ static ValNode asnxrefs [MAX_XREF_COUNT];
+ ValNodePtr retval = NULL;
+
+ if ( * restart == Med2Asn_RESTART){
+ * restart = Med2Asn_CONTINUE;
+ dex = 0;
+ }
+ if ( dex >= MAX_XREF_COUNT){
+ char msg[80];
+ sprintf( msg, "NO MORE XREF SPACE FOR UI=%d", article_ui );
+ ErrPost( CTX_NCBIMED2ASN, ERR_OUT_OF_SPACE, msg );
+ }else {
+ retval = & asnxrefs[dex ++ ];
+ }
+
+ return retval;
+}
+
+/*-----Med2AsnSupportNew()--------*/
+
+ValNodePtr
+Med2AsnSupportNew(restart)
+ int * restart;
+{
+ static dex=0;
+ static ValNode SupportIds [MAX_IDNUM_COUNT];
+ ValNodePtr retval = NULL;
+
+ if ( * restart == Med2Asn_RESTART){
+ * restart = Med2Asn_CONTINUE;
+ dex = 0;
+ }
+ if ( dex >= MAX_IDNUM_COUNT){
+ char msg[80];
+ sprintf( msg, "NO MORE SUPPORT_ID SPACE FOR UI=%d", article_ui );
+ ErrPost( CTX_NCBIMED2ASN, ERR_OUT_OF_SPACE, msg );
+ }else {
+ retval = & SupportIds[dex ++ ];
+ }
+
+ return retval;
+}
+
+/*-----Med2AsnGeneSymNew()--------*/
+
+ValNodePtr
+Med2AsnGeneSymNew(restart)
+ int * restart;
+{
+ static dex=0;
+ static ValNode GeneSyms [MAX_GENESYM_COUNT];
+ ValNodePtr retval = NULL;
+
+ if ( * restart == Med2Asn_RESTART){
+ * restart = Med2Asn_CONTINUE;
+ dex = 0;
+ }
+ if ( dex >= MAX_GENESYM_COUNT){
+ char msg[80];
+ sprintf( msg, "NO MORE GENESYM SPACE FOR UI=%d", article_ui );
+ ErrPost( CTX_NCBIMED2ASN, ERR_OUT_OF_SPACE, msg );
+ }else {
+ retval = & GeneSyms[dex ++ ];
+ }
+
+ return retval;
+}
+
+/*-----Med2AsnMeshNew()--------*/
+
+MedlineMeshPtr
+Med2AsnMeshNew(restart)
+ int * restart;
+{
+ static dex=0;
+ static MedlineMesh asnmesh[MAX_MESH_COUNT];
+ MedlineMeshPtr retval = NULL;
+
+ if ( * restart == Med2Asn_RESTART){
+ * restart = Med2Asn_CONTINUE;
+ dex = 0;
+ }
+ if ( dex >= MAX_MESH_COUNT){
+ char msg[80];
+ sprintf( msg, "NO MORE MESH SPACE FOR UI=%d", article_ui );
+ ErrPost( CTX_NCBIMED2ASN, ERR_OUT_OF_SPACE, msg );
+ }else {
+ retval = & asnmesh[dex ++ ];
+ }
+
+ return retval;
+}
+
+
+/*-----Med2AsnQualNew()--------*/
+
+ValNodePtr
+Med2AsnQualNew(restart)
+ int * restart;
+{
+ static dex=0;
+ static ValNode MeshQual
+ [MAX_QUALIFIER_COUNT * MAX_MESH_COUNT];
+ ValNodePtr retval = NULL;
+
+ if ( * restart == Med2Asn_RESTART){
+ * restart = Med2Asn_CONTINUE;
+ dex = 0;
+ }
+ if ( dex >= MAX_QUALIFIER_COUNT * MAX_MESH_COUNT ){
+ char msg[80];
+ sprintf( msg, "NO MORE QUAL SPACE FOR UI=%d", article_ui );
+ ErrPost( CTX_NCBIMED2ASN, ERR_OUT_OF_SPACE, msg );
+ }else {
+ retval = & MeshQual[dex ++ ];
+ }
+
+ return retval;
+}
+
+static Uint1
+xref_lookup(name)
+ CharPtr name;
+{
+ Uint1 retval = 0;
+ register int dex;
+ static char * known_names [13] ={
+ "ddbj",
+ "carbbank",
+ "embl",
+ "hdb",
+ "genbank",
+ "hgml",
+ "mim",
+ "msd",
+ "pdb",
+ "pir",
+ "prfseqdb",
+ "psd",
+ "swissprot"
+};
+/*
+ ddbj (1) , -- DNA Data Bank of Japan
+ carbbank (2) , -- Carbohydrate Structure Database
+ embl (3) , -- EMBL Data Library
+ hdb (4) , -- Hybridoma Data Bank
+ genbank (5) , -- GenBank
+ hgml (6) , -- Human Gene Map Library
+ mim (7) , -- Mendelian Inheritance in Man
+ msd (8) , -- Microbial Strains Database
+ pdb (9) , -- Protein Data Bank (Brookhaven)
+ pir (10) , -- Protein Identification Resource
+ prfseqdb (11) , -- Protein Research Foundation (Japan)
+ psd (12) , -- Protein Sequence Database (Japan)
+ swissprot (13) } , -- SwissProt
+*/
+ for (dex = 0; dex < 13; dex ++ ){
+ if (StringICmp(known_names[dex],name) == 0){
+ retval = (Uint1) dex + 1;
+ break;
+ }
+ }
+
+ return retval;
+}
+/*----------- parsemeddate()--------*/
+void parsemeddate(str)
+ CharPtr str;
+{
+ CharPtr strt, tmp, tmp2, tmp3;
+ int i;
+
+ journal_date.data[0] = 0; /* str date */
+ journal_date.data[1] = 0;
+ journal_date.data[2] = 0; /* clear optional elements */
+ journal_date.data[3] = 0;
+ journal_date.str = NULL;
+
+ strt = StringNCpy(datebuf, str, 80);
+
+ while ((*strt != '\0') && (*strt <= ' ')) /* skip leading blanks */
+ strt++;
+
+ if ((*strt == '1') && (*(strt+1) == '9') && /* 19xx */
+ (IS_DIGIT(*(strt+2))) && (IS_DIGIT(*(strt+3))))
+ { /* try to get date */
+ journal_date.data[0] = 1; /* std date */
+ sscanf(strt, "%d", &i);
+ journal_date.data[1] = (Uint1)(i - 1900);
+
+ while (*strt > ' ')
+ strt++;
+ while ((*strt != '\0') && (*strt <= ' ')) /* skip leading blanks */
+ strt++;
+
+ tmp = strt;
+ while ((! journal_date.data[2]) &&
+ (*tmp != '\0')) /* try to find a month */
+ {
+ for (i = 0; i < 12; i++)
+ {
+ if (! StringNICmp(tmp, NCBI_months[i], 3))
+ {
+ journal_date.data[2] = i + 1;
+ tmp2 = (tmp+3); /* excise month string */
+ while (IS_ALPHA(*tmp2))
+ tmp2++;
+ tmp3 = tmp2;
+ if (*tmp3 != '\0') /* look for day */
+ {
+ while ((*tmp3 != '\0') && (*tmp3 <= ' '))
+ tmp3++;
+ if (IS_DIGIT(*tmp3))
+ {
+ sscanf(tmp3, "%d", &i);
+ if ((i >= 1) && (i <= 31))
+ {
+ journal_date.data[3] = i;
+ while (IS_DIGIT(*tmp3))
+ tmp3++;
+ tmp2 = tmp3;
+ }
+ }
+ }
+ if (tmp != strt) /* remove leading blanks */
+ {
+ tmp--;
+ while ((tmp != strt) && (*tmp <= ' '))
+ tmp--;
+ if ((! journal_date.data[3]) && (tmp != strt))
+ { /* look for day before month */
+ if (IS_DIGIT(*tmp))
+ {
+ tmp3 = tmp;
+ while (IS_DIGIT(*tmp3) && (tmp3 != strt))
+ tmp3--;
+ sscanf(tmp3, "%d", &i);
+ if ((i >= 1) && (i <= 31))
+ {
+ journal_date.data[3] = i;
+ tmp = tmp3;
+ }
+ }
+ }
+ }
+ StringCpy(tmp, tmp2);
+ i = 12;
+ }
+ }
+
+ if (! journal_date.data[2]) /* didn't find month */
+ {
+ while (*tmp > ' ') /* skip to next word */
+tmp++;
+ while ((*tmp != '\0') && (*tmp <= ' ')) /* skip leading blanks */
+ tmp++;
+ }
+ }
+
+ while (*strt == ' ') /* anything left for season? */
+ strt++;
+ tmp = strt;
+ while ((*tmp != '\0') && (journal_date.str == NULL))
+ {
+ if (IS_ALPHANUM(*tmp))
+ journal_date.str = strt;
+ tmp++;
+ }
+ }
+ else /* only a string date */
+ journal_date.str = tmp;
+ return;
+}
+
+/*****************************************************************************/
+/* Date Added: 08/02/1994 by C. Chung
+ * Purpose: To extend full page numbers, 311-3 to 311-313.
+ ****************************************************************************/
+
+/* instances of pages:
+3351-76 contd
+74passim-75p
+9C-10C
+32P-3P
+1921A-1921B
+Suppl:1255-62
+Suppl 1:163-74
+1contd-3c
+xxxv-xli
+vii-x
+E15-9
+376-80; discussion 380-2
+2035; discussion 2035-6
+83-5, 89-90
+414-16, 418-20, 422
+1a-721a
+6091-164 and i-xxi
+53-62; quiz 163-4
+
+comments: for the following three instances,
+ only skip the '-', if it's the first char in the token
+ didn't convert "f-21-f-3" to "f-21-f-23"
+
+concil-1-3
+F-13-17
+f-21-f-23
+*/
+
+static
+ConvertPageToken( char * pages, TokenBoundPtr tbp )
+{
+ char s[20], s2[20];
+ char *p;
+ int i, d1, d2;
+ int all_chars = TRUE;
+
+ /* get the data of interest */
+
+ sprintf( s, "%.*s", tbp->end_pos - tbp->start_pos, pages+tbp->start_pos );
+
+ /* check '-' again for safegurad */
+
+ if ( ( p = strchr( s, '-' ) ) == NULL ) {
+ strcpy( tbp->data, s );
+ return(0);
+ }
+
+ /* no processing needed if data containing no digits */
+
+ for ( i = 0; i < (int)strlen(s); i++ )
+ if ( isdigit( s[i] ) ) {
+ all_chars = FALSE;
+ break;
+ }
+
+ if ( all_chars ) {
+ strcpy( tbp->data, s );
+ return(0);
+ }
+
+ /* split data into two parts, s and s2 */
+
+ strcpy( s2, p+1 );
+ *(p+1) = '\0';
+
+ /* count number of digits in the first part of data */
+
+ for ( i=0, d1=0; s[i]; i++ )
+ if ( isdigit(s[i]) ) d1++;
+
+ /* count number of digits in the second part of data */
+
+ for ( i=0, d2=0; s2[i]; i++ )
+ if ( isdigit(s2[i]) ) d2++;
+
+ for ( i=0; s[i]; i++ ) /* find first digit in the first part */
+ if ( isdigit(s[i]) ) break;;
+
+ if ( d1 - d2 <= 0 ) /* no need to extend pages */
+ sprintf( tbp->data, "%s%s", s, s2 );
+ else
+ sprintf( tbp->data, "%s%.*s%s", s, d1-d2, s+i, s2 );
+}
+
+static
+GetPageToken( char * pages, int offset, TokenBoundPtr cur_token )
+{
+ char *tpages=pages+offset;
+ char *p, *t;
+ int i;
+
+ if ( ( p = strchr( tpages, '-' ) ) == NULL )
+ return( FALSE );
+
+ if ( *p == *tpages ) /* skip first byte, it it's a '-' */
+ if ( ( p = strchr( tpages+1, '-' ) ) == NULL )
+ return( FALSE );
+
+ for ( t=p-1; t != tpages && isalnum( *t ); t-- ) ;
+ for ( i=0; tpages+i != t; i++ ) ;
+ cur_token->start_pos = (i==0) ? offset: i+offset+1;
+
+ for ( t=p+1; t < tpages+strlen(tpages)-1 && isalnum( *t ); t++ ) ;
+ for ( i=0; tpages+i != t; i++ ) ;
+
+ if ( t == pages+strlen(pages)-1 )
+ cur_token->end_pos = i+offset+1;
+ else
+ cur_token->end_pos = i+offset;
+
+ return( TRUE );
+}
+
+
+static char *
+ConvertPages( char * pages )
+{
+ TokenBound tb[10];
+ int which_token=0, i, n;
+ char *p;
+ char s[30];
+ char res[80];
+
+ tb[0].start_pos = 0;
+ tb[0].end_pos = 0;
+
+ while(1) {
+ ++which_token;
+ if ( GetPageToken( pages, tb[which_token-1].end_pos, &tb[which_token] ) )
+ ConvertPageToken( pages, &tb[which_token] );
+ else {
+ --which_token;
+ break;
+ }
+ }
+
+ res[0] = '\0';
+
+ for ( i=1; i <= which_token; i++ ) {
+ if ( ( n = tb[i].start_pos - tb[i-1].end_pos ) > 0 ) {
+ sprintf( s, "%.*s", n, pages+tb[i-1].end_pos );
+ strcat( res, s );
+ }
+ strcat( res, tb[i].data );
+ }
+
+ strcat( res, pages+tb[which_token].end_pos );
+ strcpy( pages, res );
+
+ return( ( pages[0]=='\0' ? NULL : pages ) );
+}
+
+/*****************************************************************************/
+
+/*
+ Date Added: 08/03/1994 by C. Chung
+*/
+
+static char *valid_volume_issue_chars="0123456789-?,";
+
+static void
+SeparatePartSuppl( CharPtr vol_issue, CharPtr part_sub )
+{
+ int i;
+
+ *part_sub = '\0';
+
+ /* skip leading spaces */
+ for ( i=0; vol_issue[i] && vol_issue[i]==' '; i++ ) ;
+
+ for ( ; vol_issue[i]; i++ )
+ if ( StringChr( valid_volume_issue_chars, vol_issue[i] ) == NULL )
+ break;
+
+ if ( vol_issue[i] ) { /* not end of vol_issue */
+
+ /* need to take care of 1st, 2nd, 3th ... */
+
+ if ( StringLen( vol_issue+i ) > 2 ) {
+ if ( StringNICmp( vol_issue+i, "st", 2 ) == 0 ||
+ StringNICmp( vol_issue+i, "nd", 2 ) == 0 ||
+ StringNICmp( vol_issue+i, "th", 2 ) == 0 ) {
+ for ( i=i-1 ; i >=0 ; i-- )
+ if ( ! isdigit( vol_issue[i] ) ) break;
+ if ( i == -1 ) i = 0;
+ }
+ }
+
+ /* for "1-B", "127, Pt 1" */
+
+ if ( i > 0 && ( vol_issue[i-1]=='-' ||
+ vol_issue[i-1]==',' ) ) i--;
+
+ /* copy part data */
+
+ StringCpy( part_sub, vol_issue+i );
+ vol_issue[i] = '\0';
+ }
+}
+
+/*****************************************************************************/
+
+#define AssignValue( s ) ( s[0]=='\0' ? NULL : s )
+
+MedlineEntryPtr
+medlinePub2asn ( MedArt *article, int status )
+{
+ register int art_dex;
+ MedlineEntryPtr medline_obj = & asnmedline_article, retval=NULL;
+ int restart_Med2AsnAuthNew = Med2Asn_RESTART;
+ CharPtr eptr, s;
+ int len;
+
+ InitStaticVariables(); /* added 08/04/94 */
+
+ if ( status != True ) {
+ medline_obj->cit = NULL;
+ return( medline_obj );
+ }
+ article_ui = article->ui; /* Fudge for error messages */
+
+/* MRI is discarded */
+ medline_obj -> uid = article -> ui;
+ medline_obj -> em = & entry_month;
+ entry_month.data[0] = 1;
+ entry_month.data[1] = article->entry_month / 100;
+ entry_month.data[2] = article->entry_month - 100 * entry_month.data[1] ;
+ entry_month.data[3] = 0;
+
+ medline_obj -> cit = & asn_article;
+ asn_article.title = & asn_title;
+ asn_title.choice = 1; /* name */
+ asn_title.data.ptrvalue = NULL;
+ if ( * article -> title) {
+ asn_title.data.ptrvalue = article->title; /* when take vtitle?*/
+ }
+ if ( ! asn_title.data.ptrvalue ) {
+ if ( * article -> vtitle) {
+ asn_title.data.ptrvalue = article->vtitle;
+ }
+ }
+ asn_article. authors = NULL;
+ if (article -> n_authors > 0){
+ ValNodePtr this_auth, last_auth=NULL;
+ asn_article. authors = & MedAsnAuthList;
+ MedAsnAuthList.names = NULL;
+ MedAsnAuthList.choice = 2;
+ for ( art_dex = 0; art_dex < article -> n_authors;
+ art_dex ++ ) {
+ if (* (article -> authors) [art_dex]){
+ this_auth = Med2AsnAuthNew( &
+ restart_Med2AsnAuthNew);
+ this_auth -> next = NULL;
+ if ( ! MedAsnAuthList.names){
+ MedAsnAuthList.names = this_auth;
+ }
+ if ( last_auth){
+ last_auth -> next = this_auth;
+ }
+ this_auth -> data.ptrvalue =
+ (article -> authors) [art_dex];
+ last_auth = this_auth;
+ }
+ }
+ }else{
+/*---fudge if no authors ---*/
+ ValNodePtr this_auth, last_auth=NULL;
+ asn_article. authors = & MedAsnAuthList;
+ MedAsnAuthList.names = NULL;
+ MedAsnAuthList.choice = 3;
+ for ( art_dex = 0; art_dex < article -> n_authors;
+ art_dex ++ ) {
+ this_auth = Med2AsnAuthNew( &
+ restart_Med2AsnAuthNew);
+ this_auth -> next = NULL;
+ if ( ! MedAsnAuthList.names){
+ MedAsnAuthList.names = this_auth;
+ }
+ this_auth -> data.ptrvalue = StringSave("");
+ }
+ }
+
+ if ( strlen( article->address ) == 0 )
+ MedAsnAuthList.affil = NULL;
+ else
+ {
+ MedAsnAuthList.affil = &MedAffil;
+ MedAffil.choice = 1;
+ MedAffil.affil = article->address;
+ }
+
+ asn_article.from = 1;
+ asn_article.fromptr = & asn_journal;
+ asn_journal.title = & asn_journal_title;
+ asn_journal_title.choice = article->title_type; /* iso/ml jta */
+ asn_journal_title.data.ptrvalue = AssignValue( article->med_abbr );
+ asn_journal.imp = & asn_imprint;
+ asn_imprint.date = & journal_date;
+
+ parsemeddate(article -> pubdate);
+ if (article->issue != NULL && *(article->issue) != '\0') {
+ len = StringLen(article->volume) + StringLen(article->issue);
+ s = MemNew(len+5);
+ sprintf(s, "%s (%s)", article->volume, article->issue);
+ eptr = s + len + 3;
+ } else {
+ s = Nlm_StringSave(article->volume);
+ eptr = s + StringLen(s);
+ }
+ if (!ma_get_parts(s, eptr, &asn_imprint)) {
+ /* may be error message later */
+ }
+ MemFree(s);
+ asn_imprint.pages = ConvertPages( article->pages );
+
+ asn_imprint.section = NULL; /* not in medline? */
+ asn_imprint.language = AssignValue( article->language_code );
+ asn_imprint.cprt = NULL; /* not in medline? */
+ asn_imprint.pub = NULL; /* not in medline? */
+
+ retval = medline_obj;
+ return retval;
+}
+
+/*----------- medline2asn()---------*/
+
+MedlineEntryPtr
+medline2asn (article, optionHead)
+ MedArt * article;
+ AsnOptionPtr optionHead;
+{
+ register int art_dex, dex;
+ register int art_qual_dex, qual_dex;
+ MedlineEntryPtr medline_obj = & asnmedline_article, retval=NULL;
+ int restart_Med2AsnSubNew = Med2Asn_RESTART;
+ int restart_Med2AsnXrefNew = Med2Asn_RESTART;
+ int restart_Med2AsnSupportNew = Med2Asn_RESTART;
+ int restart_Med2AsnGeneSymNew = Med2Asn_RESTART;
+ int restart_Med2AsnMeshNew = Med2Asn_RESTART;
+ int restart_Med2AsnQualNew = Med2Asn_RESTART;
+
+
+ medline_obj = medlinePub2asn( article, True );
+
+ medline_obj -> abstract = (*(article->abstract) == (char) 0)
+ ? NULL : article -> abstract;
+
+ medline_obj -> mesh = NULL;
+ if ( article -> n_mesh){
+ MedlineMeshPtr last_mesh = NULL, this_mesh;
+ Mesh * this_art_mesh;
+
+ for ( art_dex = 0; art_dex < article -> n_mesh; art_dex ++ ) {
+ this_art_mesh = & (article -> mesh[art_dex]);
+ if (* ( this_art_mesh -> heading) ){
+ this_mesh = Med2AsnMeshNew(
+ &restart_Med2AsnMeshNew);
+ this_mesh -> next = NULL;
+ if ( ! medline_obj -> mesh){
+ medline_obj -> mesh = this_mesh;
+ }
+ if ( last_mesh){
+ last_mesh -> next = this_mesh;
+ }
+ this_mesh -> term = this_art_mesh -> heading;
+ last_mesh = this_mesh;
+ if ( ( this_art_mesh -> main_point)[0] == '*'){
+ this_mesh -> mp = TRUE;
+ }else{
+ this_mesh -> mp = FALSE;
+ }
+ this_mesh -> qual = NULL;
+ if ( this_art_mesh -> n_qual > 0){
+ ValNodePtr this_qual, last_qual = NULL;
+ Qual * this_art_qual;
+
+ for ( qual_dex = art_qual_dex = 0;
+ art_qual_dex < this_art_mesh -> n_qual;
+ art_qual_dex ++ ) {
+ this_art_qual = &
+ ((this_art_mesh->qualifiers)[art_qual_dex]);
+
+ if (* (this_art_qual -> description)){
+ this_qual = Med2AsnQualNew ( &
+ restart_Med2AsnQualNew);
+ if ( ( this_art_qual -> main_point)[0] == '*'){
+ this_qual -> choice = TRUE;
+ }else{
+ this_qual -> choice = FALSE;
+ }
+ this_qual -> next = NULL;
+ if ( ! this_mesh -> qual){
+ this_mesh -> qual = this_qual;
+ }
+ if (last_qual){
+ last_qual -> next = this_qual;
+ }
+ last_qual = this_qual;
+ this_qual -> data.ptrvalue
+ = this_art_qual -> description;
+ }
+ }
+ }
+ }
+ }
+ }
+/*----
+ type ENUMERATED { -- type of record
+ nameonly (0) ,
+ cas (1) , -- CAS number
+ ec (2) } , -- EC number
+---*/
+ medline_obj -> substance = NULL;
+ if ( article -> n_substances){
+ MedlineRnPtr this_substance, last_substance=NULL;
+ for ( art_dex = 0; art_dex < article -> n_substances;
+ art_dex ++ ) {
+ if (* ((article -> substances) [art_dex]).name){
+ this_substance = Med2AsnSubNew( &
+ restart_Med2AsnSubNew);
+ this_substance -> next = NULL;
+ if ( ! medline_obj -> substance){
+ medline_obj -> substance = this_substance;
+ }
+ if ( last_substance){
+ last_substance -> next = this_substance;
+ }
+ this_substance -> type = 0;
+ this_substance -> name =
+ ((article -> substances) [art_dex]).name;
+ this_substance -> cit =
+ ((article -> substances) [art_dex]).number;
+ last_substance = this_substance;
+ if ( this_substance -> cit)
+ if (* (this_substance -> cit ) ){
+ if (strcmp (this_substance -> cit,"0" ) == 0 ){
+ this_substance -> type = 0;
+ this_substance -> cit = NULL;
+ }else{
+ this_substance -> type = 1;
+ if (* (this_substance -> cit )== 'E' &&
+ *(this_substance -> cit +1 ) == 'C' ){
+ this_substance -> type = 2;
+ (this_substance -> cit) += 2;
+ while( isspace( *(this_substance -> cit) ) )
+ (this_substance -> cit) ++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ medline_obj -> xref = NULL;
+ if ( article -> n_xrefs){
+ ValNodePtr this_xref, last_xref=NULL;
+ Uint1 choice;
+
+ for ( art_dex = 0; art_dex < article -> n_xrefs;
+ art_dex ++ ) {
+ choice = xref_lookup( ((article -> xrefs) [art_dex]).database);
+ if (* ((article -> xrefs) [art_dex]).accession && choice > 0){
+ this_xref = Med2AsnXrefNew( &
+ restart_Med2AsnXrefNew);
+ this_xref -> next = NULL;
+ if ( ! medline_obj -> xref){
+ medline_obj -> xref = this_xref;
+ }
+ if ( last_xref){
+ last_xref -> next = this_xref;
+ }
+ last_xref = this_xref;
+ this_xref -> choice = choice;
+ this_xref -> data.ptrvalue =
+ ((article -> xrefs) [art_dex]).accession;
+ }
+ }
+ }
+
+ medline_obj -> idnum = NULL;
+ if ( article -> n_idnum){
+ ValNodePtr this_idnum, last_idnum=NULL;
+ for ( art_dex = 0; art_dex < article -> n_idnum;
+ art_dex ++ ) {
+ if ( ((article -> idnums) [art_dex])[0]){
+ this_idnum = Med2AsnSupportNew( &
+ restart_Med2AsnSupportNew);
+ this_idnum -> next = NULL;
+ if ( ! medline_obj -> idnum){
+ medline_obj -> idnum = this_idnum;
+ }
+ if ( last_idnum){
+ last_idnum -> next = this_idnum;
+ }
+ last_idnum = this_idnum;
+ this_idnum -> choice = 1;
+ this_idnum -> data.ptrvalue =
+ ((article -> idnums) [art_dex]);
+ }
+ }
+ }
+
+ medline_obj -> gene = NULL;
+ if ( article -> n_gene_symbols){
+ ValNodePtr this_gene, last_gene=NULL;
+ for ( art_dex = 0; art_dex < article -> n_gene_symbols;
+ art_dex ++ ) {
+ if ( ((article -> gene_symbols) [art_dex])[0]){
+ this_gene = Med2AsnGeneSymNew( &
+ restart_Med2AsnGeneSymNew);
+ this_gene -> next = NULL;
+ if ( ! medline_obj -> gene){
+ medline_obj -> gene = this_gene;
+ }
+ if ( last_gene){
+ last_gene -> next = this_gene;
+ }
+ last_gene = this_gene;
+ this_gene -> choice = 1;
+ this_gene -> data.ptrvalue =
+ ((article -> gene_symbols) [art_dex]);
+ }
+ }
+ }
+
+ retval = medline_obj;
+ return retval;
+}
+
+/*----------MedArt_ASNTTY()-----------*/
+
+int
+MedArt_ASNTTY(fp, article)
+ FILE * fp; /* ignored for this hack */
+ MedArt * article;
+{
+ MedlineEntryPtr asnmed;
+ Boolean retval;
+
+ asnmed = medline2asn(article, NULL);
+ if ( ! aip){
+ aip = AsnIoOpen("stdout","w");
+ }
+
+ if (aip && asnmed){
+ retval = MedlineEntryAsnWrite(asnmed, aip, NULL);
+ AsnIoClose(aip);
+ return retval;
+ }else{
+ return FALSE;
+ }
+}
diff --git a/network/medarch/server/medart2asn.h b/network/medarch/server/medart2asn.h
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/network/medarch/server/medart2asn.h
diff --git a/network/medarch/server/medfield.h b/network/medarch/server/medfield.h
new file mode 100644
index 00000000..e5961f30
--- /dev/null
+++ b/network/medarch/server/medfield.h
@@ -0,0 +1,78 @@
+/*
+ medline.h Process Medline database fields
+
+ MODULE: medline
+ FILES: medline.c and medline.h (this one).
+
+ The procedures in module medline support the decoding of the
+ data the Medline database elements. These are rather general
+ extraction methods as opposed to more complex extractions
+ which are highly field specific (such as the Comment field).
+
+ Edit History:
+ 16 August 1991 - Rand S. Huntzinger
+ Added GetCharsetErrors();
+
+ Work started: 25 July 1991 - Rand S. Huntzinger, NLM/NCBI.
+*
+*
+* RCS Modification History:
+* $Log: medfield.h,v $
+* Revision 6.0 1997/08/25 18:36:31 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:08 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_MEDLINE
+#define DEFS_MODULE_MEDLINE
+
+/* Define the Medline unit record field element types */
+
+#define MEDLINE_DA 100 /* DATE OF ENTRY */
+#define MEDLINE_RO 101 /* RECORD ORIGINATOR */
+#define MEDLINE_LR 102 /* LAST REVISION DATE */
+#define MEDLINE_CU 103 /* CLASSUP DATE */
+#define MEDLINE_RN 261 /* CAS REGISTRY NUMBER */
+#define MEDLINE_IS 301 /* INTL STAND SER NO */
+#define MEDLINE_TA 305 /* TITLE ABBREVIATION */
+#define MEDLINE_LA 306 /* LANGUAGE */
+#define MEDLINE_ZN 308 /* MESH Z TREE NUMBER */
+#define MEDLINE_JC 320 /* JOURNAL TITLE CODE */
+#define MEDLINE_PY 323 /* INDEXING PRIORITY */
+#define MEDLINE_SB 324 /* JOURNAL SUBSET */
+#define MEDLINE_GS 328 /* GENE SYMBOL */
+#define MEDLINE_LI 329 /* SPECIAL LIST IND */
+#define MEDLINE_UI 350 /* UNIQUE IDENTIFIER */
+#define MEDLINE_MH 351 /* MESH HEADING */
+#define MEDLINE_TI 352 /* TITLE */
+#define MEDLINE_PG 353 /* PAGINATION */
+#define MEDLINE_DP 354 /* DATE OF PUBLICATION */
+#define MEDLINE_PT 360 /* PUBLICATION TYPE */
+#define MEDLINE_MRI 368 /* MACHINE-READABLE ID */
+#define MEDLINE_NP 369 /* NOT FOR PUBLICATION */
+#define MEDLINE_AB 370 /* ABSTRACT */
+#define MEDLINE_AA 371 /* ABSTRACT AUTHOR */
+#define MEDLINE_AU 372 /* AUTHOR */
+#define MEDLINE_IP 373 /* ISSUE/PART/SUPP */
+#define MEDLINE_NI 376 /* NO-AUTHOR INDICATOR */
+#define MEDLINE_RF 377 /* NUMBER OF REFS */
+#define MEDLINE_AD 378 /* ADDRESS */
+#define MEDLINE_PS 379 /* PERSONAL NAME AS SUBJECT */
+#define MEDLINE_TT 380 /* TRANSLIT/VERNAC TITLE */
+#define MEDLINE_VI 381 /* VOLUME/ISSUE */
+#define MEDLINE_EA 382 /* ENGLISH ABSTRACT INDEX */
+#define MEDLINE_EM 383 /* ENTRY MONTH */
+#define MEDLINE_CM 440 /* COMMENTS */
+#define MEDLINE_CA 525 /* CALL NUMBER */
+#define MEDLINE_SI 606 /* SECONDARY SOURCE ID */
+#define MEDLINE_ID 640 /* ID NUMBER */
+
+/* Define the codes specific to identifying Monographs in the JC/TA fields */
+
+#define MEDLINE_MONOGRAPH_JC "IDM"
+#define MEDLINE_MONOGRAPH_TA "(Monograph)"
+
+#endif /* DEFS_MODULE_MEDLINE */
diff --git a/network/medarch/server/medretrieve.c b/network/medarch/server/medretrieve.c
new file mode 100644
index 00000000..44e6a352
--- /dev/null
+++ b/network/medarch/server/medretrieve.c
@@ -0,0 +1,783 @@
+/*
+ * Program: medretrieve.c
+ *
+ * RCS Modification History:
+ * $Log: medretrieve.c,v $
+ * Revision 6.0 1997/08/25 18:36:33 madden
+ * Revision changed to 6.0
+ *
+ * Revision 1.10 1995/07/12 18:00:33 tatiana
+ * core dump in SybaseMedlineCitMatch fixed
+ *
+ * Revision 1.9 1995/07/12 14:48:38 tatiana
+ * first page only in the query in SybaseMedlineCitMatch()
+ *
+ * Revision 1.8 1995/07/05 19:20:34 tatiana
+ * no default server and database.
+ *
+ * Revision 1.7 1995/05/30 21:57:59 tatiana
+ * remove TitleMsgNew() and TitleMsgListNew()
+ *
+ * Revision 1.6 1995/05/30 18:01:01 tatiana
+ * *** empty log message ***
+ *
+ * Revision 1.5 1995/05/17 17:55:12 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <stdlib.h>
+#include <objmedli.h>
+#include <objbibli.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+
+#include "ma_global.h"
+#include "error.h"
+#include "ma_intfc.h"
+
+#include <sybfront.h>
+#include <sybdb.h>
+#include <syberror.h>
+
+#include "mappings.h"
+#include <objmla.h>
+
+/*
+ * Define default server names, databases, user names and passwords for
+ * G5 and MEDLINE machine.
+ */
+
+#define T_SERVER 0
+#define T_DATABASE 1
+#define T_USER 2
+#define T_PASSWORD 3
+#define G5_SERVER 4
+#define G5_DATABASE 5
+#define G5_USER 6
+#define G5_PASSWORD 7
+
+static DBPROCESS *db;
+static MedArt article;
+
+extern MedlineEntryPtr medline2asn(MedArt *article, AsnOptionPtr optionHead);
+extern MedlineEntryPtr medlinePub2asn(MedArt *article, int status);
+/***************************************************************************
+ *
+ * function: CopyString
+ *
+ ***************************************************************************/
+static
+CopyString( char *new, char *text )
+{
+ char *p, *np;
+ char quote = '\'';
+ int blank_data = 1;
+
+ for( p = text, np = new; *p; *np++ = *p++ )
+ if( *p == quote ) *np++ = *p;
+
+ *np = '\0';
+
+ for ( np = new; *np; np++ )
+ if ( *np != ' ' ) { blank_data = 0; break; }
+
+ if ( blank_data ) *new = '\0';
+}
+
+/*************************************************************************
+ *
+ * function: ma_err_handler
+ * desc: Sybase error handler
+ *
+ **************************************************************************/
+
+int ma_err_handler( dbproc, severity, dberr, oserr, dberrstr, oserrstr )
+ DBPROCESS *dbproc;
+ int severity, dberr, oserr;
+ char *dberrstr, *oserrstr;
+{
+
+ if ( ( dbproc == NULL ) || DBDEAD( dbproc ) )
+ return( INT_EXIT );
+ else
+ {
+ fprintf( stderr, "DB-Library error:\n\t%s\n", dberrstr );
+
+ if ( oserr != DBNOERR )
+ fprintf( stderr, "Operating-system error:\n\t%s\n", oserrstr );
+
+ return( INT_CANCEL );
+ }
+}
+
+/*************************************************************************
+ *
+ * function: ma_msg_handler
+ * desc: Sybase message handler
+ *
+ **************************************************************************/
+
+int ma_msg_handler( dbproc, msgno, msgstate, severity, msgtext,
+ srvname, procname, line )
+ DBPROCESS *dbproc;
+ DBINT msgno;
+ int msgstate, severity;
+ char *msgtext, *srvname, *procname;
+ DBUSMALLINT line;
+{
+ if ( msgno >= 5701 && msgno <= 5704 ) return( 0 );
+
+ fprintf( stderr, "Msg %ld, Level %d, State %d\n",
+ msgno, severity, msgstate );
+
+ if ( strlen( srvname ) ) fprintf( stderr, "Server '%s', ", srvname );
+
+ if ( strlen( procname ) ) fprintf( stderr, "Procedure '%s', ", procname );
+
+ if ( line > 0 ) fprintf( stderr, "Line %d", line );
+
+ fprintf( stderr, "\n\t%s\n", msgtext );
+
+ return( 0 );
+}
+
+
+/*************************************************************************
+ *
+ * function: MA_InitDBConnection
+ *
+ **************************************************************************/
+
+DBPROCESS *MA_InitDBConnection( char *appl, char *server, char *dbname,
+ char *user, char *password )
+{
+ LOGINREC *login;
+ DBPROCESS *dbproc;
+
+ if ( dbinit() == FAIL ) exit( ERREXIT );
+
+ dberrhandle( ma_err_handler );
+ dbmsghandle( ma_msg_handler );
+
+ if ( ( login = dblogin() ) == NULL ) return( NULL );
+
+ DBSETLUSER( login, user );
+ DBSETLPWD ( login, password );
+ DBSETLAPP ( login, appl );
+
+ if ( ( dbproc = dbopen( login, server ) ) == NULL ) return( NULL );
+
+ dbloginfree( login );
+
+ if ( dbuse( dbproc, dbname ) == FAIL )
+ return( NULL );
+
+ return( dbproc );
+}
+
+/**************************************************************************
+ *
+ * CloseDatabaseConnection
+ *
+ **************************************************************************/
+
+CloseDatabaseConnection()
+{
+ dbexit();
+}
+
+/*************************************************************************
+ *
+ * function: OutSybaseCommand
+ *
+ **************************************************************************/
+
+static
+void OutSybaseCommand( dbproc )
+ DBPROCESS *dbproc;
+{
+ static FILE *fd = NULL;
+ char buffer[61];
+ int len = dbstrlen( dbproc );
+ char *stub = "Query:";
+ int index = 0;
+ int copy_count;
+ register char *p;
+
+
+ if ( fd == NULL ) fd = fopen( "medserv.sql", "w" );
+
+fprintf(fd, "length of dbproc = %d\n", len );
+
+ /* Dump the query out to SybaseQueryPrintFile */
+
+ while( index < len )
+ {
+ copy_count = (( len - index ) > (sizeof(buffer) - 1))
+ ? (sizeof(buffer) - 1) : (len - index);
+ dbstrcpy( dbproc, index, copy_count , buffer );
+ for(p=buffer; *p; p++) if(isspace(*p)) *p = ' ';
+ fprintf(fd, "%-12.12s || %s ||\n", stub, buffer);
+ stub = "";
+ index += copy_count;
+ }
+ fprintf(fd, "\n" );
+ fflush(fd);
+}
+
+/***************************************************************************
+ *
+ * Function: InitMedlineDB
+ *
+ ***************************************************************************/
+
+InitMedlineDB()
+{
+/* static char *def_server = "TECH2"; */
+ static char *def_server = "MOZART_SYS10";
+ static char *def_database = "molbiolit";
+
+
+ if ( ( flagServer = getenv ( "SYB_MB_SERVER" ) ) == NULL ) {
+/* flagServer = def_server; */
+ fprintf(stderr, "SYB_MB_SERVER is not set\n");
+ return FALSE;
+ }
+ if ( ( flagDatabase = getenv( "SYB_MB_DATABASE" ) ) == NULL ) {
+/* flagDatabase = def_database; */
+ fprintf(stderr, "SYB_MB_DATABASE is not set\n");
+ return FALSE;
+ }
+ db = MA_InitDBConnection( "medretrieve",
+ flagServer, flagDatabase, "asnreport", "AsnReport" );
+
+ if( db == (DBPROCESS *) NULL ) {
+ return( FALSE );
+ }
+
+ return( TRUE );
+}
+
+/***************************************************************************
+ *
+ * Function: CloseMedlineDB
+ *
+ ***************************************************************************/
+
+
+void CloseMedlineDB()
+{
+ CloseDatabaseConnection();
+}
+
+
+/***************************************************************************
+ *
+ * Function: MedlineArticleExists
+ *
+ ***************************************************************************/
+
+static int MedlineArticleExists( Int4 ui )
+{
+
+ dbcancel( db );
+ dbfcmd( db, "select ui from Article where ui = %d\n", ui );
+
+ if( ExecSybaseCommand( db ) != SUCCEED )
+ return( FALSE );
+
+ if ( DBROWS( db ) == SUCCEED )
+ return( TRUE );
+ else
+ return( FALSE );
+}
+
+
+/***************************************************************************
+ *
+ * Function: CheckValidMedlineUids
+ * Description: Given the number and the list of ui's,
+ * find out how many articles of interest exist in the
+ * database.
+ *
+ ***************************************************************************/
+
+int CheckValidMedlineUids( int numid, Int4Ptr uids )
+{
+ int entries_found = 0, i;
+
+ for ( i = 0; i< numid; i++ )
+ if ( MedlineArticleExists( uids[i] ) ) entries_found++;
+
+ return( entries_found );
+}
+
+/***************************************************************************
+ *
+ * Function: SybaseMedlineEntryGet
+ *
+ ***************************************************************************/
+
+MedlineEntryPtr SybaseMedlineEntryGet( Int4 ui )
+{
+ int flags=0;
+
+ if ( ! MedlineArticleExists( ui ) )
+ return( (MedlineEntryPtr)NULL );
+
+ if ( GetMedlineArticle(db, (int)ui, flags, &article) == True )
+ return( medline2asn( &article, NULL ) );
+ else
+ return( (MedlineEntryPtr)NULL );
+}
+
+
+/***************************************************************************
+ *
+ * Function: SybaseMedlinePubGet
+ * Description: This function retrieves data for article->cit
+ *
+ ***************************************************************************/
+
+CitArtPtr SybaseMedlinePubGet( Int4 ui )
+{
+ int flags=0, status;
+ MedlineEntryPtr asn_article;
+
+
+ if ( ! MedlineArticleExists( ui ) )
+ return( (CitArtPtr)NULL );
+
+ status = GetMedlinePub(db, (int)ui, flags, &article);
+
+ asn_article = medlinePub2asn( &article, status );
+
+ if ( asn_article == NULL )
+ return( (CitArtPtr)NULL );
+ else
+ return( asn_article->cit );
+}
+
+/***************************************************************************
+ *
+ * Functions for SybaseMedlineGetTitle
+ *
+ ***************************************************************************/
+
+#define syb_med_code 0
+#define syb_med_abbr 1
+#define syb_coden 2
+#define syb_issn 3
+#define syb_iso_abbr 4
+#define syb_name 5
+
+#define MAX_TITLE_DATA 6
+#define MAX_TITLE_ROWS 10
+
+#define TITLE_NOT_SET 0
+#define TITLE_NAME 1
+#define TITLE_JTA 4
+#define TITLE_ISO_JTA 5
+#define TITLE_ML_JTA 6
+#define TITLE_CODEN 7
+#define TITLE_ISSN 8
+#define TITLE_ALL 255
+
+#define MAX_TITLE_SIZE 250
+
+typedef struct SybTitleNode {
+ char data[ MAX_TITLE_DATA ][ MAX_TITLE_SIZE ];
+} SybTitle, *SybTitlePtr;
+
+typedef struct SybTitleArray {
+ int index;
+ SybTitle s[ MAX_TITLE_ROWS ];
+} SybTitleArray;
+
+
+static int which_index = 0; /* for sorting */
+
+/***************************************************************************
+ *
+ * Function: TitleCompare
+ * Description: Sort title rows by the title field specified in
+ * which_index.
+ *
+ ***************************************************************************/
+
+static
+int TitleCompare( const void *t1, const void *t2 )
+{
+ return( strcmp( ((SybTitlePtr) t1)->data[which_index],
+ ((SybTitlePtr) t2)->data[which_index] ) );
+}
+
+/***************************************************************************
+ *
+ * Function: GetTitleColumnIndex
+ * Description: Given ans.1 title_type, return index of respective
+ * title field.
+ *
+ ***************************************************************************/
+
+static
+GetTitleColumnIndex( int title_type )
+{
+ int index = -1;
+
+ switch( title_type )
+ {
+ case TITLE_NAME: index = syb_name; break;
+ case TITLE_JTA: index = syb_med_abbr; break;
+ case TITLE_ISO_JTA: index = syb_iso_abbr; break;
+ case TITLE_ML_JTA: index = syb_med_abbr; break;
+ case TITLE_CODEN: index = syb_coden; break;
+ case TITLE_ISSN: index = syb_issn; break;
+ default: break;
+ }
+
+ return( index );
+}
+
+
+/***************************************************************************
+ *
+ * Function: InsertTitleToList
+ * Description: Insert the title field of interest into return list.
+ *
+ * type: return title type ( can be all )
+ * title_type: specify what type of data returned
+ * data: returned title data
+ *
+ ***************************************************************************/
+
+static
+int InsertTitleToList( TitleMsgListPtr tmlp, int type, int title_type, char *data )
+{
+ int len;
+ TitleMsgPtr t;
+
+ if ( data == NULL ) return( 0 );
+
+ if ( strlen( data ) == 0 ) return( 0 );
+
+ t = (TitleMsgPtr) MemNew(sizeof(TitleMsg));
+ t->type = type;
+ t->next = tmlp->titles; /* insert at head of the list */
+
+ t->title = ( TitlePtr ) ValNodeNew(NULL);
+ t->title->choice = title_type;
+ t->title->data.ptrvalue = StringSave( data );
+
+ tmlp->titles = t;
+
+ ++( tmlp->num );
+}
+
+
+/***************************************************************************
+ *
+ * Function: BuildTitleMsgList
+ * Description: Insert the non-null title field(s) specified by
+ * title_type into the returned list; return number
+ * of nodes in the list. Duplicate data will be
+ * eliminated.
+ *
+ ***************************************************************************/
+
+static
+BuildTitleMsgList( TitleMsgListPtr tmlp, int title_type, SybTitleArray titles )
+{
+ int i, j, index;
+ char prev_data[ MAX_TITLE_SIZE ];
+
+ if ( ( index = GetTitleColumnIndex( title_type ) ) < 0 )
+ return( 0 );
+
+ if ( titles.index > 1 ) { /* sorting */
+ which_index = index;
+ qsort( titles.s, titles.index, sizeof(SybTitle), TitleCompare );
+ }
+
+ prev_data[ 0 ] = '\0';
+
+ for ( i=titles.index-1; i >= 0; i-- )
+ {
+ if ( strcmp( titles.s[i].data[index], prev_data ) == 0 )
+ continue;
+
+ InsertTitleToList( tmlp, title_type, title_type, titles.s[i].data[index] );
+
+ strcpy( prev_data, titles.s[i].data[index] );
+ }
+
+ return( tmlp->num );
+}
+
+/***************************************************************************
+ *
+ * Function: MoreTitleRows
+ * Description: Check if only one unique title row retrieved from
+ * Sybase.
+ *
+ ***************************************************************************/
+
+MoreTitleRows( SybTitleArray titles )
+{
+ int i, j;
+
+ for ( i = 1; i < titles.index; i++ )
+ for ( j = syb_med_abbr; j <= syb_name; j++ ) {
+ if ( strcmp( titles.s[0].data[j], titles.s[i].data[j] ) )
+ return( 1 );
+ }
+
+ return( 0 );
+}
+
+/***************************************************************************
+ *
+ * Function: BuildAllTitleMsgList
+ * Description:
+ *
+ * For title_type = all,
+ * If only one unique title row retrieved from Sybase,
+ * return all title fields
+ * else
+ * return ml-jta( med_abbr ) from each title row.
+ *
+ ***************************************************************************/
+
+static
+BuildAllTitleMsgList( TitleMsgListPtr tmlp, SybTitleArray titles )
+{
+ int i;
+ static int title_type_list[6] =
+ { 0, TITLE_ML_JTA, TITLE_CODEN, TITLE_ISSN, TITLE_ISO_JTA, TITLE_NAME };
+
+ if ( MoreTitleRows( titles ) )
+ return( 0 );
+
+ for ( i = syb_med_abbr; i <= syb_name; i++ ) {
+ InsertTitleToList(tmlp, TITLE_ALL, title_type_list[i], titles.s[0].data[i]);
+ }
+
+ return( 1 );
+}
+
+
+/***************************************************************************
+ *
+ * Function: RetrieveTitleInfoFromSybase
+ * Description: The stored proc mr_get_title returns status, and
+ * title information if status > 0
+ *
+ ***************************************************************************/
+
+RetrieveTitleInfoFromSybase( TitleMsgPtr tmsg )
+{
+ if ( tmsg == NULL || tmsg->title->data.ptrvalue == NULL )
+ return( NULL );
+
+ dbfreebuf( db );
+ dbfcmd( db, "exec mr_get_title %d, %d, '%s'\n", tmsg->type,
+ tmsg->title->choice, tmsg->title->data.ptrvalue );
+
+OutSybaseCommand( db );
+
+ if ( ExecSybaseCommand( db ) != SUCCEED )
+ return( NULL );
+
+ return( SUCCEED );
+}
+
+
+/***************************************************************************
+ *
+ * Function: SybaseMedlineGetTitle
+ * Description:
+ * 1. retrieve title data from Sybase
+ * 2. check status, if < 0, return NULL ( indicate error )
+ * if = 0, return not found
+ * 3. store all retrieved data into temporary array
+ * 4. if request = all
+ * if rows returned = 1,
+ * return type=all, and every title column
+ * else
+ * return type=ml-jta, and med_abbr for each row
+ * 5. if request = not-set
+ * return type=ml-jta
+ * 6. otherwise,
+ * if request != ml-jta
+ * if column exist
+ * return column
+ * else
+ * return ml-jta
+ *
+ ***************************************************************************/
+
+TitleMsgListPtr SybaseMedlineGetTitle( TitleMsgPtr tmsg )
+{
+ int status, i;
+ TitleMsgListPtr tmlp = NULL;
+ SybTitleArray titles;
+ SybTitle title_value;
+
+ if ( RetrieveTitleInfoFromSybase( tmsg ) == NULL )
+ return( NULL );
+
+ dbbind( db, 1, INTBIND, 0, &status );
+ dbnextrow( db );
+
+ if ( status < 0 ) return( NULL );
+
+ tmlp = (TitleMsgListPtr) MemNew(sizeof(TitleMsgList));
+ tmlp-> num = 0;
+ tmlp->titles = NULL;
+
+ titles.index = 0;
+
+ if ( status > 0 && dbresults( db ) == SUCCEED )
+ {
+ for ( i = syb_med_code; i <= syb_name; i++ )
+ dbbind( db, i+1, NTBSTRINGBIND, 0, title_value.data[i] );
+
+ while( dbnextrow( db ) != NO_MORE_ROWS )
+ {
+ for ( i = syb_med_code; i <= syb_name; i++ )
+ strcpy( titles.s[ titles.index ].data[i], title_value.data[i] );
+ ++titles.index;
+ }
+
+ if ( titles.index )
+ {
+ switch( tmsg->type )
+ {
+ case TITLE_NOT_SET:
+ case TITLE_ML_JTA:
+ BuildTitleMsgList( tmlp, TITLE_ML_JTA, titles );
+ break;
+
+ case TITLE_ALL:
+ if ( ! BuildAllTitleMsgList( tmlp, titles ) )
+ BuildTitleMsgList( tmlp, TITLE_ML_JTA, titles );
+ break;
+
+ default:
+ if ( ! BuildTitleMsgList( tmlp, tmsg->type, titles ) )
+ BuildTitleMsgList( tmlp, TITLE_ML_JTA, titles );
+ break;
+ }
+ }
+ }
+
+ if ( tmlp->titles == NULL )
+ {
+ tmlp->num = 1;
+ tmlp->titles = tmsg;
+ tmlp->titles->type = 0; /* not-set: means not-found */
+ tmlp->titles->next = NULL;
+ tmsg->next = NULL;
+ }
+
+ return( tmlp );
+}
+
+/***************************************************************************
+ *
+ * Functions for SybaseMedlineCitMatch
+ *
+ ***************************************************************************/
+
+#define FROM_JOURNAL 1
+#define RET_ERROR 0
+
+int CheckCitNullVal( char *s )
+{
+ char ts[255];
+
+ if ( s == NULL || s[0] == '\0' )
+ dbcmd( db, ", NULL " );
+ else
+ {
+ CopyString( ts, s );
+ dbfcmd( db, ", '%s' ", ts );
+ }
+}
+
+/***************************************************************************
+ *
+ * Function: SybaseMedlineCitMatch
+ * Description: Call get_muid2 stored procedure.
+ * Return only the first ui found.
+ *
+ ***************************************************************************/
+
+int SybaseMedlineCitMatch( CitArtPtr citation )
+{
+ CitJourPtr cit_jou;
+ AuthListPtr authors;
+ AuthorPtr auth;
+ static char authname[122], page[122];
+ CharPtr p;
+ int ui, method, ret_ui=0;
+ CharPtr first_author = NULL;
+ CharPtr first_page = NULL;
+ RETCODE ret;
+
+
+ if ( ! citation || citation->from != FROM_JOURNAL )
+ return( RET_ERROR );
+
+ if ( ! ( cit_jou = ( CitJourPtr )citation->fromptr ) )
+ return( RET_ERROR );
+
+ if ( ! cit_jou->title || ! cit_jou->imp )
+ return( RET_ERROR );
+
+ if ( ( authors = ( AuthListPtr )citation->authors ) != NULL &&
+ authors->names != NULL ) {
+ if (authors->choice == 1) {
+ auth = authors->names->data.ptrvalue;
+ PersonIdLabel(auth->name, authname, 121, PIDLABEL_GENBANK);
+ first_author = authname;
+ } else {
+ first_author = authors->names->data.ptrvalue;
+ }
+ }
+ if (cit_jou->imp->pages != NULL) {
+ StringCpy(page, cit_jou->imp->pages);
+ for (first_page = p = page; *p != '\0' && *p != '-'; p++);
+ if (*p == '-') {
+ *p = '\0';
+ }
+ }
+ dbfreebuf( db );
+ dbfcmd( db, "exec get_muid2 %d, '%s' ",
+ cit_jou->title->choice, cit_jou->title->data.ptrvalue );
+ CheckCitNullVal( cit_jou->imp->volume ),
+ CheckCitNullVal( first_page ),
+ dbfcmd( db, ", %d ", cit_jou->imp->date->data[1]+1900 );
+ CheckCitNullVal( first_author );
+ dbcmd ( db, ", 1\n" );
+
+OutSybaseCommand( db );
+
+ ret = dbsqlexec( db );
+
+ if ( ret != SUCCEED || dbresults( db ) != SUCCEED )
+ return( RET_ERROR );
+
+ dbbind( db, 1, INTBIND, 0, &ui );
+ dbbind( db, 2, INTBIND, 0, &method );
+
+ while( dbnextrow( db ) != NO_MORE_ROWS )
+ {
+ if ( ret_ui ) continue;
+
+ ret_ui = ( ( ui >= 0 ) ? ui : 0 );
+ }
+
+ return( ret_ui );
+}
diff --git a/network/medarch/server/medschema.h b/network/medarch/server/medschema.h
new file mode 100644
index 00000000..98218f81
--- /dev/null
+++ b/network/medarch/server/medschema.h
@@ -0,0 +1,104 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: medschema.h,v $
+* Revision 6.0 1997/08/25 18:36:35 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:15 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_MEDSCHEMA_H
+
+#include "sybase.h"
+
+#define MAX_STRING_SIZE 255
+#define MAX_BINARY_SIZE 255
+#define MAX_ABSTRACT_SIZE (6*1024)
+#define MAX_AUTHOR_COUNT 150
+#define MAX_MESH_COUNT 40
+#define MAX_QUALIFIER_COUNT 10
+#define MAX_SUBSTANCE_COUNT 50
+#define MAX_XREF_COUNT 50
+#define MAX_IDNUM_COUNT 20
+#define MAX_GENESYM_COUNT 25
+
+#define DbString(Name,Size) DBCHAR Name[Size+1]
+#define DbBinary(Name,Size) DBBINARY Name[Size+1]
+
+/* Define the maximum character column size */
+
+typedef DBCHAR MaxString[SRV_MAXCHAR+1];
+typedef unsigned char MaxBinary[SRV_MAXCHAR];
+
+/* Define the sizes of various fields in various tables */
+
+/* Table Article */
+
+#define DBSIZE_Article_pages 40
+#define DBSIZE_Article_title 245
+#define DBSIZE_Article_title1 255
+#define DBSIZE_Article_vtitle 245
+#define DBSIZE_Article_vtitle1 255
+#define DBSIZE_Article_address 255
+
+#define DBSIZE_Abstract_abstract 255
+
+#define DBSIZE_CrossReference_accession 30
+
+#define DBSIZE_Databases_database_name 30
+
+#define DBSIZE_Issue_volume 25
+#define DBSIZE_Issue_issue 25
+#define DBSIZE_Issue_pubdate 30
+#define DBSIZE_Issue_special_list 1
+
+#define DBSIZE_Language_language_code 3
+#define DBSIZE_Mesh_heading 128
+#define DBSIZE_Mesh_main_point 1
+
+#define DBSIZE_Journal_med_abbr 128
+
+#define DBSIZE_Name_name 128
+
+#define DBSIZE_Subheading_code 2
+#define DBSIZE_Subheading_main_point 1
+#define DBSIZE_Subheading_name 30
+#define DBSIZE_Subheading_description 60
+
+#define DBSIZE_Substance_number 30
+#define DBSIZE_Substance_name 250
+
+#define DBSIZE_ResearchSupport_id 255
+
+#define DBSIZE_GeneSymbol_symbol 72
+
+#if defined(__STDC__)
+ /* NOTE: ANSI-C has a portable concatenation mechanism, unlike the
+ non ANSI-C compilers which use the code below. */
+
+#define DbNColumn(Table,Column,Name) \
+ DBCHAR Name[DBSIZE_ ## Table ## _ ## Column + 1]
+#define DbTitle(Title) \
+ DBCHAR Title[DBSIZE_Article_ ## Title + DBSIZE_Article_ ## Title ## 1 + 1]
+
+#else
+ /* WARNING- The method used for concatenation used in the macros
+ below is not portable. This method works for Sun compilers.
+ Your compiler may use a different method. If so, substitute
+ your concatenation operator for the slash,star,star,slash
+ below. If your compiler doesn't support concatenation, you'll
+ have to recode the types by hand. */
+
+#define DbNColumn(Table,Column,Name) \
+ DBCHAR Name[DBSIZE_/**/Table/**/_/**/Column + 1]
+#define DbTitle(Title) \
+ DBCHAR Title[DBSIZE_Article_/**/Title + DBSIZE_Article_/**/Title/**/1 + 1]
+
+#endif
+#define DbColumn(Table,Column) DbNColumn(Table,Column,Column)
+
+#endif /* DEFS_MODULE_MEDSCHEMA_H */
diff --git a/network/medarch/server/medserv.inp b/network/medarch/server/medserv.inp
new file mode 100644
index 00000000..4bcc3aaf
--- /dev/null
+++ b/network/medarch/server/medserv.inp
@@ -0,0 +1,19 @@
+Mla-request ::= init NULL
+
+Mla-request ::= getmle 66002703
+
+Mla-request ::= getpub 66014762
+
+Mla-request ::= getpub 67004291
+
+Mla-request ::= getpub 67172894
+
+Mla-request ::= getpub 66076891
+
+Mla-request ::= getpub 81264959
+
+Mla-request ::= getpub 85079995
+
+Mla-request ::= getpub 88152497
+
+Mla-request ::= fini NULL
diff --git a/network/medarch/server/medsmain.c b/network/medarch/server/medsmain.c
new file mode 100644
index 00000000..7d468a2c
--- /dev/null
+++ b/network/medarch/server/medsmain.c
@@ -0,0 +1,252 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: medsmain.c,v $
+* Revision 6.0 1997/08/25 18:36:38 madden
+* Revision changed to 6.0
+*
+* Revision 1.5 1996/03/01 16:08:41 grisha
+* add default clause to request switch, now we will
+* return error to the client if request code cannot
+* be proceed by server
+*
+ * Revision 1.4 1995/12/07 17:22:08 tatiana
+ * bulletproofing in main()
+ *
+ * Revision 1.3 1995/05/30 18:01:23 tatiana
+ * *** empty log message ***
+ *
+ * Revision 1.2 1995/05/17 17:55:17 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <ncbi.h>
+#include <objmedli.h>
+#include <objpub.h>
+#include <ncbinet.h>
+#include <accentr.h>
+#include "mappings.h"
+#include "objmla.h"
+
+FILE * Id_timing_file = NULL;
+
+extern MedlineEntryPtr SybaseMedlineEntryGet( Int4 ui );
+extern CitArtPtr SybaseMedlinePubGet( Int4 ui );
+extern TitleMsgListPtr SybaseMedlineGetTitle( TitleMsgPtr tmsg );
+
+main(int argc, char *argv[])
+{
+ MlaRequestPtr mlarp;
+ MlaBackPtr mlabp;
+ Boolean debug = FALSE;
+ static char envset[PATH_MAX+5];
+ extern char *getenv();
+ short erract;
+ ErrDesc err;
+ TitleMsgPtr tmsgp;
+ ValNodePtr pub;
+ TitleMsgListPtr tmlp;
+ int arg;
+ NI_HandPtr hp;
+ static Char buf[100];
+ AsnIoPtr asnin;
+ AsnIoPtr asnout;
+ int read_timeout;
+ Boolean done = FALSE;
+ MedlineEntryPtr meddata;
+ CitArtPtr pubdata;
+ ValNodePtr pbp;
+ int n, ui;
+ ValNodePtr head;
+
+ if (argc > 1) {
+ arg = 1;
+ if (StrCmp(argv[1], "-d") == 0) {
+ arg++;
+ debug = TRUE;
+ }
+ }
+
+ if (! InitMedlineDB() ) {
+ if (!debug)
+ NI_ServerNACK("Medline service: Unable to initialize Sybase");
+ return( -1 );
+ }
+
+
+ if (!debug) {
+
+ NI_ServerACK();
+
+ hp = NI_OpenASNIO();
+
+ /* this read-timeout is effectively an idle timeout for */
+ /* the server process; the process will terminate upon */
+ /* read-timeout */
+ GetAppParam("NCBI", "NET_SERV", "SERV_INACT_TIMER", "10",
+ buf, sizeof buf);
+ read_timeout = atoi(buf) * 60; /* param is minutes */
+ MsgSetReadTimeout(hp, read_timeout);
+
+ asnin = hp->raip;
+ asnout = hp->waip;
+ } else {
+ if (argc > 2) {
+ asnin = AsnIoOpen(argv[2], "r");
+ } else {
+ asnin = AsnIoOpen("medserv.inp", "r");
+ }
+ asnout = AsnIoOpen("medserv.out", "w");
+ Id_timing_file = FileOpen("medserv.tmt", "w");
+ }
+
+ while (!done) {
+ /* encountering EOF on reading is a "normal" occurrence, */
+ /* and does not merit an error message */
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err); /* clear any pending error, which can be ignored */
+
+ mlarp = MlaRequestAsnRead(asnin, NULL);
+ if (ErrFetch(&err))
+ {
+ done = TRUE;
+ Message(MSG_POST, "Error encountered on AsnReadId %d", err);
+ break; /* client terminated */
+ }
+ ErrSetOpts(erract, 0);
+
+ if (mlarp == NULL) {
+ done = TRUE;
+ Message(MSG_POST, "Null AsnReadId");
+ break; /* client terminated */
+ }
+
+ switch (mlarp->choice) {
+ case MlaRequest_init:
+ mlabp = ValNodeNew(NULL);
+ mlabp->choice = MlaBack_init;
+ mlabp->data.ptrvalue = NULL;
+ MlaBackAsnWrite (mlabp, asnout, NULL);
+ MlaBackFree (mlabp);
+ mlarp->data.ptrvalue = NULL;
+ break;
+
+ case MlaRequest_getmle:
+
+ meddata = SybaseMedlineEntryGet((Int4) mlarp->data.intvalue);
+ mlabp = ValNodeNew(NULL);
+ if (meddata == NULL) {
+ mlabp->choice = MlaBack_error;
+ mlabp->data.intvalue = 0;
+ } else {
+ mlabp->choice = MlaBack_getmle;
+ mlabp->data.ptrvalue = (Pointer) meddata;
+ }
+
+ MlaBackAsnWrite (mlabp, asnout, NULL);
+
+ if (meddata != NULL) mlabp->data.ptrvalue = NULL;
+
+ MlaBackFree (mlabp);
+ break;
+
+ case MlaRequest_getpub:
+
+ pubdata = SybaseMedlinePubGet((Int4) mlarp->data.intvalue);
+ mlabp = ValNodeNew(NULL);
+ if (pubdata == NULL) {
+ mlabp->choice = MlaBack_error;
+ mlabp->data.intvalue = 0;
+ MlaBackAsnWrite (mlabp, asnout, NULL);
+ } else {
+ mlabp->choice = MlaBack_getpub;
+ mlabp->data.ptrvalue = ValNodeNew(NULL);
+ pub = (ValNodePtr) mlabp->data.ptrvalue;
+ pub->choice = 5; /* article */
+ pub->data.ptrvalue = (Pointer) pubdata;
+ MlaBackAsnWrite (mlabp, asnout, NULL);
+ pubdata = NULL; /* for clean free */
+ pub->data.ptrvalue = NULL;
+ }
+ MlaBackFree (mlabp);
+ break;
+
+ case MlaRequest_gettitle:
+ tmsgp = (TitleMsgPtr) mlarp->data.ptrvalue;
+ mlarp->data.ptrvalue = NULL;
+ mlabp = ValNodeNew(NULL);
+ tmlp = SybaseMedlineGetTitle( tmsgp );
+
+ if (tmlp == NULL) {
+ mlabp->choice = MlaBack_error;
+ mlabp->data.intvalue = 0;
+ } else {
+ mlabp->choice = MlaBack_gettitle;
+ mlabp->data.ptrvalue = (Pointer) tmlp;
+ }
+
+ MlaBackAsnWrite (mlabp, asnout, NULL);
+
+ if (tmlp != NULL) mlabp->data.ptrvalue = NULL;
+ if (tmlp != NULL && tmlp->titles->type == 0) tmlp->titles = NULL;
+
+ MlaBackFree (mlabp);
+ TitleMsgFree( tmsgp );
+ TitleMsgListFree( tmlp );
+ break;
+
+ case MlaRequest_citmatch:
+ mlabp = ValNodeNew(NULL);
+ pub = ( ValNodePtr )mlarp->data.ptrvalue;
+ if (pub == NULL) {
+ mlabp->choice = MlaBack_error;
+ mlabp->data.intvalue = 0;
+ } else {
+ ui = SybaseMedlineCitMatch( (CitArtPtr)pub->data.ptrvalue );
+
+ if ( ui == 0 ) {
+ mlabp->choice = MlaBack_error;
+ mlabp->data.intvalue = 0;
+ } else {
+ mlabp->choice = MlaBack_citmatch;
+ mlabp->data.intvalue = ui;
+ }
+ }
+
+ MlaBackAsnWrite (mlabp, asnout, NULL);
+ MlaBackFree (mlabp);
+ break;
+
+ case MlaRequest_fini:
+ done = TRUE;
+ mlabp = ValNodeNew(NULL);
+ mlabp->choice = MlaBack_fini;
+ mlabp->data.ptrvalue = NULL;
+
+ MlaBackAsnWrite (mlabp, asnout, NULL);
+
+ MlaBackFree (mlabp);
+ mlarp->data.ptrvalue = NULL;
+ break;
+ default: /* undefined request code */
+ if ( (mlabp=ValNodeNew(NULL)) != NULL ) { /* create node */
+ mlabp->choice = MlaBack_error; /* set error back */
+ mlabp->data.intvalue = 0; /* clear value */
+ MlaBackAsnWrite (mlabp, asnout, NULL);/* send to client */
+ MlaBackFree (mlabp); /* free memory */
+ }
+ break;
+ }
+
+ AsnIoReset (asnout);
+ MlaRequestFree (mlarp);
+ }
+
+ CloseMedlineDB();
+
+ AsnIoClose (asnin);
+ AsnIoClose (asnout);
+}
diff --git a/network/medarch/server/message.c b/network/medarch/server/message.c
new file mode 100644
index 00000000..842e282f
--- /dev/null
+++ b/network/medarch/server/message.c
@@ -0,0 +1,396 @@
+/*
+ message.c General purpose message handler
+
+ MODULE: message
+ FILES message.c (this one) and message.h.
+
+ The routines in this module implement a general purpose message
+ handler. This module contains variable argument calls which
+ can be used to generate an error message and then pass control
+ to a client supplied routine which is to be used to display the
+ resulting string. A flag word is also passed so the user can
+ determine the type of error and if desired exit or perform other
+ processing.
+
+ This module was taken from the Backbone database project code
+ and slightly modified to bring it up to the standards required
+ for the Medline project.
+
+ Edit history:
+ 25 July 1991 Rand S. Huntzinger, NLM/NCBI
+ Adapted to meet Medline project standards.
+
+ Original version: 17 Jan 1990 - Rand S. Huntzinger
+ Adapted from IRx error.c module which was written 26 May 1987
+ by Rand S. Huntzinger.
+
+
+ Required modules: voutf.c
+*
+*
+* RCS Modification History:
+* $Log: message.c,v $
+* Revision 6.0 1997/08/25 18:36:40 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:21 epstein
+* add RCS log revision history
+*
+*/
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include "voutf.h"
+#include "message.h"
+#include "xalloc.h"
+
+/* Define a few basic types and parameters */
+
+#ifndef NULL
+#define NULL ((char *) 0) /* If NULL isn't defined. */
+#endif
+
+/* Forward declarations */
+
+static int use_stderr();
+
+/**************************************************************************
+
+ Local Variables
+
+**************************************************************************/
+
+static char msg_buf[ERROR_BUF_SIZE]; /* Message buffer */
+static char *msg_ptr = msg_buf; /* Advancing ptr */
+static int msg_cnt = 0; /* Space left in buffer */
+
+/* This is the preloaded "implementation hook". It may be read & altered
+ using the GetMessageHook and SetMessageHook functions respectively. */
+
+static int (*message_func)() = use_stderr; /* Default error handler */
+static char *message_data = NULL; /* Data from client call */
+
+
+/***************************************************************************
+
+ The following code is used by voutf to implement a buffersize
+ checked 'sprintf' type function. This function is only used
+ internally.
+
+***************************************************************************/
+
+/* Macro: Initializes the message buffer for use by to_message_buf */
+
+#define setup_message_buf() {msg_ptr = msg_buf; msg_cnt = ERROR_BUF_SIZE-1;}
+
+/*
+ to_message_buf Add data to a message buffer.
+
+ This routine adds data to the error message buffer. Unlike
+ the standard I/O facilities, we do test for buffer overflow
+ and do not overfill the buffer.
+
+ Parameters:
+
+ s The string to add to the buffer.
+
+ Returns:
+
+ 0 If no error occurred.
+ 1 If the buffer overflowed.
+
+ NOTE: The macro, setup_message_buf() can be used to clear the
+ message buffer before accumulating text.
+*/
+
+static
+/*
+* to_message_buf(chars)
+*/
+int to_message_buf(char *s)
+{
+ int len;
+
+ /* Handle the case of the message buffer being full */
+
+ if((len = strlen(s)) > msg_cnt) {
+ strncpy(msg_ptr, s, msg_cnt);
+ msg_ptr += msg_cnt;
+ msg_cnt = 0;
+ return(1); /* Failure, output truncated */
+ }
+
+ /* Normal case */
+
+ strcpy(msg_ptr, s);
+ msg_ptr += len;
+ msg_cnt -= len;
+ return( 0 );
+}
+
+
+/**************************************************************************
+
+ This following is the default error processing routine. It writes
+ error messages on standard error. This routine is installed in the
+ implementation hook at compile time, and reinstalled if NULL is
+ passed as a function pointer. They ignore the ptr parameter.
+
+**************************************************************************/
+
+/*
+ use_stderr Write error message to stderr
+
+ This is the default error display function. It writes an
+ error message to stderr and returns success. If another
+ error display function is to be used, the SetDpyError
+ function must be used to override this declaration.
+
+ Parameters:
+
+ ptr A pointer to an arbitrary
+ structure which is passed from
+ the client code.
+
+ flags The flags passed to the calling
+ LogError routine.
+
+ where A string stating where the error
+ occurred.
+
+ msg The error message to be logged.
+
+ Returns:
+
+ 0 Success.
+ 1 Failure.
+
+ NOTE: This is the standard argument list for all
+ error message output functions.
+*/
+
+/*ARGSUSED*/
+static
+/*
+* use_stderr(voidclient_data,intflags,charwhere,charmsg)
+*/
+int use_stderr(void *client_data, int flags, char *where, char *msg)
+{
+ /* Simply print the message */
+
+ return(fprintf(stderr, "%s: %s\n", where, msg) >= 0 ? 0 : 1);
+}
+
+
+/**************************************************************************
+
+ The following routines are the entry points for generating
+ error messages using the routines in this function. The
+ basic function, LogError, is called by the special system
+ error handling function, LogSysMessage, which handles system
+ error numbers.
+
+**************************************************************************/
+
+
+/*
+ LogMessage Output a message - make sure no error.
+
+ This routine is identical to LogError except that the message
+ only the message logging functions occur. Error processing
+ options (core dumps, exiting) is suppressed.
+
+ Parameters:
+
+ flags A set of flags used to control how the
+ error is to be handled. Bits are either
+ interpreted here or in implementation
+ hooks.
+
+ where A pointer to a character string giving
+ the place where the error occurred.
+
+ fmt The format used to generate the error
+ message. This format is interpeted by
+ voutf and is similar to a printf
+ format.
+
+ ... The remaining arguments are used to
+ generate the output string according to
+ the format in fmt.
+
+ Returns: nothing.
+*/
+
+/*
+* LogMessage(intflags,charwhere,charfmt,...)
+*/
+void LogMessage(int flags, char *where, char *fmt, ...)
+{
+ va_list args;
+
+ /* Get the fixed arguments */
+
+ va_start(args, fmt);
+
+ /* Generate the message string */
+
+ setup_message_buf();
+ voutf(to_message_buf, fmt, args);
+ va_end(args);
+
+ /* Call the message trapping function */
+
+ message_func(message_data, flags, where, msg_buf);
+
+ /* No exit functions - just quit */
+}
+
+
+/*
+ LogSysMessage Log a system generated error message.
+
+ This routine is similar to LogError except that it is used
+ to generate an error message using a system error number
+ in addition to the formatted message.
+
+ Parameters:
+
+ flags A set of flags used to control how the
+ error is to be handled. Bits are
+ interpreted by the implementation
+ routine
+
+ where A pointer to a character string giving
+ the place where the error occurred.
+
+ err_no The system error number to report.
+ If zero, this value is read from the
+ system error variable.
+
+ fmt The format used to generate the error
+ message. This format is interpeted by
+ voutf and is similar to a printf
+ format. The notation "%%s" should
+ appear where the text expansion of the
+ system error number should appear.
+
+ ... The remaining arguments are used to
+ generate the output string according to
+ the format in fmt.
+
+ Returns nothing.
+*/
+
+/*
+* LogSysMessage(intflags,charwhere,interr_no,charfmt,...)
+*/
+void LogSysMessage(int flags, char *where, int err_no, char *fmt, ...)
+{
+ va_list args;
+ char *afmt, *err_msg;
+ extern int errno;
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+
+ /* Get the fixed arguments */
+
+ va_start(args, fmt);
+ if(err_no == 0) err_no = errno;
+
+ /* Use remaining arguments to produce a format */
+
+ setup_message_buf();
+ voutf(to_message_buf, fmt, args);
+ afmt = xalloc((unsigned int) strlen(msg_buf)+1);
+ strcpy(afmt, msg_buf);
+ va_end( args );
+
+ /* Lookup the system error message */
+
+ if(err_no < 0 || err_no >= sys_nerr) {
+ static char ebuf[30];
+ err_msg = ebuf;
+ sprintf(ebuf, "Unrecognized error #%d", err_no);
+ } else err_msg = sys_errlist[err_no];
+
+ /* Log the error */
+
+ LogMessage(flags, where, afmt, err_msg);
+ xfree(afmt);
+}
+
+
+/**************************************************************************
+
+ The following routines are used to set the implementation
+ hooks for the LogError routine. Routines are provided to
+ retrieve the current hook value so the value can be reset
+ to the previous value as necessary.
+
+ The output hooks also support an arbitrary pointer parameter
+ which can be used to feed data to the user supplied routine.
+ For example, an output file could be passed in this way.
+
+**************************************************************************/
+
+
+
+/*
+ SetMessageHook Set the error display implementation hook
+
+ This routine sets the function name and data pointer used to
+ write messages from LogMessage & LogSysMessage.
+
+ Parameters:
+
+ error_handler A pointer to the user's error output
+ routine.
+
+ ptr A pointer to an arbitrary data structure
+ to be used by the user's error output
+ routine.
+
+ Returns nothing.
+*/
+
+
+/*
+* SetMessageHook(int(error_handler)(),voidptr)
+*/
+void SetMessageHook(int (*error_handler)(), void *ptr)
+{
+ if(error_handler == (int (*)()) NULL) {
+ message_func = use_stderr;
+ message_data = NULL;
+ } else {
+ message_func = error_handler;
+ message_data = ptr;
+ }
+}
+
+
+/*
+ GetMessageHook Returns the current error display function.
+
+ This routine returns to the user a pointer to the current error
+ display function and it's parameter record.
+
+ Parameters:
+
+ error_handler A pointer to a memory location where
+ the function address is to be stored.
+
+ ptr A pointer to a location where the
+ data pointer is to be stored.
+*/
+
+/*
+* GetMessageHook(int(error_handler)(),voidptr)
+*/
+void GetMessageHook(int (**error_handler)(), void **ptr)
+{
+ *error_handler = message_func;
+ *ptr = message_data;
+}
diff --git a/network/medarch/server/message.h b/network/medarch/server/message.h
new file mode 100644
index 00000000..4db9850e
--- /dev/null
+++ b/network/medarch/server/message.h
@@ -0,0 +1,47 @@
+/*
+ message.h Definitions for the message.c module.
+
+ MODULE: message
+ FILES message.c and message.h (this one).
+
+ This file contains definitions used for the generic message
+ handling module. It should be included in all programs which
+ use this module.
+
+ This module was taken from the Backbone database project code
+ and slightly modified to bring it up to the standards required
+ for the Medline project.
+
+ Edit history:
+ 25 July 1991 Rand S. Huntzinger, NLM/NCBI
+ Adapted to meet Medline project standards.
+
+ Original version: 17 Jan 1990 - Rand S. Huntzinger
+ Adapted from IRx error.h module which was written 26 May 1987
+ by Rand S. Huntzinger.
+*
+*
+* RCS Modification History:
+* $Log: message.h,v $
+* Revision 6.0 1997/08/25 18:36:42 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:24 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_MESSAGE
+#define DEFS_MODULE_MESSAGE
+
+/* Basic definitions used by message.c */
+
+#define ERROR_BUF_SIZE 1024 /* Size of error buffer */
+
+/* Define the functions in the message.c file */
+
+extern void LogMessage( int flags, char *where, char *fmt, ... );
+extern void LogSysMessage(int flags, char *where, int errno, char *fmt, ...);
+extern void GetMessageHook( int (**error_handler_address)(), void **ptr );
+
+#endif /* DEFS_MODULE_MESSAGE */
diff --git a/network/medarch/server/mfmt_medasn.c b/network/medarch/server/mfmt_medasn.c
new file mode 100644
index 00000000..01041703
--- /dev/null
+++ b/network/medarch/server/mfmt_medasn.c
@@ -0,0 +1,233 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: mfmt_medasn.c,v $
+* Revision 6.0 1997/08/25 18:36:43 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:28 epstein
+* add RCS log revision history
+*
+*/
+
+#include "ma_intfc.h"
+#include "getmedart.h"
+#include "xalloc.h"
+#include "medart2asn.h"
+
+#include <objmedli.h>
+#include <all.h>
+
+#define CTX_MFMT_MEDASN (CTX_RESERVED+1)
+#define ASN_OUTPUT_NOT_OPEN 1
+
+extern MedlineEntryPtr medline2asn(MedArt *article, AsnOptionPtr optionHead);
+
+/* This is merely a short-hand notation to avoid having to cast this stuff
+ all of the time. It casts the handle parameter (always a void *) to
+ type AsnHand before using. */
+
+#define asn_hand ((AsnHand *) handle)
+
+typedef enum { uninitialized, binary, text } IoMode;
+typedef enum { not_open, open_output, init_output } OpenState;
+typedef struct AsnHand {
+ char *name; /* Name of the handler */
+ char *file; /* Name of the output file */
+ int have_error; /* True => we have an error here! */
+ ErrDesc error; /* Error description */
+ IoMode mode; /* Binary or text */
+ AsnIoPtr ioptr; /* ASN I/O pointer */
+ OpenState open_state; /* How the file was initialized */
+ int count; /* We need to determine set stuff */
+} AsnHand;
+
+static
+AsnHand *mfmt_initialize( char *handler_name, IoMode mode )
+{
+ AsnHand *handle;
+
+ /* Allocate a handler record */
+
+ handle = (AsnHand *) xalloc( sizeof( AsnHand ) );
+
+ /* Initialize the handler record */
+
+ handle->name = handler_name;
+ handle->file = NULL;
+ handle->have_error = FALSE;
+ handle->mode = mode;
+ handle->ioptr = NULL;
+ handle->open_state = not_open;
+ handle->count = 0;
+
+ /* Done */
+
+ return( handle );
+}
+
+/*ARGSUSED*/
+static
+void *mfmt_init_binary( char *handler_name, void *data )
+{
+ /* Initialize a binary mode handle */
+
+ return( mfmt_initialize( handler_name, binary ) );
+}
+
+/*ARGSUSED*/
+static
+void *mfmt_init_text( char *handler_name, void *data )
+{
+ /* Initialize a text mode handle */
+
+ return( mfmt_initialize( handler_name, text ) );
+}
+
+static
+int mfmt_open_output( void *handle, char *file_name )
+{
+ /* Open the file using the AsnIoOpen routine */
+
+ asn_hand->ioptr = AsnIoOpen( file_name, (asn_hand->mode == binary) ?
+ "wb" : "w" );
+ if( asn_hand->ioptr == NULL ) {
+ asn_hand->have_error = ErrFetch( &asn_hand->error );
+ } else {
+ asn_hand->have_error = FALSE;
+ asn_hand->open_state = open_output;
+ asn_hand->count = 0;
+ }
+ return( asn_hand->ioptr != NULL );
+}
+
+static
+int mfmt_init_output( void *handle, char *file_name, FILE *fd )
+{
+ /* Open the file using the AsnIoOpen routine */
+
+ asn_hand->ioptr = AsnIoNew( (asn_hand->mode == binary) ?
+ ASNIO_BIN_OUT : ASNIO_TEXT_OUT, fd, NULL, NULL, NULL );
+ if( asn_hand->ioptr == NULL ) {
+ asn_hand->have_error = ErrFetch( &asn_hand->error );
+ } else {
+ asn_hand->have_error = FALSE;
+ asn_hand->open_state = init_output;
+ asn_hand->count = 0;
+ }
+ return( asn_hand->ioptr != NULL );
+}
+
+static
+int mfmt_process_article( void *handle, MedArt *article )
+{
+ MedlineEntryPtr asn_article;
+ int rv;
+
+ /* Clear error status */
+
+ asn_hand->have_error = FALSE;
+
+ /* Is the file open? */
+
+ if( asn_hand->open_state != open_output &&
+ asn_hand->open_state != init_output ) {
+
+ /* The file is closed - this is an error */
+
+ ErrPost(CTX_MFMT_MEDASN, ASN_OUTPUT_NOT_OPEN,
+ "%s: ASN output to %s was not successfully opened",
+ (asn_hand->name == NULL) ? "ASN output" : asn_hand->name,
+ (asn_hand->file == NULL) ? "???" : asn_hand->file );
+ return( FALSE );
+ }
+
+ /* If this is the first article - output the PubSet */
+
+ if( asn_hand->count == 0 ) {
+ DataVal v;
+ AsnWrite(asn_hand->ioptr, PUB_SET, &v);
+ AsnStartStruct(asn_hand->ioptr, PUB_SET_medline);
+ }
+
+ /* Convert the article to ASN1 notation */
+
+ asn_article = medline2asn( article, NULL );
+ asn_hand->have_error = ErrFetch( &asn_hand->error );
+ if( asn_hand->have_error ) return( FALSE );
+
+ /* Write out the article */
+
+ asn_hand->count++;
+ rv = MedlineEntryAsnWrite(asn_article, asn_hand->ioptr, PUB_SET_medline_E);
+ asn_hand->have_error = ErrFetch( &asn_hand->error );
+
+ /* Handle errors */
+
+ return( rv );
+}
+
+
+static
+int mfmt_close_output( void *handle )
+{
+ /* Irregardless of how we started it - close it */
+
+ if( asn_hand->count > 0 )
+ AsnEndStruct( asn_hand->ioptr, PUB_SET_medline);
+
+ switch( asn_hand->open_state ) {
+ case init_output:
+ AsnIoFlush( asn_hand->ioptr );
+ /* This trick is to fool AsnIoClose() */
+ asn_hand->ioptr->fp = fopen( "/dev/null", "w" );
+ /* Drop through */
+ case open_output:
+ AsnIoClose( asn_hand->ioptr );
+ case not_open:
+ default:
+ ; /* Do nothing - it is not open */
+ }
+
+ /* Reinitialize the record */
+
+ asn_hand->file = NULL;
+ asn_hand->have_error = FALSE;
+ asn_hand->ioptr = NULL;
+ asn_hand->open_state = not_open;
+
+ /* We always assume success */
+
+ return( True );
+}
+
+char *mfmt_get_error_string( void * handle )
+{
+ if( asn_hand->have_error )
+ return( asn_hand->error.errtext );
+ else
+ return( NULL );
+}
+
+
+ma_Obj mfmt_ASN1_text = {
+ mfmt_init_text,
+ mfmt_open_output,
+ mfmt_init_output,
+ mfmt_process_article,
+ mfmt_close_output,
+ mfmt_get_error_string,
+ NULL,
+};
+
+ma_Obj mfmt_ASN1_binary = {
+ mfmt_init_binary,
+ mfmt_open_output,
+ mfmt_init_output,
+ mfmt_process_article,
+ mfmt_close_output,
+ mfmt_get_error_string,
+ NULL,
+};
+
diff --git a/network/medarch/server/mfmt_simple.h b/network/medarch/server/mfmt_simple.h
new file mode 100644
index 00000000..edf69d8a
--- /dev/null
+++ b/network/medarch/server/mfmt_simple.h
@@ -0,0 +1,42 @@
+#ifndef DEFS_MODULE_MFMT_SIMPLE_H
+#define DEFS_MODULE_MFMT_SIMPLE_H
+
+#include <stdio.h>
+#include "ma_intfc.h"
+
+typedef struct {
+ char *name;
+ char *file;
+ FILE *fd;
+ char *error;
+ void *data;
+ int used_open;
+} SimpleOut;
+
+/*
+ NOTE: There is no mfmt_simple_process() procedure - you'll have to
+ write that itself. However, these procedures will handle most
+ everything else, except for complicated output formats which
+ require special open and close code.
+*
+*
+* RCS Modification History:
+* $Log: mfmt_simple.h,v $
+* Revision 6.0 1997/08/25 18:36:45 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:31 epstein
+* add RCS log revision history
+*
+*/
+
+void *mfmt_simple_init( char *handler_name, void *data );
+int mfmt_simple_open( void *handle, char *file_name );
+int mfmt_simple_setup( void *handle, char *file_name, FILE *fd );
+int mfmt_simple_close( void *handle );
+char *mfmt_simple_get_error( void *handle );
+
+void mfmt_simple_error( void *handle, char *message );
+void mfmt_simple_syserror( void *handle );
+
+#endif /* DEFS_MODULE_MFMT_SIMPLE_H */
diff --git a/network/medarch/server/outmedart.c b/network/medarch/server/outmedart.c
new file mode 100644
index 00000000..0b3b47ed
--- /dev/null
+++ b/network/medarch/server/outmedart.c
@@ -0,0 +1,110 @@
+#include "ma_intfc.h"
+#include "ma_global.h"
+#include "error.h"
+
+/*
+* ma_OpenOutputStreams()
+*
+*
+* RCS Modification History:
+* $Log: outmedart.c,v $
+* Revision 6.0 1997/08/25 18:36:47 madden
+* Revision changed to 6.0
+*
+* Revision 1.3 1995/05/17 17:55:38 epstein
+* add RCS log revision history
+*
+*/
+int ma_OpenOutputStreams()
+{
+ int os;
+ int rc = TRUE;
+
+ /* Loop over the input selection list from the command line, opening
+ all of the desired channels. Each one can be opened once. */
+
+ for( os = 0; os < outputStreamCount; os++ ) {
+ int rv;
+
+ /* Lookup the output handler in the handler table */
+
+ outputStreams[os].handle = ma_ValidHandler( outputStreams[os].format );
+ if( outputStreams[os].handle == (void *) NULL ) {
+ fprintf(stderr, "%s: Unable to open handler for %s format.\n",
+ programName, outputStreams[os].format);
+ return( FALSE );
+ }
+
+ /* If we found one, determine if we're opening it or simply
+ passing standard output to it. Then open the handler. */
+
+ if( strcmp( outputStreams[os].file, "-" ) == 0 )
+ rv = ma_OpenHandler( outputStreams[os].handle,
+ "standard output", stdout );
+ else
+ rv = ma_OpenHandler( outputStreams[os].handle,
+ outputStreams[os].file, NULL );
+ if( ! rv ) {
+ fprintf( stderr, "%s\n",
+ ma_GetErrorString(outputStreams[os].handle) );
+ return( FALSE );
+ }
+ rc &= rv;
+ }
+
+ /* All handlers open */
+
+ return( rc );
+}
+
+
+/*
+* ma_CloseOutputStreams()
+*/
+void ma_CloseOutputStreams()
+{
+ int os;
+
+ /* Loop over the handlers - closing each open one in turn */
+
+ for( os = 0; os < outputStreamCount; os++ )
+ if( outputStreams[os].handle != NULL )
+ (void) ma_CloseHandler( outputStreams[os].handle );
+}
+
+
+/*
+* ma_WriteOutput(MedArtarticle)
+*/
+int ma_WriteOutput( MedArt *article )
+{
+ int os;
+ int rc = TRUE;
+
+ /* Send output to each handler in turn */
+
+ for( os = 0; os < outputStreamCount; os++ ) {
+ int rv;
+
+ /* Ignore closed handles */
+
+ if( outputStreams[os].handle == NULL ) continue;
+
+ /* Write output to a handle */
+
+ rv = ma_WriteArticle( outputStreams[os].handle, article );
+ if( ! rv ) {
+ fprintf( stderr, "%s: %s writing UI\n", programName,
+ ma_GetErrorString(outputStreams[os].handle) );
+ }
+
+ /* Make a summary status */
+
+ rc &= rv;
+ }
+
+ /* Return the result */
+
+ return( rc );
+}
+
diff --git a/network/medarch/server/outmedart.h b/network/medarch/server/outmedart.h
new file mode 100644
index 00000000..46b1fd6e
--- /dev/null
+++ b/network/medarch/server/outmedart.h
@@ -0,0 +1,22 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: outmedart.h,v $
+* Revision 6.0 1997/08/25 18:36:48 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:40 epstein
+* add RCS log revision history
+*
+*/
+
+
+#ifndef MODULE_OUTMEDART_H
+#define MODULE_OUTMEDART_H
+
+int ma_OpenOutputStreams();
+int ma_CloseOutputStreams();
+int ma_WriteOutput( MedArt *article );
+
+#endif /* MODULE_OUTMEDART_H */
diff --git a/network/medarch/server/password.c b/network/medarch/server/password.c
new file mode 100644
index 00000000..a9a8db70
--- /dev/null
+++ b/network/medarch/server/password.c
@@ -0,0 +1,319 @@
+/*
+ password.c Enter a password (no echo).
+
+ MODULE: password
+ FILES password.c (this one) and password.h.
+
+ Obtain the password from the environment or from input from
+ the user's terminal.
+
+ This module was taken from the Backbone database project code
+ in May 1991. An interface file (password.h) the external entry
+ points defined and comments were added to the source to bring the
+ module up to Medline project standards.
+
+ Edit History:
+
+ 24 May 1991 - Rand S. Huntzinger, NLM/NCBI
+ Integrated into the Medline project.
+
+ 4 April 1990 - Rand S. Huntzinger
+ Added support for the SYBASE_PASSWORD environment variable,
+ which permits the password to be passed from a shell script
+ without passing it on the command line which makes it
+ trivially available via ps.
+
+ Original version: 12 March 1990 - Rand S. Huntzinger, NLM/NCBI.
+
+ ANSI CONVERSION NOTES:
+
+ 18 Oct 1991 - Rand S. Huntzinger
+ We are generating warnings because one of the include files
+ in the system area has an illegal macro substitution. Does
+ this generate usable code? I think so - I don't think the
+ macro is used.
+*
+*
+* RCS Modification History:
+* $Log: password.c,v $
+* Revision 6.0 1997/08/25 18:36:50 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:43 epstein
+* add RCS log revision history
+*
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/termios.h>
+#include <sys/ttold.h> /* For exclusive access - what is better? */
+#include <fcntl.h>
+#include "password.h"
+
+#define index(s,c) strchr(s,c)
+
+/* These variables are used to hold the TTY states for echo on (new state)
+ and echo off (old state) so we can change and restore the TTY during
+ the call. */
+
+static struct termios old_state; /* Original TTY state */
+static struct termios new_state; /* New TTY state */
+
+/* This external defines the type of the getenv() procedure */
+
+extern char *getenv(); /* Get an environment variable */
+
+
+/*
+ InitializeTtyPort Turn off echo
+
+ This procedure initializes the TTY port by turning off the
+ echo so we can enter a password without seeing what was entered.
+
+ Parameters:
+
+ tty The integer file descriptor (system call level
+ instead of standard i/o) of the tty to be
+ changed.
+
+ Returns:
+ 1 If successful.
+ 0 On an error.
+*/
+
+static
+/*
+* InitializeTtyPort(inttty)
+*/
+int InitializeTtyPort( int tty )
+{
+ /* Load the initial terminal state */
+
+ if(ioctl( tty, TCGETS, &old_state ) < 0)
+ return( 0 );
+ new_state = old_state; /* Duplicate for mods */
+
+ /* Turn off echo */
+
+ new_state.c_lflag &= ~( ISIG | ECHO );
+ new_state.c_lflag |= ( FLUSHO | ECHONL );
+
+ /* Change the settings */
+
+ if(ioctl( tty, TCSETS, &new_state ) < 0)
+ return( 0 );
+
+ /* Done */
+
+ return( 1 );
+}
+
+
+/*
+ ResetTtyPort Restore original TTY port settings
+
+ This procedure resets the TTY port to the state which existed
+ before the InitializeTtyPort call was executed.
+
+ Parameters:
+
+ tty The integer file descriptor (system call level
+ instead of standard i/o) of the tty to be
+ changed.
+
+ Returns:
+ 1 If successful.
+ 0 On an error.
+*/
+
+static
+/*
+* ResetTtyPort(inttty)
+*/
+int ResetTtyPort( int tty )
+{
+ /* Flush the barcode Input buffer */
+
+ if(ioctl( tty, TCSETS, &old_state ) < 0 )
+ return( 0 );
+
+ /* Done */
+
+ return( 1 );
+}
+
+
+/*
+ ClearTtyPort Discard any pending TTY input
+
+ This procedure deletes any input waiting in the TTY port's
+ input queues. This permits us to start input from a known
+ state (buffers empty).
+
+ Parameters:
+
+ tty The integer file descriptor (system call level
+ instead of standard i/o) of the tty to be
+ changed.
+
+ Returns:
+ 1 If successful.
+ 0 On an error.
+*/
+
+static
+/*
+* ClearTtyPort(inttty)
+*/
+int ClearTtyPort( int tty )
+{
+ /* Flush the tty input buffer */
+
+ if(ioctl( tty, TCFLSH, 0 ) < 0) /* Flush input queue */
+ return( 0 );
+
+ /* Done */
+
+ return( 1 );
+}
+
+
+/*
+ GetPassword Read a line of text with echo disabled.
+
+ This procedure reads a line of text from a TTY into a buffer
+ with input echoing disabled. It is normally used for entering
+ passwords, for security reasons. If the input port is not a
+ terminal, the procedure will always return a NULL string.
+
+ Parameters:
+
+ tty A standard i/o file descriptor (type FILE)
+ which is opened onto a terminal device.
+
+ buffer The buffer to receive the input string.
+
+ buffer_size The size of the input buffer in bytes.
+
+ Returns:
+
+ A pointer to the input buffer. The contents of the buffer
+ will be the string input minus the line terminator. If
+ the file descriptor was not a TTY, the buffer will be
+ empty (*buffer == (char) 0).
+*/
+
+/*
+* GetPassword(FILEtty,charbuffer,intbuffer_size)
+*/
+char *GetPassword( FILE *tty, char *buffer, int buffer_size )
+{
+ char *p;
+
+ /* Clear the buffer */
+
+ *buffer = (char) 0;
+
+ /* This only works on a TTY port */
+
+ if( isatty( fileno(tty) ) )
+ {
+ InitializeTtyPort( fileno(tty) );
+ ClearTtyPort( fileno(tty) );
+ (void) fgets( buffer, buffer_size, tty );
+ ResetTtyPort( fileno(tty) );
+ if( (p = index( buffer, '\n' )) != 0 )
+ *p = (char) 0; /* Get rid of new line */
+ fprintf( tty, "\r\n" );
+ }
+
+ /* Done */
+
+ return( buffer );
+}
+
+
+/*
+ RequestPassword Obtain a Sybase password.
+
+ This procedure will obtain the Sybase password from the SYBASE_PASSWORD
+ environment variable (if present) and then zip the environment
+ variable out to avoid security problems using "ps -ae". If the
+ environment variable is not present, RequestPassword() will prompt
+ the user for it and read the password with the terminal's echo
+ turned off.
+
+ Parameters:
+
+ prompt The string to be used to prompt for the
+ password.
+
+ buffer The buffer to receive the input string.
+
+ buffer_size The size of the input buffer in bytes.
+
+ Returns:
+
+ A pointer to the buffer if the password was read or NULL
+ if there was an error (unable to access the TTY). If
+ stdin is not a TTY, the buffer will always be returned
+ empty. If the account has a password, it will have to
+ be specified via the command line or an environment
+ variable.
+*/
+
+/*
+* RequestPassword(charprompt,charbuffer,intbuffer_size)
+*/
+char *RequestPassword( char *prompt, char *buffer, int buffer_size )
+{
+ char *result;
+ FILE *fd;
+ char *p;
+
+ /* Clear input buffer */
+
+ *buffer = (char) 0;
+
+ /* SECURITY MEASURE: The SYBASE_PASSWORD environment variable avoids
+ having to put the -Ppassword option on the command line where a
+ routine ps can intercept it. Unfortunately, it doesn't fully
+ protect against ps -e. Clearing the environment variable after
+ use may at least limit liability though. */
+
+ if( (p = getenv("SYBASE_PASSWORD")) != NULL && strlen( p ) <= buffer_size )
+ {
+ strcpy( buffer, p );
+ while( *p ) *p++ = (char) 0x7f; /* Zap SYBASE_PASSWORD for ps -e */
+ return( buffer );
+ }
+
+ /* Open the TTY */
+
+ if( ! isatty( fileno( stdin ) ) )
+ return( buffer );
+ fd = fopen( ttyname(fileno(stdin)), "w" );
+ if( fd == (FILE *) NULL )
+ return( NULL );
+
+ /* Prompt the user */
+
+ fprintf( fd, "%s", prompt );
+ fflush( fd );
+
+ /* Get the input */
+
+ result = GetPassword( stdin, buffer, buffer_size );
+ fprintf( fd, "\r\n" );
+
+ /* Close up shop */
+
+ (void) fclose( fd );
+
+ /* Done */
+
+ return( result );
+}
+
diff --git a/network/medarch/server/password.h b/network/medarch/server/password.h
new file mode 100644
index 00000000..3c3f33b0
--- /dev/null
+++ b/network/medarch/server/password.h
@@ -0,0 +1,50 @@
+/*
+ password.h Definitions for password module.
+
+ MODULE: password
+ FILES password.c and password.h (this one).
+
+ Obtain the Sybase password from the environment or from input from
+ the user's terminal.
+
+ This module was taken from the Backbone database project code
+ in May 1991 and this interface file was added to fit the
+ Medline project's module requirement to have an include file
+ with at least the external entry points defined.
+
+ Edit history:
+ 25 July 1991 Rand S. Huntzinger, NLM/NCBI
+ Adapted to meet Medline project standards.
+
+ Work started: 24 May 1991
+ Original version completed: 24 May 1991, Rand S. Huntzinger
+
+*
+*
+* RCS Modification History:
+* $Log: password.h,v $
+* Revision 6.0 1997/08/25 18:36:51 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:46 epstein
+* add RCS log revision history
+*
+*/
+#ifndef DEFS_MODULE_PASSWORD
+#define DEFS_MODULE_PASSWORD
+
+/* The GetPassword procedure will read a line from the tty without echoing
+ it. It does not do prompting, it merely turns echo off, reads the
+ input line and restores the tty */
+
+extern char *GetPassword( FILE *tty, char *buffer, int buffer_size );
+
+/* The Request password will attempt to get the password from the
+ SYBASE_PASSWORD environment variable and failing that prompt for
+ and receive the password from the user's terminal. It also clears
+ the password from the environment to confuse the ps -e command which
+ could be used for snooping. */
+
+extern char *RequestPassword( char *prompt, char *buffer, int buffer_size );
+
+#endif DEFS_MODULE_PASSWORD
diff --git a/network/medarch/server/patchtoiso.c b/network/medarch/server/patchtoiso.c
new file mode 100644
index 00000000..7efd821a
--- /dev/null
+++ b/network/medarch/server/patchtoiso.c
@@ -0,0 +1,182 @@
+/*
+ PROJECT: Medline database.
+ MODULE: cspatch
+ FILES: cspatch.c cstopatch.c, patchtoiso.c (this one),, cspatch.h
+
+ This file contains support procedures for translating ASCII strings
+ with their associated ISO patch strings into the richer ISO-8859
+ character set. The ISO-8859 character set is a superset of the
+ ASCII character which includes many accented international characters.
+ The ISO patch instructions are generated at the time the text is
+ converted from the Medline EBCDIC character set into ASCII before
+ loading the text into the database. In addition to describing how
+ to patch the ASCII text to produce the ISO character set, it also
+ contains data describing EBCDIC characters which could not be
+ represented in the ISO-8859 character set. These can be used in
+ the future if character sets become available which can be used
+ to support these untranslated characters.
+
+ Work started: 29 June 1991, Rand Huntzinger
+ Original version completed: 24 July 1991, Rand S. Huntzinger
+*
+*
+* RCS Modification History:
+* $Log: patchtoiso.c,v $
+* Revision 6.0 1997/08/25 18:36:53 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:49 epstein
+* add RCS log revision history
+*
+*/
+
+#include <stdio.h>
+#include "sybase.h"
+#include "patchtoiso.h"
+#include "error.h"
+
+/*
+ ApplyIsoPatches Translate and ASCII string into ISO-8859
+
+ This procedure takes an ASCII input string and the ASCII->ISO-8859
+ patch string associated with that ASCII input string and converts
+ the text to the ISO character set. It ignores the ISO patch codes
+ which indicate untranslated EBCDIC characters during the EBCDIC
+ to ASCII conversion.
+
+ Parameters:
+
+ in A pointer to the ASCII input string.
+
+ in_size The number of characters in the ASCII
+ input string. [We don't assume NULL
+ termination]
+
+ out A pointer to the buffer to receive
+ the ISO-8859 representation of the
+ text created by this procedure.
+
+ out_size The size of the output buffer.
+
+ patches A pointer to the ASCII->ISO patch
+ string which contains the conversion
+ instructions.
+
+ Returns:
+
+ The number of errors noted in the conversion. Errors include
+ buffer overflows and invalid patch instructions.
+*/
+
+int
+/*
+* (charin,intin_size,charout,intout_size,unsignedcharpatches)
+*/
+ApplyIsoPatches (char *in, int in_size, char *out, int out_size, unsigned char *patches)
+{
+ int ii, oi, pi; /* in, out and patch indices */
+ int running = TRUE;
+ static unsigned char abort[] = { POP_STOP_CODE };
+ int errors = 0;
+
+ for(ii = oi = pi = 0; running; pi++) {
+ register int code = (int) patches[pi];
+ register int base_code;
+ register int advance = 0; /* Set the character pointer */
+ register int skip = 0; /* # input chars to skip */
+ register int install = 0; /* # patch chars to copy in */
+
+ /* Decode the basic opcode */
+
+ if( (base_code = code & POP_BASIC_MASK) == POP_SPECIAL_GRP )
+ if( (base_code = code & POP_SPEC_MASK) == POP_MISC_GRP )
+ if( (base_code = code & POP_MISC_MASK) == POP_SIMPLE_GRP )
+ base_code = code;
+
+ /* Process the opcode */
+
+ switch( base_code ) {
+ case POP_PATCH_CODE:
+ skip = POP_PATCH_DELETE( code );
+ install = POP_PATCH_INSERT( code );
+ break;
+ case POP_OFFSET1_CODE:
+ advance = code & POP_BASIC_ARGMASK;
+ break;
+ case POP_OFFSET2_CODE:
+ advance = code & (POP_BASIC_ARGMASK << 8) | patches[++pi];
+ break;
+ case POP_CSET_CODE:
+ break; /* Not implemented */
+ case POP_OMIT_CODE:
+ case POP_INVALID_CODE:
+ case POP_NOISO_CODE:
+ /* These are various types on uninterpretable codes. They
+ are recorded for the future, but are ignored on output. */
+ pi += code & POP_MISC_ARGMASK;
+ break;
+ case POP_STOP_CODE:
+ advance = in_size - ii; /* Copy over rest of string */
+ running = FALSE;
+ break;
+ default: /* Anything else is an error! */
+ LogMessage( CHARSET_ERROR, "patchtoiso",
+ "Invalid ASCII->ISO patch instruction [%02x]", code );
+ advance = in_size - ii; /* Copy over rest of string */
+ patches = abort; /* Terminate patching */
+ errors++; /* Mark an error */
+ }
+
+ /* Check for buffer overflows */
+
+ if( (ii + advance + skip) > in_size ) {
+ LogMessage( CHARSET_ERROR, "patchtoiso",
+ "Patch table input offset (%d) outside input string [%-.16s%s]",
+ ii + advance + skip, in, (in_size < 16) ? "" : "..." );
+
+ /* Adjust pointers to deal with overflow */
+
+ if( (ii + advance) > in_size ) {
+ advance = in_size - ii;
+ install = 0;
+ }
+ if( (ii + advance + skip) > in_size )
+ skip = in_size - ii - advance;
+ patches = abort; /* No more patches */
+ errors++; /* Mark an error */
+ }
+ if( (oi + advance + install) > out_size ) {
+ LogMessage( CHARSET_ERROR, "patchtoiso",
+ "ISO translation of \"%-.16s%s\" truncated to %d characters",
+ in, (in_size < 16) ? "" : "..." );
+
+ /* Adjust pointers to deal with overflow */
+
+ if( (oi + advance) > out_size ) {
+ advance = out_size - oi;
+ install = 0;
+ }
+ if( (oi + advance + install) > out_size )
+ install = out_size - oi - advance;
+ patches = abort; /* No more patches */
+ errors++; /* Mark an error */
+ }
+
+ /* Advance to the proper position */
+
+ while( advance-- > 0 )
+ out[oi++] = in[ii++];
+ ii += skip;
+
+ /* Install patch characters */
+
+ while( install-- > 0 )
+ out[oi++] = patches[++pi];
+ }
+
+ /* Terminate the output string */
+
+ out[oi++] = (char) 0;
+
+ return( errors );
+}
diff --git a/network/medarch/server/patchtoiso.h b/network/medarch/server/patchtoiso.h
new file mode 100644
index 00000000..6707faa7
--- /dev/null
+++ b/network/medarch/server/patchtoiso.h
@@ -0,0 +1,137 @@
+/*
+ PROJECT: Medline database.
+ MODULE: cspatch
+ FILES: cspatch.c, cstopatch.c, patchtoiso.c, cspatch.h (this one)
+
+ This module contains the definitions needed for building and
+ interpreting patch commands used to convert the Medline character
+ set (EBCDIC) into the ASCII character set with a ISO patch
+ instruction string to indicate how to translate the ASCII into
+ ISO-8859 characters. (Ie. instructions on how to add the various
+ accent marks which aren't available in ASCII).
+
+ Work started: 10 June 1991, Rand Huntzinger
+
+ TODO: Consider using error logging package for usage error.
+ Original version completed: 24 July 1991, Rand S. Huntzinger
+*
+*
+* RCS Modification History:
+* $Log: patchtoiso.h,v $
+* Revision 6.0 1997/08/25 18:36:54 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:51 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEF_MODULE_CSPATCH
+#define DEF_MODULE_CSPATCH
+
+#include "charset.h"
+
+/*
+ Basic OPCODE interpretations.
+
+ 76543210
+ ========
+ 00xxxxxx PATCH opcode.
+ 01xxxxxx SPECIAL opcode group.
+ 10xxxxxx OFFSET1 opcode (6 bit offset)
+ 11xxxxxx OFFSET2 opcode (14 bit offset)
+*/
+
+#define POP_BASIC_MASK (0xc0) /* Mask basic opcode - bits 7&6 */
+#define POP_BASIC_ARGMASK (0x3f) /* Basic opcode argument (6 bits) */
+#define POP_PATCH_CODE (0x00) /* PATCH opcode */
+#define POP_SPECIAL_GRP (0x40) /* SPECIAL opcode group */
+#define POP_OFFSET1_CODE (0x80) /* OFFSET1 opcode */
+#define POP_OFFSET2_CODE (0xc0) /* OFFSET2 opcode */
+
+/*
+ Special opcode group interpretation
+
+ 76543210
+ ========
+ 010xxxxx MISC code group.
+ 011xxxxx CHARSET (32 character set codes)
+*/
+
+#define POP_SPEC_MASK (0xe0) /* SPECIAL opcodes */
+#define POP_MISC_GRP (0x40) /* MISC opcode group */
+#define POP_CSET_CODE (0x60) /* CHARSET opcode (not implemented) */
+#define POP_SPEC_ARGMASK (0x1f) /* Arguments for SPEC codes */
+
+/*
+ Misc opcode group interpretation
+
+ 76543210
+ ========
+ 01000xxx SIMPLE opcode group.
+ 01001xxx OMIT opcode (original codes, next 1..8 bytes).
+ 01010xxx INVALID opcode (original codes, next 1..8 bytes)
+ 01011xxx NOISO opcode (next 1..8 -> next code)
+*/
+#define POP_MISC_MASK (0xf8) /* MISC opcode mask */
+#define POP_SIMPLE_GRP (0x40) /* SIMPLE opcode group */
+#define POP_OMIT_CODE (0x48) /* OMIT opcode */
+#define POP_INVALID_CODE (0x50) /* INVALID opcode */
+#define POP_NOISO_CODE (0x58) /* NOISO opcode */
+#define POP_MISC_ARGMASK (0x07) /* Arguments for MISC codes */
+
+/*
+ Simple opcode group interpretation
+*/
+
+#define POP_SIMPLE_MASK (0xff) /* In case we need to add groups */
+#define POP_STOP_CODE (0x40) /* STOP opcode (end of patch list) */
+/* NOTE: Codes 0x41..0x47 are undefined - will be treated as NOP's */
+#define POP_NOP_CODE (0x00) /* Official NOP - a variant of PATCH */
+
+/*
+ PATCH opcode interpretation
+
+ 00dddiii Where ddd is the 3-bit delete count and
+ iii is the 3-bit insertion count.
+*/
+
+#define POP_PATCH_DELETE(C) (((C) >> 3) & 0x7) /* Bits 3..5 */
+#define POP_PATCH_INSERT(C) ((C) & 0x7) /* Bits 0..2 */
+
+/*
+ Opcode construction macros.
+*/
+
+#define POP_MAKE_PATCH(D,I) \
+ ( POP_PATCH_CODE | (((D) & 0x7) << 3) | ((D) & 7) )
+#define POP_MAKE_BASIC(C,O) \
+ ( (C) | ((O) & POP_BASIC_ARGMASK) )
+#define POP_MAKE_CHARSET(C) \
+ ( POP_CSET_CODE | ((C) & POP_SPEC_ARGMASK ) )
+#define POP_MAKE_MISC(C,A) \
+ ((C) | ((A) & POP_MISC_ARGMASK))
+
+/*
+ Define the Opcode classification codes. Used to determine the
+ grouping of opcodes. The most important distinction is class ISO
+ (which actually does a patch) and the others.
+*/
+
+#define POP_CLASS_ISO (1 << 0) /* PATCH */
+#define POP_CLASS_CONTROL (1 << 1) /* OFFSET1, OFFSET2, STOP */
+#define POP_CLASS_INVALID (1 << 2) /* INVALID */
+#define POP_CLASS_OMIT (1 << 3) /* OMIT */
+#define POP_CLASS_ERROR (1 << 4) /* Error in the patch string */
+
+/* Define the bits which we need if we're going to store a patch in the
+ database */
+
+#define POP_PATCH_REQUIRED (POP_CLASS_ISO | POP_CLASS_INVALID | POP_CLASS_OMIT)
+
+/* Externals */
+
+int ApplyIsoPatches( char *in, int in_size,
+ char *out, int out_size, unsigned char *patches );
+
+#endif /* DEF_MODULE_CSPATCH */
diff --git a/network/medarch/server/sqlstring.c b/network/medarch/server/sqlstring.c
new file mode 100644
index 00000000..f7fb0ca6
--- /dev/null
+++ b/network/medarch/server/sqlstring.c
@@ -0,0 +1,368 @@
+/*
+ sqlstring.c Translate C strings into a form where they
+ can be passed as part of SQL commands.
+
+ MODULE: sqlstring
+ FILES: sqlstring.c (this one) and sqlstring.h.
+
+ This package translates strings passed to it into a form suitable
+ for use in SQL commands. In particular, it doubles quote characters
+ within strings so that the string will not cause SQL command errors.
+
+ In order to make the package maximally useful, the package will
+ allocate data for each string which has to be modified, and then
+ all allocated strings can be freed with a single call after the
+ fact. This allows the command to be used multiple times within
+ a single worrying about freeing up multiple buffers.
+
+ Note: This module was adapted from the module of the same
+ name from the GenInfo Backbone database project. It
+ had to be slightly modified to meet Medline project
+ coding conventions. (module nomenclature)
+
+ Edit History:
+ 7 August 1991 - Rand S. Huntzinger, NLM/NCBI
+ Added the SQLbinary procedure, which allows us to use the
+ same procedures for handling binary types.
+
+ 25 July 1991 - Rand S. Huntzinger, NLM/NCBI
+ Modified to comply with Medline project coding conventions.
+
+ Original version: 22 Mar 91, Rand S. Huntzinger, NLM/NCBI
+*
+*
+* RCS Modification History:
+* $Log: sqlstring.c,v $
+* Revision 6.0 1997/08/25 18:36:56 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:55 epstein
+* add RCS log revision history
+*
+*/
+
+#include <string.h>
+#include "xalloc.h"
+
+#define index(s,c) strchr(s,c)
+
+#ifndef NULL
+#define NULL ((char *) 0)
+#endif
+
+/* The StringList type is simply a singly linked list of string pointers
+ (char *) which we used to keep track of the strings which are to be
+ cleared by the next SQLstringClear() operation. */
+
+typedef struct StringList {
+ struct StringList *next;
+ char *text;
+} StringList;
+
+static StringList *free_list = (StringList *) NULL;
+static StringList *in_use = (StringList *) NULL;
+
+
+/*
+ SQLstringAlloc INTERNAL string allocation function.
+
+ This procedure allocates a string of a given size and places it
+ into the in_use string list. This list can later be cleared by
+ the SQLstringClear() or SQLstringReset() calls.
+
+ Parameters:
+
+ size The size of the string to be allocated.
+
+ Returns:
+
+ A pointer to the allocated string. Should not be NULL unless
+ the xalloc() support routine can return NULL, which should not
+ normally be the case.
+*/
+
+static
+/*
+* SQLstringAlloc(intsize)
+*/
+char *SQLstringAlloc( int size )
+{
+ register StringList *node;
+
+ /* Is there a free node? */
+
+ if( free_list != (StringList *) NULL ) {
+ node = free_list;
+ free_list = node->next;
+ } else {
+ node = (StringList *) xalloc( sizeof( StringList ) );
+ }
+
+ /* Allocate the text */
+
+ node->text = xcalloc( size + 1, 1 );
+
+ /* Insert the node into the in_use list */
+
+ node->next = in_use;
+ in_use = node;
+
+ /* Return a pointer to the text */
+
+ return( in_use->text );
+}
+
+
+/*
+ SQLstringFree Free a string allocated with SQLstring
+
+ This procedure finds the string allocated by the SQLstring function
+ and frees it. This involves calling xfree() on the text of the
+ string and putting the link structure into the free list.
+
+ This procedure is not normally used. Normally one would use
+ SQLstringClear() to free up all of the strings generated for
+ a command or a series of commands.
+
+ NOTE: Since SQLstring does not always allocate a string, this
+ procedure will not always do anything. You can safely
+ pass strings not allocated by SQLstring; however, they
+ will not be freed.
+
+ Parameters:
+
+ text The address of the allocated string to
+ be freed.
+
+ Returns: nothing
+*/
+
+/*
+* SQLstringFree(chartext)
+*/
+void SQLstringFree( char *text )
+{
+ register StringList *node, *p;
+
+ /* If the string list is empty, simply exit */
+
+ if( in_use == (StringList *) NULL ) return;
+
+ /* Unlink the node from the in_use list */
+
+ if( in_use->text == text ) {
+ /* Special case, first in the list */
+ node = in_use;
+ in_use = node->next;
+ } else {
+ /* Not first, unlink from the middle or end */
+ node = (StringList *) NULL;
+ for( p = in_use; p->next != (StringList *) NULL; p = p->next )
+ if( p->next->text == text ) {
+ node = p->next;
+ p->next = node->next;
+ break;
+ }
+ }
+
+ /* If we found it, free it */
+
+ if( node != (StringList *) NULL ) {
+ xfree( node->text );
+ node->next = free_list;
+ free_list = node;
+ }
+
+ /* Done */
+
+ return;
+}
+
+
+/*
+ SQLstringClear Free memory allocated by SQLstring calls
+
+ This command frees all strings allocated by SQLstring calls.
+ The normal procedure would be to generate the strings to be used
+ in a SQL command (often in the argument list using SQLstring as
+ a "wrapper") and then call SQLstringClear when the command, or a
+ series of commands have been completed.
+
+ Parameters: none
+ Returns: nothing
+*/
+
+/*
+* SQLstringClear()
+*/
+void SQLstringClear()
+{
+ register StringList *node;
+
+ /* Free all text areas allocated */
+
+ while( in_use != (StringList *) NULL ) {
+ xfree( in_use->text ); /* Free the text */
+ node = in_use; /* Unlink the node */
+ in_use = in_use->next;
+ node->next = free_list; /* Put node in free list */
+ free_list = node;
+ }
+}
+
+
+/*
+ SQLstringReset Free all memory allocated by SQLstring package.
+
+ This procedure is slightly more radical than SQLstringClear. It
+ calls SQLstringClear to free all of the text strings allocated by
+ SQLstring calls and then frees the link nodes as well. Normally
+ the link nodes are kept around for reuse.
+
+ This procedure is seldom used. The link nodes do not consume much
+ space and reusing them saves xalloc and xfree calls. It can be used
+ if we're keeping allocation statistics and we want to make sure all
+ allocated data has been freed.
+
+ Parameters: none
+ Returns: nothing
+*/
+
+/*
+* SQLstringReset()
+*/
+void SQLstringReset()
+{
+ register StringList *node;
+
+ /* Free all existing strings */
+
+ SQLstringClear();
+
+ /* Clear the free list */
+
+ while( free_list != (StringList *) NULL ) {
+ node = free_list;
+ free_list = free_list->next;
+ xfree( (char *) node );
+ }
+}
+
+
+/*
+ SQLstring Translate a C string to a SQL-usable form.
+
+ This procedure processes a C language string (a pointer to text
+ terminated by a zero byte) into a SQL-usable string by truncating
+ the string (if necessary) and doubling quotes to avoid SQL command
+ errors. We allocate strings if necessary, so one must clean up
+ afterwards using the SQLstringClear() function.
+
+ Parameters:
+ text A pointer to the text string to be processed.
+
+ width The maximum width of the string to be
+ passed to the server. If negative, the
+ width of the text will be used.
+
+ quote The character to be used in quoting the
+ string. This character will be doubled
+ in the sting itself.
+
+ Returns:
+
+ A pointer to the processed string. It may be the same as
+ the input string, or may be allocated in the string space.
+*/
+
+/*
+* SQLstring(chartext,intwidth,intquote)
+*/
+char *SQLstring( char *text, int width, int quote )
+{
+ register char *p, *np, *ep;
+ char *new;
+ register int n;
+ int tw;
+
+ /* If there are no embedded quotes, simply return the text.
+ Happly, this should be the typical case. */
+
+ p = index(text, quote);
+ tw = strlen(text);
+ if( (width < 0 || tw <= width) && p == NULL )
+ return( text );
+
+ /* Figure out how long the result string will have to be. */
+
+ tw = (tw > width && width > 0) ? width : tw;
+ ep = text + tw;
+ for(n = 0; p != NULL && p < ep; p = index(p + 1, quote))
+ n++;
+
+ /* Create a new string with the proper length and quote doubling */
+
+ new = SQLstringAlloc( tw + n );
+ for( p = text, np = new; tw-- > 0; *np++ = *p++ )
+ if( *p == quote ) *np++ = *p;
+ *np = (char) 0;
+
+ return( new );
+}
+
+
+/*
+ SQLbinary Translate a binary buffer SQL-usable form.
+
+ This procedure is analogous to the SQLstring procedure for text,
+ except it prepares data to be loaded into SQL binary or image
+ types instead of char, varchar or text. The result is 0x followed
+ by an arbitrary length string of hexadecimal digits, each pair of
+ which represent one input byte. This procedure will always allocate
+ a new buffer, so the calling program will have to clean up using
+ the SQLstringClear() procedure.
+
+ Parameters:
+
+ buffer A pointer to a buffer containing the binary
+ text to be converted into a SQL usable string.
+
+ length The number of bytes in the binary string
+ to be converted.
+
+ Returns:
+
+ A pointer to the processed string.
+*/
+
+/*
+* SQLbinary(unsignedcharbuffer,intlength)
+*/
+char *SQLbinary( unsigned char *buffer, int length )
+{
+ char *new;
+ static char prefix[] = "0x";
+ static char hex[] = "0123456789ABCDEF";
+ register unsigned char *inp;
+ register char *outp;
+
+ /* Allocate space for the hex string output. It requires 2 bytes for
+ each input byte, plus 2 bytes for the 0x and one byte for the
+ string terminating null. */
+
+ if( length < 0 ) length = 0;
+ new = SQLstringAlloc( 2 * length + 3 );
+
+ /* Convert the binary buffer into a string */
+
+ strcpy( new, prefix );
+ for( inp = buffer, outp = new + strlen(prefix); length-- > 0; inp++ ) {
+ *outp++ = hex[(*inp >> 4) & 0x0f];
+ *outp++ = hex[*inp & 0x0f];
+ }
+ *outp = (char) 0;
+
+ /* Done */
+
+ return( new );
+}
diff --git a/network/medarch/server/sqlstring.h b/network/medarch/server/sqlstring.h
new file mode 100644
index 00000000..e0584261
--- /dev/null
+++ b/network/medarch/server/sqlstring.h
@@ -0,0 +1,48 @@
+/*
+ sqlstring.h Handle quotes in strings for SQL expressions.
+
+ MODULE: sqlstring
+ FILES: sqlstring.c and sqlstring.h (this one).
+
+ This package adds SQL style quoting notations so an arbitrary
+ ASCII string can be passed to Sybase without confusing the
+ query parser. This is done by doubling the quote character
+ within the string.
+
+ Note: This module was adapted from the module of the same
+ name from the GenInfo Backbone database project. It
+ had to be slightly modified to meet Medline project
+ coding conventions. (module nomenclature)
+
+ Edit History:
+ 7 August 1991 - Rand S. Huntzinger
+ Added SQLbinary() to the external calls.
+
+ 25 July 1991 - Rand S. Huntzinger, NLM/NCBI
+ Modified to comply with Medline project coding conventions.
+
+ Original version: 22 Mar 91, Rand S. Huntzinger, NLM/NCBI
+*
+*
+* RCS Modification History:
+* $Log: sqlstring.h,v $
+* Revision 6.0 1997/08/25 18:36:58 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:55:57 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_SQLSTRING
+#define DEFS_MODULE_SQLSTRING
+
+/* Define the entry points to the SQLstring module */
+
+void SQLstringFree( char *text );
+void SQLstringClear();
+void SQLstringReset();
+char *SQLstring( char *text, int width, char quote );
+char *SQLbinary( unsigned char *buffer, int length );
+
+#endif /* DEFS_MODULE_SQLSTRING */
diff --git a/network/medarch/server/sybase.h b/network/medarch/server/sybase.h
new file mode 100644
index 00000000..14cc5d5a
--- /dev/null
+++ b/network/medarch/server/sybase.h
@@ -0,0 +1,27 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: sybase.h,v $
+* Revision 6.0 1997/08/25 18:36:59 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:56:00 epstein
+* add RCS log revision history
+*
+*/
+
+/* The following is the Sybase include file package */
+
+#ifndef DEFS_MODULE_SYBASE_H
+#define DEFS_MODULE_SYBASE_H
+
+#include <sybfront.h>
+#include <sybdb.h>
+#ifdef HAVE_SRV_H
+#include <srv.h>
+#else
+#define SRV_MAXCHAR (DBMAXCHAR-1)
+#endif
+
+#endif /* DEFS_MODULE_SYBASE_H */
diff --git a/network/medarch/server/sybbind.c b/network/medarch/server/sybbind.c
new file mode 100644
index 00000000..c759e8ec
--- /dev/null
+++ b/network/medarch/server/sybbind.c
@@ -0,0 +1,249 @@
+/*
+ sybbind.c High level Sybase row loading and binding support
+
+ MODULE: sybbind
+ FILES: sybbind.c (this one) and sybbind.h.
+
+ This module provides a high-level interface to the Sybase procedures
+ for binding rows to C variables and for loading rows in form the
+ database. These procedures permit a single procedure call to bind
+ many variables in a single call. The SybaseLoad procedure call
+ adds row retrieval as well. This reduce the amounts of coding
+ detail required by lumping the dbbind() and dbnextresults() calls
+ into a single call with only a single return code to check.
+
+ Note: This module was adapted from the module of the same
+ name from the GenInfo Backbone database project. It
+ had to be slightly modified to meet Medline project
+ coding conventions. (module nomenclature)
+
+ Edit History:
+ 25 July 1991 - Rand S. Huntzinger, NLM/NCBI
+ Modified to comply with Medline project coding conventions.
+
+ Original version: circa 1989-1990, Rand S. Huntzinger, NLM/NCBI
+*
+*
+* RCS Modification History:
+* $Log: sybbind.c,v $
+* Revision 6.0 1997/08/25 18:37:01 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:56:03 epstein
+* add RCS log revision history
+*
+*/
+
+#include <stdarg.h>
+#include "sybase.h"
+#include "sybbind.h"
+
+/*
+ VSybaseBind Bind Sybase Fields to Variables (from vector)
+
+ This procedure takes a vector of arguments which originated
+ from a variable argument list from a calling procedure and uses
+ it to call dbbind() several times to bind variables for loading
+ from a Sybase database on the next dbgetnextrow() call.
+
+ Interpretation of the argument vector:
+
+ The argument vector contains groups of four parameters defined
+ as the last four parameters in the Sybase dbbind procedure. These
+ parameters are:
+
+ Field Contents
+ ===== ========
+ field_no The field number. This must be a positive
+ integer. When this value is zero, we
+ assume we've reached the end of the list.
+
+ type The binding type of the field (see dbdind()
+ documentation for valid values).
+
+ length The length of the field. Zero can be used
+ if the length is implied by the type or
+ the buffer used to hold the input is known
+ to be long enough to hold the data.
+
+ varptr A pointer to the location where the data
+ retrieved from the database is to be
+ stored. It must be at least length bytes
+ long, or long enough to hold this type.
+
+ Note that we terminate processing when field_no is set to zero.
+ Thus, the calling program should make sure that a zero argument
+ is passed after the last valid group.
+
+ Parameters:
+
+ dbproc A pointer to the Sybase database process.
+
+ args The argument vector which is interpreted
+ as given above.
+
+ Returns:
+
+ SUCCEED if all binds are successful, or the return code of
+ first dbbind() call which does not return SUCCEED (ie. which
+ fails).
+*/
+
+/*
+* VSybaseBind(dbproc,args)
+*/
+RETCODE VSybaseBind( dbproc, args )
+ DBPROCESS *dbproc;
+ va_list args;
+{
+ int field_no;
+ int type;
+ int length;
+ char *varptr;
+ RETCODE status;
+
+ /* Assume sets of field#, type, length, variable */
+
+ for( status = SUCCEED; status == SUCCEED; )
+ {
+ /* When we get to a zero field code, we're at the end of
+ the variable length input list */
+
+ field_no = va_arg( args, int );
+ if( field_no == 0 ) break;
+
+ /* Load the other arguments */
+
+ type = va_arg( args, int );
+ length = va_arg( args, int );
+ varptr = va_arg( args, char *); /* Must be a pointer! */
+
+ /* Bind us up */
+
+ status = dbbind(dbproc, field_no, type, length, varptr );
+ }
+
+ /* Done */
+
+ return( status );
+}
+
+
+/*
+ SybaseBind Bind Sybase Fields to Variables
+
+ This is a variable argument list procedure which repeatedly
+ calls the Sybase dbbind() procedure to bind sets of parameters
+ coded in it's variable argument list. A single zero parameter
+ following the last valid group terminates the list of arguments.
+
+ Normally, the argument list of this function is coded as a
+ table, with arguments for a single bind on each row, and the
+ parameters for each bind in the columns. This simply provides
+ a neater way of coding the binds.
+
+ Interpretation of the argument list:
+
+ The first argument passed is a pointer to the Sybase database
+ process where the binding is to be done. The remaining parameters
+ are grouped in sets of four, which are interpreted as follows:
+
+ Field Contents
+ ===== ========
+ field_no The field number. This must be a positive
+ integer. When this value is zero, we
+ assume we've reached the end of the list.
+
+ type The binding type of the field (see dbdind()
+ documentation for valid values).
+
+ length The length of the field. Zero can be used
+ if the length is implied by the type or
+ the buffer used to hold the input is known
+ to be long enough to hold the data.
+
+ varptr A pointer to the location where the data
+ retrieved from the database is to be
+ stored. It must be at least length bytes
+ long, or long enough to hold this type.
+
+ A single zero parameter following the last valid group (which
+ ends up as field_no == 0, terminates the argument list.
+
+ [NOTE: This is simply a variable argument list wrapper for
+ the VSybaseBind() procedure.]
+
+ Returns:
+
+ SUCCEED if all binds are successful, or the return code of
+ first dbbind() call which does not return SUCCEED (ie. which
+ fails).
+*/
+
+/*
+* SybaseBind(DBPROCESSdbproc,...)
+*/
+RETCODE SybaseBind( DBPROCESS *dbproc, ... )
+{
+ va_list args;
+ RETCODE status;
+
+ /* Extract the argument */
+
+ va_start( args, dbproc );
+
+ /* Use the vector routine to handle everything else */
+
+ status = VSybaseBind( dbproc, args );
+ va_end( args );
+
+ /* Done */
+
+ return( status );
+
+}
+
+
+/*
+ SybaseLoad Bind Sybase fields to data and Load a Record
+
+ This procedure is identical to Sybase bind except that the
+ dbnextrow() procedure is called after binding to load the
+ bound variables from a row in the database.
+
+ Parameters:
+
+ Identical to SybaseBind, see the comment on that procedure
+ (above) for details.
+
+ Returns:
+
+ Identical to Sybase bind except that the return code is
+ the value returned from the dbnextrow() call unless one of
+ the bind operations fail. In that case, the return code
+ is the value returned by the failed bind (should be FAIL).
+*/
+
+/*
+* SybaseLoad(DBPROCESSdbproc,...)
+*/
+RETCODE SybaseLoad( DBPROCESS *dbproc, ... )
+{
+ va_list args;
+ RETCODE status;
+
+ /* Extract the 'dbproc' argument */
+
+ va_start( args, dbproc );
+
+ /* Use the vector routine to handle everything else */
+
+ status = VSybaseBind( dbproc, args );
+ va_end( args );
+ if( status != SUCCEED ) return( status );
+
+ /* Load a row from the database and exit */
+
+ return( dbnextrow( dbproc ) );
+
+}
diff --git a/network/medarch/server/sybbind.h b/network/medarch/server/sybbind.h
new file mode 100644
index 00000000..afce4ac2
--- /dev/null
+++ b/network/medarch/server/sybbind.h
@@ -0,0 +1,46 @@
+/*
+ sybbind.h High level Sybase row loading and binding support
+
+ MODULE: sybbind
+ FILES: sybbind.c and sybbind.h (this one).
+
+ This module provides a high-level interface to the Sybase procedures
+ for binding rows to C variables and for loading rows in form the
+ database. These procedures permit a single procedure call to bind
+ many variables in a single call. The SybaseLoad procedure call
+ adds row retrieval as well. This reduce the amounts of coding
+ detail required by lumping the dbbind() and dbnextresults() calls
+ into a single call with only a single return code to check.
+
+ Note: This module was adapted from the module of the same
+ name from the GenInfo Backbone database project. It
+ had to be slightly modified to meet Medline project
+ coding conventions. (module nomenclature)
+
+ Edit History:
+ 25 July 1991 - Rand S. Huntzinger, NLM/NCBI
+ Modified to comply with Medline project coding conventions.
+
+ Original version: circa 1989-1990, Rand S. Huntzinger, NLM/NCBI
+*
+*
+* RCS Modification History:
+* $Log: sybbind.h,v $
+* Revision 6.0 1997/08/25 18:37:03 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:56:05 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEF_MODULE_SYBBIND
+#define DEF_MODULE_SYBBIND
+
+/* Define the procedural entry points to the sybbind module */
+
+RETCODE VSybaseBind( DBPROCESS *dbproc, void *args );
+RETCODE SybaseBind( DBPROCESS *dbproc, ... );
+RETCODE SybaseLoad( DBPROCESS *dbproc, ... );
+
+#endif /* DEF_MODULE_SYBBIND */
diff --git a/network/medarch/server/sybintfc.c b/network/medarch/server/sybintfc.c
new file mode 100644
index 00000000..8ed41da5
--- /dev/null
+++ b/network/medarch/server/sybintfc.c
@@ -0,0 +1,461 @@
+/*
+ sybintfc.c Execute a Sybase command using a
+ printf-style format for command building
+
+ MODULE: sybintf
+ FILES: sybintf.c (this one) and sybintf.h.
+
+ This module contains functions which permit a printf-style format
+ to be used for building and executing Sybase queries. This
+ avoids having the application have to piece the command together
+ from a bunch of little pieces using multiple calls to dbcmd.
+
+ Note: This package was adapted for the Medline project from
+ the same module in the GenInfo Backbone database project.
+ Some minor changes had to be made to conform to Medline
+ style conventions.
+
+ Dependencies:
+
+ voutf.c A package supporting printf-style formats with
+ output directed via function calls instead of
+ to a file or memory buffer.
+
+ Edit history:
+
+ 25 July 1991 - Rand S. Huntzinger
+ Moved to Medline project area and adapted the code to
+ meet Medline project requirements.
+
+ 5 April 1991 - Added a print query debugging option.
+
+ Original Implementation: 7 Dec 89 - Rand S. Huntzinger.
+*
+*
+* RCS Modification History:
+* $Log: sybintfc.c,v $
+* Revision 6.0 1997/08/25 18:37:05 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:56:08 epstein
+* add RCS log revision history
+*
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+#include "sybintfc.h"
+#include "voutf.h"
+
+
+/* These global variables are used for debugging. You can set them to cause
+ queries to be written to a file. */
+
+FILE *SybaseQueryPrintFile = stdout; /* Default = standard output */
+int SybaseQueryPrintCount = 0; /* Default, don't print! */
+
+
+/* These variables are used internally by the voutf processing procedure */
+
+static DBPROCESS *dbproc;
+static RETCODE status;
+
+/*
+ build_sybase_command Voutf string collection procedure.
+
+ This procedure collects the little strings generated by the
+ voutf function in interpreting it's format and directs them
+ into the dbcmd() procedure for insertion into the Sybase
+ command.
+
+ Assumptions:
+
+ * The calling program has set the static variable "dbproc"
+ to reference the DBPROCESS to be used for building the
+ command.
+
+ * The static variable "status" will return the status of the
+ last call to this procedure when voutf exits. If voutf
+ exits with an error, this will contain the error status
+ returned by dbcmd().
+
+ Parameters: (defined by voutf protocol)
+
+ s The string coming in from voutf().
+
+ Returns: (defined by voutf protocol)
+
+ TRUE (non-zero) if the command failed,
+ FALSE (zero) if the command was successful.
+*/
+
+/*
+* intbuild_sybase_command(chars)
+*/
+static int build_sybase_command( char *s )
+{
+ /* Add the string to the command */
+
+ return( (status = dbcmd( dbproc, s )) != SUCCEED );
+}
+
+
+/*
+* DumpSybaseCommand(DBPROCESSdbproc,FILEfd)
+*/
+void DumpSybaseCommand( DBPROCESS *dbproc, FILE *fd )
+{
+ char buffer[61];
+ int len = dbstrlen( dbproc );
+ char *stub = "Query:";
+ int index = 0;
+ int copy_count;
+ register char *p;
+
+ /* Dump the query out to SybaseQueryPrintFile */
+
+ while( index < len )
+ {
+ copy_count = (( len - index ) > (sizeof(buffer) - 1))
+ ? (sizeof(buffer) - 1) : (len - index);
+ dbstrcpy( dbproc, index, copy_count , buffer );
+ for(p=buffer; *p; p++) if(isspace(*p)) *p = ' ';
+ fprintf(fd, "%-12.12s || %s ||\n", stub, buffer);
+ stub = "";
+ index += copy_count;
+ }
+ fprintf(fd, "\n" );
+}
+
+
+/*
+ VExtendSybaseCommand Add to a Sybase command from a vector
+
+ This procedure extends the Sybase command buffer using a format and
+ a argument list pointer (usually passed by a variable argument
+ list calling procedure).
+
+ Parameters:
+
+ db The Sybase database process to be used.
+
+ fmt A printf-style format for generating this
+ piece of the command.
+
+ args An argument vector containing the arguments
+ which are to be interpreted according to the
+ format to generate this piece of the command
+ string.
+
+ Returns:
+
+ Zero if successful, non-zero on an error.
+*/
+
+/*
+* VExtendSybaseCommand(DBPROCESSdb,charfmt,voidargs)
+*/
+RETCODE VExtendSybaseCommand( DBPROCESS *db, char *fmt, void *args )
+{
+ /* Load the command into the command buffer */
+
+ dbproc = db;
+ (void) voutf( build_sybase_command, fmt, args );
+
+ /* Done */
+
+ return( status );
+}
+
+/*
+ VLoadSybaseCommand Load a Sybase command from a vector
+
+ This procedure loads the Sybase command buffer using a format and
+ a argument list pointer (usually passed by a variable argument
+ list calling procedure). This is identical to the
+ VExtendSybaseCommand procedure except any existing Sybase command
+ is cleared out before loading the new text.
+
+ Parameters:
+
+ db The Sybase database process to be used.
+
+ fmt A printf-style format for generating this
+ piece of the command.
+
+ args An argument vector containing the arguments
+ which are to be interpreted according to the
+ format to generate this piece of the command
+ string.
+
+ Returns:
+
+ Zero if successful, non-zero on an error.
+*/
+
+/*
+* VLoadSybaseCommand(DBPROCESSdb,charfmt,voidargs)
+*/
+RETCODE VLoadSybaseCommand( DBPROCESS *db, char *fmt, void *args )
+{
+ RETCODE status;
+
+ /* Reset the database channel */
+
+ dbproc = db;
+ if( (status = dbcancel( dbproc )) != SUCCEED )
+ return( status );
+
+ /* Load the command into the command buffer */
+
+ (void) voutf( build_sybase_command, fmt, args );
+
+ /* Done */
+
+ return( status );
+}
+
+/*
+ LoadSybaseCommand Load a Sybase command via a format.
+
+ This procedure loads the Sybase command buffer using a variable
+ argument list containing a format which is used to generate the
+ command using printf-style conversions.
+
+ Parameters:
+
+ db The Sybase database process to be used.
+
+ fmt A printf-style format for generating this
+ piece of the command.
+
+ ... The remaining arguments are interpreted according
+ to the format (fmt) using printf conventions to
+ generate the string to be loaded into the Sybase
+ command buffer.
+
+ Returns:
+
+ Zero if successful, non-zero on an error.
+*/
+
+/*
+* LoadSybaseCommand(DBPROCESSdbproc,charfmt,...)
+*/
+RETCODE LoadSybaseCommand( DBPROCESS *dbproc, char *fmt, ... )
+{
+ va_list args;
+
+ /* Extract the fixed parameters */
+
+ va_start( args, char *fmt );
+
+ /* Put the command in the buffer */
+
+ (void) VLoadSybaseCommand( dbproc, fmt, args );
+ va_end( args );
+
+ /* Done */
+
+ return( status );
+}
+
+
+/*
+ ExtendSybaseCommand Add to a Sybase command via a format.
+
+ This procedure extends the Sybase command buffer using a variable
+ argument list containing a format which is used to generate the
+ command using printf-style conversions. This procedure is
+ identical to LaodSybaseCommand execept that the string generated
+ here is appended to the existing Sybase command buffer instead of
+ replacing it.
+
+ Parameters:
+
+ db The Sybase database process to be used.
+
+ fmt A printf-style format for generating this
+ piece of the command.
+
+ ... The remaining arguments are interpreted according
+ to the format (fmt) using printf conventions to
+ generate the string to be loaded into the Sybase
+ command buffer.
+
+ Returns:
+
+ Zero if successful, non-zero on an error.
+*/
+
+/*
+* ExtendSybaseCommand(DBPROCESSdbproc,charfmt,...)
+*/
+RETCODE ExtendSybaseCommand( DBPROCESS *dbproc, char * fmt, ... )
+{
+ va_list args;
+
+ /* Extract the fixed parameters */
+
+ va_start( args, fmt );
+ dbproc = va_arg( args, DBPROCESS * );
+ fmt = va_arg( args, char * );
+
+ /* Put the command in the buffer */
+
+ (void) VExtendSybaseCommand( dbproc, fmt, args );
+ va_end( args );
+
+ /* Done */
+
+ return( status );
+}
+
+
+/*
+ ExecSybaseCommand Execute an existing Sybase command
+
+ This procedure executes the command in the Sybase command buffer
+ and returns the results of the execution.
+
+ Parameters:
+
+ dbproc The Sybase database process pointer.
+
+ Returns:
+
+ The return code of dbsqlexec() if it fails; otherwise,
+ the return code of dbresults(). Basically, this should
+ amount to SUCCEED if successful, or FAIL on an error.
+*/
+
+/*
+* ExecSybaseCommand(dbproc)
+*/
+RETCODE ExecSybaseCommand( dbproc )
+ DBPROCESS *dbproc;
+{
+ /* Execute the query */
+
+ if((status = dbsqlexec( dbproc )) != SUCCEED)
+ return( status );
+
+ /* If the query succeeded, see if we want to print it out */
+
+ if( SybaseQueryPrintCount != 0 ) {
+ DumpSybaseCommand( dbproc, SybaseQueryPrintFile );
+ if( SybaseQueryPrintCount > 0 ) SybaseQueryPrintCount--;
+ }
+
+ /* Load the results of the command */
+
+ return( dbresults( dbproc ) );
+}
+
+
+/*
+ RunSybase Execute a Sybase command specified using a
+ printf-style format and variable argument list.
+
+ This procedure permits a printf-style format and variable argument
+ list to be used to build & execute a sybase command. It performs
+ the first three steps of the Sybase command execution process,
+ 1) command construction using dbcmd(), 2) execution using dbseqlexec
+ and 3) the retrieval of results using dbresults().
+
+ Parameters: (variable argument list)
+
+ dbproc A pointer to an open Sybase database process
+ record. (ie. a channel to the database)
+
+ fmt The format string to be interpreted.
+
+ ... The remaining arguments are interpreted
+ according to the format given in the "fmt"
+ argument using printf conventions.
+
+ Returns:
+
+ The last return code returned from Sybase. If successful,
+ this should be SUCCEED; otherwise, it will be the status
+ of the first step which failed.
+*/
+
+/*
+* RunSybase(DBPROCESSdbproc,charfmt,...)
+*/
+RETCODE RunSybase( DBPROCESS *dbproc, char *fmt, ... )
+{
+ va_list args;
+
+ /* Extract the fixed parameters */
+
+ va_start( args, fmt );
+
+ /* Load the command */
+
+ (void) VLoadSybaseCommand( dbproc, fmt, args );
+ va_end( args );
+ if( status != SUCCEED ) return( status );
+
+ /* Execute the Sybase command */
+
+ return( ExecSybaseCommand( dbproc ) );
+}
+
+
+/*
+ RunSybaseCheck Count records returned by a Sybase command
+
+ Executes a Sybase command and returns the number of records
+ retrieved by the command. The data is not available.
+
+
+ Parameters: (variable argument list)
+
+ dbproc A pointer to an open Sybase database process
+ record. (ie. a channel to the database)
+
+ fmt The format string to be interpreted.
+
+ ... The remaining arguments are interpreted
+ according to the format given in the "fmt"
+ argument using printf conventions.
+
+ Returns:
+
+ The number of rows retrieved or -1 on an error.
+
+*/
+
+/*
+* RunSybaseCheck(DBPROCESSdbproc,charfmt,...)
+*/
+int RunSybaseCheck( DBPROCESS *dbproc, char *fmt, ... )
+{
+ va_list args;
+ int count;
+
+ /* Extract the fixed parameters */
+
+ va_start( args, fmt );
+ dbproc = va_arg( args, DBPROCESS * );
+ fmt = va_arg( args, char * );
+
+ /* Load the command */
+
+ (void) VLoadSybaseCommand( dbproc, fmt, args );
+ va_end( args );
+ if( status != SUCCEED ) return( -1 );
+
+ /* Execute the Sybase command */
+
+ if( ExecSybaseCommand( dbproc ) != SUCCEED )
+ return( -1 );
+
+ count = DBROWS( dbproc );
+ (void) dbcancel( dbproc );
+
+ return( count );
+}
+
diff --git a/network/medarch/server/sybintfc.h b/network/medarch/server/sybintfc.h
new file mode 100644
index 00000000..cdf58163
--- /dev/null
+++ b/network/medarch/server/sybintfc.h
@@ -0,0 +1,70 @@
+/*
+ sybintfc.h Execute a Sybase command using a
+ printf-style format for command building
+
+ MODULE: sybintf
+ FILES: sybintf.c and sybintf.h (this one).
+
+ This module contains functions which permit a printf-style format
+ to be used for building and executing Sybase queries. This
+ avoids having the application have to piece the command together
+ from a bunch of little pieces using multiple calls to dbcmd.
+
+ Note: This package was adapted for the Medline project from
+ the same module in the GenInfo Backbone database project.
+ Some minor changes had to be made to conform to Medline
+ style conventions.
+
+ Dependencies:
+
+ voutf A package supporting printf-style formats with
+ output directed via function calls instead of
+ to a file or memory buffer.
+
+ Edit history:
+
+ 25 July 1991 - Rand S. Huntzinger
+ Moved to Medline project area and adapted the code to
+ meet Medline project requirements.
+
+ 5 April 1991 - Added a print query debugging option.
+
+ Original Implementation: 7 Dec 89 - Rand S. Huntzinger.
+*
+*
+* RCS Modification History:
+* $Log: sybintfc.h,v $
+* Revision 6.0 1997/08/25 18:37:06 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:56:11 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_SYBINTFC
+#define DEFS_MODULE_SYBINTFC
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "sybase.h"
+
+/* These variables can be set in the debugger or by a program to help
+ in debugging by printing out Sybase queries before they are executed. */
+
+FILE *SybaseQueryPrintFile;
+int SybaseQueryPrintCount;
+
+/* The following are the entry points to the sybintfc module */
+
+void DumpSybaseCommand( DBPROCESS *db, FILE *fd );
+RETCODE VExtendSybaseCommand( DBPROCESS *db, char *fmt, void *args);
+RETCODE VLoadSybaseCommand( DBPROCESS *db, char *fmt, void *args);
+RETCODE LoadSybaseCommand( DBPROCESS *db, char *fmt, ... );
+RETCODE ExtendSybaseCommand( DBPROCESS *db, char *fmt, ... );
+RETCODE ExecSybaseCommand( DBPROCESS *db );
+RETCODE RunSybase( DBPROCESS *db, char *fmt, ... );
+RETCODE RunSybaseCheck( DBPROCESS *db, char *fmt, ... );
+
+
+#endif DEFS_MODULE_SYBINTFC
diff --git a/network/medarch/server/voutf.c b/network/medarch/server/voutf.c
new file mode 100644
index 00000000..77b0847e
--- /dev/null
+++ b/network/medarch/server/voutf.c
@@ -0,0 +1,259 @@
+/*
+ voutf.c Process formatted text through an output function.
+
+ MODULE: voutf
+ FILES: voutf.c (this one) and voutf.h.
+
+ This package implements a flexible variable argument list
+ output function similar to the System V vprintf function;
+ however, it differs by using a function as an output sink
+ instead of a string buffer or an output file. This increases
+ the flexibility of the package by allowing the supplied
+ function to post-process and redirect the output as required
+ by the application.
+
+ Note: This procedure was adapted from earlier projects and
+ edited slightly to fit Medline project syle criteria.
+
+ Edit History:
+
+ 25 July 1991 Rand S. Huntzinger, NLM/NCBI
+ Adapted to meet style criterial for modules in the
+ Medline project.
+
+ 14 Dec 1989 Modified to permit unlimited-length
+ format statements and output of
+ super long strings with unqualified
+ %s format (ie. %s not %30s).
+
+ Written: 5/21/87 by Rand S. Huntzinger
+*
+*
+* RCS Modification History:
+* $Log: voutf.c,v $
+* Revision 6.0 1997/08/25 18:37:08 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:56:14 epstein
+* add RCS log revision history
+*
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "voutf.h"
+
+#define index(s,c) strchr(s,c)
+
+/* Local definitions and declarations */
+
+#define MAX_ARG_EXPANSION 128 /* Largest single output field */
+#define MAX_FMT_ITEM 128 /* Largest single field format */
+#define EOS '\0' /* End of string marker */
+#ifndef TRUE
+#define TRUE 1 /* Boolean constants */
+#define FALSE 0
+#endif
+
+typedef int ifunc();
+
+/* Macro to support error handling in the output function */
+
+#define OUTPUT(S) if((rv = out_func(S)) != 0) return (rv)
+
+/* List of printf style format characters recognized by voutf */
+
+static char *fmt_chars = "sdcfgGeEduoxX%";
+
+/* External functions required */
+
+
+/*
+ voutf Variable argument list output function.
+
+ This routine implements interprets a variable length argument
+ list with respect to a format in a manner similar to the
+ printf functions in the standard I/O package. As each output
+ field is interpreted, the resulting string is passed to a
+ supplied output function, which processes it as required by
+ the application [usually collects it into a string or outputs
+ it].
+
+ Parameters:
+
+ out_func The address of the function to be used
+ as an output sink. It is called for
+ each output field (including constant
+ fields).
+
+ fmt A printf-style format statement
+ describing how to format the remaining
+ arguments into strings to pass to
+ out_func.
+
+ args A variable of type va_list (from a
+ variable argument list in the calling
+ program).
+
+ Returns:
+
+ 0 If no error.
+ NOT 0 An error status from out_func.
+ Interpretation depends upon out_func.
+*/
+
+/*
+* voutf(int(out_func)(),charfmt,voidargs)
+*/
+int voutf(int (*out_func)(), char *fmt, void *args)
+{
+ char buf[MAX_ARG_EXPANSION+1];
+ char afmt[MAX_FMT_ITEM];
+ int rv;
+
+ /* Scan the format and output text */
+
+ rv = 0; /* Assume success for now */
+ while(*fmt) {
+ char *p; /* Advancing char pointer */
+ char f_char; /* Formatting character */
+ short longvar; /* TRUE if a long integer */
+ short shortvar; /* TRUE if a long integer */
+
+ /* Variables to hold arguments of various types */
+
+ double dval; char * sval;
+ int ival; long lval;
+
+ /* Non-formatting codes simply get output */
+ if(*fmt != '%') {
+ for(p = buf; *fmt && *fmt!= '%'; *p++ = *fmt++)
+ if(p == &buf[MAX_ARG_EXPANSION]) {
+ *p = EOS;
+ OUTPUT(buf);
+ p = buf;
+ }
+ *p = EOS;
+ OUTPUT(buf);
+ }
+ /* Format items require conversion */
+ if(*fmt == '%') {
+ /* Extract the conversion specification */
+ longvar = shortvar = FALSE;
+ p = afmt;
+ *p++ = *fmt++;
+ while(*fmt && index(fmt_chars, *fmt) == NULL) {
+ char ivstr[32], *q;
+ if(*fmt == '*') {
+ /* Get format width from data */
+ ival= va_arg(args, int);
+ sprintf(ivstr, "%d", ival);
+ for(q=ivstr; *q; ) *p++ = *q++;
+ fmt++; /* Skip * */
+ continue;
+ }
+ if(*fmt == 'l') longvar = TRUE;
+ if(*fmt == 'h') shortvar = TRUE;
+ *p++ = *fmt++;
+ }
+ *p++ = f_char = *fmt;
+ *p = EOS;
+ if(*fmt) fmt++;
+ /* Convert next argument by format */
+ switch(f_char) {
+ case '%': /* Quoted % */
+ strcpy(buf, "%");
+ break;
+ case 'd': /* Integer conversions */
+ case 'o': case 'u': case 'x': case 'X':
+ case 'c': /* char is an integer on stack */
+ if(longvar) {
+ lval = va_arg(args, long);
+ sprintf(buf, afmt, lval);
+ } else if(shortvar) {
+ lval = va_arg(args, int);
+ sprintf(buf, afmt, lval);
+ } else {
+ ival = va_arg(args, int);
+ sprintf(buf, afmt, ival);
+ }
+ break;
+ case 'f': /* Floating point conversions */
+ case 'e': case 'E': case 'g': case 'G':
+ /* NOTE - PROBLEMS if float <> double? */
+ dval = va_arg(args, double);
+ sprintf(buf, afmt, dval);
+ break;
+ case 's': /* String argument */
+ sval = va_arg(args, char *);
+ if(strcmp(afmt, "%s") == 0) {
+ OUTPUT( sval ); /* Unrestricted string */
+ continue;
+ } else sprintf(buf, afmt, sval);
+ break;
+ case EOS: /* End of string */
+ default: /* Unexpected character */
+ strcpy(buf, afmt);
+ break;
+ }
+ /* Output the resulting string */
+ OUTPUT(buf);
+ }
+ }
+
+ /* Exit at this point */
+
+ return( rv );
+}
+
+
+/*
+ voutput Output with variable argument list.
+
+ Call voutf with a direct variable argument list. This is
+ used when the function is not called from a variable argument
+ list function.
+
+ Parameters:
+
+ out_func The address of the function to be used
+ as an output sync. It is called for
+ each output field (including constant
+ fields).
+
+ fmt A printf-style format statement
+ describing how to format the remaining
+ arguments into strings to pass to
+ out_func.
+
+ args ... The remaining arguments are interpreted
+ according to the format passed as 'fmt'.
+
+ Returns:
+
+ 0 If no error.
+ NOT 0 An error status from out_func.
+ Interpretation depends upon out_func.
+*/
+
+/*
+* voutput(int(out_func)(),charfmt,...)
+*/
+int voutput(int (*out_func)(), char *fmt, ...)
+{
+ va_list args;
+ int rv;
+
+ /* Extract the fixed parameters */
+
+ va_start(args, fmt);
+
+ /* Now use voutf */
+
+ rv = voutf(out_func, fmt, args);
+ va_end( args );
+
+ /* Done */
+
+ return( rv );
+}
diff --git a/network/medarch/server/voutf.h b/network/medarch/server/voutf.h
new file mode 100644
index 00000000..35e54355
--- /dev/null
+++ b/network/medarch/server/voutf.h
@@ -0,0 +1,45 @@
+/*
+ voutf.h Process formatted text through an output function.
+
+ MODULE: voutf
+ FILES: voutf.c and voutf.h (this one).
+
+ This package implements a flexible variable argument list
+ output function similar to the System V vprintf function;
+ however, it differs by using a function as an output sink
+ instead of a string buffer or an output file. This increases
+ the flexibility of the package by allowing the supplied
+ function to post-process and redirect the output as required
+ by the application.
+
+ Note: This file was added to meet Medline project module
+ criteria (include file with entry points defined)
+ when the voutf.c program was adapted from the GenInfo
+ Backbone database project.
+
+ Original version completed: 25 July 1991, Rand S. Huntzinger NLM/NCBI
+*
+*
+* RCS Modification History:
+* $Log: voutf.h,v $
+* Revision 6.0 1997/08/25 18:37:10 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:56:17 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_VOUTF
+#define DEFS_MODULE_VOUTF
+
+#include <stdarg.h>
+
+/* Define the entry points to the voutf module. In the statements assume
+ IFUNC refers to the name of an integer function. */
+
+typedef int IFUNC();
+extern int voutf( int (*func)(), char *fmt, void *list);
+extern int voutput( int (*func)(), char *fmt, ...);
+
+#endif /* DEFS_MODULE_VOUTF */
diff --git a/network/medarch/server/xalloc.c b/network/medarch/server/xalloc.c
new file mode 100644
index 00000000..fdabd972
--- /dev/null
+++ b/network/medarch/server/xalloc.c
@@ -0,0 +1,491 @@
+/*
+ xalloc.c Extended memory allocation routines.
+
+ This package provides an interface to the standard Unix memory
+ allocation routines to give better error handling facilities
+ as well as facilities for keeping track of heap usage.
+
+ History:
+
+ 10/18/91 Converted to ANSI C.
+
+ 12/31/86 Rand S. Huntzinger - Original version.
+
+ Basic entry points:
+
+ xalloc(size) Allocate size bytes (malloc equivalent)
+ xrealloc(p, size) Reallocate ptr to size bytes (realloc).
+ xcalloc(nelem, esize) Allocate an array of elements (calloc).
+ xfree(p) Free space at this pointer (free).
+ xmemerr(func) Pass name of function to call on error.
+ xmemstat(srec) Keep memory access statistics.
+ xnullok(null_ok) If argument TRUE, allow xalloc routines
+ to return NULL, else abort the program.
+
+ NOTE:
+ Associated packages:
+
+ heapman The heap manager. Records memory requests and
+ keeps records of what needs to be freed.
+
+ malloc System package for memory allocation. This
+ package interfaces to these routines.
+
+ ---------------------------------------------------------------
+
+ The error hook: (routine to call on an error).
+
+ The error hook function is called whenever a call to one of the
+ system memory allocation routines fails (returns NULL). The
+ error hook can do several things. It can free some memory and
+ attempt to reallocate. It can issue an error diagnostic and
+ either return NULL to the calling program, or it can abort the
+ program via exit or a quit signal (to force a core dump).
+
+ The error hook is passed the following parameters:
+
+ ptr Type (char *). If this was a realloc call,
+ this is the pointer to reallocate; otherwise,
+ NULL is passed.
+
+ nelem Type size_t. The number of elements to allocate.
+ If a calloc call, the 1st argument to calloc is
+ passed; otherwise, a 1 is passed.
+
+ size Type size_t. The number of bytes to be allocated
+ for each element if calloc, the allocation size if
+ malloc or realloc.
+
+ errnum The number of the error returned by the allocation
+ routine.
+
+ func Type (char *). The name of the function which
+ returned the error as a text string. Always one
+ of "malloc", "calloc" or "realloc". You can
+ determine which one by testing the first character.
+
+ If the error hook returns, it should return:
+
+ A pointer to the allocated memory of the error hook found
+ a way to allocate it or NULL if the memory is still
+ unallocated.
+*
+*
+* RCS Modification History:
+* $Log: xalloc.c,v $
+* Revision 6.0 1997/08/25 18:37:12 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:56:20 epstein
+* add RCS log revision history
+*
+*/
+
+#include <stdlib.h>
+#include <stdio.h> /* For error message printout */
+#include "xalloc.h" /* Header file for these routines */
+
+#ifndef NULL
+#define NULL 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef ALLOC_ERR
+#define ALLOC_ERR 255
+#endif
+
+/* These declarations are used to define the types of the underlying Unix
+ memory allocation functions. They'll probably change soon of course
+ with the new type codes becoming available. */
+
+extern int errno; /* Unix error number */
+
+/* These variables hold the data stored by the hook setting functions. The
+ error logging procedure, the statistics accumulator buffers and the
+ variable which permits xalloc routines to return NULL */
+
+static XMESTAT *mestat = NULL; /* Memory status register */
+static CPFUNC *err_hook = NULL; /* Error function */
+static short null_is_OK = FALSE; /* If TRUE, we'll return with NULL */
+
+
+/*
+ err_handler Error handler function.
+
+ This routine calls the user's error handler function and
+ handles errors if necessary. In particular it dispatches to
+ the proper error handler and makes sure than we never return
+ NULL unless we do something special to permit it.
+
+ Parameters:
+
+ ptr Type (char *). If this was a realloc call,
+ this is the pointer to reallocate; otherwise,
+ NULL is passed.
+
+ ni Type size_t. The number of elements to allocate.
+ If a calloc call, the 1st argument to calloc is
+ passed; otherwise, a 1 is passed.
+
+ sz Type size_t. The number of bytes to be allocated
+ for each element if calloc, the allocation size if
+ malloc or realloc.
+
+ en The number of the error returned by the allocation
+ routine.
+
+ fn Type (char *). The name of the function which
+ returned the error as a text string. Always one
+ of "malloc", "calloc" or "realloc". You can
+ determine which one by testing the first character.
+
+ Returns:
+
+ The value returned by the error handler procedure called.
+ We do not exit (ie. we abort the program) if the null_is_OK
+ variable is false (the normal case) and err_handler returns
+ NULL.
+*/
+
+static
+/*
+* err_handler(charptr,size_tni,size_tsz,size_ten,charfn)
+*/
+char *err_handler(char *ptr, size_t ni, size_t sz, size_t en, char *fn)
+{
+ char *p; /* Temporary pointer */
+
+ /* Call the user error handler (if any) */
+
+ if(err_hook != NULL)
+ p = err_hook(ptr, ni, sz, en, fn);
+ else if(! null_is_OK) {
+ /* This is the default error handler! */
+
+ fprintf(stderr, "Memory allocation error: ");
+ switch(*fn) {
+ case 'm': /* malloc */
+ fprintf(stderr, "malloc(size=%d)\n", sz); break;
+ case 'r': /* realloc */
+ fprintf(stderr, "realloc(ptr=%X, size=%d)\n", ptr, sz);
+ break;
+ case 'c': /* calloc */
+ fprintf(stderr, "calloc(n=%d, size=%d)\n", ni, sz);
+ break;
+ default: /* Weird value */
+ fprintf(stderr, "function = %s\n", fn);
+ }
+ fprintf(stderr, "Exiting program\n");
+ p = NULL; /* Failure */
+ }
+
+ /* Do we permit NULL to be returned? */
+
+ if(p != NULL || null_is_OK)
+ return(p);
+
+ exit(ALLOC_ERR); /* Exit status for alloc error */
+ /*NOTREACHED*/
+}
+
+
+/*
+ xalloc Allocate a block of a given size.
+
+ This routine uses malloc to allocate a block of memory of a
+ given size. If an error hook function exists, it is called
+ prior to issuing a diagnostic. Memory statistics are kept
+ if this feature has been enabled.
+
+ Parameters:
+
+ size size_t The number of bytes to allocate.
+
+ Returns:
+
+ A pointer to the block of memory allocated or NULL if the
+ allocation failed and the error hook returned NULL.
+*/
+
+/*
+* xalloc(size_tsize)
+*/
+char *xalloc(size_t size)
+{
+ register char *p;
+
+ /* Do the actual memory allocation */
+
+ if((p = malloc(size)) == NULL) {
+ /* Failure, call the error hook */
+ if(mestat != NULL) mestat->xerrcals++;
+ p = err_handler(p, (size_t) 1, size, errno,
+ "malloc");
+ }
+
+ /* Record statistics */
+
+ if(mestat != NULL) {
+ mestat->xallocs++;
+ if(p == NULL) mestat->xfails++;
+ }
+
+ /* Exit with the pointer */
+
+ return(p);
+}
+
+
+/*
+ xcalloc Allocate an array of a given size.
+
+ This routine uses calloc to allocate an array of memory a
+ given size. If an error hook function exists, it is called
+ prior to issuing a diagnostic. Memory statistics are kept
+ if this feature has been enabled.
+
+ Parameters:
+
+ nelem size_t The number of items in the array.
+
+ size size_t The number of bytes to allocate for
+ each item.
+
+ Returns:
+
+ A pointer to the block of memory allocated or NULL if the
+ allocation failed and the error hook returned NULL.
+*/
+
+/*
+* xcalloc(size_tnelem,size_tsize)
+*/
+char *xcalloc(size_t nelem, size_t size)
+{
+ register char *p;
+
+ /* Do the actual memory allocation */
+
+ if((p = calloc(nelem, size)) == NULL) {
+ /* Failure, call the error hook */
+ if(mestat != NULL) mestat->xerrcals++;
+ p = err_handler(p, nelem, size, errno, "calloc");
+ }
+
+ /* Record statistics */
+
+ if(mestat != NULL) {
+ mestat->xcallocs++;
+ if(p == NULL) mestat->xfails++;
+ }
+
+ /* Exit with the pointer */
+
+ return(p);
+}
+
+/*
+ xrealloc Adjust a pointers memory allocation.
+
+ This routine uses realloc to alter the block of memory associated
+ with a given memory pointer. If an error hook function exists, it
+ is called prior to issuing a diagnostic. Memory statistics are
+ kept if this feature has been enabled.
+
+ Parameters:
+
+ ptr (char *) The number of items in the array.
+
+ size size_t The number of bytes to allocated
+ to this pointer after the call.
+
+ Returns:
+
+ A pointer to the block of memory allocated or NULL if the
+ allocation failed and the error hook returned NULL.
+*/
+
+/*
+* xrealloc(voidptr,size_tsize)
+*/
+char *xrealloc(void *ptr, size_t size)
+{
+ register void *p;
+
+ /* Do the actual memory allocation */
+
+ if((p = realloc(ptr, size)) == NULL) {
+ /* Failure, call the error hook */
+ if(mestat != NULL) mestat->xerrcals++;
+ p = err_handler(ptr, (size_t) 1, size, errno,
+ "realloc");
+ }
+
+ /* Record statistics */
+
+ if(mestat != NULL) {
+ mestat->xreallocs++;
+ if(p == NULL) mestat->xfails++;
+ }
+
+ /* Exit with the pointer */
+
+ return(p);
+}
+
+
+/*
+ xfree Free memory allocated by malloc.
+
+ This routine frees a block of memory allocated by malloc.
+ It is identical to the system free routine except that
+ statistics are logged and the system avoids passing NULL
+ to free. [On some systems this is OK, on others, this
+ can be disasterous!]
+
+ Parameters:
+
+ ptr Pointer to the data to be freed.
+
+ Returns:
+
+ Nothing. No errors are returned since I see no
+ consistent definition of errors from free itself.
+*/
+
+/*
+* xfree(voidptr)
+*/
+void xfree(void *ptr)
+{
+ /* If the pointer is not NULL, free it */
+
+ if(ptr == NULL) {
+ if(mestat != NULL) mestat->xfree0s++;
+ } else {
+ (void) free(ptr);
+ if(mestat != NULL) mestat->xfrees++;
+ }
+}
+
+
+/*
+ xmemstat Enable/disable memory allocation statistics
+
+ This procedure is used to enable or disable memory allocation
+ statistics and to clear the counters (when desired). The
+ procedure passes a pointer to the buffer to receive the statistics
+ and returns the previous pointer. This allows the calling program
+ to swap out a counter temporarily.
+
+ Parameters:
+
+ sptr A pointer to the statistics accumulation
+ buffer to be used for future calls or
+ NULL to disable statistics gathering.
+
+ zero True => zero the accumulators before
+ collecting statistics. Otherwise, future
+ calls will be added to the data in the
+ buffer.
+
+ Returns:
+
+ A pointer to the statistics accumulation buffer used prior
+ to this call or NULL if statistics were disabled.
+*/
+
+/*
+* xmemstat(sptr,zero)
+*/
+XMESTAT *xmemstat(sptr, zero)
+ XMESTAT *sptr;
+ int zero;
+{
+ XMESTAT *tmp;
+
+ /* Update the memory allocation statistics record */
+
+ tmp = mestat;
+ mestat = sptr;
+ if(sptr != NULL && zero)
+ sptr->xallocs = sptr->xcallocs = sptr->xreallocs =
+ sptr->xfrees = sptr->xfree0s = sptr->xerrcals =
+ sptr->xfails = 0;
+
+ return(tmp); /* Return previous value */
+}
+
+
+/*
+ xmemerr Replace the memory allocation error handler.
+
+ This procedure installs the procedure passed as an argument as the
+ memory allocation error handler and returns the address of the
+ previously defined error handler (so it can be reestablished later
+ if necessary). This procedure will be called, with a standard set
+ of arguments, when a memory allocation of free function fails.
+
+ Parameters:
+
+ func The address of the new error handler
+ function.
+
+ Returns:
+
+ The address of the the error handler which was in place before
+ the call. The default error handler is returned as NULL.
+*/
+
+/*
+* xmemerr(func)
+*/
+CPFUNC *xmemerr(func)
+ CPFUNC *func;
+{
+ CPFUNC *tmp;
+
+ /* Save the new function and return the old one */
+
+ tmp = err_hook;
+ err_hook = func;
+ return(tmp);
+}
+
+
+/*
+ xnullok Permit xalloc routines to return NULL or not.
+
+ This procedure is used to permit the xalloc returns to return
+ NULL if a memory allocation of free operation fails. The default
+ setting causes xalloc to exit the program if a memory allocation
+ fails.
+
+ Parameters:
+
+ null_ok If True, the xalloc routines can return
+ null if a memory allocation fails. If
+ False, the xalloc routines will cause the
+ program to exit on a memory allocation
+ failure.
+
+ Returns:
+
+ The setting of this parameter prior to this call.
+*/
+
+/*
+* xnullok(null_ok)
+*/
+int xnullok(null_ok)
+ int null_ok;
+{
+ int x;
+ x = null_is_OK;
+ null_is_OK = (null_ok != 0);
+ return(x);
+}
diff --git a/network/medarch/server/xalloc.h b/network/medarch/server/xalloc.h
new file mode 100644
index 00000000..fffdfa8a
--- /dev/null
+++ b/network/medarch/server/xalloc.h
@@ -0,0 +1,77 @@
+/*
+
+ xalloc.h Declarations for xalloc.c
+
+ MODULE: xalloc
+ FILES: xalloc.c and xalloc.h (this one).
+
+ This file contains definitions used by the memory allocation
+ functions implemented by xalloc.c. This package uses malloc
+ and related system library functions to do memory allocation
+ and recovery, but adds error recovery and statistics gathering
+ functions.
+
+ Note: This module was adapted from the module of the same
+ name from the GenInfo Backbone database project. It
+ had to be slightly modified to meet Medline project
+ coding conventions. (module nomenclature)
+
+ Edit History:
+
+ 18 October 1991 - Rand S. Huntzinger
+ Converted to ANSI-C
+
+ 25 July 1991 - Rand S. Huntzinger, NLM/NCBI
+ Modified to comply with Medline project coding conventions.
+
+ Original version: unknown date, Rand S. Huntzinger, NLM/NCBI
+*
+*
+* RCS Modification History:
+* $Log: xalloc.h,v $
+* Revision 6.0 1997/08/25 18:37:14 madden
+* Revision changed to 6.0
+*
+* Revision 1.2 1995/05/17 17:56:23 epstein
+* add RCS log revision history
+*
+*/
+
+#ifndef DEFS_MODULE_XALLOC
+#define DEFS_MODULE_XALLOC
+
+#include <stdlib.h>
+
+/* The following structure defines the memory allocation statistics
+ record. It contains counts of the various types of memory requests. */
+
+typedef struct XMESTAT {
+ long xallocs;
+ long xcallocs;
+ long xreallocs;
+ long xfrees;
+ long xfree0s;
+ long xerrcals;
+ long xfails;
+} XMESTAT;
+
+/* Type CPFUNC refers to a function which returns a character pointer */
+
+typedef char *CPFUNC();
+
+/* The following are forward declarations for the functions defined in
+ the xalloc module. The arguments to each routine are the same as the
+ arguments to the underlying module. */
+
+char *xalloc(size_t); /* Interface to malloc() function */
+char *xcalloc(size_t, size_t); /* Interface to calloc() function */
+char *xrealloc(void *, size_t); /* Interface to realloc() function */
+void xfree(void *); /* Interface to free() function */
+
+/* These stubs are used for enabling statistics and error handling procedures */
+
+XMESTAT *xmemstat(XMESTAT *, int); /* Enable/disable statistics */
+CPFUNC *xmemerr(CPFUNC func); /* Set memory error handler function */
+int xnullok(int); /* Permit/Prohibit NULL return values */
+
+#endif /* DEFS_MODULE_XALLOC */
diff --git a/network/ncsasock/a_ftp.h b/network/ncsasock/a_ftp.h
new file mode 100644
index 00000000..239cf82d
--- /dev/null
+++ b/network/ncsasock/a_ftp.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1983, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)ftp.h 5.5 (Berkeley) 6/1/90
+*
+*
+* RCS Modification History:
+* $Log: a_ftp.h,v $
+* Revision 6.0 1997/08/25 18:37:15 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:56:26 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Definitions for FTP
+ * See RFC-765
+ */
+
+/*
+ * Reply codes.
+ */
+#define PRELIM 1 /* positive preliminary */
+#define COMPLETE 2 /* positive completion */
+#define CONTINUE 3 /* positive intermediate */
+#define TRANSIENT 4 /* transient negative completion */
+#define ERROR 5 /* permanent negative completion */
+
+/*
+ * Type codes
+ */
+#define TYPE_A 1 /* ASCII */
+#define TYPE_E 2 /* EBCDIC */
+#define TYPE_I 3 /* image */
+#define TYPE_L 4 /* local byte size */
+
+#ifdef FTP_NAMES
+char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" };
+#endif
+
+/*
+ * Form codes
+ */
+#define FORM_N 1 /* non-print */
+#define FORM_T 2 /* telnet format effectors */
+#define FORM_C 3 /* carriage control (ASA) */
+#ifdef FTP_NAMES
+char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" };
+#endif
+
+/*
+ * Structure codes
+ */
+#define STRU_F 1 /* file (no record structure) */
+#define STRU_R 2 /* record structure */
+#define STRU_P 3 /* page structure */
+#ifdef FTP_NAMES
+char *strunames[] = {"0", "File", "Record", "Page" };
+#endif
+
+/*
+ * Mode types
+ */
+#define MODE_S 1 /* stream */
+#define MODE_B 2 /* block */
+#define MODE_C 3 /* compressed */
+#ifdef FTP_NAMES
+char *modenames[] = {"0", "Stream", "Block", "Compressed" };
+#endif
+
+/*
+ * Record Tokens
+ */
+#define REC_ESC '\377' /* Record-mode Escape */
+#define REC_EOR '\001' /* Record-mode End-of-Record */
+#define REC_EOF '\002' /* Record-mode End-of-File */
+
+/*
+ * Block Header
+ */
+#define BLK_EOR 0x80 /* Block is End-of-Record */
+#define BLK_EOF 0x40 /* Block is End-of-File */
+#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */
+#define BLK_RESTART 0x10 /* Block is Restart Marker */
+
+#define BLK_BYTECOUNT 2 /* Bytes in this block */
diff --git a/network/ncsasock/a_inet.h b/network/ncsasock/a_inet.h
new file mode 100644
index 00000000..d0368cee
--- /dev/null
+++ b/network/ncsasock/a_inet.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)inet.h 5.4 (Berkeley) 6/1/90
+*
+*
+* RCS Modification History:
+* $Log: a_inet.h,v $
+* Revision 6.0 1997/08/25 18:37:17 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:56:29 epstein
+ * add RCS log revision history
+ *
+ */
+
+/* External definitions for functions in inet(3) */
+
+#ifdef __STDC__
+extern unsigned long inet_addr(const char *);
+extern char *inet_ntoa(struct in_addr);
+extern struct in_addr inet_makeaddr(int , int);
+extern unsigned long inet_network(const char *);
+extern unsigned long inet_lnaof(struct in_addr);
+extern unsigned long inet_netof(struct in_addr);
+#else
+extern unsigned long inet_addr();
+extern char *inet_ntoa();
+extern struct in_addr inet_makeaddr();
+extern unsigned long inet_network();
+extern unsigned long inet_lnaof();
+extern unsigned long inet_netof();
+#endif
diff --git a/network/ncsasock/a_namesr.h b/network/ncsasock/a_namesr.h
new file mode 100644
index 00000000..94db7330
--- /dev/null
+++ b/network/ncsasock/a_namesr.h
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 1983, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)nameser.h 5.24 (Berkeley) 6/1/90
+ *
+ *
+ * RCS Modification History:
+ * $Log: a_namesr.h,v $
+ * Revision 6.0 1997/08/25 18:37:20 madden
+ * Revision changed to 6.0
+ *
+ * Revision 4.0 1995/07/26 13:56:09 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.4 1995/05/18 08:23:22 epstein
+ * add RCS modification history (after PowerPC port)
+ *
+ */
+
+/*
+ * Define constants based on rfc883
+ */
+#define PACKETSZ 512 /* maximum packet size */
+#define MAXDNAME 256 /* maximum domain name */
+#define MAXCDNAME 255 /* maximum compressed domain name */
+#define MAXLABEL 63 /* maximum length of domain label */
+ /* Number of bytes of fixed size data in query structure */
+#define QFIXEDSZ 4
+ /* number of bytes of fixed size data in resource record */
+#define RRFIXEDSZ 10
+
+/*
+ * Internet nameserver port number
+ */
+#define NAMESERVER_PORT 53
+
+/*
+ * Currently defined opcodes
+ */
+#define QUERY 0x0 /* standard query */
+#define IQUERY 0x1 /* inverse query */
+#define STATUS 0x2 /* nameserver status query */
+/*#define xxx 0x3 */ /* 0x3 reserved */
+ /* non standard */
+#define UPDATEA 0x9 /* add resource record */
+#define UPDATED 0xa /* delete a specific resource record */
+#define UPDATEDA 0xb /* delete all nemed resource record */
+#define UPDATEM 0xc /* modify a specific resource record */
+#define UPDATEMA 0xd /* modify all named resource record */
+
+#define ZONEINIT 0xe /* initial zone transfer */
+#define ZONEREF 0xf /* incremental zone referesh */
+
+/*
+ * Currently defined response codes
+ */
+#define NOERROR 0 /* no error */
+#define FORMERR 1 /* format error */
+#define SERVFAIL 2 /* server failure */
+#define NXDOMAIN 3 /* non existent domain */
+#define NOTIMP 4 /* not implemented */
+#define REFUSED 5 /* query refused */
+ /* non standard */
+#define NOCHANGE 0xf /* update failed to change db */
+
+/*
+ * Type values for resources and queries
+ */
+#define T_A 1 /* host address */
+#define T_NS 2 /* authoritative server */
+#define T_MD 3 /* mail destination */
+#define T_MF 4 /* mail forwarder */
+#define T_CNAME 5 /* connonical name */
+#define T_SOA 6 /* start of authority zone */
+#define T_MB 7 /* mailbox domain name */
+#define T_MG 8 /* mail group member */
+#define T_MR 9 /* mail rename name */
+#define T_NULL 10 /* null resource record */
+#define T_WKS 11 /* well known service */
+#define T_PTR 12 /* domain name pointer */
+#define T_HINFO 13 /* host information */
+#define T_MINFO 14 /* mailbox information */
+#define T_MX 15 /* mail routing information */
+#define T_TXT 16 /* text strings */
+ /* non standard */
+#define T_UINFO 100 /* user (finger) information */
+#define T_UID 101 /* user ID */
+#define T_GID 102 /* group ID */
+#define T_UNSPEC 103 /* Unspecified format (binary data) */
+ /* Query type values which do not appear in resource records */
+#define T_AXFR 252 /* transfer zone of authority */
+#define T_MAILB 253 /* transfer mailbox records */
+#define T_MAILA 254 /* transfer mail agent records */
+#define T_ANY 255 /* wildcard match */
+
+/*
+ * Values for class field
+ */
+
+#define C_IN 1 /* the arpa internet */
+#define C_CHAOS 3 /* for chaos net at MIT */
+#define C_HS 4 /* for Hesiod name server at MIT */
+ /* Query class values which do not appear in resource records */
+#define C_ANY 255 /* wildcard match */
+
+/*
+ * Status return codes for T_UNSPEC conversion routines
+ */
+#define CONV_SUCCESS 0
+#define CONV_OVERFLOW -1
+#define CONV_BADFMT -2
+#define CONV_BADCKSUM -3
+#define CONV_BADBUFLEN -4
+
+#ifndef BYTE_ORDER
+#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */
+#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
+#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */
+
+#if defined(vax) || defined(ns32000) || defined(sun386) || defined(MIPSEL) || defined(BIT_ZERO_ON_RIGHT)
+#define BYTE_ORDER LITTLE_ENDIAN
+
+#endif
+
+#if defined(THINK_C) && !defined(mc68000) && !defined(powerc)
+#define mc68000
+#endif
+
+#if defined(__MWERKS__) && !defined(mc68000) && !defined(powerc)
+#define mc68000
+#endif
+
+#if defined(sel) || defined(pyr) || defined(mc68000) || defined(powerc) || defined(sparc) || defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || defined(MIPSEB) || defined (BIT_ZERO_ON_LEFT)
+#define BYTE_ORDER BIG_ENDIAN
+#endif
+#endif /* BYTE_ORDER */
+
+#ifndef BYTE_ORDER
+ /* you must determine what the correct bit order is for your compiler */
+ UNDEFINED_BIT_ORDER;
+#endif
+/*
+ * Structure for query header, the order of the fields is machine and
+ * compiler dependent, in our case, the bits within a byte are assignd
+ * least significant first, while the order of transmition is most
+ * significant first. This requires a somewhat confusing rearrangement.
+ */
+
+typedef struct {
+ u_short id; /* query identification number */
+#if BYTE_ORDER == BIG_ENDIAN
+ /* fields in third byte */
+ u_char qr:1; /* response flag */
+ u_char opcode:4; /* purpose of message */
+ u_char aa:1; /* authoritive answer */
+ u_char tc:1; /* truncated message */
+ u_char rd:1; /* recursion desired */
+ /* fields in fourth byte */
+ u_char ra:1; /* recursion available */
+ u_char pr:1; /* primary server required (non standard) */
+ u_char unused:2; /* unused bits */
+ u_char rcode:4; /* response code */
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+ /* fields in third byte */
+ u_char rd:1; /* recursion desired */
+ u_char tc:1; /* truncated message */
+ u_char aa:1; /* authoritive answer */
+ u_char opcode:4; /* purpose of message */
+ u_char qr:1; /* response flag */
+ /* fields in fourth byte */
+ u_char rcode:4; /* response code */
+ u_char unused:2; /* unused bits */
+ u_char pr:1; /* primary server required (non standard) */
+ u_char ra:1; /* recursion available */
+#endif
+ /* remaining bytes */
+ u_short qdcount; /* number of question entries */
+ u_short ancount; /* number of answer entries */
+ u_short nscount; /* number of authority entries */
+ u_short arcount; /* number of resource entries */
+} HEADER;
+
+/*
+ * Defines for handling compressed domain names
+ */
+#define INDIR_MASK 0xc0
+
+/*
+ * Structure for passing resource records around.
+ */
+struct rrec {
+ short r_zone; /* zone number */
+ short r_class; /* class number */
+ short r_type; /* type number */
+ u_long r_ttl; /* time to live */
+ int r_size; /* size of data area */
+ char *r_data; /* pointer to data */
+};
+
+extern u_short _getshort();
+extern u_long _getlong();
+
+/*
+ * Inline versions of get/put short/long.
+ * Pointer is advanced; we assume that both arguments
+ * are lvalues and will already be in registers.
+ * cp MUST be u_char *.
+ */
+#define GETSHORT(s, cp) { \
+ (s) = *(cp)++ << 8; \
+ (s) |= *(cp)++; \
+}
+
+#define GETLONG(l, cp) { \
+ (l) = *(cp)++ << 8; \
+ (l) |= *(cp)++; (l) <<= 8; \
+ (l) |= *(cp)++; (l) <<= 8; \
+ (l) |= *(cp)++; \
+}
+
+
+#define PUTSHORT(s, cp) { \
+ *(cp)++ = (s) >> 8; \
+ *(cp)++ = (s); \
+}
+
+/*
+ * Warning: PUTLONG destroys its first argument.
+ */
+#define PUTLONG(l, cp) { \
+ (cp)[3] = l; \
+ (cp)[2] = (l >>= 8); \
+ (cp)[1] = (l >>= 8); \
+ (cp)[0] = l >> 8; \
+ (cp) += sizeof(u_long); \
+}
diff --git a/network/ncsasock/a_telnet.h b/network/ncsasock/a_telnet.h
new file mode 100644
index 00000000..8a4b3c2b
--- /dev/null
+++ b/network/ncsasock/a_telnet.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted provided
+ * that: (1) source distributions retain this entire copyright notice and
+ * comment, and (2) distributions including binaries display the following
+ * acknowledgement: ``This product includes software developed by the
+ * University of California, Berkeley and its contributors'' in the
+ * documentation or other materials provided with the distribution and in
+ * all advertising materials mentioning features or use of this software.
+ * Neither the name of the University nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)telnet.h 5.10 (Berkeley) 6/28/90
+*
+*
+* RCS Modification History:
+* $Log: a_telnet.h,v $
+* Revision 6.0 1997/08/25 18:37:22 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:56:32 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Definitions for the TELNET protocol.
+ */
+#define IAC 255 /* interpret as command: */
+#define DONT 254 /* you are not to use option */
+#define DO 253 /* please, you use option */
+#define WONT 252 /* I won't use option */
+#define WILL 251 /* I will use option */
+#define SB 250 /* interpret as subnegotiation */
+#define GA 249 /* you may reverse the line */
+#define EL 248 /* erase the current line */
+#define EC 247 /* erase the current character */
+#define AYT 246 /* are you there */
+#define AO 245 /* abort output--but let prog finish */
+#define IP 244 /* interrupt process--permanently */
+#define BREAK 243 /* break */
+#define DM 242 /* data mark--for connect. cleaning */
+#define NOP 241 /* nop */
+#define SE 240 /* end sub negotiation */
+#define EOR 239 /* end of record (transparent mode) */
+#define ABORT 238 /* Abort process */
+#define SUSP 237 /* Suspend process */
+#define xEOF 236 /* End of file: EOF is already used... */
+
+#define SYNCH 242 /* for telfunc calls */
+
+#ifdef TELCMDS
+char *telcmds[] = {
+ "EOF", "SUSP", "ABORT", "EOR",
+ "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
+ "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",
+};
+#define TELCMD_FIRST xEOF
+#define TELCMD_LAST IAC
+#define TELCMD_OK(x) ((x) <= TELCMD_LAST && (x) >= TELCMD_FIRST)
+#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
+#endif
+
+/* telnet options */
+#define TELOPT_BINARY 0 /* 8-bit data path */
+#define TELOPT_ECHO 1 /* echo */
+#define TELOPT_RCP 2 /* prepare to reconnect */
+#define TELOPT_SGA 3 /* suppress go ahead */
+#define TELOPT_NAMS 4 /* approximate message size */
+#define TELOPT_STATUS 5 /* give status */
+#define TELOPT_TM 6 /* timing mark */
+#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
+#define TELOPT_NAOL 8 /* negotiate about output line width */
+#define TELOPT_NAOP 9 /* negotiate about output page size */
+#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
+#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
+#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
+#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
+#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
+#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
+#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
+#define TELOPT_XASCII 17 /* extended ascic character set */
+#define TELOPT_LOGOUT 18 /* force logout */
+#define TELOPT_BM 19 /* byte macro */
+#define TELOPT_DET 20 /* data entry terminal */
+#define TELOPT_SUPDUP 21 /* supdup protocol */
+#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
+#define TELOPT_SNDLOC 23 /* send location */
+#define TELOPT_TTYPE 24 /* terminal type */
+#define TELOPT_EOR 25 /* end or record */
+#define TELOPT_TUID 26 /* TACACS user identification */
+#define TELOPT_OUTMRK 27 /* output marking */
+#define TELOPT_TTYLOC 28 /* terminal location number */
+#define TELOPT_3270REGIME 29 /* 3270 regime */
+#define TELOPT_X3PAD 30 /* X.3 PAD */
+#define TELOPT_NAWS 31 /* window size */
+#define TELOPT_TSPEED 32 /* terminal speed */
+#define TELOPT_LFLOW 33 /* remote flow control */
+#define TELOPT_LINEMODE 34 /* Linemode option */
+#define TELOPT_XDISPLOC 35 /* X Display Location */
+#define TELOPT_ENVIRON 36 /* Environment variables */
+#define TELOPT_AUTHENTICATION 45 /* XXX Auto Authenticate */
+#define TELOPT_EXOPL 255 /* extended-options-list */
+
+#define NTELOPTS (1+TELOPT_AUTHENTICATION)
+#ifdef TELOPTS
+char *telopts[NTELOPTS] = {
+ "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
+ "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
+ "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
+ "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
+ "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
+ "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
+ "TACACS UID", "OUTPUT MARKING", "TTYLOC",
+ "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
+ "LINEMODE", "XDISPLOC", "ENVIRON",
+ "UNKNOWN 37", "UNKNOWN 38", "UNKNOWN 39", "UNKNOWN 40", "UNKNOWN 41",
+ "UNKNOWN 42", "UNKNOWN 43", "UNKNOWN 44", "AUTHENTICATION",
+};
+#define TELOPT_FIRST TELOPT_BINARY
+#define TELOPT_LAST TELOPT_AUTHENTICATION
+#define TELOPT_OK(x) ((x) <= TELOPT_LAST && (x) >= TELOPT_FIRST)
+#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
+#endif
+
+/* sub-option qualifiers */
+#define TELQUAL_IS 0 /* option is... */
+#define TELQUAL_SEND 1 /* send option */
+#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
+
+/*
+ * LINEMODE suboptions
+ */
+
+#define LM_MODE 1
+#define LM_FORWARDMASK 2
+#define LM_SLC 3
+
+#define MODE_EDIT 0x01
+#define MODE_TRAPSIG 0x02
+#define MODE_ACK 0x04
+#define MODE_SOFT_TAB 0x08
+#define MODE_LIT_ECHO 0x10
+
+#define MODE_MASK 0x1f
+
+/* Not part of protocol, but needed to simplify things... */
+#define MODE_FLOW 0x0100
+#define MODE_ECHO 0x0200
+#define MODE_INBIN 0x0400
+#define MODE_OUTBIN 0x0800
+#define MODE_FORCE 0x1000
+
+#define SLC_SYNCH 1
+#define SLC_BRK 2
+#define SLC_IP 3
+#define SLC_AO 4
+#define SLC_AYT 5
+#define SLC_EOR 6
+#define SLC_ABORT 7
+#define SLC_EOF 8
+#define SLC_SUSP 9
+#define SLC_EC 10
+#define SLC_EL 11
+#define SLC_EW 12
+#define SLC_RP 13
+#define SLC_LNEXT 14
+#define SLC_XON 15
+#define SLC_XOFF 16
+#define SLC_FORW1 17
+#define SLC_FORW2 18
+
+#define NSLC 18
+
+#define SLC_NAMES "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
+ "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+ "LNEXT", "XON", "XOFF", "FORW1", "FORW2"
+
+#define SLC_NOSUPPORT 0
+#define SLC_CANTCHANGE 1
+#define SLC_VARIABLE 2
+#define SLC_DEFAULT 3
+#define SLC_LEVELBITS 0x03
+
+#define SLC_FUNC 0
+#define SLC_FLAGS 1
+#define SLC_VALUE 2
+
+#define SLC_ACK 0x80
+#define SLC_FLUSHIN 0x40
+#define SLC_FLUSHOUT 0x20
+
+#define ENV_VALUE 0
+#define ENV_VAR 1
+#define ENV_ESC 2
+
+/*
+ * AUTHENTICATION suboptions
+ */
+
+#define TELQUAL_AUTHTYPE_NONE 0
+#define TELQUAL_AUTHTYPE_PRIVATE 1
+#define TELQUAL_AUTHTYPE_KERBEROS 2
+
+/* Kerberos-specific */
+
+#define TELQUAL_AUTHTYPE_KERBEROS_V4 4
+#define TELQUAL_AUTHTYPE_KERBEROS_V5 5
+#define TELQUAL_AUTHTYPE_KERBEROS_USERNAME 1
diff --git a/network/ncsasock/a_tftp.h b/network/ncsasock/a_tftp.h
new file mode 100644
index 00000000..8fb626f2
--- /dev/null
+++ b/network/ncsasock/a_tftp.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)tftp.h 5.3 (Berkeley) 6/1/90
+*
+*
+* RCS Modification History:
+* $Log: a_tftp.h,v $
+* Revision 6.0 1997/08/25 18:37:24 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:56:35 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Trivial File Transfer Protocol (IEN-133)
+ */
+#define SEGSIZE 512 /* data segment size */
+
+/*
+ * Packet types.
+ */
+#define RRQ 01 /* read request */
+#define WRQ 02 /* write request */
+#define DATA 03 /* data packet */
+#define ACK 04 /* acknowledgement */
+#define ERROR 05 /* error code */
+
+struct tftphdr {
+ short th_opcode; /* packet type */
+ union {
+ short tu_block; /* block # */
+ short tu_code; /* error code */
+ char tu_stuff[1]; /* request packet stuff */
+ } th_u;
+ char th_data[1]; /* data or error string */
+};
+
+#define th_block th_u.tu_block
+#define th_code th_u.tu_code
+#define th_stuff th_u.tu_stuff
+#define th_msg th_data
+
+/*
+ * Error codes.
+ */
+#define EUNDEF 0 /* not defined */
+#define ENOTFOUND 1 /* file not found */
+#define EACCESS 2 /* access violation */
+#define ENOSPACE 3 /* disk full or allocation exceeded */
+#define EBADOP 4 /* illegal TFTP operation */
+#define EBADID 5 /* unknown transfer ID */
+#define EEXISTS 6 /* file already exists */
+#define ENOUSER 7 /* no such user */
diff --git a/network/ncsasock/dprintf.c b/network/ncsasock/dprintf.c
new file mode 100644
index 00000000..93ab68b7
--- /dev/null
+++ b/network/ncsasock/dprintf.c
@@ -0,0 +1,49 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: dprintf.c,v $
+* Revision 6.0 1997/08/25 18:37:25 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.3 1995/06/02 16:29:03 kans
+ * *** empty log message ***
+ *
+ * Revision 1.2 1995/05/17 17:56:38 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * dprintf -
+ * debugging printf. Most of the debugging code is in disrepair, use
+ * with caution.
+ */
+
+#include <stdio.h>
+#include <StdArg.h>
+
+dprintf(char *fmt,...)
+{
+ va_list nextArg;
+
+ va_start(nextArg,fmt);
+
+ (void) vfprintf(stderr,fmt,nextArg);
+ va_end(nextArg); /* this is actually a null macro */
+ return 0;
+}
diff --git a/network/ncsasock/ma_types.h b/network/ncsasock/ma_types.h
new file mode 100644
index 00000000..bc542cc4
--- /dev/null
+++ b/network/ncsasock/ma_types.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)machtypes.h 7.4 (Berkeley) 6/25/90
+*
+*
+* RCS Modification History:
+* $Log: ma_types.h,v $
+* Revision 6.0 1997/08/25 18:37:27 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:56:41 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifndef _MACHTYPES_H_
+#define _MACHTYPES_H_
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _SIZE_T_
+ * typedef _SIZE_T_ size_t;
+ * #undef _SIZE_T_
+ * #endif
+ *
+ * Thanks, ANSI!
+ */
+// #define _CLOCK_T_ unsigned long /* clock() */
+// #define _TIME_T_ long /* time() */ /* in time.h for the mac */
+#define _PTRDIFF_T_ int /* ptr1 - ptr2 */
+#define _SIZE_T_ unsigned int /* sizeof() */
+#define _VA_LIST_ char * /* va_list */
+#define _WCHAR_T_ unsigned short /* wchar_t */
+
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+typedef struct _physadr {
+ int r[1];
+} *physadr;
+typedef struct label_t {
+ int val[14];
+} label_t;
+#endif
+#endif /* _MACHTYPES_H_ */
diff --git a/network/ncsasock/macsockd.h b/network/ncsasock/macsockd.h
new file mode 100644
index 00000000..922b7174
--- /dev/null
+++ b/network/ncsasock/macsockd.h
@@ -0,0 +1,68 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: macsockd.h,v $
+* Revision 6.0 1997/08/25 18:37:28 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:56:44 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Various #defines to make the DTM source compile on a Mac and
+ * use the NCSA socket library. This file written by
+ * Charlie Reiman, NCSA
+ * Wednesday, July 11, 1990 9:18:40 AM
+ *
+ * BE CAREFUL if you use this file, as you can no longer access all of the Mac
+ * Standard C library without extreme difficulty. Well, you might be able to,
+ * but I can't think of a nice 'n easy way to do it.
+ */
+
+#define socket s_socket
+#define bind s_bind
+#define listen s_listen
+#define accept s_accept
+#define connect s_connect
+#define read s_read
+#define recvfrom s_recvfrom
+#define recv s_recv
+#define writev s_writev
+#define write s_write
+#define sendto s_sendto
+#define send s_send
+#define sendmsg s_sendmsg
+#define select s_select
+#define close s_close
+#define getdtablesize s_getdtablesize
+#define getsockname s_getsockname
+#define getpeername s_getpeername
+#define shutdown s_shutdown
+#define fcntl s_fcntl
+#define dup2 s_dup2
+#define dup s_dup
+#define ioctl s_ioctl
+#define setsockopt s_setsockopt
+#define perror s_perror
+
+/*
+ * There is also a s_spinroutine, but there is no unix parallel for this,
+ * so it has no place in this list.
+ */
diff --git a/network/ncsasock/netdb.c b/network/ncsasock/netdb.c
new file mode 100644
index 00000000..adb33f80
--- /dev/null
+++ b/network/ncsasock/netdb.c
@@ -0,0 +1,712 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: netdb.c,v $
+* Revision 6.0 1997/08/25 18:37:31 madden
+* Revision changed to 6.0
+*
+* Revision 4.1 1995/08/01 16:17:20 kans
+* New gethostbyname and gethostbyaddr contributed by Doug Corarito
+*
+ * Revision 4.0 1995/07/26 13:56:09 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.3 1995/05/17 17:56:47 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Internet name routines that every good unix program uses...
+ *
+ * gethostbyname
+ * gethostbyaddr
+ * gethostid
+ * gethostname
+ * getdomainname
+ * inet_addr
+ * inet_ntoa
+ * getservbyname
+ * getprotobyname
+ */
+
+#ifdef USEDUMP
+# pragma load "Socket.dump"
+#else
+# include <Stdio.h>
+# include <Types.h>
+# include <Resources.h>
+# include <Errors.h>
+# include <OSUtils.h>
+
+# include <s_types.h>
+# include <netdb.h>
+# include <neti_in.h>
+# include <s_socket.h>
+# include <s_time.h>
+# include <neterrno.h>
+
+# include "sock_str.h"
+# include "sock_int.h"
+#endif
+
+#include <Ctype.h>
+#include <a_namesr.h>
+#include <s_param.h>
+#include <sock_ext.h>
+
+
+extern SocketPtr sockets;
+extern SpinFn spinroutine;
+pascal void DNRDone(struct hostInfo *hostinfoPtr,Boolean *done);
+
+int h_errno;
+
+/*
+ * Gethostbyname and gethostbyaddr each return a pointer to an
+ * object with the following structure describing an Internet
+ * host referenced by name or by address, respectively. This
+ * structure contains the information obtained from the MacTCP
+ * name server.
+ *
+ * struct hostent
+ * {
+ * char *h_name;
+ * char **h_aliases;
+ * int h_addrtype;
+ * int h_length;
+ * char **h_addr_list;
+ * };
+ * #define h_addr h_addr_list[0]
+ *
+ * The members of this structure are:
+ *
+ * h_name Official name of the host.
+ *
+ * h_aliases A zero terminated array of alternate names for the host.
+ *
+ * h_addrtype The type of address being returned; always AF_INET.
+ *
+ * h_length The length, in bytes, of the address.
+ *
+ * h_addr_list A zero terminated array of network addresses for the host.
+ *
+ * Error return status from gethostbyname and gethostbyaddr is
+ * indicated by return of a null pointer. The external integer
+ * h_errno may then be checked to see whether this is a
+ * temporary failure or an invalid or unknown host. The
+ * routine herror can be used to print an error message
+ * describing the failure. If its argument string is non-NULL,
+ * it is printed, followed by a colon and a space. The error
+ * message is printed with a trailing newline.
+ *
+ * h_errno can have the following values:
+ *
+ * HOST_NOT_FOUND No such host is known.
+ *
+ * TRY_AGAIN This is usually a temporary error and
+ * means that the local server did not
+ * receive a response from an authoritative
+ * server. A retry at some later time may
+ * succeed.
+ *
+ * NO_RECOVERY Some unexpected server failure was encountered.
+ * This is a non-recoverable error.
+ *
+ * NO_DATA The requested name is valid but does not
+ * have an IP address; this is not a
+ * temporary error. This means that the name
+ * is known to the name server but there is
+ * no address associated with this name.
+ * Another type of request to the name server
+ * using this domain name will result in an
+ * answer; for example, a mail-forwarder may
+ * be registered for this domain.
+ * (NOT GENERATED BY THIS IMPLEMENTATION)
+ */
+
+static struct hostInfo macHost;
+
+#define MAXALIASES 0
+static char *aliasPtrs[MAXALIASES+1] = {NULL};
+static ip_addr *addrPtrs[NUM_ALT_ADDRS+1];
+
+static struct hostent unixHost =
+{
+ macHost.cname,
+ aliasPtrs,
+ AF_INET,
+ sizeof(ip_addr),
+ (char **) addrPtrs
+};
+
+#if 0
+struct hostent *
+gethostbyname(char *name)
+{
+ Boolean done;
+ int i;
+ OSErr rsult;
+#ifdef __MACTCP__
+ ResultUPP proc;
+#endif
+
+#if NETDB_DEBUG >= 3
+ dprintf("gethostbyname: '%s'\n",name);
+#endif
+
+ sock_init();
+
+ for (i=0; i<NUM_ALT_ADDRS; i++)
+ macHost.addr[i] = 0;
+ done = false;
+#ifdef __MACTCP__
+ proc = NewResultProc (DNRDone);
+ rsult = StrToAddr(name,&macHost,proc,(char *) &done);
+ DisposeRoutineDescriptor (proc);
+#else
+ rsult = StrToAddr(name,&macHost,(ResultProcPtr) DNRDone,(char *) &done);
+#endif
+ if (rsult == cacheFault)
+ {
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyname: spinning\n");
+#endif
+ SPINP(!done,SP_NAME,0L)
+
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyname: done spinning\n");
+#endif
+ }
+ switch (macHost.rtnCode)
+ {
+ case noErr: break;
+
+ case nameSyntaxErr: h_errno = HOST_NOT_FOUND; return(NULL);
+ case cacheFault: h_errno = NO_RECOVERY; return(NULL);
+ case noResultProc: h_errno = NO_RECOVERY; return(NULL);
+ case noNameServer: h_errno = HOST_NOT_FOUND; return(NULL);
+ case authNameErr: h_errno = HOST_NOT_FOUND; return(NULL);
+ case noAnsErr: h_errno = TRY_AGAIN; return(NULL);
+ case dnrErr: h_errno = NO_RECOVERY; return(NULL);
+ case outOfMemory: h_errno = TRY_AGAIN; return(NULL);
+ case notOpenErr: h_errno = NO_RECOVERY; return(NULL);
+ default: h_errno = NO_RECOVERY; return(NULL);
+ }
+
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyname: name '%s' addrs %08x %08x %08x %08x\n",
+ macHost.cname,
+ macHost.addr[0],macHost.addr[1],
+ macHost.addr[2],macHost.addr[3]);
+#endif
+
+ /* was the 'name' an IP address? */
+ if (macHost.cname[0] == 0)
+ {
+ h_errno = HOST_NOT_FOUND;
+ return(NULL);
+ }
+
+ /* for some reason there is a dot at the end of the name */
+ i = strlen(macHost.cname) - 1;
+ if (macHost.cname[i] == '.')
+ macHost.cname[i] = 0;
+
+ for (i=0; i<NUM_ALT_ADDRS && macHost.addr[i]!=0; i++)
+ {
+ addrPtrs[i] = &macHost.addr[i];
+ }
+ addrPtrs[i] = NULL;
+
+ return(&unixHost);
+}
+
+struct hostent *
+gethostbyaddr(ip_addr *addrP,int len,int type)
+{
+#pragma unused(len)
+#pragma unused(type)
+ Boolean done;
+ int i;
+ OSErr rsult;
+#ifdef __MACTCP__
+ ResultUPP proc;
+#endif
+
+#if NETDB_DEBUG >= 3
+ dprintf("gethostbyaddr: %08x\n",*addrP);
+#endif
+
+ sock_init();
+
+ for (i=0; i<NUM_ALT_ADDRS; i++)
+ macHost.addr[i] = 0;
+ done = false;
+#ifdef __MACTCP__
+ proc = NewResultProc (DNRDone);
+ rsult = AddrToName(*addrP,&macHost,proc,(char *) &done);
+ DisposeRoutineDescriptor (proc);
+#else
+ rsult = AddrToName(*addrP,&macHost,(ResultProcPtr) DNRDone,(char *) &done);
+#endif
+ if (rsult == cacheFault)
+ {
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyaddr: spinning\n");
+#endif
+
+ SPINP(!done,SP_ADDR,0L)
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyaddr: done spinning\n");
+#endif
+ }
+ switch (macHost.rtnCode)
+ {
+ case noErr: break;
+
+ case cacheFault: h_errno = NO_RECOVERY; return(NULL);
+ case noNameServer: h_errno = HOST_NOT_FOUND; return(NULL);
+ case authNameErr: h_errno = HOST_NOT_FOUND; return(NULL);
+ case noAnsErr: h_errno = TRY_AGAIN; return(NULL);
+ case dnrErr: h_errno = NO_RECOVERY; return(NULL);
+ case outOfMemory: h_errno = TRY_AGAIN; return(NULL);
+ case notOpenErr: h_errno = NO_RECOVERY; return(NULL);
+ default: h_errno = NO_RECOVERY; return(NULL);
+ }
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyaddr: name '%s' addrs %08x %08x %08x %08x\n",
+ macHost.cname,
+ macHost.addr[0],macHost.addr[1],
+ macHost.addr[2],macHost.addr[3]);
+#endif
+ /* for some reason there is a dot at the end of the name */
+ i = strlen(macHost.cname) - 1;
+ if (macHost.cname[i] == '.')
+ macHost.cname[i] = 0;
+
+ for (i=0; i<NUM_ALT_ADDRS; i++)
+ {
+ addrPtrs[i] = &macHost.addr[i];
+ }
+ addrPtrs[NUM_ALT_ADDRS] = NULL;
+
+ return(&unixHost);
+}
+#endif
+
+/* New gethostbyname and gethostbyaddr contributed by Doug Corarito */
+
+ struct hostent *
+ gethostbyname(char *name)
+ {
+ Boolean done;
+ int i;
+ OSErr rsult;
+#ifdef __MACTCP__
+ ResultUPP proc = NewResultProc (DNRDone);
+#endif
+
+#if NETDB_DEBUG >= 3
+ dprintf("gethostbyname: '%s'\n",name);
+#endif
+
+ sock_init();
+
+ for (i=0; i<NUM_ALT_ADDRS; i++)
+ macHost.addr[i] = 0;
+ done = false;
+#ifdef __MACTCP__
+ rsult = StrToAddr(name,&macHost,proc,(char *) &done);
+#else
+ rsult = StrToAddr(name,&macHost,(ResultProcPtr) DNRDone,(char *) &done);
+#endif
+ if (rsult == cacheFault)
+ {
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyname: spinning\n");
+#endif
+ SPINP(!done,SP_NAME,0L)
+
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyname: done spinning\n");
+#endif
+ }
+
+#ifdef __MACTCP__
+ DisposeRoutineDescriptor (proc);
+#endif
+
+
+ switch (macHost.rtnCode)
+ {
+ case noErr: break;
+
+ case nameSyntaxErr: h_errno = HOST_NOT_FOUND; return(NULL);
+ case cacheFault: h_errno = NO_RECOVERY; return(NULL);
+ case noResultProc: h_errno = NO_RECOVERY; return(NULL);
+ case noNameServer: h_errno = HOST_NOT_FOUND; return(NULL);
+ case authNameErr: h_errno = HOST_NOT_FOUND; return(NULL);
+ case noAnsErr: h_errno = TRY_AGAIN; return(NULL);
+ case dnrErr: h_errno = NO_RECOVERY; return(NULL);
+ case outOfMemory: h_errno = TRY_AGAIN; return(NULL);
+ case notOpenErr: h_errno = NO_RECOVERY; return(NULL);
+ default: h_errno = NO_RECOVERY; return(NULL);
+ }
+
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyname: name '%s' addrs %08x %08x %08x %08x\n",
+ macHost.cname,
+ macHost.addr[0],macHost.addr[1],
+ macHost.addr[2],macHost.addr[3]);
+#endif
+
+ /* was the 'name' an IP address? */
+ if (macHost.cname[0] == 0)
+ {
+ h_errno = HOST_NOT_FOUND;
+ return(NULL);
+ }
+
+ /* for some reason there is a dot at the end of the name */
+ i = strlen(macHost.cname) - 1;
+ if (macHost.cname[i] == '.')
+ macHost.cname[i] = 0;
+
+ for (i=0; i<NUM_ALT_ADDRS && macHost.addr[i]!=0; i++)
+ {
+ addrPtrs[i] = &macHost.addr[i];
+ }
+ addrPtrs[i] = NULL;
+
+ return(&unixHost);
+ }
+
+ struct hostent *
+ gethostbyaddr(ip_addr *addrP,int len,int type)
+ {
+#pragma unused(len)
+#pragma unused(type)
+ Boolean done;
+ int i;
+ OSErr rsult;
+#ifdef __MACTCP__
+ ResultUPP proc = NewResultProc (DNRDone);
+#endif
+
+#if NETDB_DEBUG >= 3
+ dprintf("gethostbyaddr: %08x\n",*addrP);
+#endif
+
+ sock_init();
+
+ for (i=0; i<NUM_ALT_ADDRS; i++)
+ macHost.addr[i] = 0;
+ done = false;
+#ifdef __MACTCP__
+ rsult = AddrToName(*addrP,&macHost,proc,(char *) &done);
+ #else
+ rsult = AddrToName(*addrP,&macHost,(ResultProcPtr) DNRDone,(char *)
+&done);
+#endif
+ if (rsult == cacheFault)
+ {
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyaddr: spinning\n");
+#endif
+
+ SPINP(!done,SP_ADDR,0L)
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyaddr: done spinning\n");
+#endif
+ }
+
+#ifdef __MACTCP__
+ DisposeRoutineDescriptor (proc);
+#endif
+
+ switch (macHost.rtnCode)
+ {
+ case noErr: break;
+
+ case cacheFault: h_errno = NO_RECOVERY; return(NULL);
+ case noNameServer: h_errno = HOST_NOT_FOUND; return(NULL);
+ case authNameErr: h_errno = HOST_NOT_FOUND; return(NULL);
+ case noAnsErr: h_errno = TRY_AGAIN; return(NULL);
+ case dnrErr: h_errno = NO_RECOVERY; return(NULL);
+ case outOfMemory: h_errno = TRY_AGAIN; return(NULL);
+ case notOpenErr: h_errno = NO_RECOVERY; return(NULL);
+ default: h_errno = NO_RECOVERY; return(NULL);
+ }
+#if NETDB_DEBUG >= 5
+ dprintf("gethostbyaddr: name '%s' addrs %08x %08x %08x %08x\n",
+ macHost.cname,
+ macHost.addr[0],macHost.addr[1],
+ macHost.addr[2],macHost.addr[3]);
+#endif
+ /* for some reason there is a dot at the end of the name */
+ i = strlen(macHost.cname) - 1;
+ if (macHost.cname[i] == '.')
+ macHost.cname[i] = 0;
+
+ for (i=0; i<NUM_ALT_ADDRS; i++)
+ {
+ addrPtrs[i] = &macHost.addr[i];
+ }
+ addrPtrs[NUM_ALT_ADDRS] = NULL;
+
+ return(&unixHost);
+ }
+
+/* End of new gethostbyname and gethostbyaddr code */
+
+char *
+inet_ntoa(ip_addr inaddr)
+{
+ sock_init();
+
+ (void) AddrToStr(inaddr,macHost.cname);
+ return(macHost.cname);
+}
+
+ip_addr
+inet_addr(char *address)
+{
+#ifndef JAE
+OSErr retval;
+#endif
+ sock_init();
+#ifndef JAE
+ if ((retval = StrToAddr(address,&macHost,NULL,NULL)) != noErr)
+#else
+
+
+ if (StrToAddr(address,&macHost,NULL,NULL) != noErr)
+#endif
+ return((ip_addr)-1);
+
+#if NETDB_DEBUG >= 5
+ dprintf("inet_addr: name '%s' addr %08x\n",
+ macHost.cname,macHost.addr[0]);
+#endif
+
+ /* was the 'address' really a name? */
+ if (macHost.cname[0] != 0)
+ return((ip_addr)-1);
+
+ return(macHost.addr[0]);
+}
+
+/*
+ * gethostid()
+ *
+ * Get Internet address. If the application can get by with just
+ * this, it avoids the muss and fuss of DNR.
+ */
+
+unsigned long gethostid()
+{
+ ip_addr ipaddr;
+
+ ipaddr = xIPAddr();
+
+ return ((unsigned long) ipaddr);
+}
+
+/*
+ * gethostname()
+ *
+ * Try to get my host name from DNR. If it fails, just return my
+ * IP address as ASCII. This is non-standard, but it's a mac,
+ * what do you want me to do?
+ */
+
+gethostname( machname, buflen)
+ char *machname;
+ long buflen;
+{
+ ip_addr ipaddr;
+ struct hostent *hp;
+
+#if NETDB_DEBUG >= 3
+ dprintf("gethostname: \n");
+#endif
+
+ sock_init(); /* initialize the socket stuff. */
+ ipaddr = xIPAddr();
+ hp = gethostbyaddr( &ipaddr, sizeof(ip_addr), AF_INET);
+ if( hp == NULL)
+ sprintf (machname, "%d.%d.%d.%d",ipaddr>>24,
+ ipaddr>>16 & 0xff,
+ ipaddr>>8 & 0xff,
+ ipaddr & 0xff);
+ else
+ strncpy( machname, hp->h_name, buflen);
+
+ machname[buflen-1] = 0; /* extra safeguard */
+ return(0);
+}
+
+
+/*
+ * getservbybname()
+ *
+ * Real kludgy. Should at least consult a resource file as the service
+ * database.
+ */
+typedef struct services {
+ char sv_name[12];
+ short sv_number;
+ char sv_protocol[5];
+} services_t, *services_p;
+
+static struct services slist[] =
+{
+ {"echo", 7, "udp"},
+ {"discard", 9, "udp"},
+ {"time", 37, "udp"},
+ {"domain", 53, "udp"},
+ {"sunrpc", 111, "udp"},
+ {"tftp", 69, "udp"},
+ {"biff", 512, "udp"},
+ {"who", 513, "udp"},
+ {"talk", 517, "udp"},
+ {"route", 520, "udp"},
+ {"new-rwho", 550, "udp"},
+ {"netstat", 15, "tcp"},
+ {"ftp-data", 20, "tcp"},
+ {"ftp", 21, "tcp"},
+ {"telnet", 23, "tcp"},
+ {"smtp", 25, "tcp"},
+ {"time", 37, "tcp"},
+ {"whois", 43, "tcp"},
+ {"domain", 53, "tcp"},
+ {"hostnames", 101, "tcp"},
+ {"nntp", 119, "tcp"},
+ {"finger", 79, "tcp"},
+ {"uucp-path", 117, "tcp"},
+ {"untp", 119, "tcp"},
+ {"ntp", 123, "tcp"},
+ {"exec", 512, "tcp"},
+ {"login", 513, "tcp"},
+ {"shell", 514, "tcp"},
+ {"printer", 515, "tcp"},
+ {"courier", 530, "tcp"},
+ {"uucp", 540, "tcp"},
+ {"", 0, "" }
+};
+
+#define MAX_SERVENT 10
+static struct servent servents[MAX_SERVENT];
+static int servent_count=0;
+
+struct servent *
+getservbyname (name, proto)
+char *name, *proto;
+{
+ int i;
+ struct servent *se;
+
+ if (strcmp (proto, "udp") == 0 || strcmp (proto, "tcp") == 0)
+ {
+ for (i=0; slist[i].sv_number != 0; i++)
+ if (strcmp (slist[i].sv_name, name) == 0)
+ if (strcmp (slist[i].sv_protocol, proto) == 0)
+ {
+ se = &servents[servent_count];
+ se->s_name = slist[i].sv_name;
+ se->s_aliases = NULL;
+ se->s_port = slist[i].sv_number;
+ se->s_proto = slist[i].sv_protocol;
+ servent_count = (servent_count +1) % MAX_SERVENT;
+ return (se);
+ }
+ return (NULL);
+ }
+ else
+ {
+ errno = errno_long = EPROTONOSUPPORT;
+ return(NULL);
+ }
+}
+
+static char tcp[] = "tcp";
+static char udp[] = "udp";
+#define MAX_PROTOENT 10
+static struct protoent protoents[MAX_PROTOENT];
+static int protoent_count=0;
+struct protoent *
+getprotobyname (name)
+char *name;
+{
+ struct protoent *pe;
+
+ pe = &protoents[protoent_count];
+ if (strcmp (name, "udp") == 0)
+ {
+ pe->p_name = udp;
+ pe->p_proto = IPPROTO_UDP;
+ }
+ else if (strcmp (name, "tcp") == 0)
+ {
+ pe->p_name = tcp;
+ pe->p_proto = IPPROTO_TCP;
+ }
+ else
+ {
+ errno = errno_long = EPROTONOSUPPORT;
+ return(NULL);
+ }
+ pe->p_aliases = NULL;
+ protoent_count = (protoent_count +1) % MAX_PROTOENT;
+ return (pe);
+}
+
+char *h_errlist[] =
+{
+ "Error 0",
+ "Unknown host", /* 1 HOST_NOT_FOUND */
+ "Host name lookup failure", /* 2 TRY_AGAIN */
+ "Unknown server error", /* 3 NO_RECOVERY */
+ "No address associated with name", /* 4 NO_ADDRESS */
+};
+
+const int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) };
+
+void herror(char *s)
+ {
+ fprintf(stderr,"%s: ",s);
+ if (h_errno < h_nerr)
+ fprintf(stderr,h_errlist[h_errno]);
+ else
+ fprintf(stderr,"error %d",h_errno);
+ fprintf(stderr,"\n");
+ }
+
+char *herror_str(int theErr) {
+ if (theErr > h_nerr )
+ return NULL;
+ else
+ return h_errlist[theErr];
+ }
+
+#pragma segment SOCK_RESIDENT
+pascal void DNRDone(hostinfoPtr,done)
+ struct hostInfo *hostinfoPtr;
+ Boolean *done;
+{
+#pragma unused(hostinfoPtr)
+ *done = true;
+}
diff --git a/network/ncsasock/netdb.h b/network/ncsasock/netdb.h
new file mode 100644
index 00000000..fd1361c3
--- /dev/null
+++ b/network/ncsasock/netdb.h
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 1980, 1983, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)netdb.h 5.11 (Berkeley) 5/21/90
+*
+*
+* RCS Modification History:
+* $Log: netdb.h,v $
+* Revision 6.0 1997/08/25 18:37:33 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:56:51 epstein
+ * add RCS log revision history
+ *
+ */
+
+#define _PATH_HEQUIV "/etc/hosts.equiv"
+#define _PATH_HOSTS "/etc/hosts"
+#define _PATH_NETWORKS "/etc/networks"
+#define _PATH_PROTOCOLS "/etc/protocols"
+#define _PATH_SERVICES "/etc/services"
+
+/*
+ * Structures returned by network data base library. All addresses are
+ * supplied in host order, and returned in network order (suitable for
+ * use in system calls).
+ */
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ Int4 h_addrtype; /* host address type */
+ Int4 h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+#define h_addr h_addr_list[0] /* address, for backward compatiblity */
+};
+
+/*
+ * Assumption here is that a network number
+ * fits in 32 bits -- probably a poor one.
+ */
+struct netent {
+ char *n_name; /* official name of net */
+ char **n_aliases; /* alias list */
+ Int4 n_addrtype; /* net address type */
+ unsigned long n_net; /* network # */
+};
+
+struct servent {
+ char *s_name; /* official service name */
+ char **s_aliases; /* alias list */
+ Int4 s_port; /* port # */
+ char *s_proto; /* protocol to use */
+};
+
+struct protoent {
+ char *p_name; /* official protocol name */
+ char **p_aliases; /* alias list */
+ Int4 p_proto; /* protocol # */
+};
+
+struct hostent *gethostbyname(), *gethostbyaddr(), *gethostent();
+struct netent *getnetbyname(), *getnetbyaddr(), *getnetent();
+struct servent *getservbyname(char *name, char *proto), *getservbyport(), *getservent();
+struct protoent *getprotobyname(), *getprotobynumber(), *getprotoent();
+unsigned long gethostid(void);
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
diff --git a/network/ncsasock/neterrno.h b/network/ncsasock/neterrno.h
new file mode 100644
index 00000000..185892e4
--- /dev/null
+++ b/network/ncsasock/neterrno.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)errno.h 7.10 (Berkeley) 6/28/90
+*
+*
+* RCS Modification History:
+* $Log: neterrno.h,v $
+* Revision 6.1 1997/10/19 23:15:59 kans
+* latest CodeWarrior needs EACCES defined here
+*
+* Revision 6.0 1997/08/25 18:37:34 madden
+* Revision changed to 6.0
+*
+* Revision 4.1 1997/01/28 22:35:23 kans
+* new symbol collisions in CodeWarrior fixed
+*
+ * Revision 4.0 1995/07/26 13:56:09 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.3 1995/05/17 17:56:54 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifndef _NETERRNO_
+#define _NETERRNO_
+
+#ifndef KERNEL
+extern int errno; /* global error number */
+extern long errno_long; /* same as errno, but of known length (for variable length ints) */
+#endif
+
+#include <errno.h>
+
+#ifdef __MWERKS__
+#define EPERM 1 /* Operation not permitted */
+/*#define ENOENT 2*/ /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* Input/output error */
+#endif /* __MWERKS__ */
+
+#ifndef ENXIO
+#define ENXIO 6 /* Device not configured */
+#endif /* ENXIO */
+
+#ifdef __MWERKS__
+#define E2BIG 7 /* Argument list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file descriptor */
+#define ECHILD 10 /* No child processes */
+#define EDEADLK 11 /* Resource deadlock avoided */
+ /* 11 was EAGAIN */
+#endif /* __MWERKS__ */
+
+#ifndef ENOMEM
+#define ENOMEM 12 /* Cannot allocate memory */
+#endif /* ENOMEM */
+
+#ifdef __MWERKS__
+#define EACCES 13 /* Permission denied */
+#endif /* __MWERKS__ */
+
+#ifndef EFAULT
+#define EFAULT 14 /* Bad address */
+#endif /* EFAULT */
+
+#ifdef __MWERKS__
+#ifndef _POSIX_SOURCE
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device busy */
+#endif
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* Operation not supported by device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* Too many open files in system */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Inappropriate ioctl for device */
+#ifndef _POSIX_SOURCE
+#define ETXTBSY 26 /* Text file busy */
+#endif
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+
+#endif /* __MWERKS__ */
+
+#ifdef NOWAY
+/* math software */
+#define EDOM 33 /* Numerical argument out of domain */
+#define ERANGE 34 /* Numerical result out of range */
+#endif /* NOWAY */
+
+/* non-blocking and interrupt i/o */
+#define EAGAIN 35 /* Resource temporarily unavailable */
+#ifndef _POSIX_SOURCE
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define EINPROGRESS 36 /* Operation now in progress */
+#define EALREADY 37 /* Operation already in progress */
+
+/* ipc/network software -- argument errors */
+#define ENOTSOCK 38 /* Socket operation on non-socket */
+#define EDESTADDRREQ 39 /* Destination address required */
+#define EMSGSIZE 40 /* Message too long */
+#define EPROTOTYPE 41 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 42 /* Protocol not available */
+#define EPROTONOSUPPORT 43 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
+#define EOPNOTSUPP 45 /* Operation not supported on socket */
+#define EPFNOSUPPORT 46 /* Protocol family not supported */
+#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
+#define EADDRINUSE 48 /* Address already in use */
+#define EADDRNOTAVAIL 49 /* Can't assign requested address */
+
+/* ipc/network software -- operational errors */
+#define ENETDOWN 50 /* Network is down */
+#define ENETUNREACH 51 /* Network is unreachable */
+#define ENETRESET 52 /* Network dropped connection on reset */
+#define ECONNABORTED 53 /* Software caused connection abort */
+#define ECONNRESET 54 /* Connection reset by peer */
+#define ENOBUFS 55 /* No buffer space available */
+#define EISCONN 56 /* Socket is already connected */
+#define ENOTCONN 57 /* Socket is not connected */
+#define ESHUTDOWN 58 /* Can't send after socket shutdown */
+#define ETOOMANYREFS 59 /* Too many references: can't splice */
+#define ETIMEDOUT 60 /* Connection timed out */
+#define ECONNREFUSED 61 /* Connection refused */
+
+#define ELOOP 62 /* Too many levels of symbolic links */
+#endif /* _POSIX_SOURCE */
+#define ENAMETOOLONG 63 /* File name too long */
+
+/* should be rearranged */
+#ifndef _POSIX_SOURCE
+#define EHOSTDOWN 64 /* Host is down */
+#define EHOSTUNREACH 65 /* No route to host */
+#endif /* _POSIX_SOURCE */
+#define ENOTEMPTY 66 /* Directory not empty */
+
+/* quotas & mush */
+#ifndef _POSIX_SOURCE
+#define EPROCLIM 67 /* Too many processes */
+#define EUSERS 68 /* Too many users */
+#define EDQUOT 69 /* Disc quota exceeded */
+
+/* Network File System */
+#define ESTALE 70 /* Stale NFS file handle */
+#define EREMOTE 71 /* Too many levels of remote in path */
+#define EBADRPC 72 /* RPC struct is bad */
+#define ERPCMISMATCH 73 /* RPC version wrong */
+#define EPROGUNAVAIL 74 /* RPC prog. not avail */
+#define EPROGMISMATCH 75 /* Program version wrong */
+#define EPROCUNAVAIL 76 /* Bad procedure for program */
+#endif /* _POSIX_SOURCE */
+
+#define ENOLCK 77 /* No locks available */
+#ifdef ENOSYS
+#undef ENOSYS
+#endif
+#define ENOSYS 78 /* Function not implemented */
+
+#ifdef KERNEL
+/* pseudo-errors returned inside kernel to modify return to process */
+#define ERESTART -1 /* restart syscall */
+#define EJUSTRETURN -2 /* don't modify regs, just return */
+#endif
+
+#endif /* defined _NETERRNO_ */
+
diff --git a/network/ncsasock/neti_in.h b/network/ncsasock/neti_in.h
new file mode 100644
index 00000000..542ad247
--- /dev/null
+++ b/network/ncsasock/neti_in.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1982, 1986, 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)in.h 7.10 (Berkeley) 6/28/90
+*
+*
+* RCS Modification History:
+* $Log: neti_in.h,v $
+* Revision 6.0 1997/08/25 18:37:36 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:56:57 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Constants and structures defined by the internet system,
+ * Per RFC 790, September 1981.
+ */
+
+/*
+ * Protocols
+ */
+#define IPPROTO_IP 0 /* dummy for IP */
+#define IPPROTO_ICMP 1 /* control message protocol */
+#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */
+#define IPPROTO_TCP 6 /* tcp */
+#define IPPROTO_EGP 8 /* exterior gateway protocol */
+#define IPPROTO_PUP 12 /* pup */
+#define IPPROTO_UDP 17 /* user datagram protocol */
+#define IPPROTO_IDP 22 /* xns idp */
+#define IPPROTO_TP 29 /* tp-4 w/ class negotiation */
+#define IPPROTO_EON 80 /* ISO cnlp */
+
+#define IPPROTO_RAW 255 /* raw IP packet */
+#define IPPROTO_MAX 256
+
+
+/*
+ * Local port number conventions:
+ * Ports < IPPORT_RESERVED are reserved for
+ * privileged processes (e.g. root).
+ * Ports > IPPORT_USERRESERVED are reserved
+ * for servers, not necessarily privileged.
+ */
+#define IPPORT_RESERVED 1024
+#define IPPORT_USERRESERVED 5000
+
+/*
+ * Internet address (a structure for historical reasons)
+ */
+struct in_addr {
+ u_long s_addr;
+};
+
+/*
+ * Definitions of bits in internet address integers.
+ * On subnets, the decomposition of addresses to host and net parts
+ * is done according to subnet mask, not the masks here.
+ */
+#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST 0x00ffffff
+#define IN_CLASSA_MAX 128
+
+#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST 0x0000ffff
+#define IN_CLASSB_MAX 65536
+
+#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST 0x000000ff
+
+#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
+#define IN_MULTICAST(i) IN_CLASSD(i)
+
+#define IN_EXPERIMENTAL(i) (((long)(i) & 0xe0000000) == 0xe0000000)
+#define IN_BADCLASS(i) (((long)(i) & 0xf0000000) == 0xf0000000)
+
+#define INADDR_ANY (u_long)0x00000000
+#define INADDR_BROADCAST (u_long)0xffffffff /* must be masked */
+#ifndef KERNEL
+#define INADDR_NONE 0xffffffff /* -1 return */
+#endif
+
+#define IN_LOOPBACKNET 127 /* official! */
+
+/*
+ * Socket address, internet style.
+ */
+struct sockaddr_in {
+ u_char sin_len;
+ u_char sin_family;
+ u_short sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+};
+
+/*
+ * Structure used to describe IP options.
+ * Used to store options internally, to pass them to a process,
+ * or to restore options retrieved earlier.
+ * The ip_dst is used for the first-hop gateway when using a source route
+ * (this gets put into the header proper).
+ */
+struct ip_opts {
+ struct in_addr ip_dst; /* first hop, 0 w/o src rt */
+ char ip_opts[40]; /* actually variable in size */
+};
+
+/*
+ * Options for use with [gs]etsockopt at the IP level.
+ * First word of comment is data type; bool is stored in int.
+ */
+#define IP_OPTIONS 1 /* buf/ip_opts; set/get IP per-packet options */
+#define IP_HDRINCL 2 /* int; header is included with data (raw) */
+#define IP_TOS 3 /* int; IP type of service and precedence */
+#define IP_TTL 4 /* int; IP time to live */
+#define IP_RECVOPTS 5 /* bool; receive all IP options w/datagram */
+#define IP_RECVRETOPTS 6 /* bool; receive IP options for response */
+#define IP_RECVDSTADDR 7 /* bool; receive IP dst addr w/datagram */
+#define IP_RETOPTS 8 /* ip_opts; set/get IP per-packet options */
+
+//
+// The network macros are in machine/endian.h for 4.3reno, but for
+// sun compatibility, I placed them here- Charlie Reiman
+//
+#define ntohl(x) x
+#define ntohs(x) x
+#define htonl(x) x
+#define htons(x) x
+
+#ifdef KERNEL
+extern struct domain inetdomain;
+extern struct protosw inetsw[];
+struct in_addr in_makeaddr();
+u_long in_netof(), in_lnaof();
+#endif
diff --git a/network/ncsasock/neti_tcp.h b/network/ncsasock/neti_tcp.h
new file mode 100644
index 00000000..20a853bc
--- /dev/null
+++ b/network/ncsasock/neti_tcp.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)tcp.h 7.7 (Berkeley) 6/28/90
+*
+*
+* RCS Modification History:
+* $Log: neti_tcp.h,v $
+* Revision 6.0 1997/08/25 18:37:38 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:00 epstein
+ * add RCS log revision history
+ *
+ */
+
+typedef u_long tcp_seq;
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+ u_short th_sport; /* source port */
+ u_short th_dport; /* destination port */
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_char th_x2:4, /* (unused) */
+ th_off:4; /* data offset */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_char th_off:4, /* data offset */
+ th_x2:4; /* (unused) */
+#endif
+ u_char th_flags;
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+ u_short th_win; /* window */
+ u_short th_sum; /* checksum */
+ u_short th_urp; /* urgent pointer */
+};
+
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+
+/*
+ * Default maximum segment size for TCP.
+ * With an IP MSS of 576, this is 536,
+ * but 512 is probably more convenient.
+ * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
+ */
+#define TCP_MSS 512
+
+#define TCP_MAXWIN 65535 /* largest value for window */
+
+/*
+ * User-settable options (used with setsockopt).
+ */
+#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
+#define TCP_MAXSEG 0x02 /* set maximum segment size */
diff --git a/network/ncsasock/rexec.c b/network/ncsasock/rexec.c
new file mode 100644
index 00000000..ee5de8be
--- /dev/null
+++ b/network/ncsasock/rexec.c
@@ -0,0 +1,242 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: rexec.c,v $
+* Revision 6.0 1997/08/25 18:37:39 madden
+* Revision changed to 6.0
+*
+* Revision 4.1 1997/01/29 00:12:00 kans
+* include <MacTCP.h> instead of obsolete <MacTCPCommonTypes.h>
+*
+ * Revision 4.0 1995/07/26 13:56:09 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.3 1995/06/02 16:29:03 kans
+ * *** empty log message ***
+ *
+ * Revision 1.2 1995/05/17 17:57:03 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * rexec.c
+ * Mac implimentation of rexec. Uses NCSA MacTCP sockets.
+ * Written by Charlie Reiman - Tom actually had nothing to do with this file
+ * Started Friday, July 13, 1990 10:04:33 AM
+ */
+
+# include <Events.h>
+# include <Types.h>
+# include <Stdio.h>
+
+# include <s_types.h>
+# include <netdb.h>
+# include <neti_in.h>
+# include <s_socket.h>
+# include <s_time.h>
+# include <neterrno.h>
+# include <string.h>
+
+# include <MacTCP.h>
+
+#include "rexec.h"
+#include "sock_ext.h" /* uses only high level calls */
+
+#define BUFZ 256
+
+#ifndef min
+#define min(a,b) ( ( a < b ) ? a : b )
+#endif
+
+#define NIL NULL
+#define DOERR if ( anErr < 0 ) return anErr;
+
+extern int errno;
+
+
+int rexec(
+ char **ahost,
+ Int4 inport,
+ char *user,
+ char *passwd,
+ char *cmd,
+ int *fd2p)
+
+ {
+ struct hostent *hp;
+ struct sockaddr_in sa,me,her;
+ int sockOut;
+ int anErr; /* an error? */
+ Int4 herlen = sizeof(her),melen;
+ char wbuf[BUFZ];
+
+
+ hp=gethostbyname(*ahost);
+
+
+ if ( hp == NULL )
+ {
+ int a,b,c,d;
+
+ if ( sscanf(*ahost,"%d.%d.%d.%d",&a,&b,&c,&d) != 4 )
+ {
+ errno = errno_long = EHOSTUNREACH;
+ return -1;
+ }
+ else
+ {
+ herlen = (a<<24) | ( b<<16) | (c<<8) | (d);
+ bcopy((char *) &herlen,(char *) &sa.sin_addr,4);
+ }
+ }
+ else
+ bcopy((char *) hp->h_addr,(char *) &sa.sin_addr,hp->h_length);
+
+
+ sa.sin_port=htons(inport);
+ sa.sin_family=AF_INET;
+
+ sockOut=s_socket(AF_INET,SOCK_STREAM,0);
+
+ if (sockOut<0)
+ {
+ return -1;
+ }
+
+ if (s_connect(sockOut,(struct sockaddr *)&sa,sizeof(sa))<0)
+ {
+ return -1;
+ }
+
+ if (fd2p)
+ {
+ /* create listening socket */
+ *fd2p=s_socket(AF_INET,SOCK_STREAM,0);
+
+ bzero((char *)&me, sizeof(me));
+ me.sin_family = AF_INET;
+ me.sin_port = htons(0); /* any port */
+
+ if (s_bind(*fd2p, (struct sockaddr *)&me, sizeof(me) ) < 0)
+ {
+ return -1;
+ }
+
+ if (s_listen(*fd2p,1) < 0)
+ {
+ /*
+ * s_listen is the routine that actuall puts the correct
+ * IP address to the socket. Up to this point, the socket
+ * has had an address of 0, port 0.
+ */
+ return -1;
+ }
+ /*
+ * Now we must fetch the number of the port so we can tell
+ * the rexecd where to find us.
+ */
+ melen=sizeof(me);
+ s_getsockname(*fd2p, (struct sockaddr *)&me , &melen);
+ sprintf(wbuf,"%d\0",(long)me.sin_port); /* tell rexec where to hook up to */
+ }
+ else
+ *wbuf='\0'; /* pass an empty string for no stderr port */
+
+ anErr = s_write (sockOut,wbuf,strlen(wbuf)+1); /* write out string */
+
+ DOERR
+
+ if (fd2p) /* do we need to accept? */
+ {
+ struct timeval selectPoll;
+ fd_set readfds;
+
+ selectPoll.tv_sec=60; /* block for one minute */
+ selectPoll.tv_usec=0;
+ FD_ZERO(&readfds);
+ FD_SET(*fd2p,&readfds); /* only looking for connect on one socket */
+
+ anErr = s_select(32, &readfds, (fd_set *)0,
+ (fd_set *)0, &selectPoll);
+
+ if (anErr < 1 )
+ return -1;
+
+ anErr = s_accept_once(*fd2p,(struct sockaddr *)&her,&herlen);
+ /*
+ * might want to check and make sure that the connected machine
+ * is the right one, but that seems a bit execessive.
+ */
+ DOERR
+
+ }
+
+ anErr = s_write (sockOut,user,strlen(user)+1);
+ DOERR
+ anErr = s_write (sockOut,passwd,strlen(passwd)+1);
+ DOERR
+ anErr = s_write (sockOut,cmd,strlen(cmd)+1);
+ DOERR
+
+ /*
+ * Hey, wouldn't it be great if rexec sent encrypted passwords?
+ * And wouldn't it be great if it sent along a case of a really good beer?
+ * Like Keystone!
+ */
+
+ anErr = s_read (sockOut,wbuf,1); /* fetch answer */
+ DOERR
+
+ if (*wbuf!=0)
+ {
+ errno = errno_long = EACCES;
+ return -1; /* permission denied! */
+ }
+
+ return sockOut;
+ }
+
+/*
+ * Polls an exisiting stderr hookup from a previous rexec for any error
+ * text. If there is, it will be returned in str, up to strln bytes
+ *
+ * Assumes sock is connected properly and str is not null.
+ */
+int rexecerr(Int4 sock,char *str,Int4 strln)
+ {
+ fd_set rfds;
+ struct timeval tv;
+ int selectcode;
+
+ FD_ZERO(&rfds);
+
+ FD_SET(sock,&rfds);
+
+ tv.tv_sec=1;
+ tv.tv_usec=0;
+
+ selectcode = s_select(sock+1,&rfds,(fd_set *)NULL,(fd_set *)NULL,&tv);
+
+ if ( selectcode < 0 )
+ return -1;
+ else if ( !selectcode )
+ return 0;
+ else
+ if (s_read(sock,str,strln)<0)
+ return -1;
+ return 1;
+
+ }
diff --git a/network/ncsasock/rexec.h b/network/ncsasock/rexec.h
new file mode 100644
index 00000000..48c1cb18
--- /dev/null
+++ b/network/ncsasock/rexec.h
@@ -0,0 +1,53 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: rexec.h,v $
+* Revision 6.0 1997/08/25 18:37:40 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:07 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * REXECPORT should be passed as the second parameter to rexec (512)
+ *
+ * Remember to provide an stderr (fd2p) socket if you want to use
+ * rexecerr
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int rexec(
+ char **ahost,
+ Int4 inport,
+ char *user,
+ char *passwd,
+ char *cmd,
+ int *fd2p);
+
+int rexecerr(Int4 sock,char *str,Int4 strln);
+
+#define REXECPORT 512
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/network/ncsasock/s_compat.h b/network/ncsasock/s_compat.h
new file mode 100644
index 00000000..cc3e85bd
--- /dev/null
+++ b/network/ncsasock/s_compat.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)ioctl_compat.h 7.3 (Berkeley) 5/16/90
+*
+*
+* RCS Modification History:
+* $Log: s_compat.h,v $
+* Revision 6.0 1997/08/25 18:37:42 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:10 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifdef KERNEL
+#include "ttychars.h"
+#include "ttydev.h"
+#else
+#include <sys/ttychars.h>
+#include <sys/ttydev.h>
+#endif
+
+struct tchars {
+ char t_intrc; /* interrupt */
+ char t_quitc; /* quit */
+ char t_startc; /* start output */
+ char t_stopc; /* stop output */
+ char t_eofc; /* end-of-file */
+ char t_brkc; /* input delimiter (like nl) */
+};
+
+struct ltchars {
+ char t_suspc; /* stop process signal */
+ char t_dsuspc; /* delayed stop process signal */
+ char t_rprntc; /* reprint line */
+ char t_flushc; /* flush output (toggles) */
+ char t_werasc; /* word erase */
+ char t_lnextc; /* literal next character */
+};
+
+/*
+ * Structure for TIOCGETP and TIOCSETP ioctls.
+ */
+#ifndef _SGTTYB_
+#define _SGTTYB_
+struct sgttyb {
+ char sg_ispeed; /* input speed */
+ char sg_ospeed; /* output speed */
+ char sg_erase; /* erase character */
+ char sg_kill; /* kill character */
+ short sg_flags; /* mode flags */
+};
+#endif
+
+#ifdef USE_OLD_TTY
+# undef TIOCGETD
+# define TIOCGETD _IOR('t', 0, int) /* get line discipline */
+# undef TIOCSETD
+# define TIOCSETD _IOW('t', 1, int) /* set line discipline */
+#else
+# define OTIOCGETD _IOR('t', 0, int) /* get line discipline */
+# define OTIOCSETD _IOW('t', 1, int) /* set line discipline */
+#endif
+#define TIOCHPCL _IO('t', 2) /* hang up on last close */
+#define TIOCGETP _IOR('t', 8,struct sgttyb)/* get parameters -- gtty */
+#define TIOCSETP _IOW('t', 9,struct sgttyb)/* set parameters -- stty */
+#define TIOCSETN _IOW('t',10,struct sgttyb)/* as above, but no flushtty*/
+#define TIOCSETC _IOW('t',17,struct tchars)/* set special characters */
+#define TIOCGETC _IOR('t',18,struct tchars)/* get special characters */
+#define TANDEM 0x00000001 /* send stopc on out q full */
+#define CBREAK 0x00000002 /* half-cooked mode */
+#define LCASE 0x00000004 /* simulate lower case */
+#define ECHO 0x00000008 /* echo input */
+#define CRMOD 0x00000010 /* map \r to \r\n on output */
+#define RAW 0x00000020 /* no i/o processing */
+#define ODDP 0x00000040 /* get/send odd parity */
+#define EVENP 0x00000080 /* get/send even parity */
+#define ANYP 0x000000c0 /* get any parity/send none */
+#define NLDELAY 0x00000300 /* \n delay */
+#define NL0 0x00000000
+#define NL1 0x00000100 /* tty 37 */
+#define NL2 0x00000200 /* vt05 */
+#define NL3 0x00000300
+#define TBDELAY 0x00000c00 /* horizontal tab delay */
+#define TAB0 0x00000000
+#define TAB1 0x00000400 /* tty 37 */
+#define TAB2 0x00000800
+#define XTABS 0x00000c00 /* expand tabs on output */
+#define CRDELAY 0x00003000 /* \r delay */
+#define CR0 0x00000000
+#define CR1 0x00001000 /* tn 300 */
+#define CR2 0x00002000 /* tty 37 */
+#define CR3 0x00003000 /* concept 100 */
+#define VTDELAY 0x00004000 /* vertical tab delay */
+#define FF0 0x00000000
+#define FF1 0x00004000 /* tty 37 */
+#define BSDELAY 0x00008000 /* \b delay */
+#define BS0 0x00000000
+#define BS1 0x00008000
+#define ALLDELAY (NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY)
+#define CRTBS 0x00010000 /* do backspacing for crt */
+#define PRTERA 0x00020000 /* \ ... / erase */
+#define CRTERA 0x00040000 /* " \b " to wipe out char */
+#define TILDE 0x00080000 /* hazeltine tilde kludge */
+#define MDMBUF 0x00100000 /*start/stop output on carrier*/
+#define LITOUT 0x00200000 /* literal output */
+#define TOSTOP 0x00400000 /*SIGSTOP on background output*/
+#define FLUSHO 0x00800000 /* flush output to terminal */
+#define NOHANG 0x01000000 /* (no-op) was no SIGHUP on carrier drop */
+#define L001000 0x02000000
+#define CRTKIL 0x04000000 /* kill line with " \b " */
+#define PASS8 0x08000000
+#define CTLECH 0x10000000 /* echo control chars as ^X */
+#define PENDIN 0x20000000 /* tp->t_rawq needs reread */
+#define DECCTQ 0x40000000 /* only ^Q starts after ^S */
+#define NOFLSH 0x80000000 /* no output flush on signal */
+#define TIOCLBIS _IOW('t', 127, int) /* bis local mode bits */
+#define TIOCLBIC _IOW('t', 126, int) /* bic local mode bits */
+#define TIOCLSET _IOW('t', 125, int) /* set entire local mode word */
+#define TIOCLGET _IOR('t', 124, int) /* get local modes */
+#define LCRTBS (CRTBS>>16)
+#define LPRTERA (PRTERA>>16)
+#define LCRTERA (CRTERA>>16)
+#define LTILDE (TILDE>>16)
+#define LMDMBUF (MDMBUF>>16)
+#define LLITOUT (LITOUT>>16)
+#define LTOSTOP (TOSTOP>>16)
+#define LFLUSHO (FLUSHO>>16)
+#define LNOHANG (NOHANG>>16)
+#define LCRTKIL (CRTKIL>>16)
+#define LPASS8 (PASS8>>16)
+#define LCTLECH (CTLECH>>16)
+#define LPENDIN (PENDIN>>16)
+#define LDECCTQ (DECCTQ>>16)
+#define LNOFLSH (NOFLSH>>16)
+#define TIOCSLTC _IOW('t',117,struct ltchars)/* set local special chars*/
+#define TIOCGLTC _IOR('t',116,struct ltchars)/* get local special chars*/
+#define OTIOCCONS _IO('t', 98) /* for hp300 -- sans int arg */
+#define OTTYDISC 0
+#define NETLDISC 1
+#define NTTYDISC 2
diff --git a/network/ncsasock/s_fcntl.h b/network/ncsasock/s_fcntl.h
new file mode 100644
index 00000000..9f6d4ad6
--- /dev/null
+++ b/network/ncsasock/s_fcntl.h
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 1983, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)fcntl.h 5.5 (Berkeley) 5/29/90
+ */
+
+#ifndef F_DUPFD
+
+/* command values for fcntl(2) */
+#define F_DUPFD 0 /* duplicate file descriptor */
+#define F_GETFD 1 /* get file descriptor flags */
+#define F_SETFD 2 /* set file descriptor flags */
+#define F_GETFL 3 /* get file status flags */
+#define F_SETFL 4 /* set file status flags */
+#ifndef _POSIX_SOURCE
+#define F_GETOWN 5 /* get SIGIO/SIGURG proc/pgrp */
+#define F_SETOWN 6 /* set SIGIO/SIGURG proc/pgrp */
+#endif
+#define F_GETLK 7 /* get record locking information */
+#define F_SETLK 8 /* set record locking information */
+#define F_SETLKW 9 /* F_SETLK; wait if blocked */
+
+/* file descriptor flags (F_GETFD, F_SETFD) */
+#define FD_CLOEXEC 1 /* close-on-exec flag */
+
+/* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */
+#define F_RDLCK 1 /* shared or read lock */
+#define F_UNLCK 2 /* unlock */
+#define F_WRLCK 3 /* exclusive or write lock */
+
+#ifndef _POSIX_SOURCE
+/* lock operations for flock(2) */
+#define LOCK_SH 0x01 /* shared file lock */
+#define LOCK_EX 0x02 /* exclusive file lock */
+#define LOCK_NB 0x04 /* don't block when locking */
+#define LOCK_UN 0x08 /* unlock file */
+#endif
+
+#ifndef COMP_THINKC
+/* file status flags */
+#define O_RDONLY 00000 /* open for reading only */
+#define O_WRONLY 00001 /* open for writing only */
+#define O_RDWR 00002 /* open for reading and writing */
+#define O_NONBLOCK 00004 /* no delay */
+#endif /* !COMP_THINKC */
+#ifndef _POSIX_SOURCE
+#ifndef COMP_THINKC
+#define O_NDELAY O_NONBLOCK
+#endif /* !COMP_THINKC */
+#define FNDELAY O_NONBLOCK
+#endif
+/* 00008 */ /* unused */
+#ifndef COMP_THINKC
+#define O_APPEND 00010 /* set append mode */
+#ifndef _POSIX_SOURCE
+#define FAPPEND O_APPEND
+#endif
+ /* kernel placeholders */
+#if !defined(_POSIX_SOURCE) && defined(KERNEL)
+#define O_MARK 00020 /* mark during gc() */
+#define O_DEFER 00040 /* defer for next gc pass */
+#endif
+/* 00080 */ /* unused */
+#ifndef _POSIX_SOURCE
+#define O_ASYNC 00100 /* signal pgrp when data ready */
+#define FASYNC O_ASYNC
+#define O_SHLOCK 00200 /* shared file lock present */
+#define O_EXLOCK 00400 /* exclusive file lock present */
+/* 00800 */ /* unused */
+#endif
+#define O_CREAT 01000 /* create if nonexistant */
+#define O_TRUNC 02000 /* truncate to zero length */
+#define O_EXCL 04000 /* error if already exists */
+/* 08000 */ /* unused */
+
+/* defined by POSIX 1003.1; BSD default, so no bit required */
+#define O_NOCTTY 0 /* don't assign controlling terminal */
+
+/* mask for file access modes */
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+
+#if __STDC__ || c_plusplus
+#ifndef __MWERKS__
+extern int fcntl(int, int, int);
+#endif
+extern int creat(const char *, mode_t);
+extern int open(const char *, int, ...);
+#else
+extern int fcntl();
+extern int creat();
+extern int open();
+#endif
+
+#endif /* !COMP_THINKC */
+
+#endif /* !F_DUPFD */
diff --git a/network/ncsasock/s_file.h b/network/ncsasock/s_file.h
new file mode 100644
index 00000000..04e7017b
--- /dev/null
+++ b/network/ncsasock/s_file.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)file.h 7.6 (Berkeley) 6/28/90
+*
+*
+* RCS Modification History:
+* $Log: s_file.h,v $
+* Revision 6.0 1997/08/25 18:37:45 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:16 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifdef KERNEL
+#include "fcntl.h"
+#include "unistd.h"
+
+/*
+ * Descriptor table entry.
+ * One for each kernel object.
+ */
+struct file {
+ int f_flag; /* see below */
+#define DTYPE_VNODE 1 /* file */
+#define DTYPE_SOCKET 2 /* communications endpoint */
+ short f_type; /* descriptor type */
+ short f_count; /* reference count */
+ short f_msgcount; /* references from message queue */
+ struct ucred *f_cred; /* credentials associated with descriptor */
+ struct fileops {
+ int (*fo_read)();
+ int (*fo_write)();
+ int (*fo_ioctl)();
+ int (*fo_select)();
+ int (*fo_close)();
+ } *f_ops;
+ caddr_t f_data; /* inode */
+ off_t f_offset;
+};
+
+struct file *file, *fileNFILE;
+int nfile;
+
+/* convert O_RDONLY/O_WRONLY/O_RDWR to FREAD/FWRITE */
+#define FOPEN (-1)
+#define FREAD 1
+#define FWRITE 2
+
+/* kernel only versions -- deprecated, should be removed */
+#define FCREAT O_CREAT
+#define FDEFER O_DEFER
+#define FEXCL O_EXCL
+#define FEXLOCK O_EXLOCK
+#define FMARK O_MARK
+#define FSHLOCK O_SHLOCK
+#define FTRUNC O_TRUNC
+
+/* bits to save after open */
+#define FMASK (FREAD|FWRITE|O_APPEND|O_ASYNC|O_NONBLOCK)
+/* bits not settable by fcntl(F_SETFL, ...) */
+#define FCNTLCANT (FREAD|FWRITE|O_DEFER|O_EXLOCK|O_MARK|O_SHLOCK)
+
+#else
+
+#include <s_fcntl.h>
+#include <s_unistd.h>
+
+#endif
+
+/* operation for lseek(2); renamed by POSIX 1003.1 to unistd.h */
+#define L_SET 0 /* set file offset to offset */
+#define L_INCR 1 /* set file offset to current plus offset */
+#define L_XTND 2 /* set file offset to EOF plus offset */
diff --git a/network/ncsasock/s_ioctl.h b/network/ncsasock/s_ioctl.h
new file mode 100644
index 00000000..1da8b13e
--- /dev/null
+++ b/network/ncsasock/s_ioctl.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ * @(#)ioctl.h 7.12 (Berkeley) 5/18/90
+*
+*
+* RCS Modification History:
+* $Log: s_ioctl.h,v $
+* Revision 6.0 1997/08/25 18:37:47 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:20 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Ioctl definitions
+ */
+#ifndef _IOCTL_
+#define _IOCTL_
+
+/*
+ * Window/terminal size structure.
+ * This information is stored by the kernel
+ * in order to provide a consistent interface,
+ * but is not used by the kernel.
+ *
+ * Type must be "unsigned short" so that types.h not required.
+ */
+struct winsize {
+ unsigned short ws_row; /* rows, in characters */
+ unsigned short ws_col; /* columns, in characters */
+ unsigned short ws_xpixel; /* horizontal size, pixels */
+ unsigned short ws_ypixel; /* vertical size, pixels */
+};
+
+/*
+ * Pun for SUN.
+ */
+struct ttysize {
+ unsigned short ts_lines;
+ unsigned short ts_cols;
+ unsigned short ts_xxx;
+ unsigned short ts_yyy;
+};
+#define TIOCGSIZE TIOCGWINSZ
+#define TIOCSSIZE TIOCSWINSZ
+
+#ifndef _IO
+/*
+ * Ioctl's have the command encoded in the lower word,
+ * and the size of any in or out parameters in the upper
+ * word. The high 3 bits of the upper word are used
+ * to encode the in/out status of the parameter.
+ */
+#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */
+#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
+#define IOCBASECMD(x) ((x) & ~IOCPARM_MASK)
+#define IOCGROUP(x) (((x) >> 8) & 0xff)
+
+#define IOCPARM_MAX NBPG /* max size of ioctl, mult. of NBPG */
+#define IOC_VOID 0x20000000 /* no parameters */
+#define IOC_OUT 0x40000000 /* copy out parameters */
+#define IOC_IN 0x80000000 /* copy in parameters */
+#define IOC_INOUT (IOC_IN|IOC_OUT)
+#define IOC_DIRMASK 0xe0000000 /* mask for IN/OUT/VOID */
+
+#define _IOC(inout,group,num,len) \
+ (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num))
+#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0)
+#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
+#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t))
+/* this should be _IORW, but stdio got there first */
+#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
+#endif
+
+
+/*
+ * tty ioctl commands
+ */
+ /* 0-2 compat */
+#define TIOCMODG _IOR('t', 3, int) /* get modem control state */
+#define TIOCMODS _IOW('t', 4, int) /* set modem control state */
+#define TIOCM_LE 0001 /* line enable */
+#define TIOCM_DTR 0002 /* data terminal ready */
+#define TIOCM_RTS 0004 /* request to send */
+#define TIOCM_ST 0010 /* secondary transmit */
+#define TIOCM_SR 0020 /* secondary receive */
+#define TIOCM_CTS 0040 /* clear to send */
+#define TIOCM_CAR 0100 /* carrier detect */
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RNG 0200 /* ring */
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_DSR 0400 /* data set ready */
+ /* 8-10 compat */
+#define TIOCEXCL _IO('t', 13) /* set exclusive use of tty */
+#define TIOCNXCL _IO('t', 14) /* reset exclusive use of tty */
+ /* 15 unused */
+#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */
+ /* 17-18 compat */
+#define TIOCGETA _IOR('t', 19, struct termios) /* get termios struct */
+#define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */
+#define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */
+#define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */
+/*** THESE GO AWAY ***/
+#define JUNK_TIOCSETAS _IOW('t', 23, struct termios) /* SETA ign hdw state */
+#define JUNK_TIOCSETAWS _IOW('t', 24, struct termios) /* SETAW ign hdw state */
+#define JUNK_TIOCSETAFS _IOW('t', 25, struct termios) /* SETAF ign hdw state */
+/******************/
+#define TIOCGETD _IOR('t', 26, int) /* get line discipline */
+#define TIOCSETD _IOW('t', 27, int) /* set line discipline */
+ /* 127-124 compat */
+#define TIOCSBRK _IO('t', 123) /* set break bit */
+#define TIOCCBRK _IO('t', 122) /* clear break bit */
+#define TIOCSDTR _IO('t', 121) /* set data terminal ready */
+#define TIOCCDTR _IO('t', 120) /* clear data terminal ready */
+#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */
+#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */
+ /* 117-116 compat */
+#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
+#define TIOCSTI _IOW('t', 114, char) /* simulate terminal input */
+#define TIOCNOTTY _IO('t', 113) /* void tty association */
+#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */
+#define TIOCPKT_DATA 0x00 /* data packet */
+#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */
+#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */
+#define TIOCPKT_STOP 0x04 /* stop output */
+#define TIOCPKT_START 0x08 /* start output */
+#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
+#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
+#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */
+#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
+#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
+#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */
+#define TIOCMBIS _IOW('t', 108, int) /* bis modem bits */
+#define TIOCMBIC _IOW('t', 107, int) /* bic modem bits */
+#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */
+#define TIOCREMOTE _IOW('t', 105, int) /* remote input editing */
+#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */
+#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */
+#define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */
+#define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */
+#define TIOCCONS _IOW('t', 98, int) /* become virtual console */
+#define TIOCSCTTY _IO('t', 97) /* become controlling tty */
+#define TIOCEXT _IOW('t', 96, int) /* pty: external processing */
+#define TIOCSIG _IO('t', 95) /* pty: generate signal */
+
+#define TTYDISC 0 /* termios tty line discipline */
+#define TABLDISC 3 /* tablet discipline */
+#define SLIPDISC 4 /* serial IP discipline */
+
+/*
+ * Compatability with old terminal driver
+ *
+ * Source level -> #define USE_OLD_TTY
+ * Kernel level -> options COMPAT_43
+ */
+#if defined(USE_OLD_TTY) || defined(COMPAT_43)
+#ifdef KERNEL
+#include "ioctl_compat.h"
+#else
+#include <sys/ioctl_compat.h>
+#endif
+#endif
+
+#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
+#define FIONCLEX _IO('f', 2) /* remove close on exec */
+#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
+#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
+#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
+#define FIOSETOWN _IOW('f', 124, int) /* set owner */
+#define FIOGETOWN _IOR('f', 123, int) /* get owner */
+
+/* socket i/o controls */
+#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */
+#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */
+#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */
+#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */
+#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */
+#define SIOCSPGRP _IOW('s', 8, int) /* set process group */
+#define SIOCGPGRP _IOR('s', 9, int) /* get process group */
+
+#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
+#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */
+
+#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */
+#define OSIOCGIFADDR _IOWR('i',13, struct ifreq) /* get ifnet address */
+#define SIOCGIFADDR _IOWR('i',33, struct ifreq) /* get ifnet address */
+#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */
+#define OSIOCGIFDSTADDR _IOWR('i',15, struct ifreq) /* get p-p address */
+#define SIOCGIFDSTADDR _IOWR('i',34, struct ifreq) /* get p-p address */
+#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */
+#define SIOCGIFFLAGS _IOWR('i',17, struct ifreq) /* get ifnet flags */
+#define OSIOCGIFBRDADDR _IOWR('i',18, struct ifreq) /* get broadcast addr */
+#define SIOCGIFBRDADDR _IOWR('i',35, struct ifreq) /* get broadcast addr */
+#define SIOCSIFBRDADDR _IOW('i',19, struct ifreq) /* set broadcast addr */
+#define OSIOCGIFCONF _IOWR('i',20, struct ifconf) /* get ifnet list */
+#define SIOCGIFCONF _IOWR('i',36, struct ifconf) /* get ifnet list */
+#define OSIOCGIFNETMASK _IOWR('i',21, struct ifreq) /* get net addr mask */
+#define SIOCGIFNETMASK _IOWR('i',37, struct ifreq) /* get net addr mask */
+#define SIOCSIFNETMASK _IOW('i',22, struct ifreq) /* set net addr mask */
+#define SIOCGIFMETRIC _IOWR('i',23, struct ifreq) /* get IF metric */
+#define SIOCSIFMETRIC _IOW('i',24, struct ifreq) /* set IF metric */
+#define SIOCDIFADDR _IOW('i',25, struct ifreq) /* delete IF addr */
+#define SIOCAIFADDR _IOW('i',26, struct ifaliasreq) /* add/chg IF alias */
+
+#define SIOCSARP _IOW('i', 30, struct arpreq) /* set arp entry */
+#define OSIOCGARP _IOWR('i',31, struct arpreq) /* get arp entry */
+#define SIOCGARP _IOWR('i',38, struct arpreq) /* get arp entry */
+#define SIOCDARP _IOW('i', 32, struct arpreq) /* delete arp entry */
+
+#endif
diff --git a/network/ncsasock/s_param.h b/network/ncsasock/s_param.h
new file mode 100644
index 00000000..827d207c
--- /dev/null
+++ b/network/ncsasock/s_param.h
@@ -0,0 +1,41 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: s_param.h,v $
+* Revision 6.0 1997/08/25 18:37:48 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:23 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <s_types.h>
+
+// #define is68k // MPW C defines MC68000, mc68000, m68k, and
+// #define isMACINTOSH // macintosh automatically.
+
+#ifndef MPW3 // It should define MPW3, but it doesn't
+#define MPW3 1
+#endif
+
+// The endian stuff shouldn't really be here.
+#ifndef BIG_ENDIAN
+# define BIG_ENDIAN 4321
+#endif
+
+#ifndef LITTLE_ENDIAN
+# define LITTLE_ENDIAN 1234
+#endif
+
+#ifndef BYTE_ORDER
+# define BYTE_ORDER BIG_ENDIAN
+#endif
+
+#define MAXHOSTNAMELEN 256
+#define MAXPATHLEN 256
+#define NCARGS 0x100000
diff --git a/network/ncsasock/s_socket.h b/network/ncsasock/s_socket.h
new file mode 100644
index 00000000..b4232fc5
--- /dev/null
+++ b/network/ncsasock/s_socket.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 1982,1985,1986,1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)socket.h 7.10 (Berkeley) 6/28/90
+*
+*
+* RCS Modification History:
+* $Log: s_socket.h,v $
+* Revision 6.0 1997/08/25 18:37:50 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:26 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Definitions related to sockets: types, address families, options.
+ */
+
+/*
+ * Types
+ */
+#define SOCK_STREAM 1 /* stream socket */
+#define SOCK_DGRAM 2 /* datagram socket */
+#define SOCK_RAW 3 /* raw-protocol interface */
+#define SOCK_RDM 4 /* reliably-delivered message */
+#define SOCK_SEQPACKET 5 /* sequenced packet stream */
+
+/*
+ * Option flags per-socket.
+ */
+#define SO_DEBUG 0x0001 /* turn on debugging info recording */
+#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
+#define SO_REUSEADDR 0x0004 /* allow local address reuse */
+#define SO_KEEPALIVE 0x0008 /* keep connections alive */
+#define SO_DONTROUTE 0x0010 /* just use interface addresses */
+#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
+#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
+#define SO_LINGER 0x0080 /* linger on close if data present */
+#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
+
+/*
+ * Additional options, not kept in so_options.
+ */
+#define SO_SNDBUF 0x1001 /* send buffer size */
+#define SO_RCVBUF 0x1002 /* receive buffer size */
+#define SO_SNDLOWAT 0x1003 /* send low-water mark */
+#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
+#define SO_SNDTIMEO 0x1005 /* send timeout */
+#define SO_RCVTIMEO 0x1006 /* receive timeout */
+#define SO_ERROR 0x1007 /* get error status and clear */
+#define SO_TYPE 0x1008 /* get socket type */
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+ Int4 l_onoff; /* option on/off */
+ Int4 l_linger; /* linger time */
+};
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define SOL_SOCKET 0xffff /* options for socket level */
+
+/*
+ * Address families.
+ */
+#define AF_UNSPEC 0 /* unspecified */
+#define AF_UNIX 1 /* local to host (pipes, portals) */
+#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
+#define AF_IMPLINK 3 /* arpanet imp addresses */
+#define AF_PUP 4 /* pup protocols: e.g. BSP */
+#define AF_CHAOS 5 /* mit CHAOS protocols */
+#define AF_NS 6 /* XEROX NS protocols */
+#define AF_ISO 7 /* ISO protocols */
+#define AF_OSI AF_ISO
+#define AF_ECMA 8 /* european computer manufacturers */
+#define AF_DATAKIT 9 /* datakit protocols */
+#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
+#define AF_SNA 11 /* IBM SNA */
+#define AF_DECnet 12 /* DECnet */
+#define AF_DLI 13 /* DEC Direct data link interface */
+#define AF_LAT 14 /* LAT */
+#define AF_HYLINK 15 /* NSC Hyperchannel */
+#define AF_APPLETALK 16 /* Apple Talk */
+#define AF_ROUTE 17 /* Internal Routing Protocol */
+#define AF_LINK 18 /* Link layer interface */
+#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
+
+#define AF_MAX 20
+
+/*
+ * Structure used by kernel to store most
+ * addresses.
+ */
+struct sockaddr {
+ u_char sa_len; /* total length */
+ u_char sa_family; /* address family */
+ char sa_data[14]; /* actually longer; address value */
+};
+
+/*
+ * Structure used by kernel to pass protocol
+ * information in raw sockets.
+ */
+struct sockproto {
+ u_short sp_family; /* address family */
+ u_short sp_protocol; /* protocol */
+};
+
+/*
+ * Protocol families, same as address families for now.
+ */
+#define PF_UNSPEC AF_UNSPEC
+#define PF_UNIX AF_UNIX
+#define PF_INET AF_INET
+#define PF_IMPLINK AF_IMPLINK
+#define PF_PUP AF_PUP
+#define PF_CHAOS AF_CHAOS
+#define PF_NS AF_NS
+#define PF_ISO AF_ISO
+#define PF_OSI AF_ISO
+#define PF_ECMA AF_ECMA
+#define PF_DATAKIT AF_DATAKIT
+#define PF_CCITT AF_CCITT
+#define PF_SNA AF_SNA
+#define PF_DECnet AF_DECnet
+#define PF_DLI AF_DLI
+#define PF_LAT AF_LAT
+#define PF_HYLINK AF_HYLINK
+#define PF_APPLETALK AF_APPLETALK
+#define PF_ROUTE AF_ROUTE
+#define PF_LINK AF_LINK
+#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
+
+#define PF_MAX AF_MAX
+
+/*
+ * Maximum queue length specifiable by listen.
+ */
+#define SOMAXCONN 5
+
+/*
+ * Message header for recvmsg and sendmsg calls.
+ * Used value-result for recvmsg, value only for sendmsg.
+ */
+
+/*
+ * Macintosh needs 4.3 compatible headers for DTM. At the end of the file.
+ */
+
+// struct msghdr {
+// caddr_t msg_name; /* optional address */
+// u_int msg_namelen; /* size of address */
+// struct iovec *msg_iov; /* scatter/gather array */
+// u_int msg_iovlen; /* # elements in msg_iov */
+// caddr_t msg_control; /* ancillary data, see below */
+// u_int msg_controllen; /* ancillary data buffer len */
+// int msg_flags; /* flags on received message */
+// };
+
+#define MSG_OOB 0x1 /* process out-of-band data */
+#define MSG_PEEK 0x2 /* peek at incoming message */
+#define MSG_DONTROUTE 0x4 /* send without using routing tables */
+#define MSG_EOR 0x8 /* data completes record */
+#define MSG_TRUNC 0x10 /* data discarded before delivery */
+#define MSG_CTRUNC 0x20 /* control data lost before delivery */
+#define MSG_WAITALL 0x40 /* wait for full request or error */
+
+/*
+ * Header for ancillary data objects in msg_control buffer.
+ * Used for additional information with/about a datagram
+ * not expressible by flags. The format is a sequence
+ * of message elements headed by cmsghdr structures.
+ */
+struct cmsghdr {
+ u_int cmsg_len; /* data byte count, including hdr */
+ int cmsg_level; /* originating protocol */
+ int cmsg_type; /* protocol-specific type */
+/* followed by u_char cmsg_data[]; */
+};
+
+/* given pointer to struct adatahdr, return pointer to data */
+#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
+
+/* given pointer to struct adatahdr, return pointer to next adatahdr */
+#define CMSG_NXTHDR(mhdr, cmsg) \
+ (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
+ (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
+ (struct cmsghdr *)NULL : \
+ (struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
+
+#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
+
+/* "Socket"-level control message types: */
+#define SCM_RIGHTS 0x01 /* access rights (array of int) */
+
+/*
+ * 4.3 compat sockaddr, move to compat file later
+ */
+struct osockaddr {
+ u_short sa_family; /* address family */
+ char sa_data[14]; /* up to 14 bytes of direct address */
+};
+
+/*
+ * 4.3-compat message header (move to compat file later).
+ */
+struct msghdr {
+ caddr_t msg_name; /* optional address */
+ Int4 msg_namelen; /* size of address */
+ struct iovec *msg_iov; /* scatter/gather array */
+ Int4 msg_iovlen; /* # elements in msg_iov */
+ caddr_t msg_accrights; /* access rights sent/received */
+ Int4 msg_accrightslen;
+};
diff --git a/network/ncsasock/s_time.h b/network/ncsasock/s_time.h
new file mode 100644
index 00000000..84de9be8
--- /dev/null
+++ b/network/ncsasock/s_time.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1982, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)time.h 7.4 (Berkeley) 6/28/90
+*
+*
+* RCS Modification History:
+* $Log: s_time.h,v $
+* Revision 6.0 1997/08/25 18:37:51 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:29 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifndef _TIME_
+#define _TIME_
+
+/*
+ * Structure returned by gettimeofday(2) system call,
+ * and used in other calls.
+ */
+struct timeval {
+ long tv_sec; /* seconds */
+ long tv_usec; /* and microseconds */
+};
+
+struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+#define DST_NONE 0 /* not on dst */
+#define DST_USA 1 /* USA style dst */
+#define DST_AUST 2 /* Australian style dst */
+#define DST_WET 3 /* Western European dst */
+#define DST_MET 4 /* Middle European dst */
+#define DST_EET 5 /* Eastern European dst */
+#define DST_CAN 6 /* Canada */
+
+/*
+ * Operations on timevals.
+ *
+ * NB: timercmp does not work for >= or <=.
+ */
+#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#define timercmp(tvp, uvp, cmp) \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec || \
+ (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
+#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
+
+/*
+ * Names of the interval timers, and structure
+ * defining a timer setting.
+ */
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+
+#ifndef KERNEL
+#include <time.h>
+#endif
+
+#endif /* _TIME_ */
diff --git a/network/ncsasock/s_timeb.h b/network/ncsasock/s_timeb.h
new file mode 100644
index 00000000..64db6f07
--- /dev/null
+++ b/network/ncsasock/s_timeb.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ * @(#)timeb.h 7.1 (Berkeley) 6/4/86
+*
+*
+* RCS Modification History:
+* $Log: s_timeb.h,v $
+* Revision 6.0 1997/08/25 18:37:53 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:33 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Structure returned by ftime system call
+ */
+struct timeb
+{
+ time_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+};
diff --git a/network/ncsasock/s_ttych.h b/network/ncsasock/s_ttych.h
new file mode 100644
index 00000000..f264e03e
--- /dev/null
+++ b/network/ncsasock/s_ttych.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ * @(#)ttychars.h 7.3 (Berkeley) 10/18/88
+*
+*
+* RCS Modification History:
+* $Log: s_ttych.h,v $
+* Revision 6.0 1997/08/25 18:37:54 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:37 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * 4.3 COMPATIBILITY FILE
+ *
+ * User visible structures and constants
+ * related to terminal handling.
+ */
+#ifndef _TTYCHARS_
+#define _TTYCHARS_
+
+struct ttychars {
+ char tc_erase; /* erase last character */
+ char tc_kill; /* erase entire line */
+ char tc_intrc; /* interrupt */
+ char tc_quitc; /* quit */
+ char tc_startc; /* start output */
+ char tc_stopc; /* stop output */
+ char tc_eofc; /* end-of-file */
+ char tc_brkc; /* input delimiter (like nl) */
+ char tc_suspc; /* stop process signal */
+ char tc_dsuspc; /* delayed stop process signal */
+ char tc_rprntc; /* reprint line */
+ char tc_flushc; /* flush output (toggles) */
+ char tc_werasc; /* word erase */
+ char tc_lnextc; /* literal next character */
+};
+#ifdef USE_OLD_TTY
+#include <sys/ttydefaults.h> /* to pick up character defaults */
+#endif
+#endif /* _TTYCHARS */
diff --git a/network/ncsasock/s_ttydev.h b/network/ncsasock/s_ttydev.h
new file mode 100644
index 00000000..b1b92079
--- /dev/null
+++ b/network/ncsasock/s_ttydev.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ * @(#)ttydev.h 7.6 (Berkeley) 11/20/89
+*
+*
+* RCS Modification History:
+* $Log: s_ttydev.h,v $
+* Revision 6.0 1997/08/25 18:37:55 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:40 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * COMPATABILITY HEADER FILE --
+ */
+
+/*
+ * Terminal definitions related to underlying hardware.
+ */
+#ifndef _TTYDEV_
+#define _TTYDEV_
+
+#ifdef USE_OLD_TTY
+/*
+ * Speeds
+ */
+#define B0 0
+#define B50 1
+#define B75 2
+#define B110 3
+#define B134 4
+#define B150 5
+#define B200 6
+#define B300 7
+#define B600 8
+#define B1200 9
+#define B1800 10
+#define B2400 11
+#define B4800 12
+#define B9600 13
+#define EXTA 14
+#define EXTB 15
+#endif /* USE_OLD_TTY */
+
+#endif /* _TTYDEV_ */
diff --git a/network/ncsasock/s_types.h b/network/ncsasock/s_types.h
new file mode 100644
index 00000000..36be3e76
--- /dev/null
+++ b/network/ncsasock/s_types.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ * @(#)types.h 7.11 (Berkeley) 6/25/90
+*
+*
+* RCS Modification History:
+* $Log: s_types.h,v $
+* Revision 6.0 1997/08/25 18:37:57 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.3 1995/05/17 17:57:43 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifndef _TYPES_
+#define _TYPES_
+
+#if !defined(_NCBI_) && !defined(Int4)
+#define Int4 long
+#endif
+
+typedef short dev_t;
+#ifndef _POSIX_SOURCE
+ /* major part of a device */
+#define major(x) ((int)(((unsigned)(x)>>8)&0377))
+ /* minor part of a device */
+#define minor(x) ((int)((x)&0377))
+ /* make a device number */
+#define makedev(x,y) ((dev_t)(((x)<<8) | (y)))
+#endif
+
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+typedef unsigned short ushort; /* Sys V compatibility */
+
+#ifdef KERNEL
+#include "machine/machtypes.h"
+#else
+#include <ma_types.h>
+#endif
+
+#ifdef _CLOCK_T_
+typedef _CLOCK_T_ clock_t;
+#undef _CLOCK_T_
+#endif
+
+#ifdef _TIME_T_
+typedef _TIME_T_ time_t;
+#undef _TIME_T_
+#endif
+
+#ifdef _SIZE_T_
+#if !defined(THINK_C) && !defined(COMP_THINKC) && !defined(__MWERKS__) && !defined(COMP_METRO)
+typedef _SIZE_T_ size_t;
+#endif
+#undef _SIZE_T_
+#endif
+
+#ifndef _POSIX_SOURCE
+typedef struct _uquad { unsigned long val[2]; } u_quad;
+typedef struct _quad { long val[2]; } quad;
+#endif
+typedef long * qaddr_t; /* should be typedef quad * qaddr_t; */
+
+typedef long daddr_t;
+typedef char * caddr_t;
+typedef u_long ino_t;
+typedef long swblk_t;
+typedef long segsz_t;
+typedef long off_t;
+typedef u_short uid_t;
+typedef u_short gid_t;
+typedef short pid_t;
+typedef u_short nlink_t;
+typedef u_short mode_t;
+typedef u_long fixpt_t;
+
+#ifndef _POSIX_SOURCE
+#define NBBY 8 /* number of bits in a byte */
+
+/*
+ * Select uses bit masks of file descriptors in longs. These macros
+ * manipulate such bit fields (the filesystem macros use chars).
+ * FD_SETSIZE may be defined by the user, but the default here should
+ * be >= NOFILE (param.h).
+ */
+#ifndef FD_SETSIZE
+#define FD_SETSIZE 256
+#endif
+
+typedef long fd_mask;
+#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
+
+#ifndef howmany
+#define howmany(x, y) (((x)+((y)-1))/(y))
+#endif
+
+typedef struct fd_set {
+ fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+} fd_set;
+
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
+
+#endif /* !_POSIX_SOURCE */
+#endif /* _TYPES_ */
diff --git a/network/ncsasock/s_uio.h b/network/ncsasock/s_uio.h
new file mode 100644
index 00000000..101cc095
--- /dev/null
+++ b/network/ncsasock/s_uio.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1982, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)uio.h 7.5 (Berkeley) 6/28/90
+*
+*
+* RCS Modification History:
+* $Log: s_uio.h,v $
+* Revision 6.0 1997/08/25 18:37:58 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:57:46 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifndef _UIO_
+#define _UIO_
+
+struct iovec {
+ caddr_t iov_base;
+ int iov_len;
+};
+
+enum uio_rw { UIO_READ, UIO_WRITE };
+
+/*
+ * Segment flag values.
+ */
+enum uio_seg {
+ UIO_USERSPACE, /* from user data space */
+ UIO_SYSSPACE, /* from system space */
+ UIO_USERISPACE /* from user I space */
+};
+
+struct uio {
+ struct iovec *uio_iov;
+ int uio_iovcnt;
+ off_t uio_offset;
+ int uio_resid;
+ enum uio_seg uio_segflg;
+ enum uio_rw uio_rw;
+};
+
+ /*
+ * Limits
+ */
+#define UIO_MAXIOV 1024 /* max 1K of iov's */
+#define UIO_SMALLIOV 8 /* 8 on stack, else malloc */
+
+#endif /* !_UIO_ */
diff --git a/network/ncsasock/s_unistd.h b/network/ncsasock/s_unistd.h
new file mode 100644
index 00000000..bfbb1098
--- /dev/null
+++ b/network/ncsasock/s_unistd.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)unistd.h 5.7 (Berkeley) 6/28/90
+ */
+
+/* compile-time symbolic constants */
+#define _POSIX_JOB_CONTROL /* implementation supports job control */
+/*#define _POSIX_SAVED_IDS */ /* saved set-user-ID and set-group-ID */
+#define _POSIX_VERSION 198808L
+
+/* execution-time symbolic constants */
+#define _POSIX_CHOWN_RESTRICTED /* chown requires appropriate privileges */
+#define _POSIX_NO_TRUNC /* too-long path components generate errors */
+ /* may disable terminal special characters */
+#define _POSIX_VDISABLE ((unsigned char)'\377')
+
+/* access function */
+#define F_OK 0 /* test for existence of file */
+#define X_OK 0x01 /* test for execute or search permission */
+#define W_OK 0x02 /* test for write permission */
+#define R_OK 0x04 /* test for read permission */
+
+/* lseek function */
+#define SEEK_SET 0 /* set file offset to offset */
+#define SEEK_CUR 1 /* set file offset to current plus offset */
+#define SEEK_END 2 /* set file offset to EOF plus offset */
+
+/* map a stream pointer to a file descriptor */
+#define STDIN_FILENO 0 /* standard input value, stdin */
+#define STDOUT_FILENO 1 /* standard output value, stdout */
+#define STDERR_FILENO 2 /* standard error value, stdout */
+
+/* fnmatch function */
+#define FNM_PATHNAME 0x01 /* match pathnames, not filenames */
+#ifndef _POSIX_SOURCE
+#define FNM_QUOTE 0x02 /* escape special chars with \ */
+#endif
+
+#ifndef NULL
+#define NULL 0 /* null pointer constant */
+#endif
+
+/* configurable pathname variables */
+#define _PC_LINK_MAX 1
+#define _PC_MAX_CANON 2
+#define _PC_MAX_INPUT 3
+#define _PC_NAME_MAX 4
+#define _PC_PATH_MAX 5
+#define _PC_PIPE_BUF 6
+#define _PC_CHOWN_RESTRICTED 7
+#define _PC_NO_TRUNC 8
+#define _PC_VDISABLE 9
+
+/* configurable system variables */
+#define _SC_ARG_MAX 1
+#define _SC_CHILD_MAX 2
+#define _SC_CLK_TCK 3
+#define _SC_NGROUPS_MAX 4
+#define _SC_OPEN_MAX 5
+#define _SC_JOB_CONTROL 6
+#define _SC_SAVED_IDS 7
+#define _SC_VERSION 8
diff --git a/network/ncsasock/sock_ext.h b/network/ncsasock/sock_ext.h
new file mode 100644
index 00000000..e1c5fd01
--- /dev/null
+++ b/network/ncsasock/sock_ext.h
@@ -0,0 +1,159 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+ */
+
+/*
+ * External definitions for socket users.
+ * Charlie Reiman
+ * Friday, August 3, 1990 2:09:45 PM
+ */
+
+#ifndef __socket_ext__
+#define __socket_ext__
+
+#ifndef __MEMORY__
+#include <Memory.h>
+#endif /* __MEMORY__ */
+
+#ifndef _TYPES_
+#include <s_types.h>
+#endif /*_TYPES_ */
+
+#ifndef ipBadLapErr
+#include <MacTCP.h>
+#endif
+
+
+#ifndef SOCK_STATE_NO_STREAM
+
+typedef int (*SpinFn)();
+
+
+typedef enum spin_msg
+ {
+ SP_MISC, /* some weird thing, usually just return immediately if you get this */
+ SP_SELECT, /* in a select call */
+ SP_NAME, /* getting a host by name */
+ SP_ADDR, /* getting a host by address */
+ SP_TCP_READ, /* TCP read call */
+ SP_TCP_WRITE, /* TCP write call */
+ SP_UDP_READ, /* UDP read call */
+ SP_UDP_WRITE, /* UDP write call */
+ SP_SLEEP /* sleeping, passes ticks left to sleep */
+ } spin_msg;
+
+
+/*
+ * You spin routine should look like this:
+ *
+ * void myspin(spin_msg aMsg,long data)
+ * {
+ * switch (aMsg)
+ * ...
+ * }
+ *
+ * The data param is only defined for TCP read and write.
+ * For TCP reads:
+ * Nubmer of bytes left to read in.
+ * For TCP writes:
+ * Number of bytes left to write. Note that this may be 0 for writes once all
+ * the necessary writes are queued up and the library is simply waiting for
+ * them to finish.
+ */
+
+ /*
+ * High level prototypes.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Socket.c */
+
+int s_socket(Int4 domain, Int4 type, short protocol);
+int s_bind(Int4 s, struct sockaddr *name, Int4 namelen);
+int s_connect(Int4 s, struct sockaddr *addr, Int4 addrlen);
+int s_listen(Int4 s, Int4 qlen);
+int s_accept(Int4 s, struct sockaddr *addr, Int4 *addrlen);
+int s_accept_once(Int4 s, struct sockaddr *addr, Int4 *addrlen);
+int s_close(Int4 s);
+int s_read(Int4 s, void *buffer, Int4 buflen);
+int s_recv(Int4 s, void *buffer, Int4 buflen, Int4 flags);
+int s_recvfrom(Int4 s, void *buffer, Int4 buflen, Int4 flags, struct sockaddr *from, int *fromlen);
+int s_write(Int4 s, void *buffer, Int4 buflen);
+int s_writev(Int4 s, struct iovec *iov, Int4 count);
+int s_send(Int4 s, void *buffer, Int4 buflen, Int4 flags);
+int s_sendto (Int4 s, void *buffer, Int4 buflen, Int4 flags, struct sockaddr *to, Int4 tolen);
+int s_sendmsg(Int4 s,struct msghdr *msg,Int4 flags);
+int s_really_send(Int4 s, void *buffer, Int4 count, Int4 flags, struct sockaddr_in *to);
+int s_select(Int4 width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
+int s_getdtablesize(void);
+int s_getsockname(Int4 s, struct sockaddr *name, Int4 *namelen);
+int s_getpeername(Int4 s, struct sockaddr *name, Int4 *namelen);
+int s_shutdown(Int4 s, Int4 how);
+int s_fcntl(Int4 s, /* unsigned */ Int4 cmd, Int4 arg);
+int s_dup(Int4 s);
+int s_dup2(Int4 s, Int4 s1);
+int s_ioctl(Int4 d, Int4 request, int *argp); /* argp is really a caddr_t */
+int s_setsockopt(Int4 s, Int4 level, Int4 optname, char *optval, Int4 optlen);
+int s_setspin(SpinFn routine);
+SpinFn s_getspin(void);
+
+/* Socket.stdio.c */
+
+/**** GONE ****/
+#if 0
+Ptr s_fdopen(int fd, char *type);
+int s_fileno(SocketPtr sp);
+int s_fgetc(SocketPtr sp);
+int s_ungetc(char c, SocketPtr sp);
+int s_fread(char *buffer, int size, int nitems, SocketPtr sp);
+int s_fputc(char c, SocketPtr sp);
+int s_fprintf(SocketPtr sp, char *fmt, ...);
+int s_fwrite(char *buffer, int size, int nitems, SocketPtr sp);
+int s_fflush(SocketPtr sp);
+int s_fclose(SocketPtr sp);
+int s_ferror(SocketPtr sp);
+int s_feof(SocketPtr sp);
+int s_clearerr(SocketPtr sp);
+#endif
+
+/**** unGONE ****/
+
+/* netdb.c */
+
+#ifndef SOCK_DEFS_ONLY
+
+#ifdef DONT_DEFINE_INET
+typedef unsigned long ip_addr;
+#endif /* DONT_DEFINE_INET */
+
+struct hostent *gethostbyname(char *name);
+struct hostent *gethostbyaddr(ip_addr *addrP,Int4 len,Int4 type);
+#ifndef DONT_DEFINE_INET
+char *inet_ntoa(ip_addr inaddr);
+ip_addr inet_addr(char *address);
+#endif /* DONT_DEFINE_INET */
+
+#endif /* SOCK_DEFS_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* FOLLOWING LINE ADDED FOR THINKC -- JAE 03/20/92 */
+
+
+#endif /* SOCK_STATE_NO_STREAM */
+#endif /*__socket_ext__ */
diff --git a/network/ncsasock/sock_int.h b/network/ncsasock/sock_int.h
new file mode 100644
index 00000000..a69df956
--- /dev/null
+++ b/network/ncsasock/sock_int.h
@@ -0,0 +1,153 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+ *
+ *
+ * RCS Modification History:
+ * $Log: sock_int.h,v $
+ * Revision 6.0 1997/08/25 18:38:02 madden
+ * Revision changed to 6.0
+ *
+ * Revision 4.0 1995/07/26 13:56:09 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.5 1995/06/02 16:29:03 kans
+ * *** empty log message ***
+ *
+ * Revision 1.4 1995/05/18 08:23:19 epstein
+ * add RCS modification history (after PowerPC port)
+ *
+ */
+
+/*
+ * Internal prototypes for the socket library.
+ * There is duplication between socket.ext.h and socket.int.h, but
+ * there are too many complications in combining them.
+ */
+
+#ifndef __socket_int__
+#define __socket_int__
+
+#ifdef __MWERKS__
+#include <MacTCP.h>
+#endif
+
+typedef enum spin_msg
+ {
+ SP_MISC, /* some weird thing */
+ SP_SELECT, /* in a select call */
+ SP_NAME, /* getting a host by name */
+ SP_ADDR, /* getting a host by address */
+ SP_TCP_READ, /* TCP read call */
+ SP_TCP_WRITE, /* TCP write call */
+ SP_UDP_READ, /* UDP read call */
+ SP_UDP_WRITE, /* UDP write call */
+ SP_SLEEP /* sleeping */
+ } spin_msg;
+
+
+/* spin routine prototype, doesn't work. Sigh. */
+
+extern int (*spinroutine)(int mesg,int param);
+
+/* tcpglue.c */
+
+#ifndef __MWERKS__
+#ifdef __MACTCP__
+#define TCPIOCompletionProc TCPIOCompletionUPP
+#define TCPNotifyProc TCPNotifyUPP
+#define UDPIOCompletionProc UDPIOCompletionUPP
+#else
+#define TCPIOCompletionUPP TCPIOCompletionProc
+#define TCPNotifyUPP TCPNotifyProc
+#define UDPIOCompletionUPP UDPIOCompletionProc
+#endif
+
+#endif
+
+
+OSErr xPBControlSync(TCPiopb *pb);
+OSErr xPBControl(TCPiopb *pb, TCPIOCompletionUPP completion);
+
+
+OSErr xOpenDriver(void);
+OSErr xTCPCreate(int buflen, TCPNotifyUPP notify, TCPiopb *pb);
+OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion);
+OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, TCPIOCompletionUPP completion);
+OSErr xTCPRcv(TCPiopb *pb, char *buf, int buflen, int timeout, TCPIOCompletionUPP completion);
+OSErr xTCPNoCopyRcv(TCPiopb *,rdsEntry *,int,int,TCPIOCompletionUPP);
+OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion);
+OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion);
+OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion);
+OSErr xTCPAbort(TCPiopb *pb);
+OSErr xTCPRelease(TCPiopb *pb);
+int xTCPBytesUnread(SocketPtr sp);
+int xTCPBytesWriteable(SocketPtr sp);
+int xTCPWriteBytesLeft(SocketPtr sp);
+int xTCPState(TCPiopb *pb);
+OSErr xUDPCreate(SocketPtr sp,int buflen,ip_port port);
+OSErr xUDPRead(SocketPtr sp,UDPIOCompletionUPP completion);
+OSErr xUDPBfrReturn(SocketPtr sp);
+OSErr xUDPWrite(SocketPtr sp,ip_addr host,ip_port port,miniwds *wds,
+ UDPIOCompletionUPP completion);
+OSErr xUDPRelease(SocketPtr sp);
+ip_addr xIPAddr(void);
+long xNetMask(void);
+unsigned short xMaxMTU(void);
+
+
+/* socket.tcp.c */
+pascal void sock_tcp_notify(
+ StreamPtr tcpStream,
+ unsigned short eventCode,
+ Ptr userDataPtr,
+ unsigned short terminReason,
+ ICMPReport *icmpMsg);
+int sock_tcp_new_stream(SocketPtr sp);
+int sock_tcp_connect(SocketPtr sp, struct sockaddr_in *addr);
+int sock_tcp_listen(SocketPtr sp);
+int sock_tcp_accept(SocketPtr sp, struct sockaddr_in *from, Int4 *fromlen);
+int sock_tcp_accept_once(SocketPtr sp, struct sockaddr_in *from, Int4 *fromlen);
+int sock_tcp_recv(SocketPtr sp, char *buffer, int buflen, int flags);
+int sock_tcp_can_read(SocketPtr sp);
+int sock_tcp_send(SocketPtr sp, char *buffer, int count, int flags);
+int sock_tcp_can_write(SocketPtr sp);
+int sock_tcp_close(SocketPtr sp);
+
+/* socket.udp.c */
+
+int sock_udp_new_stream(SocketPtr sp);
+int sock_udp_connect(SocketPtr sp,struct sockaddr_in *addr);
+int sock_udp_recv(SocketPtr sp, char *buffer, int buflen, int flags, struct sockaddr_in *from, int *fromlen);
+int sock_udp_can_recv(SocketPtr sp);
+int sock_udp_send(SocketPtr sp, struct sockaddr_in *to, char *buffer, int count, int flags);
+int sock_udp_can_send(SocketPtr sp);
+int sock_udp_close(SocketPtr sp);
+
+/* socket.util.c */
+
+int sock_init(void);
+void sock_close_all(void);
+int sock_free_fd(int f);
+void sock_dup_fd(int s,int s1);
+void sock_clear_fd(int s);
+void sock_init_fd(int s);
+int sock_err(int err_code);
+void sock_copy_addr(void *from, void *to, Int4 *tolen);
+void sock_dump(void);
+void sock_print(char *title, SocketPtr sp);
+StreamHashEntPtr sock_find_shep(StreamPtr);
+StreamHashEntPtr sock_new_shep(StreamPtr);
+void *sock_fetch_pb(SocketPtr);
+
+#endif /*__socket_int__ */
+
diff --git a/network/ncsasock/sock_std.c b/network/ncsasock/sock_std.c
new file mode 100644
index 00000000..631cd3e6
--- /dev/null
+++ b/network/ncsasock/sock_std.c
@@ -0,0 +1,565 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: sock_std.c,v $
+* Revision 6.1 1997/12/12 22:39:21 kans
+* DisposPtr now DisposePtr
+*
+* Revision 6.0 1997/08/25 18:38:04 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.3 1995/06/02 16:29:03 kans
+ * *** empty log message ***
+ *
+ * Revision 1.2 1995/05/17 17:57:56 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * A really hacked up stdio interface for the MacTCP socket library
+ *
+ * routines:
+ *
+ * fdopen
+ * fileno
+ * fgetc
+ * ungetc
+ * fread
+ * fputc
+ * fwrite
+ * fprintf
+ * fflush
+ * fclose
+ * ferror
+ * feof
+ * clearerr
+ *
+ * hacks:
+ *
+ * the stdio data are stored in the socket descriptor. fdopen() calls
+ * simply return a pointer to the descriptor. The first call per
+ * socket initializes stdio for both read and write. (The "rw"
+ * parameter to fdopen() is ignored.) The first fclose() will destroy
+ * all stdio streams open on the socket.
+ *
+ * ungetc will return EOF if the buffer is full.
+ *
+ * printf uses a fixed size buffer to build the message.
+ *
+ * non-blocking i/o
+ *
+ * all read operations which would block return EOF with errno set
+ * to EWOULDBLOCK courtesy of the read() call.
+ *
+ * write operations hide the EINPROGRESS 'error' from the write()
+ * call, but generate EALREADY when a second operation is attempted.
+ *
+ * NOTE: the write() call ties up the stdio buffer until it finishes.
+ *
+ * How to code a write operation....
+ *
+ * for(;;)
+ * {
+ * errno = 0;
+ * if (s_fprintf(stream, blah, blah) != EOF)
+ * break;
+ *
+ * if (errno == EALREADY)
+ * {
+ * Handle_Mac_Events();
+ * continue;
+ * }
+ * else
+ * {
+ * a real error ...
+ * }
+ * }
+ *
+ * How to code a read ...
+ *
+ * for(;;)
+ * {
+ * errno = 0;
+ * c = s_fgetc(inFile);
+ * if (c != EOF)
+ * break;
+ * if (errno == EWOULDBLOCK || errno == EALREADY)
+ * {
+ * Handle_Mac_Events();
+ * continue;
+ * }
+ * else if (errno == 0)
+ * {
+ * a real end of file ...
+ * }
+ * else
+ * {
+ * a real error ...
+ * }
+ * }
+ */
+
+#ifdef USEDUMP
+# pragma load "Socket.dump"
+
+#else
+# include <Events.h>
+# include <Memory.h>
+# include <Types.h>
+# include <Stdio.h>
+
+# include <s_types.h>
+# include <neti_in.h>
+# include <neterrno.h>
+# include <s_socket.h>
+# include <s_time.h>
+# include <s_uio.h>
+
+# include "sock_str.h"
+# include "sock_int.h"
+
+#endif
+
+#include <StdArg.h>
+
+static int stdio_write( SocketPtr sp, char *buffer, unsigned long buflen);
+
+extern SocketPtr sockets;
+extern SpinFn spinroutine;
+
+/*
+ * tuneable constants
+ */
+#define SOCK_IOINBUF_SIZE 128 /* Size of stdio input buffer */
+#define SOCK_IOOUTBUF_SIZE 128 /* Size of stdio output buffer */
+
+static struct timeval select_poll = {0,0};
+
+/*
+ * s_fdopen() - open a stdio stream on a socket
+ */
+Ptr s_fdopen(
+ int fd,
+ char *type)
+{
+#pragma unused(type)
+ SocketPtr sp;
+
+#if SOCK_STDIO_DEBUG >= 3
+ dprintf("s_fdopen: opening on fd %d\n",fd);
+#endif
+ if (! sock_good_fd(fd))
+ {
+ (void)sock_err(EBADF);
+ return(NULL);
+ }
+
+ sp = sockets+fd;
+ if (is_stdio(sp))
+ return((Ptr)sp);
+
+ sp->inbuf = (char *)NewPtr(SOCK_IOINBUF_SIZE);
+ if (sp->inbuf == NULL)
+ {
+ errno = ENOMEM;
+ return(NULL);
+ }
+ sp->outbuf = (char *)NewPtr(SOCK_IOOUTBUF_SIZE);
+ if (sp->outbuf == NULL)
+ {
+ DisposePtr(sp->inbuf);
+ errno = ENOMEM;
+ return(NULL);
+ }
+
+ sp->inbufptr = sp->inbuf;
+ sp->inbufcount = 0;
+ sp->outbufptr = sp->outbuf;
+ sp->outbufcount = 0;
+
+ sp->ioerr = false;
+ sp->ioeof = false;
+
+ return((Ptr)sp);
+}
+
+/*
+ * s_fileno()
+ */
+int s_fileno(
+ SocketPtr sp)
+{
+#if SOCK_STDIO_DEBUG >= 3
+ dprintf("s_fileno: on FILE * %08x\n",sp);
+#endif
+ if (! is_stdio(sp))
+ {
+ return(sock_err(EBADF));
+ return(EOF);
+ }
+#if SOCK_STDIO_DEBUG >= 5
+ dprintf(" returning fd %d\n",sp->fd);
+#endif
+ return(sp->fd);
+}
+
+/*
+ * s_fgetc()
+ *
+ */
+int s_fgetc(
+ SocketPtr sp)
+{
+ char c;
+
+ if (stdio_read(sp, &c, 1) != 1)
+ return(EOF);
+
+ return(c);
+}
+
+/*
+ * s_ungetc()
+ *
+ */
+int s_ungetc(
+ char c,
+ SocketPtr sp)
+{
+
+#if SOCK_STDIO_DEBUG >=3
+ dprintf("s_ungetc: %08x\n",sp);
+#endif
+
+ if (! is_stdio(sp))
+ {
+ (void)sock_err(EBADF);
+ return(EOF);
+ }
+
+ if (sp->ioeof) /* Once an EOF; Always an EOF */
+ return(EOF);
+
+ /*
+ * Pop onto buffer, if there is room.
+ */
+ if (sp->inbufptr == sp->inbuf)
+ return(EOF);
+ else
+ {
+ *(sp->inbufptr++) = c;
+ sp->inbufcount++;
+ return(0);
+ }
+}
+
+/*
+ * s_fread()
+ */
+int s_fread(
+ char *buffer,
+ int size,
+ int nitems,
+ SocketPtr sp)
+{
+ return(stdio_read(sp, buffer, size*nitems));
+}
+
+/*
+ * stdio_read()
+ *
+ * Buffered i/o. Read buflen chars into buf.
+ * Returns length read, EOF on error.
+ */
+static int stdio_read(
+ SocketPtr sp,
+ char *buffer,
+ int buflen)
+{
+ unsigned long tocopy;
+ Ptr buf;
+ unsigned long len;
+ int cache = false; /* a flag ===> read into sp->inbuf */
+
+#if SOCK_STDIO_DEBUG >=3
+ dprintf("stdio_read: %08x for %d bytes\n",sp,buflen);
+#endif
+
+ if (! is_stdio(sp))
+ {
+ (void)sock_err(EBADF);
+ return(EOF);
+ }
+
+ if (sp->ioeof) /* Once an EOF; Always an EOF */
+ return(EOF);
+
+ /*
+ * return already buffered characters
+ */
+ if (sp->inbufcount != 0)
+ {
+ tocopy = min(sp->inbufcount, buflen);
+ bcopy(sp->inbufptr, buffer, tocopy);
+ sp->inbufptr += tocopy;
+ sp->inbufcount -= tocopy;
+ return(tocopy);
+ }
+
+ if (buflen > SOCK_IOINBUF_SIZE)
+ {
+ /*
+ * Read into user's buffer
+ */
+ buf = buffer;
+ len = buflen;
+ }
+ else
+ {
+ /*
+ * Read into stdio buffer
+ */
+ cache = true;
+ buf = sp->inbuf;
+ len = SOCK_IOINBUF_SIZE;
+ }
+
+ len = s_read(sp->fd, buf, len);
+ switch(len)
+ {
+ case -1:
+ sp->ioerr = true;
+ return(EOF);
+
+ case 0:
+ sp->ioeof = true;
+ return(EOF);
+ }
+ if (cache)
+ {
+ tocopy = min(buflen, len);
+ bcopy(sp->inbuf, buffer, tocopy); /* copy to client's buffer */
+ sp->inbufcount = len - tocopy;
+ sp->inbufptr = sp->inbuf + tocopy;
+ return(tocopy);
+ }
+ return(len);
+}
+
+
+/*
+ * s_fputc()
+ *
+ */
+int s_fputc(
+ char c,
+ SocketPtr sp)
+{
+ if (stdio_write(sp, &c, 1) == EOF)
+ return(EOF);
+
+ return(c);
+}
+
+/*
+ * s_fprintf()
+ * Modified to use StdArg macros by Charlie Reiman
+ * Wednesday, August 8, 1990 2:52:31 PM
+ *
+ */
+int s_fprintf(
+ SocketPtr sp,
+ char *fmt,
+ ...)
+{
+ va_list nextArg;
+ int len;
+ char buf[1000];
+
+ va_start(nextArg,fmt);
+
+ (void) vsprintf(buf,fmt,nextArg);
+ len = strlen(buf);
+ return(stdio_write(sp, buf, len));
+}
+
+/*
+ * s_fwrite()
+ *
+ */
+
+int s_fwrite(
+ char *buffer,
+ int size,
+ int nitems,
+ SocketPtr sp)
+{
+ return(stdio_write(sp, buffer, size*nitems));
+}
+
+/*
+ * stdio_write()
+ *
+ * Buffered i/o. Move buflen chars into stdio buf., writing out as necessary.
+ * Returns # of characters written, or EOF.
+ */
+static int stdio_write(
+ SocketPtr sp,
+ char *buffer,
+ unsigned long buflen)
+{
+ long buffree;
+ struct iovec iov[2];
+
+#if SOCK_STDIO_DEBUG >=3
+ dprintf("stdio_write: %08x for %d bytes\n",sp,buflen);
+#endif
+
+ if (! is_stdio(sp))
+ {
+ (void) sock_err(EBADF);
+ return(EOF);
+ }
+
+ /* will the new stuff fit in the buffer? */
+ buffree = SOCK_IOOUTBUF_SIZE - sp->outbufcount;
+ if (buflen < buffree)
+ {
+ /* yes...add it in */
+ bcopy(buffer, sp->outbufptr, buflen);
+ sp->outbufptr += buflen;
+ sp->outbufcount += buflen;
+ return(buflen);
+ }
+ else
+ {
+ /* no...send both buffers now */
+ iov[0].iov_len = sp->outbufcount;
+ iov[0].iov_base = sp->outbuf;
+ iov[1].iov_len = buflen;
+ iov[1].iov_base = buffer;
+ /* hide the 'error' generated by a non-blocking write */
+ if (s_writev(sp->fd,&iov[0],2) < 0 && errno != EINPROGRESS)
+ {
+ sp->ioerr = true;
+ return(EOF);
+ }
+
+ sp->outbufptr = sp->outbuf;
+ sp->outbufcount = 0;
+
+ return(buflen);
+ }
+}
+
+/*
+ * s_fflush()
+ *
+ */
+int s_fflush(
+ SocketPtr sp)
+{
+#if SOCK_STDIO_DEBUG >=3
+ dprintf("s_fflush: %08x\n",sp);
+#endif
+ if (! is_stdio(sp))
+ {
+ (void)sock_err(EBADF);
+ return(EOF);
+ }
+
+ if (sp->outbufcount == 0)
+ return(0);
+
+ if (s_write(sp->fd,sp->outbuf,sp->outbufcount) < 0)
+ /* hide the 'error' generated by non-blocking I/O */
+ if (errno != EINPROGRESS)
+ {
+ sp->ioerr = true;
+ return(EOF);
+ }
+
+ sp->outbufptr = sp->outbuf;
+ sp->outbufcount = 0;
+ return(0);
+}
+
+/*
+ * s_fclose() - close the stdio stream AND the underlying socket
+ */
+int s_fclose(
+ SocketPtr sp)
+{
+#if SOCK_STDIO_DEBUG >=3
+ dprintf("s_fclose: %08x\n",sp);
+#endif
+
+ if (s_fflush(sp) == EOF) /* flush validates sp */
+ return(EOF);
+
+ if (sp->inbuf != NULL) DisposePtr(sp->inbuf);
+ if (sp->outbuf != NULL) DisposePtr(sp->outbuf);
+
+ return(s_close(sp->fd));
+}
+
+/*
+ * s_ferror()
+ */
+int s_ferror(
+ SocketPtr sp)
+{
+ if (! is_stdio(sp))
+ {
+ (void)sock_err(EBADF);
+ return(EOF);
+ }
+ return(sp->ioerr);
+}
+
+/*
+ * s_feof()
+ */
+int s_feof(
+ SocketPtr sp)
+{
+ if (! is_stdio(sp))
+ {
+ (void)sock_err(EBADF);
+ return(EOF);
+ }
+ return(sp->ioeof);
+}
+
+/*
+ * s_clearerr()
+ */
+int s_clearerr(
+ SocketPtr sp)
+{
+ if (! is_stdio(sp))
+ {
+ (void)sock_err(EBADF);
+ return(EOF);
+ }
+ sp->ioerr = false;
+ sp->ioeof = false;
+ return (0);
+}
+
diff --git a/network/ncsasock/sock_str.h b/network/ncsasock/sock_str.h
new file mode 100644
index 00000000..da79ee00
--- /dev/null
+++ b/network/ncsasock/sock_str.h
@@ -0,0 +1,178 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: sock_str.h,v $
+* Revision 6.0 1997/08/25 18:38:06 madden
+* Revision changed to 6.0
+*
+* Revision 4.1 1997/01/29 00:12:00 kans
+* include <MacTCP.h> instead of obsolete <MacTCPCommonTypes.h>
+*
+ * Revision 4.0 1995/07/26 13:56:09 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.3 1995/05/23 15:31:16 kans
+ * new CodeWarrior 6 errors and warnings fixed
+ *
+ * Revision 1.2 1995/05/17 17:57:59 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * Internal Structures for the Toronto socket library
+ * Most of the complicated header stuff goes here.
+ */
+
+#ifndef ipBadLapErr
+#include <MacTCP.h>
+#endif
+#ifdef ParamBlockHeader
+#undef ParamBlockHeader
+#endif
+#include <GetMyIPAddr.h>
+#include <TCPPB.h>
+#include <UDPPB.h>
+#include <AddressXlation.h>
+
+#ifdef __MWERKS__
+typedef unsigned char byte;
+#endif
+
+#define TCPStateClosed 0
+#define TCPStateListen 2
+#define TCPStateSynReceived 4
+#define TCPStateSynSent 6
+#define TCPStateEstablished 8
+#define TCPStateFinWait1 10
+#define TCPStateFinWait2 12
+#define TCPStateCloseWait 14
+#define TCPStateClosing 16
+#define TCPStateLastAck 18
+#define TCPStateTimeWait 20
+
+/* NUM_SOCKETS must be a power of 2 for the stream->socket hasing to work */
+#define NUM_SOCKETS 32 /* Number of sockets. Should never exceed 32 */
+#define SOCKETS_MASK (NUM_SOCKETS-1) /* used for hash table wrap around via bitwise and */
+#define NUM_PBS (NUM_SOCKETS+1) /* number of pbs in global pool */
+
+#define STREAM_BUFFER_SIZE 32768 /* memory for MacTCP streams */
+
+#define UDP_MAX_MSG 65507 /* MacTCP max legal udp message */
+#define TCP_MAX_MSG 65535 /* MacTCP max legal tcp message */
+
+#define TCP_MAX_WDS 4 /* arbitrary number of wds to alloc in sock_tcp_send */
+
+/*
+ * In use and shutdown status.
+ */
+#define SOCK_STATUS_USED 0x1 /* Used socket table entry */
+#define SOCK_STATUS_NOREAD 0x2 /* No more reading allowed from socket */
+#define SOCK_STATUS_NOWRITE 0x4 /* No more writing allowed to socket */
+
+/*
+ * Socket connection states.
+ */
+#define SOCK_STATE_NO_STREAM 0 /* Socket doesn't have a MacTCP stream yet */
+#define SOCK_STATE_UNCONNECTED 1 /* Socket is unconnected. */
+#define SOCK_STATE_LISTENING 2 /* Socket is listening for connection. */
+#define SOCK_STATE_LIS_CON 3 /* Socket is in transition from listen to connected. */
+#define SOCK_STATE_CONNECTING 4 /* Socket is initiating a connection. */
+#define SOCK_STATE_CONNECTED 5 /* Socket is connected. */
+#define SOCK_STATE_CLOSING 6 /* Socket is closing */
+
+typedef union AllPb
+ {
+ TCPiopb tcp;
+ UDPiopb udp;
+ } AllPb;
+
+typedef struct SocketRecord
+{
+ StreamPtr stream; /* stream pointer */
+ byte status; /* Is file descriptor in use */
+ int fd; /* fd number */
+ short protocol; /* Protocol (e.g. TCP, UDP) */
+ Boolean nonblocking;/* socket set for non-blocking I/O. */
+ char *recvBuf; /* receive buffer */
+ int recvd; /* amount received */
+ int torecv; /* amount to receive */
+ struct sockaddr_in sa; /* My address. */
+ struct sockaddr_in peer; /* Her address. */
+ byte sstate; /* socket's connection state. */
+ unsigned long dataavail; /* Amount of data available on connection. */
+ int asyncerr; /* Last async error to arrive. zero if none. */
+ /* stdio stuff */
+#ifndef DONT_INCLUDE_SOCKET_STDIO
+ char *outbuf; /* Ptr to array to buffer output */
+ int outbufcount;/* # of characters in outbuf */
+ Ptr outbufptr; /* Pointer into outbuf */
+ char *inbuf; /* Ptr to array to buffer input */
+ int inbufcount; /* # of characters in inbuf */
+ Ptr inbufptr; /* Pointer into inbuf */
+ Boolean ioerr; /* Holds error status for stdio calls */
+ Boolean ioeof; /* EOF was detected on stream */
+#endif
+} SocketRecord, *SocketPtr;
+
+/*
+ * Quick note for hash table:
+ * Stream = 0 => unused
+ * Stream = -1 => deleted
+ * Stream = anything else => stream ptr
+ */
+typedef struct StreamHashEnt
+ {
+ StreamPtr stream;
+ SocketPtr socket;
+ } StreamHashEnt, *StreamHashEntPtr;
+
+typedef struct miniwds
+ {
+ unsigned short length;
+ char * ptr;
+ unsigned short terminus; /* must be zero'd for use */
+ } miniwds;
+
+#ifndef __socket_ext__
+typedef int (*SpinFn)();
+#endif /* __socket_ext__ */
+
+/*-------------------------------------------------------------------------*/
+#define SOCK_MIN_PTR (Ptr)0x1400 /* Minimum reasonable pointer */
+#define goodptr(p) (((Ptr) p) > SOCK_MIN_PTR)
+#define is_used(p) (goodptr(p) && (p)->status & SOCK_STATUS_USED)
+#define is_stdio(p) (is_used(p) && (p)->inbuf != NULL)
+#define sock_good_fd(s) ((0 <= s && s < NUM_SOCKETS) && is_used (sockets+s))
+#define sock_nowrite(p) ((p)->status & SOCK_STATUS_NOWRITE)
+#define sock_noread(p) ((p)->status & SOCK_STATUS_NOREAD)
+
+#define TVTOTICK(tvsec,tvusec) ( ((tvsec)*60) + ((tvusec)/16666) )
+#define min(a,b) ( (a) < (b) ? (a) : (b))
+#define max(a,b) ( (a) > (b) ? (a) : (b))
+
+/* SPIN returns a -1 on user cancel for fn returning integers */
+#define SPIN(cond,mesg,param) do {if (spinroutine)\
+ if ((*spinroutine)(mesg,param))\
+ return -1;\
+ }while(cond);
+
+/* SPINP returns a NULL on user cancel, for fn returning pointers */
+#define SPINP(cond,mesg,param) do {if (spinroutine)\
+ if ((*spinroutine)(mesg,param))\
+ return NULL;\
+ }while(cond);
+
+
diff --git a/network/ncsasock/sock_tcp.c b/network/ncsasock/sock_tcp.c
new file mode 100644
index 00000000..68c5f41b
--- /dev/null
+++ b/network/ncsasock/sock_tcp.c
@@ -0,0 +1,1035 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+ *
+ *
+ * RCS Modification History:
+ * $Log: sock_tcp.c,v $
+ * Revision 6.0 1997/08/25 18:38:08 madden
+ * Revision changed to 6.0
+ *
+ * Revision 4.0 1995/07/26 13:56:09 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.8 1995/05/23 15:31:16 kans
+ * new CodeWarrior 6 errors and warnings fixed
+ *
+ * Revision 1.7 1995/05/18 08:23:16 epstein
+ * add RCS modification history (after PowerPC port)
+ *
+ */
+
+#ifdef USEDUMP
+# pragma load "Socket.dump"
+
+#else
+# include <Events.h>
+# include <Memory.h>
+# include <Types.h>
+# include <OSUtils.h> /* for SysBeep */
+# include <Events.h> /* for TickCount */
+# include <Stdio.h>
+#ifdef __MWERKS__
+#include <MacTCP.h>
+#endif
+
+
+# include <s_types.h>
+# include <neti_in.h>
+# include <neterrno.h>
+# include <s_socket.h>
+# include <s_time.h>
+# include <s_uio.h>
+
+# include "sock_str.h"
+# include "sock_int.h"
+
+#endif
+
+#if !defined(THINK_C) && !defined(__MWERKS__)
+# include "sock_int.h"
+#endif
+
+extern SocketPtr sockets;
+extern SpinFn spinroutine; /* The spin routine. */
+
+static void sock_tcp_send_done(TCPiopb *pb);
+static void sock_tcp_listen_done(TCPiopb *pb);
+static void sock_tcp_connect_done(TCPiopb *pb);
+static void sock_tcp_recv_done(TCPiopb *pb);
+
+
+static TCPNotifyUPP sock_tcp_notify_proc ;
+static TCPIOCompletionUPP sock_tcp_connect_done_proc ;
+static TCPIOCompletionUPP sock_tcp_listen_done_proc ;
+static TCPIOCompletionUPP sock_tcp_send_done_proc ;
+static TCPIOCompletionUPP sock_tcp_recv_done_proc ;
+
+#ifndef __MACTCP__
+#if GENERATINGCFM
+#define NewTCPNotifyProc(userRoutine) \
+ (TCPNotifyUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppTCPNotifyProcInfo, GetCurrentArchitecture())
+#else
+#define NewTCPNotifyProc(userRoutine) \
+ ((TCPNotifyUPP) (userRoutine))
+#endif
+
+#if GENERATINGCFM
+#define NewTCPIOCompletionProc(userRoutine) \
+ (TCPIOCompletionUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppTCPIOCompletionProcInfo, GetCurrentArchitecture())
+#else
+#define NewTCPIOCompletionProc(userRoutine) \
+ ((TCPIOCompletionUPP) (userRoutine))
+#endif
+#endif
+
+void sock_tcp_init ( void )
+{
+ sock_tcp_notify_proc = NewTCPNotifyProc(sock_tcp_notify);
+ sock_tcp_connect_done_proc = NewTCPIOCompletionProc (sock_tcp_connect_done);
+ sock_tcp_listen_done_proc = NewTCPIOCompletionProc (sock_tcp_listen_done);
+ sock_tcp_send_done_proc = NewTCPIOCompletionProc (sock_tcp_send_done);
+ sock_tcp_recv_done_proc = NewTCPIOCompletionProc (sock_tcp_recv_done);
+
+}
+
+/*
+ * sock_tcp_new_stream
+ *
+ * Create a new tcp stream.
+ */
+int sock_tcp_new_stream(
+ SocketPtr sp)
+{
+ OSErr io;
+ TCPiopb pb;
+ StreamHashEntPtr shep;
+
+#if SOCK_TCP_DEBUG >= 2
+ sock_print("sock_tcp_new_stream", sp);
+#endif
+
+ sock_tcp_init() ;
+
+ io = xTCPCreate(STREAM_BUFFER_SIZE, sock_tcp_notify_proc, &pb);
+ switch(io)
+ {
+ case noErr: break;
+ case streamAlreadyOpen: return(sock_err(io));
+ case invalidLength: return(sock_err(ENOBUFS));
+ case invalidBufPtr: return(sock_err(ENOBUFS));
+ case insufficientResources: return(sock_err(EMFILE));
+ default: /* error from PBOpen */ return(sock_err(ENETDOWN));
+ }
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+ sp->peer.sin_family = AF_INET;
+ sp->peer.sin_addr.s_addr = 0;
+ sp->peer.sin_port = 0;
+ bzero(&sp->peer.sin_zero[0], 8);
+ sp->dataavail = 0;
+ sp->asyncerr = 0;
+ sp->stream = pb.tcpStream;
+
+ if ((shep = sock_new_shep(sp->stream))!=NULL)
+ {
+ shep -> stream = sp->stream;
+ shep -> socket = sp;
+ return(0);
+ }
+ else
+ return -1;
+}
+
+
+
+/*
+ * sock_tcp_connect - initiate a connection on a TCP socket
+ *
+ */
+int sock_tcp_connect(
+ SocketPtr sp,
+ struct sockaddr_in *addr)
+{
+ OSErr io;
+ TCPiopb *pb;
+
+#if SOCK_TCP_DEBUG >= 2
+ sock_print("sock_tcp_connect",sp);
+#endif
+
+ /* Make sure this socket can connect. */
+ if (sp->sstate == SOCK_STATE_CONNECTING)
+ return(sock_err(EALREADY));
+ if (sp->sstate != SOCK_STATE_UNCONNECTED)
+ return(sock_err(EISCONN));
+
+ sp->sstate = SOCK_STATE_CONNECTING;
+
+ if (!(pb=sock_fetch_pb(sp)))
+ return sock_err(ENOMEM);
+
+#ifdef __MACTCP__
+ io = xTCPActiveOpen(pb, sp->sa.sin_port,addr->sin_addr.s_addr, addr->sin_port,
+ sock_tcp_connect_done_proc);
+#else
+ io = xTCPActiveOpen(pb, sp->sa.sin_port,addr->sin_addr.s_addr, addr->sin_port,
+ sock_tcp_connect_done);
+#endif
+
+ if (io != noErr)
+ {
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+ return(sock_err(io));
+ }
+
+ if (sp->nonblocking)
+ return(sock_err(EINPROGRESS));
+
+ /* sync connect - spin till TCPActiveOpen completes */
+
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("spinning in connect\n");
+#endif
+
+ SPIN (pb->ioResult==inProgress,SP_MISC,0L)
+
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("done spinning\n");
+#endif
+
+ if ( pb->ioResult != noErr )
+ return sock_err(pb->ioResult);
+ else
+ return 0;
+}
+
+
+/*
+ * sock_tcp_listen() - put s into the listen state.
+ */
+int sock_tcp_listen(
+ SocketPtr sp)
+{
+ OSErr io;
+ TCPiopb *pb;
+
+#if SOCK_TCP_DEBUG >= 2
+ sock_print("sock_tcp_listen",sp);
+#endif
+
+ if (!(pb = sock_fetch_pb(sp)))
+ return (sock_err(ENOMEM));
+
+ if (sp->sstate != SOCK_STATE_UNCONNECTED)
+ return(sock_err(EISCONN));
+
+ sp->sstate = SOCK_STATE_LISTENING;
+
+#ifdef __MACTCP__
+ io = xTCPPassiveOpen(pb, sp->sa.sin_port, sock_tcp_listen_done_proc);
+#else
+ io = xTCPPassiveOpen(pb, sp->sa.sin_port, sock_tcp_listen_done);
+#endif
+ if (io != noErr)
+ {
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+ return(sock_err(io));
+ }
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_listen: about to spin for port number - ticks %d\n",
+ TickCount());
+#endif
+ while (pb->csParam.open.localPort == 0)
+ {
+#if SOCK_TCP_DEBUG >= 5
+ tcpCheckNotify();
+#endif
+ SPIN(false,SP_MISC,0L)
+ }
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_listen: port number is %d ticks %d\n",
+ pb->csParam.open.localPort,TickCount());
+#endif
+ sp->sa.sin_addr.s_addr = pb->csParam.open.localHost;
+ sp->sa.sin_port = pb->csParam.open.localPort;
+ return(0);
+}
+
+/*
+ * sock_tcp_accept()
+ */
+int sock_tcp_accept(
+ SocketPtr sp,
+ struct sockaddr_in *from,
+ Int4 *fromlen)
+{
+ int s1;
+ TCPiopb *pb;
+ StreamHashEntPtr shep;
+
+#if SOCK_TCP_DEBUG >= 2
+ sock_print("sock_tcp_accept",sp);
+#endif
+
+ if (sp->sstate == SOCK_STATE_UNCONNECTED)
+ {
+ if (sp->asyncerr != 0)
+ {
+ (void) sock_err(sp->asyncerr);
+ sp->asyncerr = 0;
+ return(-1);
+ }
+ else
+ return(sock_err(ENOTCONN));
+ }
+ if (sp->sstate != SOCK_STATE_LISTENING && sp->sstate != SOCK_STATE_LIS_CON)
+ return(sock_err(ENOTCONN));
+
+ if (sp->sstate == SOCK_STATE_LISTENING)
+ {
+ if (sp->nonblocking)
+ return(sock_err(EWOULDBLOCK));
+
+ /* Spin till sock_tcp_listen_done runs. */
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("--- blocking...\n");
+#endif
+
+ SPIN(sp->sstate == SOCK_STATE_LISTENING,SP_MISC,0L);
+
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("--- done blocking...\n");
+#endif
+
+ /* got notification - was it success? */
+ if (sp->sstate != SOCK_STATE_LIS_CON)
+ {
+#if SOCK_TCP_DEBUG >=3
+ dprintf("--- failed state %04x code %d\n",sp->sstate,sp->asyncerr);
+#endif
+ (void) sock_err(sp->asyncerr);
+ sp->asyncerr = 0;
+ return(-1);
+ }
+ }
+#if SOCK_TCP_DEBUG >= 3
+ dprintf("sock_tcp_accept: Have connection, peer is %08x/%d, duplicating socket.\n",
+ sp->peer.sin_addr,sp->peer.sin_port);
+#endif
+ /*
+ * Have connection. Duplicate this socket. The client gets the connection
+ * on the new socket and I create a new stream on the old socket and put it
+ * in listen state.
+ */
+ sp->sstate = SOCK_STATE_CONNECTED;
+
+ s1 = sock_free_fd(0);
+ if (s1 < 0)
+ {
+ /* No descriptors left. Abort the incoming connection. */
+#if SOCK_TCP_DEBUG >= 2
+ dprintf("sock_tcp_accept: No descriptors left.\n");
+#endif
+ if (!(pb = sock_fetch_pb (sp)))
+ return sock_err(ENOMEM);
+
+ (void) xTCPAbort(pb);
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+
+ /* try and put the socket back in listen mode */
+ if (sock_tcp_listen(sp) < 0)
+ {
+#if SOCK_TCP_DEBUG >= 1
+ dprintf("sock_tcp_accept: sock_tcp_listen fails\n");
+#endif
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+ return(-1); /* errno already set */
+ }
+ return(sock_err(EMFILE));
+ }
+
+ /* copy the incoming connection to the new socket */
+ sock_dup_fd(sp->fd,s1);
+#if SOCK_TCP_DEBUG >= 3
+ dprintf("sock_tcp_accept: new socket is %d\n",s1);
+ sock_dump();
+#endif
+
+ /* quitely adjust the StreamHash table */
+ if ((shep = sock_find_shep(sp->stream))!=NULL)
+ {
+ shep->socket = sockets+s1; /* point to new socket */
+ }
+
+ /* Create a new MacTCP stream on the old socket and put it into */
+ /* listen state to accept more connections. */
+ if (sock_tcp_new_stream(sp) < 0 || sock_tcp_listen(sp) < 0)
+ {
+#if SOCK_TCP_DEBUG >= 2
+ dprintf("accept: failed to restart old socket\n");
+#endif
+ /* nothing to listen on */
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+
+ /* kill the incoming connection */
+ if (!(pb=sock_fetch_pb(sockets+s1)))
+ return sock_err(ENOMEM);
+
+ xTCPRelease(pb);
+ sock_clear_fd(s1);
+
+ return(-1); /* errno set */
+ }
+#if SOCK_TCP_DEBUG >= 3
+ dprintf("sock_tcp_accept: got new stream\n");
+ sock_dump();
+#endif
+
+ /* return address of partner */
+ sock_copy_addr(&sockets[s1].peer, from, fromlen);
+
+ return(s1);
+}
+
+/*
+ * sock_tcp_accept_once()
+ */
+int sock_tcp_accept_once(
+ SocketPtr sp,
+ struct sockaddr_in *from,
+ Int4 *fromlen)
+{
+
+#if SOCK_TCP_DEBUG >= 2
+ sock_print("sock_tcp_accept_once",sp);
+#endif
+
+ if (sp->sstate == SOCK_STATE_UNCONNECTED)
+ {
+ if (sp->asyncerr != 0)
+ {
+ (void) sock_err(sp->asyncerr);
+ sp->asyncerr = 0;
+ return(-1);
+ }
+ else
+ return(sock_err(ENOTCONN));
+ }
+ if (sp->sstate != SOCK_STATE_LISTENING && sp->sstate != SOCK_STATE_LIS_CON)
+ return(sock_err(ENOTCONN));
+
+ if (sp->sstate == SOCK_STATE_LISTENING)
+ {
+ if (sp->nonblocking)
+ return(sock_err(EWOULDBLOCK));
+
+ /* Spin till sock_tcp_listen_done runs. */
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("--- blocking...\n");
+#endif
+
+ SPIN(sp->sstate == SOCK_STATE_LISTENING,SP_MISC,0L);
+
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("--- done blocking...\n");
+#endif
+
+ /* got notification - was it success? */
+ if (sp->sstate != SOCK_STATE_LIS_CON)
+ {
+#if SOCK_TCP_DEBUG >=3
+ dprintf("--- failed state %04x code %d\n",sp->sstate,sp->asyncerr);
+#endif
+ (void) sock_err(sp->asyncerr);
+ sp->asyncerr = 0;
+ return(-1);
+ }
+ }
+#if SOCK_TCP_DEBUG >= 3
+ dprintf("sock_tcp_accept_once: Have connection, peer is %08x/%d.\n",
+ sp->peer.sin_addr,sp->peer.sin_port);
+#endif
+ /*
+ * Have connection.
+ */
+ sp->sstate = SOCK_STATE_CONNECTED;
+
+ /* return address of partner */
+ sock_copy_addr(&(sp->peer), from, fromlen);
+
+ return(0);
+}
+
+/*
+ * sock_tcp_recv()
+ *
+ * returns bytes received or -1 and errno
+ */
+int sock_tcp_recv(
+ SocketPtr sp,
+ char *buffer,
+ int buflen,
+ int flags)
+{
+#pragma unused(flags)
+ TCPiopb *pb;
+ int iter; /* iteration */
+
+#if SOCK_TCP_DEBUG >= 2
+ sock_print("sock_tcp_recv",sp);
+#endif
+
+ /* socket hasn't finished connecting yet */
+ if (sp->sstate == SOCK_STATE_CONNECTING)
+ {
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_recv: connection still in progress\n");
+#endif
+ if (sp->nonblocking)
+ return(sock_err(EWOULDBLOCK));
+
+ /* async connect and sync recv? */
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_recv: spinning on connect\n");
+#endif
+
+ SPIN(sp->sstate == SOCK_STATE_CONNECTING,SP_MISC,0L)
+
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_recv: done spinning\n");
+#endif
+ }
+
+ /* socket is not connected */
+ if (! (sp->sstate == SOCK_STATE_CONNECTED))
+ {
+ /* see if the connect died (pretty poor test) */
+ if (sp->sstate == SOCK_STATE_UNCONNECTED && sp->asyncerr != 0)
+ {
+ (void) sock_err(sp->asyncerr);
+ sp->asyncerr = 0;
+ return(-1);
+ }
+
+ /* I guess he just forgot */
+ return(sock_err(ENOTCONN));
+ }
+
+ if (sp->dataavail == 0)
+ sp->dataavail = xTCPBytesUnread(sp); /* sync. call */
+#if SOCK_TCP_DEBUG >= 3
+ dprintf("sock_tcp_recv: %d bytes available\n", sp->dataavail);
+#endif
+ if (sp->nonblocking && sp->dataavail == 0)
+ return(sock_err(EWOULDBLOCK));
+
+ sp->torecv = 1; /* # of bytes to try to receive */
+ sp->recvBuf = buffer;
+ sp->recvd = 0; /* count of bytes received */
+ pb = sock_fetch_pb(sp);
+
+ /* make 2 iterations; on 1st try, read 1 byte; on 2nd, read
+ all outstanding available bytes, up to buflen ... this mechanism seems to
+ be necessary for decent performance, because TCPRcv only completes when one
+ of the following takes place:
+ * enough data has arrived to fill the receive buffer
+ * pushed data arrives
+ * urgent data is outstanding
+ * some reasonable period passes after the arrival of nonpushed, nonurgent data
+ * the amount of data received is greater than or equal to 25 percent of the total
+ receive buffering for this stream
+ * the command time-out expires
+
+ In the case when a caller has requested N bytes, and the data is "normal" TCP
+ data, the "reasonable" period must expire before this function will return. This
+ "reasonable" period appears to be about one second (MacTCP version 1.1), and is
+ not configurable. The hope in the algorithm implemented here is that a reasonable
+ amount of data will arrive along with the first byte, and that the caller is
+ capable of issuing another read() to obtain more data. The one-second "reasonable"
+ delay is thus eliminated.
+
+ J. Epstein, NCBI, 06/24/92
+ */
+
+ for (iter = 0; iter < 2; iter++) {
+
+ sp->asyncerr = inProgress;
+
+ xTCPRcv(pb, sp->recvBuf, min (sp->torecv,TCP_MAX_MSG),0,sock_tcp_recv_done_proc);
+
+ SPIN(sp->torecv&&(pb->ioResult==noErr||pb->ioResult==inProgress),
+ SP_TCP_READ,sp->torecv)
+
+ if ( pb->ioResult == commandTimeout )
+ pb->ioResult = noErr;
+
+ switch(pb->ioResult)
+ {
+ case noErr:
+#if SOCK_TCP_DEBUG >= 3
+ dprintf("sock_tcp_recv: got %d bytes\n", sp->recvd);
+#endif
+ sp->dataavail = xTCPBytesUnread(sp);
+ sp->asyncerr = noErr;
+ if (sp->dataavail <= 0 || buflen <= 1 || iter == 1)
+ return(sp->recvd);
+ /* loop back and obtain the remaining outstanding data */
+ sp->torecv = min(sp->dataavail, buflen - 1);
+ sp->recvBuf = &buffer[1];
+ break;
+
+ case connectionClosing:
+#if SOCK_TCP_DEBUG >= 2
+ dprintf("sock_tcp_recv: connection closed\n");
+#endif
+ return (sp->recvd);
+ break;
+
+
+ case connectionTerminated:
+ /* The connection is aborted. */
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+#if SOCK_TCP_DEBUG >= 1
+ dprintf("sock_tcp_recv: connection gone!\n");
+#endif
+ return(sock_err(ENOTCONN));
+
+ case commandTimeout: /* this one should be caught by sock_tcp_recv_done */
+ case connectionDoesntExist:
+ case invalidStreamPtr:
+ case invalidLength:
+ case invalidBufPtr:
+ default:
+ return(sock_err(pb->ioResult));
+ }
+ }
+ return(0);
+}
+
+/*
+ * sock_tcp_can_read() - returns non-zero if data or a connection is available
+ * must also return one if the connection is down to force an exit from the
+ * select routine (select is the only thing that uses this).
+ */
+int sock_tcp_can_read(SocketPtr sp)
+ {
+ TCPiopb *pb;
+
+ if (sp->sstate == SOCK_STATE_LIS_CON)
+ return(1);
+
+ else if (sp->sstate == SOCK_STATE_CONNECTED)
+ {
+ if (!(pb=sock_fetch_pb(sp)))
+ return sock_err (ENOMEM);
+
+ sp->dataavail = xTCPBytesUnread(sp);
+ if (sp->dataavail > 0)
+ return(1);
+ }
+ else if ( ( sp->sstate == SOCK_STATE_UNCONNECTED ) ||
+ ( sp->sstate == SOCK_STATE_CLOSING ) )
+ return 1;
+
+ return(0);
+ }
+
+/* avoid using standard library here because size of an int may vary externally */
+void *sock_memset(void *s, int c, size_t n)
+{
+ char *t = s;
+
+ for (; n > 0; n--, t++)
+ *t = c;
+ return((void *)0);
+}
+
+
+/*
+ * sock_tcp_send() - send data
+ *
+ * returns bytes sent or -1 and errno
+ */
+int sock_tcp_send(
+ SocketPtr sp,
+ char *buffer,
+ int count,
+ int flags)
+{
+ int bytes,towrite;
+ miniwds *thiswds;
+ short wdsnum;
+ TCPiopb *pb;
+ miniwds wdsarray[TCP_MAX_WDS];
+
+#if SOCK_TCP_DEBUG >= 2
+ sock_print("sock_tcp_send",sp);
+#endif
+
+ /* socket hasn't finished connecting yet */
+ if (sp->sstate == SOCK_STATE_CONNECTING)
+ {
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_send: connection still in progress\n");
+#endif
+ if (sp->nonblocking)
+ return(sock_err(EALREADY));
+
+ /* async connect and sync send? */
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_send: spinning on connect\n");
+#endif
+ while(sp->sstate == SOCK_STATE_CONNECTING)
+ {
+#if SOCK_TCP_DEBUG >= 5
+ tcpCheckNotify();
+#endif
+ SPIN(false,SP_MISC,0L)
+ }
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_send: done spinning\n");
+#endif
+ }
+
+ /* socket is not connected */
+ if (! (sp->sstate == SOCK_STATE_CONNECTED))
+ {
+ /* see if a previous operation failed */
+ if (sp->sstate == SOCK_STATE_UNCONNECTED && sp->asyncerr != 0)
+ {
+ (void) sock_err(sp->asyncerr);
+ sp->asyncerr = 0;
+ return(-1);
+ }
+
+ /* I guess he just forgot */
+ return(sock_err(ENOTCONN));
+ }
+
+ if ( (xTCPBytesWriteable(sp) < count) && (sp->nonblocking) )
+ return sock_err(EWOULDBLOCK);
+
+ bytes=count; /* save count before we nuke it */
+ sock_memset(wdsarray,0,TCP_MAX_WDS*sizeof(miniwds)); /* clear up terminus and mark empty */
+ thiswds = wdsarray;
+ wdsnum = 0;
+
+ while (count > 0)
+ {
+ /* make sure the thing that just finished worked ok */
+ if (sp->asyncerr != 0)
+ {
+ (void) sock_err(sp->asyncerr);
+ sp->asyncerr = 0;
+ return(-1);
+ }
+
+/*
+ * for deBUGging: try replacing TCP_MAX_MSG with a small value (like 7) so
+ * you can test that the loop won't choke while waiting for writes to finish
+ */
+ towrite=min(count,TCP_MAX_MSG);
+
+ /* find a clean wds */
+
+ while ( thiswds->length != 0 )
+ {
+ wdsnum = (short)((wdsnum+1)%TCP_MAX_WDS); /* generates compiler warning w/o short - why? */
+ if (wdsnum)
+ thiswds++;
+ else
+ thiswds = wdsarray;
+ SPIN(false,SP_TCP_WRITE,count); /* spin once */
+ }
+
+ /* find a clean pb */
+
+ if (!(pb=sock_fetch_pb(sp)))
+ return sock_err(ENOMEM);
+
+
+ thiswds->length = (short)towrite;
+ thiswds->ptr=buffer;
+
+#ifdef __MACTCP__
+ xTCPSend(pb,(wdsEntry *)thiswds,(count <= TCP_MAX_MSG), /* push */
+ flags & MSG_OOB, /*urgent*/
+ sock_tcp_send_done_proc);
+#else
+ xTCPSend(pb,(wdsEntry *)thiswds,(count <= TCP_MAX_MSG), /* push */
+ flags & MSG_OOB, /*urgent*/
+ sock_tcp_send_done);
+#endif
+
+ SPIN(false,SP_TCP_WRITE,count);
+ count -= towrite;
+ buffer += towrite;
+ }
+
+ SPIN(pb->ioResult == inProgress,SP_TCP_WRITE,0);
+
+ if ( pb->ioResult == noErr )
+ {
+ return(bytes);
+ }
+ else
+ return(sock_err(pb->ioResult));
+}
+
+
+/*
+ * sock_tcp_can_write() - returns non-zero if a write will not block
+ * Very lousy check. Need to check (send window)-(unack data).
+ */
+int sock_tcp_can_write(
+ SocketPtr sp)
+{
+ return (sp->sstate == SOCK_STATE_CONNECTED);
+}
+
+/*
+ * sock_tcp_close() - close down a socket being careful about i/o in progress
+ */
+int sock_tcp_close(
+ SocketPtr sp)
+{
+ OSErr io;
+ TCPiopb *pb;
+
+ void sock_flush_out(SocketPtr);
+ void sock_flush_in(SocketPtr);
+
+#if SOCK_TCP_DEBUG >= 2
+ sock_print("sock_tcp_close ",sp);
+#endif
+
+ if (!(pb=sock_fetch_pb(sp)))
+ return sock_err(ENOMEM);
+
+ sock_flush_out(sp);
+
+ /* close the stream */
+ io = xTCPClose(pb,(TCPIOCompletionUPP)(-1));
+
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_close: xTCPClose returns %d\n",io);
+#endif
+
+ switch (io)
+ {
+ case noErr:
+ case connectionClosing:
+ break;
+ case connectionDoesntExist:
+ case connectionTerminated:
+ break;
+ case invalidStreamPtr:
+ default:
+ return(sock_err(io));
+ }
+
+ sock_flush_in(sp);
+
+ /* destroy the stream */
+ if ((io = xTCPRelease(pb)) != noErr)
+ {
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_close: xTCPRelease error %d\n",io);
+#endif
+ return(sock_err(io));
+ }
+ /* check for errors from async writes etc */
+ if (( sp->asyncerr != noErr ) && ( sp->asyncerr != connectionTerminated ))
+ {
+#if SOCK_TCP_DEBUG >= 5
+ dprintf("sock_tcp_close: asyncerr %d\n",sp->asyncerr);
+#endif
+ return(sock_err(sp->asyncerr));
+ }
+ return(0);
+}
+
+static void sock_flush_out(SocketPtr sp) {
+ while (xTCPWriteBytesLeft(sp)>0) {
+ (*spinroutine)(SP_MISC,0L);
+ }
+ }
+
+static void sock_flush_in(SocketPtr sp) {
+ TCPiopb *pb;
+ rdsEntry rdsarray[TCP_MAX_WDS+1];
+ int passcount;
+ const int maxpass =4;
+
+ if (!(pb = sock_fetch_pb(sp)))
+ return;
+
+ for (passcount=0;passcount<maxpass;passcount++) {
+ if (xTCPNoCopyRcv(pb,rdsarray,TCP_MAX_WDS,1,0)==noErr) {
+ xTCPBufReturn(pb,rdsarray,0);
+ (*spinroutine)(SP_MISC,0L);
+ }
+ else
+ break;
+ }
+
+ if (passcount == maxpass) { /* remote side isn't being nice */
+ (void)xTCPAbort(pb); /* then try again */
+
+ for (passcount=0;passcount<maxpass;passcount++) {
+ if (xTCPNoCopyRcv(pb,rdsarray,TCP_MAX_WDS,1,0)==noErr) {
+ xTCPBufReturn(pb,rdsarray,0);
+ (*spinroutine)(SP_MISC,0L);
+ }
+ else
+ break;
+ }
+ }
+ }
+
+
+#pragma segment SOCK_RESIDENT
+/*
+ * Interrupt routines - MUST BE IN A RESIDENT SEGMENT! Most important to
+ * MacApp programmers
+ */
+pascal void sock_tcp_notify(
+ StreamPtr tcpStream,
+ unsigned short eventCode,
+ Ptr userDataPtr,
+ unsigned short terminReason,
+ ICMPReport *icmpMsg)
+ {
+#pragma unused (userDataPtr,terminReason,icmpMsg)
+ register StreamHashEntPtr shep;
+
+
+ shep = sock_find_shep(tcpStream);
+ if ( shep )
+ {
+ SocketPtr sp = shep->socket;
+
+ if ( eventCode == TCPClosing )
+ {
+ sp->sstate = SOCK_STATE_CLOSING;
+ }
+ else if ( eventCode == TCPTerminate )
+ {
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+ }
+ }
+ }
+
+static void sock_tcp_connect_done(TCPiopb *pb)
+ {
+ SocketPtr sp;
+
+ sp = sock_find_shep(pb->tcpStream)->socket;
+
+ if (pb->ioResult == noErr )
+ {
+ sp->sa.sin_addr.s_addr = pb->csParam.open.localHost;
+ sp->sa.sin_port = pb->csParam.open.localPort;
+ sp->peer.sin_addr.s_addr = pb->csParam.open.remoteHost;
+ sp->peer.sin_port = pb->csParam.open.remotePort;
+ sp->sstate = SOCK_STATE_CONNECTED;
+ sp->asyncerr = noErr;
+ }
+ }
+
+
+static void
+sock_tcp_listen_done(TCPiopb *pb)
+{
+ SocketPtr sp;
+
+ sp = sock_find_shep(pb->tcpStream)->socket;
+
+ switch(pb->ioResult)
+ {
+ case noErr:
+ sp->peer.sin_addr.s_addr = pb->csParam.open.remoteHost;
+ sp->peer.sin_port = pb->csParam.open.remotePort;
+ sp->sstate = SOCK_STATE_LIS_CON;
+ sp->asyncerr = 0;
+ break;
+
+ case openFailed:
+ case invalidStreamPtr:
+ case connectionExists:
+ case duplicateSocket:
+ case commandTimeout:
+ default:
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+ sp->asyncerr = pb->ioResult;
+ break;
+ }
+}
+
+
+static void
+sock_tcp_recv_done(
+ TCPiopb *pb)
+ {
+ register readin;
+ register SocketPtr sp;
+
+ sp = sock_find_shep( pb->tcpStream )->socket;;
+
+ if (pb->ioResult == noErr)
+ {
+ readin = pb->csParam.receive.rcvBuffLen;
+ sp -> recvBuf += readin;
+ sp -> recvd += readin;
+ sp -> torecv -= readin;
+ if ( sp -> torecv )
+ {
+ xTCPRcv(pb,sp->recvBuf,min(sp -> torecv,TCP_MAX_MSG),1, sock_tcp_recv_done_proc);
+ }
+ }
+ }
+
+
+static void
+sock_tcp_send_done(
+ TCPiopb *pb)
+{
+ SocketPtr sp;
+
+ sp = sock_find_shep(pb->tcpStream)->socket;
+
+ switch(pb->ioResult)
+ {
+ case noErr:
+ ((wdsEntry *)(pb->csParam.send.wdsPtr))->length = 0; /* mark it free */
+ break;
+
+ case ipNoFragMemErr:
+ case connectionClosing:
+ case connectionTerminated:
+ case connectionDoesntExist:
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+ sp->asyncerr = ENOTCONN;
+ break;
+
+ case ipDontFragErr:
+ case invalidStreamPtr:
+ case invalidLength:
+ case invalidWDS:
+ default:
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+ sp->asyncerr = pb->ioResult;
+ break;
+ }
+
+}
+
diff --git a/network/ncsasock/sock_udp.c b/network/ncsasock/sock_udp.c
new file mode 100644
index 00000000..ece4fac6
--- /dev/null
+++ b/network/ncsasock/sock_udp.c
@@ -0,0 +1,436 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+ *
+ *
+ * RCS Modification History:
+ * $Log: sock_udp.c,v $
+ * Revision 6.0 1997/08/25 18:38:10 madden
+ * Revision changed to 6.0
+ *
+ * Revision 4.0 1995/07/26 13:56:09 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.5 1995/05/23 15:31:16 kans
+ * new CodeWarrior 6 errors and warnings fixed
+ *
+ * Revision 1.4 1995/05/18 08:23:12 epstein
+ * add RCS modification history (after PowerPC port)
+ *
+ */
+
+#ifdef USEDUMP
+# pragma load "Socket.dump"
+
+#else
+# include <Events.h>
+# include <Memory.h>
+# include <Errors.h>
+# include <Types.h>
+# include <OSUtils.h>
+# include <Stdio.h>
+
+# include <s_types.h>
+# include <neti_in.h>
+# include <neterrno.h>
+# include <s_socket.h>
+# include <s_time.h>
+# include <s_uio.h>
+
+# include "sock_str.h"
+# include "sock_int.h"
+
+#endif
+
+extern SocketPtr sockets;
+extern SpinFn spinroutine;
+
+static void sock_udp_read_ahead_done(UDPiopb *pb);
+static void sock_udp_send_done(UDPiopb *pb);
+
+#if 0
+/*
+ * asynchronous notification routine
+ */
+static int notified = 0;
+static int lastNotifyCount = 0;
+
+static StreamPtr notifyUdpStream;
+static unsigned short notifyEventCode;
+static Ptr notifyUserDataPtr;
+static unsigned short notifyTerminReason;
+static struct ICMPReport *notifyIcmpMsg;
+
+pascal void sock_udp_notify(
+ StreamPtr udpStream,
+ unsigned short eventCode,
+ Ptr userDataPtr,
+ struct ICMPReport *icmpMsg)
+{
+ notified++;
+
+ notifyUdpStream = udpStream;
+ notifyEventCode = eventCode;
+ notifyUserDataPtr = userDataPtr;
+ notifyIcmpMsg = icmpMsg;
+}
+
+static char *eventNames[] =
+{
+ "event 0",
+ "data arrival",
+ "ICMP message"
+};
+static char *icmpMessages[] =
+{
+ "net unreachable",
+ "host unreachable",
+ "protocol unreachable",
+ "port unreachable",
+ "fragmentation required",
+ "source route failed",
+ "time exceeded",
+ "parameter problem",
+ "missing required option"
+};
+
+
+int udpCheckNotify()
+{
+ if (notified == lastNotifyCount)
+ return(0);
+
+ lastNotifyCount = notified;
+ dprintf("notify count is now %d\n",lastNotifyCount);
+ dprintf("stream %08x\n",notifyUdpStream);
+ dprintf("event %d '%s'\n",notifyEventCode,eventNames[notifyEventCode]);
+ if (notifyEventCode == UDPDataArrival)
+ dprintf("%d bytes\n",notifyTerminReason/*!?*/);
+ dprintf("icmp msg %08x\n",notifyIcmpMsg);
+ if (notifyEventCode == UDPICMPReceived)
+ {
+ dprintf("stream %08x\n",notifyIcmpMsg->streamPtr);
+ dprintf("local %08x/%d\n",notifyIcmpMsg->localHost,notifyIcmpMsg->localPort);
+ dprintf("remote %08x/%d\n",notifyIcmpMsg->remoteHost,notifyIcmpMsg->remotePort);
+ dprintf("%s\n",icmpMessages[notifyIcmpMsg->reportType]);
+ dprintf("optionalAddlInfo %04x\n",notifyIcmpMsg->optionalAddlInfo);
+ dprintf("optionalAddlInfoPtr %08x\n",notifyIcmpMsg->optionalAddlInfoPtr);
+ }
+ dprintf("userdata %s\n",notifyUserDataPtr);
+ return(1);
+}
+
+#endif
+
+/*
+ * sock_udp_new_stream() - create the MacTCP stream for this socket. not
+ * called till the last minute while we wait for
+ * a bind to come in.
+ *
+ * called from whichever of connect, recv, send or
+ * select (can_recv or can_send) is called first.
+ */
+int sock_udp_new_stream(
+ SocketPtr sp)
+{
+OSErr io;
+StreamHashEntPtr shep;
+
+#if SOCK_UDP_DEBUG >= 2
+ dprintf("sock_udp_new_stream: sp %08x port %d\n", sp, sp->sa.sin_port);
+#endif
+
+ if ( (io=xUDPCreate(sp, STREAM_BUFFER_SIZE, sp->sa.sin_port)) != noErr )
+ return(sock_err(io));
+
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+
+ if ((shep = sock_new_shep(sp->stream)) != NULL)
+ {
+ shep -> stream = sp->stream;
+ shep -> socket = sp;
+ }
+ else
+ return -1;
+
+ sp-> recvd = 0;
+ sp-> recvBuf = 0;
+ sp-> asyncerr = inProgress;
+
+ /* start up the read ahead */
+ return(sock_udp_read_ahead(sp));
+}
+
+
+/*
+ * sock_udp_connect() - sets the peer process we will be talking to
+ */
+int sock_udp_connect(
+ SocketPtr sp,
+ struct sockaddr_in *addr)
+{
+ int status;
+
+ /* make the stream if its not made already */
+ if (sp->sstate == SOCK_STATE_NO_STREAM)
+ {
+ status = sock_udp_new_stream(sp);
+ if (status != 0)
+ return(status);
+ }
+
+ /* record our peer */
+ sp->peer.sin_len = sizeof(struct sockaddr_in);
+ sp->peer.sin_addr.s_addr = addr->sin_addr.s_addr;
+ sp->peer.sin_port = addr->sin_port;
+ sp->peer.sin_family = AF_INET;
+ sp->sstate = SOCK_STATE_CONNECTED;
+
+ if (sp-> recvBuf) {
+ xUDPBfrReturn(sp);
+ }
+ /* flush the read-ahead buffer if its not from our new friend */
+ (void) sock_udp_can_recv(sp);
+
+ return(0);
+}
+
+/*
+ * sock_udp_read_ahead() - start up the one packet read-ahead
+ *
+ * called from new_stream, recv and can_recv
+ */
+static int sock_udp_read_ahead(SocketPtr sp)
+ {
+ OSErr io;
+
+ io = xUDPRead(sp, (UDPIOCompletionUPP)sock_udp_read_ahead_done);
+ if (io != noErr)
+ return(sock_err(io));
+
+ return(0);
+ }
+
+/*
+ * sock_udp_return_buffer() - return the receive buffer to MacTCP
+ */
+static
+int sock_udp_return_buffer(
+ SocketPtr sp)
+{
+ OSErr io;
+
+ if (sp->recvBuf)
+ {
+ io = xUDPBfrReturn(sp);
+ if (io != noErr)
+ return(sock_err(io));
+ }
+ return(noErr);
+}
+
+/*
+ * sock_udp_recv()
+ *
+ * returns bytes received or -1 and errno
+ */
+int sock_udp_recv(
+ SocketPtr sp,
+ char *buffer,
+ int buflen,
+ int flags,
+ struct sockaddr_in *from,
+ int *fromlen)
+{
+#pragma unused(flags)
+
+#if SOCK_UDP_DEBUG >= 2
+ dprintf("sock_udp_recv: sp %08x buflen %d state %04x\n", sp,buflen,sp->sstate);
+#endif
+
+ /* make the stream if its not made already */
+ if (sp->sstate == SOCK_STATE_NO_STREAM)
+ {
+ int status = sock_udp_new_stream(sp);
+ if (status != 0)
+ return(status);
+ }
+
+ /* dont block a non-blocking socket */
+ if (sp->nonblocking && !sock_udp_can_recv(sp))
+ return(sock_err(EWOULDBLOCK));
+
+ SPIN(!sock_udp_can_recv(sp),SP_UDP_READ,0)
+
+ if (sp->asyncerr!=noErr)
+ return(sock_err(sp->asyncerr));
+
+ /* return the data to the user - truncate the packet if necessary */
+ buflen = min(buflen,sp->recvd);
+ BlockMove(sp->recvBuf,buffer,buflen);
+
+#if (SOCK_UDP_DEBUG >= 7) || defined(UDP_PACKET_TRACE)
+/*
+ hex_dump(buffer, buflen, "udp from %08x/%d\n",
+ sp->apb.pb.udp.csParam.receive.remoteHost,
+ sp->apb.pb.udp.csParam.receive.remotePort);
+*/
+#endif
+
+ if (from != NULL && *fromlen >= sizeof(struct sockaddr_in))
+ {
+ (*from) = sp->peer;
+ (*fromlen) = sizeof (struct sockaddr_in);
+ }
+
+ /* continue the read-ahead - errors which occur */
+ /* here will show up next time around */
+ (void) sock_udp_return_buffer(sp);
+ (void) sock_udp_read_ahead(sp);
+
+ return(buflen);
+}
+
+
+/*
+ * sock_udp_can_recv() - returns non-zero if a packet has arrived.
+ *
+ * Used by select, connect and recv.
+ */
+int sock_udp_can_recv(SocketPtr sp)
+ {
+ if (sp->sstate == SOCK_STATE_NO_STREAM)
+ {
+ int status = sock_udp_new_stream(sp);
+ if (status != 0)
+ return(-1);
+ }
+
+ if (sp->asyncerr == inProgress)
+ return(0);
+
+ return 1; // must recieve if not reading, even if an error occured - must handle error.
+ }
+
+/*
+ * sock_udp_send() - send the data in the (already prepared) wds
+ *
+ * returns bytes sent or -1 and errno
+ */
+int sock_udp_send(SocketPtr sp,struct sockaddr_in *to,char *buffer,int count,int flags)
+ {
+#pragma unused(flags)
+ miniwds awds;
+ OSErr io;
+
+#if SOCK_UDP_DEBUG >= 2
+ dprintf("sock_udp_send: %08x state %04x\n",sp,sp->sstate);
+#endif
+
+ /* make the stream if its not made already */
+ if (sp->sstate == SOCK_STATE_NO_STREAM)
+ {
+ io = sock_udp_new_stream(sp);
+ if (io != 0)
+ return(io);
+ }
+
+ if ( count > UDP_MAX_MSG )
+ return sock_err(EMSGSIZE);
+
+ awds.terminus = 0;
+ awds.length = count;
+ awds.ptr = buffer;
+
+ // if no address passed, hope we have one already in peer field
+ if (to == NULL)
+ if (sp->peer.sin_len)
+ to = &sp->peer;
+ else
+ return (sock_err(EHOSTUNREACH));
+
+ io = xUDPWrite(sp, to->sin_addr.s_addr,to->sin_port, &awds,
+ (UDPIOCompletionUPP)sock_udp_send_done);
+
+ if (io != noErr )
+ return(io);
+
+ // get sneaky. compl. proc sets ptr to nil on completion, and puts result code in
+ // terminus field.
+
+ SPIN(awds.ptr != NULL,SP_UDP_WRITE,count)
+ return (awds.terminus);
+ }
+
+/*
+ * sock_udp_can_send() - returns non-zero if a write will not block
+ */
+int sock_udp_can_send(SocketPtr sp)
+ {
+ if (sp->sstate == SOCK_STATE_NO_STREAM)
+ {
+ if ( sock_udp_new_stream(sp) != 0 )
+ return(-1);
+ }
+
+ return (1);
+ }
+
+/*
+ * sock_udp_close()
+ */
+int sock_udp_close(SocketPtr sp)
+ {
+ OSErr io;
+
+ if (sp->sstate == SOCK_STATE_NO_STREAM)
+ return(0);
+ io = xUDPRelease(sp);
+ if (io != noErr)
+ return(sock_err(io));
+ return(0);
+ }
+
+#pragma segment SOCK_RESIDENT
+/*
+ * Interrupt routines - MUST BE IN A RESIDENT SEGMENT! Most important to
+ * MacApp programmers
+ */
+
+
+/*
+ * sock_udp_send_done
+ */
+
+static void sock_udp_send_done(UDPiopb *pb) {
+ ((miniwds *)pb->csParam.send.wdsPtr)->terminus = pb->ioResult;
+ ((miniwds *)pb->csParam.send.wdsPtr)->ptr = NULL;
+ }
+
+/*
+ * sock_udp_read_ahead_done
+ */
+static void sock_udp_read_ahead_done(UDPiopb *pb) {
+ register SocketPtr sp;
+
+ sp = sock_find_shep( pb->udpStream )->socket;
+ if (pb->ioResult == noErr) {
+ sp->recvBuf = pb->csParam.receive.rcvBuff;
+ sp->recvd = pb->csParam.receive.rcvBuffLen;
+ }
+ else {
+ sp-> recvd = 0;
+ sp-> recvBuf = 0;
+ }
+ sp->asyncerr = pb->ioResult;
+ }
+
diff --git a/network/ncsasock/sock_utl.c b/network/ncsasock/sock_utl.c
new file mode 100644
index 00000000..3bdf82c4
--- /dev/null
+++ b/network/ncsasock/sock_utl.c
@@ -0,0 +1,442 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: sock_utl.c,v $
+* Revision 6.1 1997/12/12 22:39:23 kans
+* DisposPtr now DisposePtr
+*
+* Revision 6.0 1997/08/25 18:38:12 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.3 1995/05/23 15:31:16 kans
+ * new CodeWarrior 6 errors and warnings fixed
+ *
+ * Revision 1.2 1995/05/17 17:58:02 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifdef USEDUMP
+# pragma load "Socket.dump"
+#else
+# include <Events.h>
+# include <Types.h>
+# include <Memory.h>
+# include <Stdio.h>
+# include <OSUtils.h>
+
+# include <s_types.h>
+# include <neti_in.h>
+# include <neterrno.h>
+# include <s_file.h>
+# include <s_ioctl.h>
+# include <s_socket.h>
+# include <s_time.h>
+# include <s_uio.h>
+
+# include "sock_str.h"
+# include "sock_int.h"
+#endif
+
+#include <StdLib.h>
+
+extern SocketPtr sockets;
+extern AllPb *pbList;
+extern short pbLast;
+extern StreamHashEntPtr streams;
+extern SpinFn spinroutine;
+
+long errno_long; /* same as errno, but of known length */
+
+/*
+ * sock_init() - initialize everything.
+ * BUG NOTE: returns error codes, but no one that calls it actually checks the return
+ * codes. probably bad.
+ */
+int sock_init()
+{
+ OSErr io;
+ int i;
+
+ if (sockets != NULL)
+ return 0;
+
+ sock_find_shep((StreamPtr) NULL); /* load resident segment */
+
+ /*
+ * call up driver
+ */
+
+ xOpenDriver();
+
+#if SOCK_UTIL_DEBUG >= 2
+ dprintf("sock_init: first time through\n");
+ dprintf("sock_init: allocating %d bytes for %d socket records\n",
+ NUM_SOCKETS * sizeof(SocketRecord),NUM_SOCKETS);
+#endif
+
+ /* allocate storage for socket records */
+ sockets = (SocketPtr)NewPtrClear(NUM_SOCKETS * sizeof(SocketRecord));
+ if (sockets == NULL)
+ return(sock_err(ENOMEM));
+
+ /* allocate storage for pbs */
+ pbList = (AllPb *)NewPtrClear(NUM_PBS * sizeof (AllPb));
+ if ( pbList == NULL )
+ return sock_err(ENOMEM);
+
+ /* allocate storage for stream->socket hash table */
+ streams = (StreamHashEntPtr)NewPtrClear(NUM_SOCKETS * sizeof(StreamHashEnt));
+ if ( streams == NULL )
+ return(sock_err(ENOMEM));
+
+ /* initialize them */
+ for (i=0; i<NUM_SOCKETS; i++)
+ {
+ sock_clear_fd(i);
+ }
+
+ /* load the MacTCP name server resolver */
+#if SOCK_UTIL_DEBUG >= 2
+ dprintf("sock_init: loading name server resolver\n");
+#endif
+
+ io = OpenResolver(NULL);
+
+#if SOCK_UTIL_DEBUG >= 1
+ if (io != noErr)
+ dprintf("sock_init: failed to load name server resolver code %d\n",io);
+ else
+ dprintf("sock_init: loaded name server ok.\n");
+#endif
+
+ /* establish our clean up man */
+ atexit(sock_close_all);
+
+#if SOCK_UTIL_DEBUG >= 1
+ dprintf("sock_init: exiting.\n");
+#endif
+ return(0);
+}
+
+/*
+ * sock_close_all() - Close all sockets (aborting their connections) and
+ * release dynamic storage.
+ */
+void sock_close_all()
+{
+ int s;
+ SocketPtr sp;
+ TCPiopb *tpb;
+ UDPiopb *upb;
+
+ for (s = 0 ; s < NUM_SOCKETS ; ++s)
+ {
+ sp = sockets+s;
+ if (sp->status == SOCK_STATUS_USED)
+ {
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ upb = sock_fetch_pb(sp); /* must succeed */
+ (void) xUDPRelease(sp);
+ break;
+
+ case IPPROTO_TCP:
+ tpb = sock_fetch_pb(sp);
+ (void) xTCPRelease(tpb);
+ break;
+ }
+ sock_clear_fd(s);
+ }
+ }
+ DisposePtr((Ptr)sockets);
+ DisposePtr((Ptr)streams);
+ DisposePtr((Ptr)pbList);
+
+ /* release name server resources */
+ (void) CloseResolver();
+}
+
+/*
+ * sock_free_fd()
+ *
+ * Get the next free file descriptor >= f. Return -1 if none available.
+ */
+int sock_free_fd(
+ int f)
+{
+ int s;
+
+ for (s = f; s < NUM_SOCKETS; s++)
+ if (! is_used(sockets+s))
+ return(s);
+ return(-1);
+}
+
+/*
+ * sock_dup_fd() - duplicate a socket table entry. Very dangerous (ie. dumb) routine.
+ * IMPORTANT: It is up to the caller to straighten out the StreamHash table
+ * to reflect the new situation. Nasty things may happen if s/he doesn't.
+ */
+void sock_dup_fd(
+ int s,
+ int s1)
+{
+ BlockMove((Ptr)(sockets+s), (Ptr)(sockets+s1), sizeof(SocketRecord));
+ sock_init_fd(s1);
+}
+
+/*
+ * sock_clear_fd() - Clear out a socket table entry freeing any
+ * storage attached to it.
+ *
+ * Then re-initialize it for reuse.
+ */
+void sock_clear_fd(
+ int s)
+{
+ SocketPtr sp = sockets+s;
+ StreamHashEntPtr shep;
+
+ if ((shep=sock_find_shep(sp->stream))!=NULL) /* in hash table */
+ shep->stream = -1; /* mark as deleted */
+
+ bzero(sp, sizeof(SocketRecord));
+ sp->sa.sin_family = AF_UNSPEC;
+ sp->status &= ~SOCK_STATUS_USED;
+
+ sock_init_fd(s);
+}
+
+
+/*
+ * Close relative of sock_find_shep, sock_new_shep returns a StreamHashEntPtr
+ * that is unused and most appropriate for the passed stream.
+ */
+StreamHashEntPtr sock_new_shep(StreamPtr newStream)
+ {
+ StreamHashEntPtr shep;
+ int counter,start;
+
+ /* start at hash point */
+ start = counter = (newStream & (SOCKETS_MASK << 3) ) >> 3; /* extract some arbitrary bits */
+ shep = streams + counter;
+ do
+ {
+ /*
+ * scan till we find entry or unused or deleted slot.
+ */
+ if ( (shep->stream == newStream) || (shep->stream == (StreamPtr) NULL) ||
+ (shep->stream == -1) )
+ break;
+ else
+ {
+ counter = (counter+1) & SOCKETS_MASK;
+ if (counter)
+ shep++;
+ else
+ shep = streams;
+ }
+ }
+ while(counter != start);
+
+ if ( (shep->stream == (StreamPtr) NULL ) || (shep->stream == -1 ) )
+ return shep;
+ else
+ return NULL; /* error: already in table or table full. Should never happen. (right...) */
+ }
+
+/*
+ * sock_fetch_pb grabs a pb from the global pool, making sure it isn't
+ * used. It may block for a long time if all pb are in progress. Declared
+ * void * because I'm getting sick of typecasting every goddamn little pointer
+ */
+void *sock_fetch_pb(SocketPtr sp)
+ {
+ AllPb *pb;
+ do
+ {
+ pbLast ++;
+ if (pbLast == NUM_PBS)
+ pbLast = 0;
+
+ pb = pbList + pbLast;
+ }
+ while ( pb->tcp.ioResult == inProgress );
+
+ pb->tcp.tcpStream = sp->stream; /* all the calls have the stream at the same offset */
+ /* thank god. */
+ return ((void *)pb);
+ }
+
+
+void sock_init_fd(
+ int s)
+{
+ SocketPtr sp = sockets+s;
+
+ sp->fd = s;
+}
+
+
+/*
+ * Convert a MacTCP err code into a unix error code, if needed. Otherwise it
+ * will pass thru unmolested.
+ */
+int sock_err( int MacTCPerr )
+ {
+ switch ( MacTCPerr )
+ {
+ case ipBadLapErr:
+ case ipBadCnfgErr:
+ case ipNoCnfgErr:
+ case ipLoadErr:
+ case ipBadAddr:
+ errno = ENXIO; /* device not configured */ /* a cheap cop out */
+ break;
+
+ case connectionClosing:
+ errno = ESHUTDOWN; /* Can't send after socket shutdown */
+ break;
+
+ case connectionExists:
+ errno = EISCONN; /* Socket is already connected */
+ break;
+
+ case connectionTerminated:
+ errno = ENOTCONN; /* Connection reset by peer */ /* one of many possible */
+ break;
+
+ case openFailed:
+ errno = ECONNREFUSED; /* Connection refused */
+ break;
+
+ case duplicateSocket: /* technically, duplicate port */
+ errno = EADDRINUSE; /* Address already in use */
+ break;
+
+ case ipDestDeadErr:
+ errno = EHOSTDOWN; /* Host is down */
+ break;
+
+ case ipRouteErr:
+ errno = EHOSTUNREACH; /* No route to host */
+ break;
+
+ default:
+ errno = MacTCPerr; /* cop out; an internal err, unix err, or no err */
+ break;
+ }
+#if SOCK_UTIL_DEBUG >= 1
+ dprintf("SOCK error %d\n", errno);
+#endif
+
+ errno_long = errno;
+ return (-1);
+ }
+
+/*
+ * sock_copy_addr
+ */
+void sock_copy_addr(
+ void *from,
+ void *to,
+ Int4 *tolen)
+{
+ *tolen = min(*tolen, sizeof(struct sockaddr_in));
+ BlockMove((Ptr)from, (Ptr)to, *tolen);
+}
+
+
+#if SOCK_UTIL_DEBUG > 1
+/*
+ * print the socket records.
+ */
+void sock_dump()
+{
+ int s;
+ char title[20];
+
+ for (s=0; s<NUM_SOCKETS; s++)
+ {
+ if (! is_used(sockets+s))
+ continue;
+ sprintf(title,"%2d",s);
+ sock_print(title,sockets+s);
+ }
+}
+
+void sock_print(
+ char *title,
+ SocketPtr sp)
+{
+ dprintf("%s: %08x %s %08x addr %08x/%d %08x/%d state %d/%d err %d\n",
+ title, sp,
+ (sp->protocol == IPPROTO_UDP ? "udp" : "tcp"),
+ (sp->protocol == IPPROTO_UDP ? sp->pb.udp.udpStream : sp->pb.tcp.tcpStream),
+ sp->sa.sin_addr.s_addr,sp->sa.sin_port,
+ sp->peer.sin_addr.s_addr,sp->peer.sin_port,
+ sp->sstate,xTCPState(&sp->pb),
+ sp->asyncerr);
+}
+#endif
+
+
+
+#pragma segment SOCK_RESIDENT
+/*
+ * sock_find_shep returns a StreamHashEntPtr for the passed
+ * stream. Will return 0 if the stream doesn't exits.
+ */
+StreamHashEntPtr sock_find_shep(StreamPtr theStream)
+ {
+ StreamHashEntPtr shep;
+ int counter,start;
+
+ if (!goodptr(theStream)) /* DO NOT CHANGE THESE TWO LINES! */
+ return NULL; /* used to load the resident segment */
+
+ /* start at hash point */
+ start = counter = (theStream & (SOCKETS_MASK << 3) ) >> 3; /* extract a bunch of arbitrary bits */
+ shep = streams + counter;
+ do
+ {
+ /*
+ * scan till we find entry or unused slot. Uses linear
+ * collision resolution because it's too complicated to
+ * do anything else for this small of a hash table.
+ */
+ if ( (shep->stream == theStream) || (shep->stream == (StreamPtr) NULL))
+ break;
+ else
+ {
+ counter = (counter+1) & SOCKETS_MASK;
+ if (counter)
+ shep++;
+ else
+ shep = streams;
+ }
+ }
+ while(counter != start);
+
+ if ( shep->stream == theStream ) /* found it */
+ return shep;
+ else
+ return NULL;
+ }
diff --git a/network/ncsasock/socket.c b/network/ncsasock/socket.c
new file mode 100644
index 00000000..762aa6a4
--- /dev/null
+++ b/network/ncsasock/socket.c
@@ -0,0 +1,1710 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: socket.c,v $
+* Revision 6.0 1997/08/25 18:38:15 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.4 1995/06/02 16:29:03 kans
+ * *** empty log message ***
+ *
+ * Revision 1.3 1995/05/23 15:31:16 kans
+ * new CodeWarrior 6 errors and warnings fixed
+ *
+ * Revision 1.2 1995/05/17 17:58:06 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ *
+ * The following calls are implemented
+ *
+ * socket
+ * bind
+ * listen
+ * accept
+ * connect
+ * read
+ * recv
+ * recvfrom
+ * write
+ * writev
+ * send
+ * sendto
+ * select
+ * close
+ * getdtablesize
+ * getsockname
+ * getpeername
+ * shutdown
+ * fcntl(F_DUPFD)
+ * fcntl(F_GETFL)
+ * fcntl(F_SETFL,FNDELAY)
+ * dup
+ * dup2
+ * ioctl(FIONBIO)
+ * ioctl(FIONREAD)
+ *
+ * Non-blocking I/O is supported. All calls which would block return
+ * immediately with an 'error' indicating so. Select() may be used to
+ * determine when an operation can be performed.
+ *
+ * Ioctl(FIONBIO) or fcntl(F_SETFL,FNDELAY) can be used to toggle or set
+ * the blocking status of a socket.
+ *
+ * In a blocking situation, accept() and read() return EWOULDBLOCK and
+ * refuse to do anything. Select() for read() to learn when a incoming
+ * connection is available.
+ *
+ * Connect() and write() (which shouldn't take too long anyway) start
+ * the operation and return EINPROGRESS. Select for write() to learn
+ * when connect() has completed. Write() on a socket which is still
+ * 'inprogress' return EALREADY.
+ *
+ *
+ * Socket operations are single threaded and half-duplex. Fixing this is
+ * left as an execise for the reader. Shouldn't be a terrible problem
+ * anyway. Read() never blocks and write() only blocks for long if there
+ * is a problem.
+ *
+ * Calls which find the socket busy will return EALREADY. These are
+ * read() or write() with a connect() or write() in progress.
+ *
+ *
+ * Socket options are not supported. Hence no setsockopt() and getsockopt()
+ * calls.
+ *
+ *
+ * CR: I attempted to support OOB data for send and recv, but not promises are
+ * made as I didn't have any immediate tests for them.
+ *
+ *
+ * Readv() is not implemented.
+ *
+ *
+ * All calls which encounter an error will set the global variable errno
+ * to indicate the problem. Some common values for errno are...
+ *
+ * EBADF the socket parameter is not a valid socket descriptor.
+ *
+ * EFAULT a pointer parameters is rubbish.
+ *
+ * EINVAL a non-pointer parameters is rubbish.
+ *
+ * ENOTCONN the socket should be in a connected state for this
+ * operation, but isn't.
+ *
+ * EISCONN the socket is already connected.
+ *
+ * ----------------- non-blocking I/O
+ *
+ * EWOULDBLOCK accept() or one of the read() calls would block.
+ *
+ * EINPROGRESS connect() or one of the write() operations has been
+ * started.
+ *
+ * ----------------- SINGLE THREAD
+ *
+ * EALREADY an operation is already in progress on the socket.
+ *
+ * ----------------
+ *
+ * EBUG an internal error occured.
+ */
+
+#ifdef USEDUMP
+# pragma load "socket.dump"
+
+#else
+# include <Events.h>
+# include <Types.h>
+# include <Stdio.h>
+
+# include <s_types.h>
+# include <neti_in.h>
+# include <neterrno.h>
+# include <s_file.h>
+# include <s_ioctl.h>
+# include <s_socket.h>
+# include <s_time.h>
+# include <s_uio.h>
+
+# include "sock_str.h"
+# include "sock_int.h"
+
+#endif
+
+#include "sock_ext.h"
+
+int s_recvfrom(Int4 s, void *buffer, Int4 buflen, Int4 flags, struct sockaddr *from, int *fromlen);
+int s_really_send(Int4 s, void *buffer, Int4 count, Int4 flags, struct sockaddr_in *to);
+void bzero(char *sp, int len);
+
+
+/*
+ * GET YOUR GLOBALS HERE!
+ */
+
+int defaultSpin(spin_msg msg,long param);
+SocketPtr sockets = NULL; /* The socket table. */
+AllPb *pbList = NULL; /* The pb array */
+short pbLast = 0; /* last pb used */
+StreamHashEntPtr streams = NULL; /* The streams hash table */
+SpinFn spinroutine = (SpinFn) defaultSpin; /* The spin routine. */
+
+/*
+ * s_socket(domain, type, protocol)
+ *
+ * socket creates a MacTCP socket and returns a descriptor.
+ *
+ * Domain must be AF_INET
+ *
+ * Type may be SOCK_STREAM to create a TCP socket or
+ * SOCK_DGRAM to create a UDP socket.
+ *
+ * Protocol is ignored. (isn't it always?)
+ *
+ * TCP sockets provide sequenced, reliable, two-way connection
+ * based byte streams.
+ *
+ * A TCP socket must be in a connected
+ * state before any data may be sent or received on it. A
+ * connection to another socket is created with a connect() call
+ * or the listen() and accept() calls.
+ * Once connected, data may be transferred using read() and
+ * write() calls or some variant of the send() and recv()
+ * calls. When a session has been completed a close() may be
+ * performed.
+ *
+ *
+ * A UDP socket supports the exchange of datagrams (connectionless,
+ * unreliable messages of a fixed maximum length) with
+ * correspondents named in send() calls. Datagrams are
+ * generally received with recv(), which returns the next
+ * datagram with its return address.
+ *
+ * An fcntl() or ioctl() call can be used to enable non-blocking I/O.
+ *
+ * The return value is a descriptor referencing the socket or -1
+ * if an error occurs, in which case global variable errno is
+ * set to one of:
+ *
+ * ENOMEM Failed to allocate memory for the socket
+ * data structures.
+ *
+ * EAFNOSUPPORT Domain wasn't AF_INET.
+ *
+ * ESOCKTNOSUPPORT Type wasn't SOCK_STREAM or SOCK_DGRAM.
+ *
+ * EMFILE The socket descriptor table is full.
+ */
+int s_socket(
+ Int4 domain,
+ Int4 type,
+ short protocol)
+{
+ SocketPtr sp;
+ int s;
+
+#if SOCK_DEBUG >= 3
+ dprintf("s_socket:\n");
+#endif
+
+ sock_init();
+
+ /*
+ * Support only Internet family
+ */
+ if (domain != AF_INET)
+ return(sock_err(EAFNOSUPPORT));
+
+ switch(type)
+ {
+ case SOCK_DGRAM:
+ protocol = IPPROTO_UDP;
+ break;
+ case SOCK_STREAM:
+ protocol = IPPROTO_TCP;
+ break;
+ default:
+ return(sock_err(ESOCKTNOSUPPORT));
+ }
+
+ /*
+ * Create a socket table entry
+ */
+ s = sock_free_fd(0); /* Get next free file descriptor */
+ if (s == -1)
+ return(sock_err(EMFILE));
+ sp = sockets+s;
+ sp->fd = s;
+ sp->protocol = protocol;
+ bzero((char *) &sp->sa, sizeof(struct sockaddr_in));
+ bzero((char *) &sp->peer, sizeof(struct sockaddr_in));
+ sp->sa.sin_family = AF_INET;
+ sp->sa.sin_len = sizeof(struct sockaddr_in);
+ sp->status = SOCK_STATUS_USED;
+ sp->nonblocking = false;
+
+
+ /* Create a new stream on the socket. */
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ /* udp streams are not created until the last minute */
+ /* because we dont know if the caller wants to assign */
+ /* a special port number yet (via bind) and mactcp */
+ /* assigns udp port numbers at stream creation */
+ sp->sstate = SOCK_STATE_NO_STREAM;
+ break;
+
+ case IPPROTO_TCP:
+ /* the tcp stream is created now because tcp port numbers */
+ /* are assigned during active/passiveOpen which is done */
+ /* during listen or connect */
+ sp->sstate = SOCK_STATE_UNCONNECTED;
+ if (sock_tcp_new_stream(sp) < 0)
+ return(-1); /* sock_err already called */
+ }
+
+ return(s);
+}
+
+
+/*
+ * s_bind(s, name, namelen)
+ *
+ * bind requests that the name (ip address and port) pointed to by
+ * name be assigned to the socket s.
+ *
+ * The return value is 0 on success or -1 if an error occurs,
+ * in which case global variable errno is set to one of:
+ *
+ * EAFNOSUPPORT The address family in name is not AF_INET.
+ *
+ * EINVAL The socket is already bound to an address.
+ *
+ * EADDRNOTAVAIL The specified address is not available
+ * from the local machine. ie. the address
+ * portion of name was not this machine's address.
+ *
+ * MacTCP does not separate name binding and connection establishment.
+ * Therefore the port number is not verified, just stored for later use.
+ *
+ * If a specific local port is not required, bind is optional in this
+ * implementation.
+ */
+int s_bind(
+ Int4 s,
+ struct sockaddr *sa_name,
+ Int4 namelen)
+{
+ SocketPtr sp;
+ struct sockaddr_in *name=(struct sockaddr_in *)sa_name;
+
+#if SOCK_DEBUG >= 3
+ dprintf("s_bind: bind %d to %08x/%d\n",
+ s, name->sin_addr.s_addr, name->sin_port);
+#endif
+
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+ sp = sockets+s;
+
+ if (namelen < sizeof(struct sockaddr_in))
+ return(sock_err(EINVAL));
+
+ if (!goodptr(name))
+ return(sock_err(EFAULT));
+
+ if (name->sin_family != AF_INET)
+ return(sock_err(EAFNOSUPPORT));
+
+ if (sp->sa.sin_port != 0) /* already bound */
+ return(sock_err(EINVAL));
+
+ /*
+ * If client passed a local IP address, assure it is the right one
+ */
+ if (name->sin_addr.s_addr != 0)
+ {
+ if (name->sin_addr.s_addr != xIPAddr())
+ return(sock_err(EADDRNOTAVAIL));
+ }
+
+ /*
+ * NOTE: can't check a TCP port for EADDRINUSE
+ * just save the address and port away for connect or listen or...
+ */
+ sp->sa.sin_addr.s_addr = name->sin_addr.s_addr;
+ sp->sa.sin_port = name->sin_port;
+ return(0);
+}
+
+/*
+ * s_connect - initiate a connection on a MacTCP socket
+ *
+ * If the parameter s is a UDP socket,
+ * then this call specifies the address to which datagrams
+ * are to be sent, and the only address from which datagrams
+ * are to be received.
+ *
+ * If it is a TCP socket, then this call attempts to make a
+ * connection to another socket. The other socket is specified
+ * by an internet address and port.
+ *
+ * TCP sockets may successfully connect() only once;
+ *
+ * UDP sockets may use connect() multiple times to change
+ * their association. UDP sockets may dissolve the association
+ * by connecting to an invalid address, such as a null
+ * address.
+ *
+ * If the connection or binding succeeds, then 0 is returned.
+ * Otherwise a -1 is returned, and a more specific error code
+ * is stored in errno.
+ *
+ * EAFNOSUPPORT The address family in addr is not AF_INET.
+ *
+ * EHOSTUNREACH The TCP connection came up half-way and
+ * then failed.
+ *
+ * -------------- some day instead of EHOSTUNREACH -----------------
+ *
+ * EADDRNOTAVAIL The specified address is not available
+ * on the remote machine.
+ *
+ * ETIMEDOUT Connection establishment timed out
+ * without establishing a connection.
+ *
+ * ECONNREFUSED The attempt to connect was forcefully
+ * rejected.
+ *
+ * ENETUNREACH The network is not reachable from here.
+ *
+ * EHOSTUNREACH The host is not reachable from here.
+ *
+ * EADDRINUSE The address is already in use.
+ */
+int s_connect(
+ Int4 s,
+ struct sockaddr *sa_addr,
+ Int4 addrlen)
+{
+ SocketPtr sp;
+ struct sockaddr_in *addr=(struct sockaddr_in *)sa_addr;
+
+#if SOCK_DEBUG >= 2
+ dprintf("s_connect: connect %d to %08x/%d\n",
+ s, addr->sin_addr.s_addr, addr->sin_port);
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ if (addrlen != sizeof(struct sockaddr_in))
+ return(sock_err(EINVAL));
+
+ if (! goodptr(addr))
+ return(sock_err(EFAULT));
+
+ if (addr->sin_family != AF_INET)
+ return(sock_err(EAFNOSUPPORT));
+
+ sp = sockets+s;
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ return(sock_udp_connect(sp,addr));
+
+ case IPPROTO_TCP:
+ return(sock_tcp_connect(sp,addr));
+ }
+ return(0);
+}
+
+/*
+ * s_listen()
+ *
+ * To accept connections, a socket is first created with
+ * socket(), a backlog for incoming connections is specified
+ * with listen() and then the connections are accepted with
+ * accept(). The listen() call applies only to TCP sockets.
+ *
+ * The qlen parameter is supposed to define the maximum length
+ * the queue of pending connections may grow to. It is ignored.
+ *
+ * A 0 return value indicates success; -1 indicates an error.
+ *
+ * EOPNOTSUPP s is not a TCP socket.
+ */
+int s_listen(
+ Int4 s,
+ Int4 qlen)
+{
+#pragma unused(qlen)
+ SocketPtr sp;
+
+#if SOCK_DEBUG >= 2
+ dprintf("listen: listen %d\n", s);
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ sp = sockets+s;
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ return(sock_err(EOPNOTSUPP));
+
+ case IPPROTO_TCP:
+ return(sock_tcp_listen(sp));
+ }
+ return(0);
+}
+
+/*
+ * s_accept(s, addr, addrlen)
+ *
+ * s is a socket that has been created with socket, bind, listen.
+ *
+ * Accept extracts the first connection on the queue of pending
+ * connections, creates a new socket with the same properties of s
+ * and allocates a new file descriptor, ns, for the socket.
+ *
+ * If no pending connections are present on the queue, and the socket
+ * is not marked as non-blocking, accept blocks the caller until
+ * a connection is present.
+ *
+ * If the socket is marked non-blocking and no pending connections
+ * are present on the queue, accept returns an error EWOULDBLOCK.
+ *
+ * The accepted socket, ns, is used to read and write data to and
+ * from the socket which connected to this one; it is not used
+ * to accept more connections. The original socket s remains
+ * open for accepting further connections.
+ *
+ * The argument addr is a result parameter that is filled in
+ * with the address of the connecting socket. The addrlen is
+ * a value-result parameter; it should initially contain the
+ * amount of space pointed to by addr; on return it will contain
+ * the actual length (in bytes) of the address returned.
+ *
+ * This call is used with TCP sockets only.
+ *
+ * It is possible to select a socket for the purposes of
+ * doing an accept by selecting it for read.
+ *
+ * Translation: To check and see if there is a connection pending,
+ * call s_select and check for pending reads.
+ *
+ * The call returns -1 on error. If it succeeds, it returns a
+ * non-negative integer that is a descriptor for the accepted
+ * socket.
+ *
+ * EOPNOTSUPP s is not a TCP socket.
+ *
+ * EMFILE The socket descriptor table is full.
+ */
+int s_accept(
+ Int4 s,
+ struct sockaddr *sa_addr,
+ Int4 *addrlen)
+{
+ SocketPtr sp;
+ struct sockaddr_in *addr=(struct sockaddr_in *)sa_addr;
+
+#if SOCK_DEBUG >= 2
+ dprintf("s_accept: %d\n", s);
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ if (!goodptr(addr) || !goodptr(addrlen))
+ return(sock_err(EFAULT));
+
+ if (*addrlen < 0)
+ return(sock_err(EINVAL));
+
+ if (sock_free_fd(0) == -1)
+ return(sock_err(EMFILE));
+
+ sp = sockets+s;
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ return(sock_err(EOPNOTSUPP));
+ case IPPROTO_TCP:
+ return(sock_tcp_accept(sp,addr,addrlen));
+ }
+ return(0);
+}
+
+/*
+ * s_accept_once
+ *
+ * A mac specific routine, designed to compenstate for a bug
+ * in MacTCP. If you close a passive, unconnected stream,
+ * MacTCP will generate an error. s_accept always creates
+ * a new listening (passive open) stream that will eventually
+ * need to be closed. s_accept_once does not create a new
+ * listening socket. It will return the same socket originally
+ * passed to it, and NO more connections will be accepted
+ * on the old listening port.
+ *
+ * Other than that, it is identical to s_accept.
+ */
+int s_accept_once(
+ Int4 s,
+ struct sockaddr *sa_addr,
+ Int4 *addrlen)
+{
+ SocketPtr sp;
+ struct sockaddr_in *addr=(struct sockaddr_in *)sa_addr;
+
+#if SOCK_DEBUG >= 2
+ dprintf("s_accept: %d\n", s);
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ if (!goodptr(addr) || !goodptr(addrlen))
+ return(sock_err(EFAULT));
+
+ if (*addrlen < 0)
+ return(sock_err(EINVAL));
+
+ if (sock_free_fd(0) == -1)
+ return(sock_err(EMFILE));
+
+ sp = sockets+s;
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ return(sock_err(EOPNOTSUPP));
+ case IPPROTO_TCP:
+ {
+ int returnCode;
+
+ returnCode=sock_tcp_accept_once(sp,addr,addrlen);
+ return (returnCode ? returnCode : s );
+ }
+ }
+ return(0);
+}
+
+/*
+ * s_close(s)
+ *
+ * The close call destroys the socket s. If this is the last reference
+ * to the underlying MacTCP stream, then the stream will be released.
+ *
+ * A 0 return value indicates success; -1 indicates an error.
+ *
+ * NOTE: if non-blocking I/O is enabled EWOULDBLOCK will be returned
+ * if there are TCP writes in progress. (UDP writes are
+ * performed synchronously.)
+ *
+ * All reads are terminated and unread data is lost.
+ */
+int s_close(
+ Int4 s)
+{
+ int t;
+ SocketPtr sp;
+ int status;
+
+#if SOCK_DEBUG >= 2
+ dprintf("s_close: %d\n", s);
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ sp = sockets+s;
+
+ /*
+ * Look for duplicates of the socket. Only close down the connection
+ * if there are no duplicates(i.e. socket not dup'd).
+ */
+ for (t = 0; t < NUM_SOCKETS; t++)
+ {
+ if (t == s)
+ continue;
+ if (!(sockets[t].status & SOCK_STATUS_USED))
+ continue;
+ else if (sockets[t].protocol == sp->protocol && sockets[t].stream == sp->stream )
+ { /* found a duplicate */
+#if SOCK_DEBUG >= 3
+ dprintf("s_close: found a dup at %d(%d, don't close stream\n",
+ t, sockets[t].protocol);
+#endif
+ sock_clear_fd(s);
+ return(0);
+ }
+ }
+
+ /*
+ * No duplicates, close the stream.
+ */
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ status = sock_udp_close(sp);
+ break;
+
+ case IPPROTO_TCP:
+ status = sock_tcp_close(sp);
+ break;
+ }
+ if (status != EWOULDBLOCK)
+ sock_clear_fd(s);
+ return(status);
+}
+
+
+/*
+ * s_read(s, buffer, buflen)
+ *
+ * s_recv(s, buffer, buflen, flags)
+ *
+ * s_recvfrom(s, buffer, buflen, flags, from, fromlen)
+ *
+ * read() attempts to read nbytes of data from the socket s.
+ *
+ * recv() and recvfrom() attempt to receive a message (ie a datagram)
+ * on the socket s.
+ *
+ * from returns the address of the socket which sent the message.
+ * fromlen is the usual value-result length parameter.
+ *
+ * Typically, read() is used with a TCP stream and recv() with
+ * UDP where the idea of a message makes more sense. But in fact,
+ * read() and recv() are equivalent.
+ *
+ * For UDP...
+ * If a message (ie. datagram) is too long to fit in the supplied
+ * buffer, excess bytes will be discarded..
+ *
+ * If no messages are available at the socket, the receive call
+ * waits for a message to arrive, unless the socket is non-
+ * blocking in which case -1 is returned with errno set to
+ * EWOULDBLOCK.
+ *
+ * For TCP...
+ * Regardless of non-blocking status, if less data is available
+ * than has been requested, only that much data is returned.
+ *
+ * If the socket is marked for non-blocking I/O, and the socket
+ * is empty, the operation will fail with the error EWOULDBLOCK.
+ * Otherwise, the operation will block until data is available
+ * or an error occurs.
+ *
+ * A return value of zero indicates that the stream has been
+ * closed and all data has already been read. ie. end-of-file.
+ *
+ * Flags is ignored.
+ *
+ * If successful, the number of bytes actually received is
+ * returned. Otherwise, a -1 is returned and the global variable
+ * errno is set to indicate the error.
+ *
+ * ESHUTDOWN The socket has been shutdown for receive operations.
+ */
+int s_read(
+ Int4 s,
+ char *buffer,
+ Int4 buflen)
+{
+ int fromlen = 0;
+ return(s_recvfrom(s, buffer, buflen, 0, NULL, &fromlen));
+}
+
+int s_recv(
+ Int4 s,
+ char *buffer,
+ Int4 buflen,
+ Int4 flags)
+{
+ int fromlen = 0;
+ return(s_recvfrom(s, buffer, buflen, flags, NULL, &fromlen));
+}
+
+int s_recvfrom(
+ Int4 s,
+ void *buffer,
+ Int4 buflen,
+ Int4 flags,
+ struct sockaddr *sa_from,
+ int *fromlen)
+{
+ SocketPtr sp;
+ struct sockaddr_in *from=(struct sockaddr_in *)sa_from;
+
+#if SOCK_DEBUG >= 3
+ dprintf ("s_recvfrom: %d\n", s);
+#endif
+ if (s < 0 || s >= NUM_SOCKETS)
+ return (sock_err (EBADF));
+
+ sp = sockets+s;
+ if (! is_used (sp))
+ return (sock_err (EBADF));
+
+ if (!goodptr((char *)buffer))
+ return (sock_err (EFAULT));
+
+ if (buflen <= 0)
+ return(sock_err(EINVAL));
+
+ if (! (from == NULL || goodptr(from)) )
+ return(sock_err(EFAULT));
+
+ if (! (fromlen == NULL || goodptr(fromlen)) )
+ return(sock_err(EFAULT));
+ else
+ if ( *fromlen < 0 )
+ return(sock_err(EINVAL));
+
+ if (sock_noread(sp))
+ return(sock_err(ESHUTDOWN));
+
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ return(sock_udp_recv(sp, (char *)buffer, buflen, flags, from, (int *)fromlen));
+
+ case IPPROTO_TCP:
+ return(sock_tcp_recv(sp, (char *)buffer, buflen, flags));
+ }
+ return(0);
+}
+
+
+/*
+ * s_write(s, buffer, buflen)
+ *
+ * s_writev(s, iov, iovcnt)
+ *
+ * s_send(s, buffer, buflen, flags)
+ *
+ * s_sendto(s, buffer, buflen, flags, to, tolen)
+ *
+ * write() attempts to write nbytes of data to the socket s from
+ * the buffer pointed to by buffer.
+ *
+ * writev() gathers the output data from the buffers specified
+ * by the members of the iov array. Each iovec entry specifies
+ * the base address and length of an area in memory from which
+ * data should be written.
+ *
+ * send() and sendto() are used to transmit a message to another
+ * socket on the socket s.
+ *
+ * Typically, write() is used with a TCP stream and send() with
+ * UDP where the idea of a message makes more sense. But in fact,
+ * write() and send() are equivalent.
+ *
+ * For UDP...
+ *
+ * Write() and send() operations are completed as soon as the
+ * data is placed on the transmission queue.???????
+ *
+ * The address of the target is given by to.
+ *
+ * The message must be short enough to fit into one datagram.
+ *
+ * Buffer space must be available to hold the message to be
+ * transmitted, regardless of its non-blocking I/O state.
+ *
+ * For TCP...
+ * Write() and send() operations are not considered complete
+ * until all data has been sent and acknowledged.
+ *
+ * If a socket is marked for non-blocking I/O, the operation
+ * will return an 'error' of EINPROGRESS.
+ *
+ * If the socket is not marked for non-blocking I/O, the write will
+ * block until space becomes available.
+ *
+ * write() and send() may be used only when the socket is in a connected
+ * state, sendto() may be used at any time.
+ *
+ * Flags is ignored.
+ *
+ * These calls return the number of bytes sent, or -1 if an error
+ * occurred.
+ *
+ * EINVAL The sum of the iov_len values in the iov array was
+ * greater than 65535 (TCP) or 65507 (UDP) or there
+ * were too many entries in the array (16 for TCP or
+ * 6 for UDP).
+ *
+ * ESHUTDOWN The socket has been shutdown for send operations.
+ *
+ * EMSGSIZE The message is too big to send in one datagram. (UDP)
+ *
+ * ENOBUFS The transmit queue is full. (UDP)
+ */
+
+int s_write(
+ Int4 s,
+ char *buffer,
+ Int4 buflen)
+{
+ return(s_really_send(s, buffer, buflen, 0, NULL));
+}
+
+int s_writev(
+ Int4 s,
+ struct iovec *iov,
+ Int4 count)
+{
+ int result,tally=0;
+
+ while (count--)
+ {
+ if ( !goodptr( iov ) )
+ return sock_err(EFAULT);
+ result= s_really_send(s, (char *)(iov->iov_base),
+ (int)(iov->iov_len), 0, NULL);
+ if (result < 0)
+ return sock_err(result);
+ iov++;
+ tally+=result;
+ }
+ return tally;
+}
+
+int s_send(
+ Int4 s,
+ char *buffer,
+ Int4 buflen,
+ Int4 flags)
+{
+ return(s_really_send(s, buffer, buflen, flags, NULL));
+}
+
+int s_sendto (
+ Int4 s,
+ char *buffer,
+ Int4 buflen,
+ Int4 flags,
+ struct sockaddr *sa_to,
+ Int4 tolen)
+{
+ SocketPtr sp;
+ struct sockaddr_in *to=(struct sockaddr_in *)sa_to;
+
+ if (s < 0 || s >= NUM_SOCKETS)
+ return (sock_err (EBADF));
+
+ sp = sockets+s;
+
+ if (! is_used (sp))
+ return (sock_err (EBADF));
+
+ if (!goodptr(buffer))
+ return (sock_err (EFAULT));
+
+ if (buflen <= 0)
+ return(sock_err(EINVAL));
+
+ if (to != NULL && !goodptr(to))
+ return(sock_err(EFAULT));
+
+ if (to != NULL && tolen < sizeof(struct sockaddr_in))
+ return(sock_err(EINVAL));
+
+ return(s_really_send(s, buffer, buflen, flags, to));
+}
+
+int s_sendmsg(Int4 s,struct msghdr *msg,Int4 flags) {
+ SocketPtr sp;
+ struct iovec *iov=NULL;
+ int tally=0,result,count;
+
+ if (s < 0 || s >= NUM_SOCKETS)
+ return (sock_err (EBADF));
+
+ sp = sockets+s;
+
+ if (! is_used (sp))
+ return (sock_err (EBADF));
+ if (!goodptr(msg))
+ return (sock_err (EFAULT));
+ if ( msg->msg_name != NULL && !goodptr(msg->msg_name) )
+ return (sock_err (EFAULT));
+ if ( msg->msg_name != NULL && msg->msg_namelen < sizeof (struct sockaddr_in))
+ return (sock_err (EFAULT));
+
+ count = msg->msg_iovlen;
+ iov = msg->msg_iov;
+ while ( count -- ) {
+ if ( !goodptr( iov ) )
+ return sock_err(EFAULT);
+ result= s_really_send(s, (char *)(iov->iov_base),
+ (int)(iov->iov_len), flags,(struct sockaddr_in *)msg->msg_name);
+ if (result < 0)
+ return (sock_err(result));
+ iov++;
+ tally+=result;
+ }
+ return tally;
+ }
+
+int s_really_send(
+ Int4 s,
+ void *buffer,
+ Int4 count,
+ Int4 flags,
+ struct sockaddr_in *to)
+
+ {
+ SocketPtr sp;
+ int tally=0;
+
+#if SOCK_DEBUG >= 2
+ dprintf("s_really_send: %d %d bytes", s, count);
+ if (to != NULL)
+ dprintf(" to %08x/%d",to->sin_addr.s_addr,to->sin_port);
+ dprintf("\n");
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+ sp = sockets+s;
+
+#if SOCK_DEBUG >= 2
+ dprintf("state %d\n",sp->sstate);
+ dprintf("peer %08x/%d\n",sp->peer.sin_addr.s_addr,sp->peer.sin_port);
+#endif
+
+ if (sock_nowrite(sp))
+ return(sock_err(ESHUTDOWN));
+
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ if (to == NULL && sp->sstate != SOCK_STATE_CONNECTED)
+ return(sock_err(ENOTCONN));
+ return(sock_udp_send(sp, to, (char *)buffer, count, flags));
+ break;
+
+ case IPPROTO_TCP:
+ if (to != NULL) /* sendto */
+ return(sock_err(EOPNOTSUPP));
+ if (sp->sstate != SOCK_STATE_CONNECTED)
+ return(sock_err(ENOTCONN));
+ return ( sock_tcp_send(sp, (char *)buffer, count,0 ));
+ break;
+ }
+ return(0);
+ }
+
+
+/*
+ * s_select(width, readfds, writefds, exceptfds, timeout)
+ *
+ * select() examines the I/O descriptor sets whose addresses
+ * are passed in readfds, writefds, and exceptfds to see if
+ * some of their descriptors are ready for reading, ready for
+ * writing, or have an exceptional condition pending. width is
+ * the number of bits to be checked in each bit mask that
+ * represent a file descriptor; the descriptors from 0 through
+ * width-1 in the descriptor sets are examined. Typically
+ * width has the value returned by getdtablesize for the
+ * maximum number of file descriptors. On return, select
+ * replaces the given descriptor sets with subsets consisting
+ * of those descriptors that are ready for the requested opera-
+ * tion. The total number of ready descriptors in all the sets
+ * is returned.
+ *
+ * If timeout is not a NULL pointer, it specifies a maximum
+ * interval to wait for the selection to complete. If timeout
+ * is a NULL pointer, the select blocks indefinitely. To
+ * effect a poll, the timeout argument should be a non-NULL
+ * pointer, pointing to a zero-valued timeval structure.
+ *
+ * Any of readfds, writefds, and exceptfds may be given as NULL
+ * pointers if no descriptors are of interest.
+ *
+ * Using select to open a socket for reading is analogous to
+ * performing an accept call.
+ *
+ * select() returns the number of ready descriptors that are
+ * contained in the descriptor sets, or -1 if an error
+ * occurred. If the time limit expires then select() returns
+ * 0. If select() returns with an error the descriptor sets
+ * will be unmodified.
+ */
+int s_select(
+ Int4 width,
+ fd_set *readfds,
+ fd_set *writefds,
+ fd_set *exceptfds,
+ struct timeval *timeout)
+{
+ SocketPtr sp;
+ long count;
+ int s;
+ long starttime, waittime;
+ fd_set rd, wd, ed;
+ int errorHappened;
+
+#if SOCK_DEBUG >= 2
+ dprintf("select: socket: width %d\n",width);
+#endif
+ if (!goodptr(timeout) && timeout != NULL)
+ return(sock_err(EFAULT));
+ if (!goodptr(readfds) && readfds != NULL)
+ return(sock_err(EFAULT));
+ if (!goodptr(writefds) && writefds != NULL)
+ return(sock_err(EFAULT));
+ if (!goodptr(exceptfds) && exceptfds != NULL)
+ return(sock_err(EFAULT));
+
+#if SOCK_DEBUG >= 3
+ dprintf("select: timeout %d sec, read %08x write %08x except %08x\n",
+ (timeout ? timeout->tv_sec : 99999),
+ (readfds!=NULL ? *readfds : 0L),
+ (writefds!=NULL ? *writefds : 0L),
+ (exceptfds!=NULL ? *exceptfds : 0L));
+#endif
+
+ if (width > NUM_SOCKETS) /* for now..xxx. */
+ width = NUM_SOCKETS;
+ count = 0;
+ FD_ZERO(&rd);
+ FD_ZERO(&wd);
+ FD_ZERO(&ed);
+
+ if (timeout)
+ {
+ waittime = TVTOTICK(timeout->tv_sec,timeout->tv_usec);
+ starttime = TickCount();
+ }
+#if SOCK_DEBUG >= 5
+ dprintf(" starttime = %d(tics); waittime = %d\n",starttime, waittime);
+#endif
+
+ do
+ {
+ for (s = 0 , sp = sockets ; s < width ; ++s, ++sp)
+ {
+ if (is_used(sp))
+ {
+ errorHappened = 0;
+
+ /* Check if there is data or connection available. */
+ if (readfds && FD_ISSET(s,readfds))
+ {
+
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ switch (sock_udp_can_recv(sp))
+ {
+ case 1:
+ FD_SET(s,&rd);
+ ++count;
+ break;
+ case -1:
+ errorHappened = 1;
+ break;
+ }
+ break;
+
+ case IPPROTO_TCP:
+ /* Must exit if stream is dead to avoid eternal lock up */
+ if (sock_tcp_can_read(sp) ) {
+ FD_SET(s,&rd);
+ ++count;
+ }
+ break;
+ }
+ }
+ if (writefds && FD_ISSET(s,writefds))
+ {
+ switch(sp->protocol)
+ {
+ case IPPROTO_UDP:
+ switch (sock_udp_can_send(sp))
+ {
+ case 1:
+ FD_SET(s,&wd);
+ ++count;
+ break;
+ case -1:
+ errorHappened = 1;
+ break;
+ }
+ break;
+
+ case IPPROTO_TCP:
+ if (sock_tcp_can_write(sp))
+ {
+ FD_SET(s,&wd);
+ ++count;
+ }
+ break;
+ }
+ }
+ if (exceptfds && FD_ISSET(s,exceptfds))
+ {
+ if (errorHappened)
+ {
+ FD_SET(s,&ed);
+ ++count;
+ }
+ }
+ }
+ }
+ SPIN(false,SP_SELECT,0)
+ }
+ while(count == 0 &&(timeout == 0 || TickCount() - starttime < waittime));
+
+ if (readfds)
+ *readfds = rd;
+ if (writefds)
+ *writefds = wd;
+ if (exceptfds)
+ *exceptfds = ed;
+#if SOCK_DEBUG >= 5
+ dprintf(" elapsed = %d(tics) count %d, read %08x write %08x except %08x\n",
+ TickCount()-starttime,count,
+ (readfds!=NULL ? *readfds : 0L),
+ (writefds!=NULL ? *writefds : 0L),
+ (exceptfds!=NULL ? *exceptfds : 0L));
+#endif
+ return(count);
+}
+
+/*
+ * s_getdtablesize()
+ *
+ * The entries in the socket descriptor table are numbered with small
+ * integers starting at 0. getdtablesize returns the size of the
+ * descriptor table.
+ */
+int s_getdtablesize()
+{
+ return(NUM_SOCKETS);
+}
+
+/*
+ * s_getsockname(s, name, namelen)
+ *
+ * getsockname returns the current name for the socket s.
+ * Namelen should be initialized to
+ * indicate the amount of space pointed to by name. On return
+ * it contains the actual size of the name returned (in bytes).
+ *
+ * A 0 is returned if the call succeeds, -1 if it fails.
+ */
+
+int s_getsockname(
+ Int4 s,
+ struct sockaddr *name,
+ Int4 *namelen)
+{
+#if SOCK_DEBUG >= 3
+ dprintf("GETSOCKNAME: %d\n", s);
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ if (! goodptr(name))
+ return(sock_err(EFAULT));
+
+ if (*namelen < 0)
+ return(sock_err(EINVAL));
+
+ sock_copy_addr(&sockets[s].sa, name, namelen);
+ return(0);
+}
+
+/*
+ * s_getpeername(s, name, namelen)
+ *
+ * getpeername returns the name of the peer connected to socket s.
+ *
+ * The int pointed to by the namelen parameter
+ * should be initialized to indicate the amount of space
+ * pointed to by name. On return it contains the actual size
+ * of the name returned (in bytes). The name is truncated if
+ * the buffer provided is too small.
+ *
+ * A 0 is returned if the call succeeds, -1 if it fails.
+ */
+int s_getpeername(
+ Int4 s,
+ struct sockaddr *name,
+ Int4 *namelen)
+{
+ SocketPtr sp;
+
+#if SOCK_DEBUG >= 2
+ dprintf("getpeername: socket %d\n", s);
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ sp = sockets+s;
+ if (! is_used (sp))
+ return (sock_err (EBADF));
+
+ if (! goodptr(name))
+ return(sock_err(EFAULT));
+
+ if (*namelen < 0)
+ return(sock_err(EINVAL));
+
+ if (sp->sstate != SOCK_STATE_CONNECTED)
+ return(sock_err(ENOTCONN));
+
+ sock_copy_addr(&sockets[s].peer, name, namelen);
+
+ return(0);
+}
+
+/*
+ * s_shutdown(s, how)
+ *
+ * shutdown call causes all or part of a full-duplex
+ * connection on the socket s to be shut down. If
+ * how is 0, then further receives will be disallowed. If how
+ * is 1, then further sends will be disallowed. If how is 2,
+ * then further sends and receives will be disallowed.
+ *
+ * A 0 is returned if the call succeeds, -1 if it fails.
+ */
+int s_shutdown(
+ Int4 s,
+ Int4 how)
+{
+ SocketPtr sp;
+
+#if SOCK_DEBUG >= 2
+ dprintf("shutdown: shutdown %d\n", s);
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+ sp = sockets+s;
+
+ switch(how)
+ {
+ case 0 :
+ sp->status |= SOCK_STATUS_NOREAD;
+ break;
+
+ case 1 :
+ sp->status |= SOCK_STATUS_NOWRITE;
+ break;
+
+ case 2 :
+ sp->status |= SOCK_STATUS_NOREAD | SOCK_STATUS_NOWRITE;
+ break;
+
+ default :
+ return(sock_err(EINVAL));
+ }
+ return(0);
+}
+
+/*
+ * fcntl() operates on the socket s according to the order in cmd:
+ *
+ * F_DUPFD Like Dup. Returns a new descriptor which refers to the
+ * same MacTCP stream as s and has the same descriptor
+ * status.
+ *
+ * F_GETFL returns the descriptor status flags for s. The only
+ * flag supported is FNDELAY for non-blocking i/o.
+ *
+ * F_SETFL sets descriptor status flags for s. The only
+ * flag supported is FNDELAY for non-blocking i/o.
+ *
+ * A dup or F_DUPFD operation copies the descriptor status flags
+ * maintained by F_SETFL, but once the copy is done, the two are
+ * disjoint. THIS IS DIFFERENT FROM UNIX.
+ *
+ * Upon successful completion, the value returned depends on
+ * cmd as follows:
+ * F_DUPFD A new descriptor.
+ * F_GETFL Value of flags.
+ * F_SETFL 0.
+ *
+ * On error, a value of -1 is returned and errno is set to indicate
+ * the error.
+ *
+ * EBADF s is not a valid open descriptor.
+ *
+ * EMFILE cmd is F_DUPFD and socket descriptor table is full.
+ *
+ * EINVAL cmd is F_DUPFD and arg is negative or
+ * greater than the maximum allowable
+ * number (see getdtablesize).
+ */
+int s_fcntl(
+ Int4 s,
+ unsigned Int4 cmd,
+ Int4 arg)
+{
+#if SOCK_DEBUG >= 2
+ dprintf("s_fcntl: %d\n", s);
+#endif
+
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ switch(cmd)
+ {
+ /*
+ * Duplicate a socket.
+ */
+ case F_DUPFD :
+ {
+ int s1;
+
+ if (arg < 0 || arg >= NUM_SOCKETS)
+ return(sock_err(EINVAL));
+
+ s1 = sock_free_fd(arg);
+ if (s1 == -1)
+ return(sock_err(EMFILE));
+
+ sock_dup_fd(s,s1);
+ return(s1);
+ }
+
+ /*
+ * Get socket status. This is like getsockopt().
+ * Only supported descriptor status is FNDELAY.
+ */
+ case F_GETFL :
+ {
+ SocketPtr sp;
+
+ sp = sockets+s;
+ if (sp->nonblocking)
+ return(FNDELAY);
+ else
+ return(0);
+ }
+
+ /*
+ * Set socket status. This is like setsockopt().
+ * Only supported descriptor status is FNDELAY.
+ */
+ case F_SETFL :
+ {
+ SocketPtr sp;
+
+ sp = sockets+s;
+ if (arg & FNDELAY)
+ sp->nonblocking = true;
+ else
+ sp->nonblocking = false;
+
+ return(0);
+ }
+ }
+ return(0);
+}
+
+/*
+ * dup(s)
+ *
+ * dup2(s, news)
+ *
+ * dup() duplicates an existing socket descriptor. The argu-
+ * ment s is a small non-negative integer index in the per-
+ * process descriptor table. The value must be less than the
+ * size of the table, which is returned by getdtablesize(2).
+ * The new descriptor returned by the call is the lowest num-
+ * bered descriptor that is not currently in use by the pro-
+ * cess.
+ *
+ * In the second form of the call, the value of the new
+ * descriptor desired is specified. If that descriptor is
+ * already in use, the descriptor is first deallocated as if a
+ * close(2) call had been done first.
+ *
+ * The value -1 is returned if an error occurs in either call.
+ * The external variable errno indicates the cause of the
+ * error.
+ *
+ * EBADF s or news is not a valid socket
+ * descriptor.
+ *
+ * EMFILE Too many descriptors are active.
+ */
+int s_dup(
+ Int4 s)
+{
+ return(s_fcntl(s, F_DUPFD, 0));
+}
+
+int s_dup2(
+ Int4 s,
+ Int4 s1)
+{
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ if (s1 < 0 || s1 >= NUM_SOCKETS)
+ return(sock_err(EBADF));
+
+ if (is_used(sockets+s1))
+ {
+ if (s_close(s1) == -1)
+ return(-1);
+ }
+ sock_dup_fd(s,s1);
+ return(s1);
+}
+
+
+/*
+ * s_Ioctl()
+ */
+int s_ioctl(
+ Int4 d,
+ Int4 request,
+ Int4 *argp)
+{
+ struct ifreq *ifr;
+ TCPiopb *tpb;
+ SocketPtr sp;
+ int size;
+
+#if SOCK_DEBUG >= 2
+ dprintf("s_ioctl: %d, request %d\n", d,request);
+#endif
+
+ if (! sock_good_fd(d))
+ return(sock_err(EBADF));
+
+ sp = sockets+d;
+
+ /*
+ * Interpret high order word to find amount of data to be copied
+ * to/from the user's address space.
+ */
+ size =(request &~(IOC_INOUT | IOC_VOID)) >> 16;
+
+ /*
+ * Zero the buffer on the stack so the user gets back something deterministic.
+ */
+ if ((request & IOC_OUT) && size)
+ bzero((char *) argp, size);
+
+ ifr =(struct ifreq *)argp;
+ switch(request)
+ {
+ /* Non-blocking I/O */
+ case FIONBIO:
+ sp->nonblocking = *(Boolean *)argp;
+ return(0);
+
+ /* Number of bytes on input Q */
+ case FIONREAD:
+ tpb = sock_fetch_pb(sp);
+ sp->dataavail = xTCPBytesUnread(sp);
+ *(int *)argp=sp->dataavail;
+ return 0;
+
+#ifdef IOCTL_LATER
+ /*
+ * Get interface list. Pass in buffer and buffer length.
+ * Returns list of length one of ifreq's
+ */
+ case SIOCGIFCONF:
+ {
+ struct ifconf *ifc =(struct ifconf *)argp;
+ struct ifreq *req = ifc->ifc_req;
+ int reqlen;
+ struct sockaddr_in *addr;
+
+ /*
+ * Fill in req fields for the IF's name and local IP addr.
+ */
+ strncpy(req->ifr_name, myIFName, IFNAMSIZ);
+ addr =(struct sockaddr_in *)&req->ifr_addr;
+ addr->sin_family = AF_INET;
+ addr->sin_addr.s_addr = myIPAddress;
+ addr->sin_port = 0;
+ bzero(addr->sin_zero, sizeof(addr->sin_zero));
+ ifc->ifc_len = sizeof(*req);
+
+ return(0);
+ }
+
+ /*
+ * Returns MTU of specified IF.
+ */
+ case SIOCGIFMTU:
+ {
+ /* don't check IF specification - we only have one anyway */
+ *(int *)ifr->ifr_data= xMaxMTU();
+ return(0);
+ }
+
+ /*
+ * Returns local IP Address of IF
+ */
+ case SIOCGIFADDR:
+ {
+ struct sockaddr_in *addr;
+
+ /* don't check IF specification - we only have one anyway */
+
+ addr = &ifr->ifr_addr;
+ addr->sin_addr.s_addr = xIPAddr();
+ addr->sin_family = AF_INET;
+ return(0);
+ }
+
+ case SIOCGIFDSTADDR: /* For point to point, which we don't support */
+ return(sock_err(EINVAL));
+
+ case SIOCGIFFLAGS: /* Returns IF flags(none yet) */
+ ifr->ifr_flags = 0;
+ return(0);
+
+ /*
+ * Return broadcast address - net address plus all ones in host part
+ */
+ case SIOCGIFBRDADDR:
+ {
+ struct sockaddr_in *addr;
+
+ /* don't check IF specification */
+ /* we only have one and its broadcast */
+
+ addr = &ifr->ifr_addr;
+ addr->sin_addr.s_addr = xIPAddr() | ~xNetMask();
+ return(0);
+ }
+#endif /* IOCTL_LATER */
+ default :
+ return(sock_err(EOPNOTSUPP));
+ }
+}
+
+/*
+ * s_setsockopt()
+ *
+ * Set socket options. None implemented. In Unix there are...
+ *
+ * SO_REUSEADDR toggle local address reuse
+ * SO_KEEPALIVE toggle keep connections alive
+ * SO_DONTROUTE toggle routing bypass for outgoing
+ * messages
+ * SO_LINGER linger on close if data present
+ * SO_BROADCAST toggle permission to transmit
+ * broadcast messages
+ * SO_OOBINLINE toggle reception of out-of-band
+ * data in band
+ * SO_SNDBUF set buffer size for output
+ * SO_RCVBUF set buffer size for input
+ * SO_TYPE get the type of the socket (get
+ * only)
+ * SO_ERROR get and clear error on the socket
+ * (get only)
+ */
+int s_setsockopt(
+ Int4 s,
+ Int4 level,
+ Int4 optname,
+ char *optval,
+ Int4 optlen)
+{
+#pragma unused(optval)
+#pragma unused(optlen)
+ SocketPtr sp;
+
+#if SOCK_DEBUG >= 3
+ dprintf("SETSOCKOPT: socket: %d option: %d \n", s,optname);
+#endif
+ if (! sock_good_fd(s))
+ return(sock_err(EBADF));
+
+ sp = sockets+s;
+
+ /*
+ * demultiplex to socket option handlers at other protocol levels.(None
+ * supported yet).
+ */
+ switch(level)
+ {
+ case SOL_SOCKET : /* socket level option */
+ switch(optname)
+ {
+ default :
+ return(0);
+ }
+ break;
+ case IPPROTO_TCP:
+ switch(optname)
+ {
+ default:
+ return(0);
+ }
+ break;
+ default :
+ return(sock_err(ENOPROTOOPT));
+ }
+ return(0);
+}
+
+
+/*
+ * s_setspin() - define a routine to be called repeatedly when
+ * socket routines are blocked (ie. spinning)
+ *
+ * pass a NULL pointer to turn off a previously
+ * defined spin routine.
+ */
+int s_setspin(
+ SpinFn routine)
+{
+ if (routine == NULL || goodptr(routine))
+ {
+ spinroutine = routine;
+ return(0);
+ }
+ else
+ return(sock_err(EFAULT));
+}
+
+/*
+ * s_getspin() - returns current spinroutine
+ */
+SpinFn s_getspin()
+ {
+ return (spinroutine);
+ }
+
+int defaultSpin(spin_msg msg,long param)
+ {
+#pragma unused (msg,param)
+ EventRecord evrec;
+
+ WaitNextEvent(0, &evrec, 1 /* ticks */, NULL);
+ return 0; /* return non-zero to exit current routine */
+ }
diff --git a/network/ncsasock/syslog.c b/network/ncsasock/syslog.c
new file mode 100644
index 00000000..e6bed312
--- /dev/null
+++ b/network/ncsasock/syslog.c
@@ -0,0 +1,114 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: syslog.c,v $
+* Revision 6.0 1997/08/25 18:38:17 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.3 1995/06/02 16:29:03 kans
+ * *** empty log message ***
+ *
+ * Revision 1.2 1995/05/17 17:58:10 epstein
+ * add RCS log revision history
+ *
+ */
+
+/*
+ * syslog, openlog, closelog - hacked from Unix - use dprintf
+ * perror - hacked from Unix - uses dprintf
+ * Modified to use StdArg by Charlie Reiman.
+ * Wednesday, August 8, 1990 2:55:43 PM
+ */
+
+#include <syslog.h>
+#include <StdArg.h>
+#include <stdio.h>
+
+extern int errno;
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+/*
+ * a version of dprintf was here, but it was also defined in
+ * dprintf.c. I've removed this one.
+ * Charlie Reiman
+ * Wednesday, August 8, 1990 2:53:49 PM
+ */
+
+#define MAXLINE 1000
+
+static int LogMask = LOG_DEBUG;
+static char LogTag[100] = "";
+
+openlog(char *ident, int logstat)
+{
+ if (logstat >= LOG_ALERT && logstat <= LOG_DEBUG)
+ LogMask = logstat;
+
+ if (ident)
+ strcpy(LogTag,ident);
+ return 0;
+}
+
+closelog()
+{
+ return 0;
+}
+
+syslog(int pri,char *fmt,...)
+{
+ register char *b, *f = fmt, c;
+ char buf[MAXLINE+50];
+ char oline[MAXLINE];
+ va_list nextArg;
+
+ va_start(nextArg,fmt);
+
+ if (pri > LogMask)
+ return 0;
+
+ b = buf;
+ while ((c = *f++) != '\0' && b < buf + MAXLINE)
+ {
+ if (c != '%')
+ {
+ *b++ = c;
+ continue;
+ }
+ c = *f++;
+ if (c != 'm')
+ {
+ *b++ = '%', *b++ = c;
+ continue;
+ }
+ if ((unsigned)errno > sys_nerr)
+ sprintf(b, "error %d", errno);
+ else
+ sprintf(b, "%s", sys_errlist[errno]);
+ b += strlen(b);
+ }
+ if (b[-1] != '\n')
+ *b++ = '\n';
+ *b = '\0';
+
+ vsprintf(oline, buf, nextArg);
+
+ dprintf("%s: %s\n", LogTag,oline);
+ return 0;
+}
+
diff --git a/network/ncsasock/syslog.h b/network/ncsasock/syslog.h
new file mode 100644
index 00000000..65259d5f
--- /dev/null
+++ b/network/ncsasock/syslog.h
@@ -0,0 +1,83 @@
+/* @(#)syslog.h 1.5 88/08/19 SMI; from UCB 7.1 6/5/86 */
+
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+*
+*
+* RCS Modification History:
+* $Log: syslog.h,v $
+* Revision 6.0 1997/08/25 18:38:19 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.2 1995/05/17 17:58:13 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifndef _sys_syslog_h
+#define _sys_syslog_h
+
+/*
+ * Facility codes
+ */
+#define LOG_KERN (0<<3) /* kernel messages */
+#define LOG_USER (1<<3) /* random user-level messages */
+#define LOG_MAIL (2<<3) /* mail system */
+#define LOG_DAEMON (3<<3) /* system daemons */
+#define LOG_AUTH (4<<3) /* security/authorization messages */
+#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
+#define LOG_LPR (6<<3) /* line printer subsystem */
+#define LOG_NEWS (7<<3) /* netnews subsystem */
+#define LOG_UUCP (8<<3) /* uucp subsystem */
+#define LOG_CRON (15<<3) /* cron/at subsystem */
+ /* other codes through 15 reserved for system use */
+#define LOG_LOCAL0 (16<<3) /* reserved for local use */
+#define LOG_LOCAL1 (17<<3) /* reserved for local use */
+#define LOG_LOCAL2 (18<<3) /* reserved for local use */
+#define LOG_LOCAL3 (19<<3) /* reserved for local use */
+#define LOG_LOCAL4 (20<<3) /* reserved for local use */
+#define LOG_LOCAL5 (21<<3) /* reserved for local use */
+#define LOG_LOCAL6 (22<<3) /* reserved for local use */
+#define LOG_LOCAL7 (23<<3) /* reserved for local use */
+
+#define LOG_NFACILITIES 24 /* maximum number of facilities */
+#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
+
+/*
+ * Priorities (these are ordered)
+ */
+#define LOG_EMERG 0 /* system is unusable */
+#define LOG_ALERT 1 /* action must be taken immediately */
+#define LOG_CRIT 2 /* critical conditions */
+#define LOG_ERR 3 /* error conditions */
+#define LOG_WARNING 4 /* warning conditions */
+#define LOG_NOTICE 5 /* normal but signification condition */
+#define LOG_INFO 6 /* informational */
+#define LOG_DEBUG 7 /* debug-level messages */
+
+#define LOG_PRIMASK 0x0007 /* mask to extract priority part (internal) */
+
+/*
+ * arguments to setlogmask.
+ */
+#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
+#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
+
+/*
+ * Option flags for openlog.
+ *
+ * LOG_ODELAY no longer does anything; LOG_NDELAY is the
+ * inverse of what it used to be.
+ */
+#define LOG_PID 0x01 /* log the pid with each message */
+#define LOG_CONS 0x02 /* log on the console if errors in sending */
+#define LOG_ODELAY 0x04 /* delay open until syslog() is called */
+#define LOG_NDELAY 0x08 /* don't delay open */
+#define LOG_NOWAIT 0x10 /* if forking to log on console, don't wait() */
+
+#endif /*!_sys_syslog_h*/
diff --git a/network/ncsasock/tcpglue.c b/network/ncsasock/tcpglue.c
new file mode 100644
index 00000000..aa1094bb
--- /dev/null
+++ b/network/ncsasock/tcpglue.c
@@ -0,0 +1,557 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+ *
+ *
+ * RCS Modification History:
+ * $Log: tcpglue.c,v $
+ * Revision 6.1 1997/12/12 22:39:24 kans
+ * DisposPtr now DisposePtr
+ *
+ * Revision 6.0 1997/08/25 18:38:20 madden
+ * Revision changed to 6.0
+ *
+ * Revision 4.0 1995/07/26 13:56:09 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.5 1995/05/18 08:23:09 epstein
+ * add RCS modification history (after PowerPC port)
+ *
+ */
+
+/*
+ * Glue routines to call the MacTCP drivers
+ */
+
+#ifdef USEDUMP
+# pragma load "socket.dump"
+
+#else
+# include <Memory.h>
+# include <Files.h>
+# include <Errors.h>
+
+# include <s_types.h>
+# include <neti_in.h>
+
+# include "sock_str.h"
+
+# include "sock_int.h"
+
+#endif
+
+#include <Devices.h>
+
+static short driver = 0;
+
+/*
+ * Hack fix for MacTCP 1.0.X bug
+ */
+
+#if !defined(powerc) && !defined(__powerc) && !defined(__POWERPC)
+pascal char *ReturnA5(void) = {0x2E8D};
+#endif
+
+OSErr xOpenDriver()
+{
+ if (driver == 0)
+ {
+ ParamBlockRec pb;
+ OSErr io;
+
+ pb.ioParam.ioCompletion = 0L;
+ pb.ioParam.ioNamePtr = "\p.IPP";
+ pb.ioParam.ioPermssn = fsCurPerm;
+ io = PBOpen(&pb,false);
+ if (io != noErr)
+ return(io);
+ driver = pb.ioParam.ioRefNum;
+ }
+ return noErr;
+}
+
+
+/*
+ * create a TCP stream
+ */
+OSErr xTCPCreate(
+ int buflen,
+ TCPNotifyUPP notify,
+ TCPiopb *pb)
+{
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPCreate;
+ pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
+ pb->csParam.create.rcvBuffLen = buflen;
+ pb->csParam.create.notifyProc = (TCPNotifyUPP) notify;
+ return (xPBControlSync(pb));
+}
+
+/*
+ * start listening for a TCP connection
+ */
+OSErr xTCPPassiveOpen(
+ TCPiopb *pb,
+ short port,
+ TCPIOCompletionUPP completion)
+{
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPPassiveOpen;
+ pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
+ pb->csParam.open.ulpTimeoutValue = 255 /* seconds */;
+ pb->csParam.open.ulpTimeoutAction = 0 /* 1:abort 0:report */;
+ pb->csParam.open.commandTimeoutValue = 0 /* infinity */;
+ pb->csParam.open.remoteHost = 0;
+ pb->csParam.open.remotePort = 0;
+ pb->csParam.open.localHost = 0;
+ pb->csParam.open.localPort = port;
+ pb->csParam.open.dontFrag = 0;
+ pb->csParam.open.timeToLive = 0;
+ pb->csParam.open.security = 0;
+ pb->csParam.open.optionCnt = 0;
+ return (xPBControl(pb,completion));
+}
+
+/*
+ * connect to a remote TCP
+ */
+OSErr xTCPActiveOpen(
+ TCPiopb *pb,
+ short port,
+ long rhost,
+ short rport,
+ TCPIOCompletionUPP completion)
+{
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPActiveOpen;
+ pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
+ pb->csParam.open.ulpTimeoutValue = 60 /* seconds */;
+ pb->csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */;
+ pb->csParam.open.commandTimeoutValue = 0;
+ pb->csParam.open.remoteHost = rhost;
+ pb->csParam.open.remotePort = rport;
+ pb->csParam.open.localHost = 0;
+ pb->csParam.open.localPort = port;
+ pb->csParam.open.dontFrag = 0;
+ pb->csParam.open.timeToLive = 0;
+ pb->csParam.open.security = 0;
+ pb->csParam.open.optionCnt = 0;
+ return (xPBControl(pb,completion));
+}
+
+OSErr xTCPNoCopyRcv(
+ TCPiopb *pb,
+ rdsEntry *rds,
+ int rdslen,
+ int timeout,
+ TCPIOCompletionUPP completion)
+{
+
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPNoCopyRcv;
+ pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
+ pb->csParam.receive.rdsPtr = (Ptr)rds;
+ pb->csParam.receive.rdsLength = rdslen;
+ return (xPBControl(pb,completion));
+}
+
+OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion)
+ {
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPRcvBfrReturn;
+ pb->csParam.receive.rdsPtr = (Ptr)rds;
+
+ return (xPBControl(pb,completion));
+ }
+
+/*
+ * send data
+ */
+OSErr xTCPSend(
+ TCPiopb *pb,
+ wdsEntry *wds,
+ Boolean push,
+ Boolean urgent,
+ TCPIOCompletionUPP completion)
+{
+ if (driver == 0)
+ return invalidStreamPtr;
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPSend;
+ pb->csParam.send.validityFlags = timeoutValue | timeoutAction;
+ pb->csParam.send.ulpTimeoutValue = 60 /* seconds */;
+ pb->csParam.send.ulpTimeoutAction = 0 /* 0:abort 1:report */;
+ pb->csParam.send.pushFlag = push;
+ pb->csParam.send.urgentFlag = urgent;
+ pb->csParam.send.wdsPtr = (Ptr)wds;
+ return (xPBControl(pb,completion));
+}
+
+
+/*
+ * close a connection
+ */
+OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion)
+{
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPClose;
+ pb->csParam.close.validityFlags = timeoutValue | timeoutAction;
+ pb->csParam.close.ulpTimeoutValue = 60 /* seconds */;
+ pb->csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */;
+ return (xPBControl(pb,completion));
+}
+
+/*
+ * abort a connection
+ */
+OSErr xTCPAbort(TCPiopb *pb)
+{
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPAbort;
+ return (xPBControlSync(pb));
+}
+
+/*
+ * close down a TCP stream (aborting a connection, if necessary)
+ */
+OSErr xTCPRelease(
+ TCPiopb *pb)
+{
+ OSErr io;
+
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPRelease;
+ io = xPBControlSync(pb);
+ if (io == noErr)
+ DisposePtr(pb->csParam.create.rcvBuff); /* there is no release pb */
+ return(io);
+}
+
+int
+xTCPBytesUnread(SocketPtr sp)
+{
+ TCPiopb *pb;
+ OSErr io;
+
+ if (!(pb = sock_fetch_pb(sp)))
+ return -1; /* panic */
+
+ if (driver == 0)
+ return(-1);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPStatus;
+ io = xPBControlSync(pb);
+ if (io != noErr)
+ return(-1);
+ return(pb->csParam.status.amtUnreadData);
+}
+
+int
+xTCPBytesWriteable(SocketPtr sp)
+ {
+ TCPiopb *pb;
+ OSErr io;
+ long amount;
+
+ if (!(pb = sock_fetch_pb(sp)))
+ return -1; /* panic */
+
+ if (driver == 0)
+ return(-1);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPStatus;
+ io = xPBControlSync(pb);
+ if (io != noErr)
+ return(-1);
+ amount = pb->csParam.status.sendWindow-pb->csParam.status.amtUnackedData;
+ if (amount < 0)
+ amount = 0;
+ return amount;
+ }
+
+int xTCPWriteBytesLeft(SocketPtr sp)
+ {
+ TCPiopb *pb;
+ OSErr io;
+
+ if (!(pb = sock_fetch_pb(sp)))
+ return -1; /* panic */
+
+ if (driver == 0)
+ return(-1);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPStatus;
+ io = xPBControlSync(pb);
+ if (io != noErr)
+ return(-1);
+ return (pb->csParam.status.amtUnackedData);
+ }
+
+int xTCPState(TCPiopb *pb)
+ {
+ OSErr io;
+
+ if (driver == 0)
+ return(-1);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPStatus;
+ io = xPBControlSync(pb);
+ if (io != noErr)
+ return(-1);
+ return(pb->csParam.status.connectionState);
+ }
+
+
+/*
+ * create a UDP stream, hook it to a socket.
+ */
+OSErr xUDPCreate(SocketPtr sp,int buflen,ip_port port)
+ {
+ UDPiopb *pb;
+ OSErr io;
+
+ if ( !(pb = sock_fetch_pb(sp) ) )
+ return -1;
+
+ pb->ioCRefNum = driver;
+ pb->csCode = UDPCreate;
+ pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
+ pb->csParam.create.rcvBuffLen = buflen;
+ pb->csParam.create.notifyProc = NULL;
+ pb->csParam.create.localPort = port;
+ if ( (io = xPBControlSync( (TCPiopb *)pb ) ) != noErr)
+ return io;
+
+ sp->stream = pb->udpStream;
+ sp->sa.sin_port = pb->csParam.create.localPort;
+ return noErr;
+ }
+
+/*
+ * ask for incoming data
+ */
+OSErr xUDPRead(SocketPtr sp,UDPIOCompletionUPP completion)
+ {
+ UDPiopb *pb;
+
+ if ( !(pb = sock_fetch_pb(sp) ))
+ return -1;
+
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = UDPRead;
+ pb->csParam.receive.timeOut = 0 /* infinity */;
+ pb->csParam.receive.secondTimeStamp = 0/* must be zero */;
+ return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionUPP)completion ));
+ }
+
+OSErr xUDPBfrReturn(SocketPtr sp)
+ {
+ UDPiopb *pb;
+
+ if ( !(pb = sock_fetch_pb(sp) ))
+ return -1;
+
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = UDPBfrReturn;
+ pb->csParam.receive.rcvBuff = sp->recvBuf;
+ sp->recvBuf = 0;
+ sp->recvd = 0;
+ return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionUPP)-1 ) );
+ }
+
+/*
+ * send data
+ */
+OSErr xUDPWrite(SocketPtr sp,ip_addr host,ip_port port,miniwds *wds,
+ UDPIOCompletionUPP completion)
+ {
+ UDPiopb *pb;
+
+ if ( !(pb = sock_fetch_pb(sp) ))
+ return -1;
+
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = UDPWrite;
+ pb->csParam.send.remoteHost = host;
+ pb->csParam.send.remotePort = port;
+ pb->csParam.send.wdsPtr = (Ptr)wds;
+ pb->csParam.send.checkSum = true;
+ pb->csParam.send.sendLength = 0/* must be zero */;
+ return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionUPP)completion));
+ }
+
+/*
+ * close down a UDP stream (aborting a read, if necessary)
+ */
+OSErr xUDPRelease(SocketPtr sp) {
+ UDPiopb *pb;
+ OSErr io;
+
+ if ( !(pb = sock_fetch_pb(sp) ))
+ return -1;
+
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = UDPRelease;
+ io = xPBControlSync( (TCPiopb *)pb );
+ if (io == noErr) {
+ DisposePtr(pb->csParam.create.rcvBuff);
+ }
+ return(io);
+ }
+
+ip_addr xIPAddr(void)
+{
+#if !defined(__GETMYIPADDR__) && !defined (__MWERKS__)
+ struct IPParamBlock pbr;
+#else
+#ifdef __MWERKS__
+ GetAddrParamBlock pbr;
+#else
+ struct GetAddrParamBlock pbr;
+#endif
+#endif
+ OSErr io;
+
+ pbr.ioCRefNum = driver;
+ pbr.csCode = ipctlGetAddr;
+ io = xPBControlSync( (TCPiopb *)&pbr );
+ if (io != noErr)
+ return(0);
+ return(pbr.ourAddress);
+}
+
+long xNetMask()
+{
+#if !defined(__GETMYIPADDR__) && !defined (__MWERKS__)
+ struct IPParamBlock pbr;
+#else
+#ifdef __MWERKS__
+ GetAddrParamBlock pbr;
+#else
+ struct GetAddrParamBlock pbr;
+#endif
+#endif
+ OSErr io;
+
+ pbr.ioCRefNum = driver;
+ pbr.csCode = ipctlGetAddr;
+ io = xPBControlSync( (TCPiopb *)&pbr);
+ if (io != noErr)
+ return(0);
+ return(pbr.ourNetMask);
+}
+
+unsigned short xMaxMTU()
+{
+#ifdef __MWERKS__
+ UDPiopb pbr;
+#else
+ struct UDPiopb pbr;
+#endif
+ OSErr io;
+
+ pbr.ioCRefNum = driver;
+ pbr.csCode = UDPMaxMTUSize;
+ pbr.csParam.mtu.remoteHost = xIPAddr();
+ io = xPBControlSync( (TCPiopb *)&pbr );
+ if (io != noErr)
+ return(0);
+ return(pbr.csParam.mtu.mtuSize);
+}
+
+OSErr xPBControlSync(TCPiopb *pb)
+{
+ (pb)->ioCompletion = 0L;
+ return PBControl((ParmBlkPtr)(pb),false);
+}
+
+#pragma segment SOCK_RESIDENT
+
+OSErr xTCPRcv(
+ TCPiopb *pb,
+ Ptr buf,
+ int buflen,
+ int timeout,
+ TCPIOCompletionUPP completion)
+{
+
+ if (driver == 0)
+ return(invalidStreamPtr);
+
+ pb->ioCRefNum = driver;
+ pb->csCode = TCPRcv;
+ pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
+ pb->csParam.receive.rcvBuff = buf;
+ pb->csParam.receive.rcvBuffLen = buflen;
+ return (xPBControl(pb,completion));
+}
+
+
+OSErr xPBControl(TCPiopb *pb,TCPIOCompletionUPP completion)
+{
+
+#if !defined(powerc) && !defined(__powerc) && !defined(__POWERPC)
+ pb->ioNamePtr = ReturnA5();
+#endif
+
+ if (completion == 0L)
+ {
+ (pb)->ioCompletion = 0L;
+ return(PBControl((ParmBlkPtr)(pb),false)); /* sync */
+ }
+ else if (completion == (TCPIOCompletionUPP)-1L)
+ {
+ (pb)->ioCompletion = 0L;
+ return(PBControl((ParmBlkPtr)(pb),true)); /* async */
+ }
+ else
+ {
+ (pb)->ioCompletion = (TCPIOCompletionUPP) completion;
+ return(PBControl((ParmBlkPtr)(pb),true)); /* async */
+ }
+}
+
diff --git a/network/ncsasock/unixlib.c b/network/ncsasock/unixlib.c
new file mode 100644
index 00000000..365786d6
--- /dev/null
+++ b/network/ncsasock/unixlib.c
@@ -0,0 +1,640 @@
+/*
+ * BSD-style socket emulation library for the Mac
+ * Original author: Tom Milligan
+ * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
+ *
+ * This source file is placed in the public domian.
+ * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
+ *
+ * National Center for Supercomputing Applications
+ * 152 Computing Applications Building
+ * 605 E. Springfield Ave.
+ * Champaign, IL 61820
+*
+*
+* RCS Modification History:
+* $Log: unixlib.c,v $
+* Revision 6.0 1997/08/25 18:38:22 madden
+* Revision changed to 6.0
+*
+* Revision 4.0 1995/07/26 13:56:09 ostell
+* force revision to 4.0
+*
+ * Revision 1.5 1995/05/23 15:31:16 kans
+ * new CodeWarrior 6 errors and warnings fixed
+ *
+ * Revision 1.4 1995/05/17 17:58:16 epstein
+ * add RCS log revision history
+ *
+ */
+
+#ifdef USEDUMP
+# pragma load "socket.dump"
+#else
+# include <Errors.h>
+# include <Events.h>
+# include <Files.h>
+# include <OSUtils.h>
+# include <Types.h>
+
+# include <s_types.h>
+# include <s_time.h>
+
+#endif
+
+#ifdef THINK_C
+#include <FCntl.h>
+#endif
+
+#include <neti_in.h>
+#include <sock_ext.h>
+#include <sock_str.h>
+#ifdef THINK_C
+#include <pascal.h>
+#else
+#include <Strings.h> /* for c2pstr */
+#endif /* THINK_C */
+#include <ToolUtils.h>
+
+#include <s_timeb.h>
+
+extern int errno;
+extern long errno_long;
+extern SpinFn spinroutine;
+
+/*
+ * unix getwd
+ *
+ * where must point to 256 bytes
+ *
+ * work up from the current directory to the root collecting
+ * name segments as we go
+ */
+
+char *getwd(where) char *where;
+{
+ WDPBRec pb;
+ CInfoPBRec cpb;
+ char wdtemp[256],*start,*store,*trav;
+ int i;
+
+ /* get default volume and directory last set by PBSetVol or PBHSetVol */
+ pb.ioNamePtr = (StringPtr) where;
+ PBHGetVol(&pb,false);
+
+ /* add a colon */
+ (*where)++;
+ where[*where] = ':';
+
+ trav = wdtemp; /* build name here */
+ cpb.dirInfo.ioCompletion = 0L;
+
+ cpb.dirInfo.ioVRefNum = pb.ioWDVRefNum; /* vRefNum of volume on which */
+ /* working dir exists */
+
+ cpb.dirInfo.ioDrDirID = pb.ioWDDirID; /* directory ID of working directory */
+
+ while(cpb.dirInfo.ioDrDirID != 0)
+ {
+ cpb.hFileInfo.ioNamePtr = (StringPtr) trav; /* put name segment here */
+ cpb.hFileInfo.ioFDirIndex = -1;
+ if (PBGetCatInfo(&cpb,false) != 0)
+ {
+ cpb.dirInfo.ioDrDirID = 0;
+ break;
+ }
+ if (*trav == 0)
+ {
+ cpb.dirInfo.ioDrDirID=0;
+ break;
+ }
+ i=*trav; /* save length */
+ *trav=0; /* null over length */
+ start=trav+1; /* addr of 1st char */
+ trav+=i+1; /* point past current string for next name segment */
+ *trav=0; /* initially zero length */
+
+ cpb.dirInfo.ioDrDirID = cpb.dirInfo.ioDrParID; /* point up to parent directory */
+ }
+
+ *wdtemp=0;
+ store=where+*where+1; /* start storing after volume name */
+
+ if (trav-wdtemp)
+ *where=(trav-wdtemp); /* set length of where as length of trav */
+ if (trav!=wdtemp)
+ start=trav-1;
+ else
+ start=wdtemp;
+
+ if (start!=wdtemp)
+ {
+ while(*start) start--; /* Go to beginning of string */
+ if (start!=wdtemp)
+ start--;
+ }
+
+ while(start!=wdtemp)
+ {
+ while(*start) /* Go to beginning of string */
+ start--;
+ trav=start+1;
+ while (*trav) /* store it */
+ {
+ *store=*trav;
+ store++;
+ trav++;
+ }
+ *store=':'; /* Ready to move directory name */
+ store++;
+ if (start!=wdtemp)
+ start--;
+ *store=0;
+ }
+ return(p2cstr((unsigned char *) where));
+}
+
+/*
+ * unix change working directory
+ */
+static int currentWD = 0;
+
+#ifndef __MWERKS__
+int chdir(pathName) char *pathName;
+{
+ WDPBRec pb;
+ char tempst[256];
+ long default_ioWDDirID;
+ short wdToClose;
+
+ /*
+ * get default volume last set by PBSetVol or PBHSetVol
+ */
+ pb.ioNamePtr = 0L;
+ PBHGetVol(&pb,false);
+ default_ioWDDirID = pb.ioWDDirID;
+
+ /*
+ * create a new mac working directory using the default volume and
+ * the callers partial pathname
+ */
+ strcpy(tempst,pathName);
+ pb.ioNamePtr = (StringPtr)c2pstr(tempst);
+ pb.ioVRefNum = 0;
+ pb.ioWDDirID = default_ioWDDirID;
+ pb.ioCompletion = 0L;
+ pb.ioWDProcID = 'UTCS';
+
+ if ((errno = errno_long = PBOpenWD(&pb,0)) != noErr)
+ return(-1);
+
+ /*
+ * make the mac working directory which has just been created in 'pb'
+ * the new default directory. destroy the mac working directory which
+ * was the previous default.
+ */
+#ifdef THINK_C
+ if ((errno = errno_long = SetVol(0L, pb.ioVRefNum)) != noErr)
+#else
+ if ((errno = errno_long = setvol(0L, pb.ioVRefNum)) != noErr)
+#endif
+ {
+ wdToClose = pb.ioVRefNum;
+ }
+ else
+ {
+ wdToClose = currentWD;
+ currentWD = pb.ioVRefNum;
+ }
+
+ /*
+ * close the previous working directory
+ */
+ if (wdToClose == 0) /* nothing more to do, return */
+ return(0);
+
+ pb.ioVRefNum = wdToClose;
+ pb.ioCompletion = 0L;
+ (void) PBCloseWD(&pb, false); /* ignore error */
+
+ return(0);
+}
+#endif
+
+/*
+ * Mac version of Unix system call gettimeofday.
+ *
+ * Time is converted to the Unix epoch: Jan 1, 1970.
+ *
+ * The current timezone is always GMT.
+ */
+
+static struct DateTimeRec unixEpochDtr = {1970,1,1, 0,0,0, 1};
+gettimeofday(tp,tzp) struct timeval *tp; struct timezone *tzp;
+{
+
+ unsigned long unixEpochSecs,currentMacSecs;
+
+ Date2Secs(&unixEpochDtr,&unixEpochSecs);
+ GetDateTime(&currentMacSecs);
+ tp->tv_sec = currentMacSecs - unixEpochSecs;
+ tp->tv_usec = 0;
+
+ if (tzp != NULL)
+ {
+ tzp->tz_minuteswest = 0; /* minutes west of Greenwich */
+ tzp->tz_dsttime = 0; /* no dst correction */
+ }
+ return(0);
+}
+
+#if 0
+/*
+ * Backwards compatible time call.
+ */
+time_t
+time(t)
+ time_t *t;
+{
+ struct timeval tt;
+
+ if (gettimeofday(&tt, (struct timezone *)0) < 0)
+ return (-1);
+ if (t)
+ *t = tt.tv_sec;
+ return (tt.tv_sec);
+}
+#endif
+
+
+/*
+ * The arguments are the number of minutes of time
+ * you are westward from Greenwich and whether DST is in effect.
+ * It returns a string
+ * giving the name of the local timezone.
+ *
+ * Sorry, I don't know all the names.
+ */
+
+static struct zone {
+ int offset;
+ char *stdzone;
+ char *dlzone;
+} zonetab[] = {
+ -1*60, "MET", "MET DST", /* Middle European */
+ -2*60, "EET", "EET DST", /* Eastern European */
+ 4*60, "AST", "ADT", /* Atlantic */
+ 5*60, "EST", "EDT", /* Eastern */
+ 6*60, "CST", "CDT", /* Central */
+ 7*60, "MST", "MDT", /* Mountain */
+ 8*60, "PST", "PDT", /* Pacific */
+#ifdef notdef
+ /* there's no way to distinguish this from WET */
+ 0, "GMT", 0, /* Greenwich */
+#endif
+ 0*60, "WET", "WET DST", /* Western European */
+ -10*60, "EST", "EST", /* Aust: Eastern */
+ -10*60+30, "CST", "CST", /* Aust: Central */
+ -8*60, "WST", 0, /* Aust: Western */
+ -9*60, "JST", 0, /* Japanese */
+ -1
+};
+
+char *timezone(zone, dst)
+{
+ register struct zone *zp;
+ static char czone[10];
+ char *sign;
+ register char *p, *q;
+ char *getenv(), *strchr();
+
+ if ((p = getenv("TZNAME")) != NULL) {
+ if ((q = strchr(p, ',')) != NULL) {
+ if (dst)
+ return(++q);
+ else {
+ *q = '\0';
+ strncpy(czone, p, sizeof(czone)-1);
+ czone[sizeof(czone)-1] = '\0';
+ *q = ',';
+ return (czone);
+ }
+ }
+ return(p);
+ }
+ for (zp=zonetab; zp->offset!=-1; zp++)
+ if (zp->offset==zone) {
+ if (dst && zp->dlzone)
+ return(zp->dlzone);
+ if (!dst && zp->stdzone)
+ return(zp->stdzone);
+ }
+ if (zone<0) {
+ zone = -zone;
+ sign = "+";
+ } else
+ sign = "-";
+ sprintf(czone, "GMT%s%d:%02d", sign, zone/60, zone%60);
+ return(czone);
+}
+
+#ifdef JAE
+/*
+ * Sleep now calls the spinroutine to keep things
+ * moving
+ */
+sleep(seconds) unsigned seconds;
+ {
+ long int wakeup = TickCount() + 60*seconds;
+ long left;
+
+ for (;;)
+ {
+ left = wakeup-TickCount();
+
+ if (left <= 0)
+ return;
+
+ SPIN(false,SP_SLEEP,left)
+ }
+ }
+#endif /* JAE */
+
+#if 0
+long int getpid()
+{
+ return (42);
+}
+#endif
+
+long int getuid()
+{
+ return (0/*root*/);
+}
+
+struct passwd *getpwent()
+{
+ return (NULL /*not found*/);
+}
+
+struct passwd *getpwuid()
+{
+ return (NULL /*not found*/);
+}
+
+struct passwd *getpwnam()
+{
+ return (NULL /*not found*/);
+}
+
+#ifdef JAE
+char *getlogin()
+{
+ return("macuser");
+}
+#endif /* JAE */
+
+int chmod(path, mode)
+ char *path;
+ int mode;
+{
+#pragma unused(path)
+#pragma unused(mode)
+ return(0);
+}
+
+#if 0
+access(path, mode)
+ char *path;
+ int mode;
+{
+#pragma unused(path)
+#pragma unused(mode)
+ return(0);
+}
+
+char *mktemp(template)
+ char *template;
+{
+ return(template);
+}
+
+abort()
+{
+ exit(-1);
+}
+#endif
+
+void bzero( b, s)
+ char *b;
+ long s;
+{
+ for( ; s ; ++b, --s)
+ *b = 0;
+}
+
+bfill( b, s, fill)
+ char *b;
+ long s;
+ char fill;
+{
+ for( ; s ; ++b, --s)
+ *b = fill;
+ return(0);
+}
+
+void bcopy (c1, c2, s)
+ char *c1, *c2;
+ long s;
+{
+ for ( ; s ; --s)
+ *c2++ = *(c1++);
+}
+
+
+bcmp (c1, c2, s)
+ char *c1, *c2;
+ long s;
+{
+ for ( ; s ; --s)
+ if(*c2++ != *(c1++)) return(1);
+ return(0);
+}
+
+char *sys_errlist[] = {
+ "Error 0",
+ "Not owner", /* 1 - EPERM */
+ "No such file or directory", /* 2 - ENOENT */
+ "No such process", /* 3 - ESRCH */
+ "Interrupted system call", /* 4 - EINTR */
+ "I/O error", /* 5 - EIO */
+ "No such device or address", /* 6 - ENXIO */
+ "Arg list too long", /* 7 - E2BIG */
+ "Exec format error", /* 8 - ENOEXEC */
+ "Bad file number", /* 9 - EBADF */
+ "No children", /* 10 - ECHILD */
+ "No more processes", /* 11 - EAGAIN */
+ "Not enough core", /* 12 - ENOMEM */
+ "Permission denied", /* 13 - EACCES */
+ "Bad address", /* 14 - EFAULT */
+ "Block device required", /* 15 - ENOTBLK */
+ "Mount device busy", /* 16 - EBUSY */
+ "File exists", /* 17 - EEXIST */
+ "Cross-device link", /* 18 - EXDEV */
+ "No such device", /* 19 - ENODEV */
+ "Not a directory", /* 20 - ENOTDIR */
+ "Is a directory", /* 21 - EISDIR */
+ "Invalid argument", /* 22 - EINVAL */
+ "File table overflow", /* 23 - ENFILE */
+ "Too many open files", /* 24 - EMFILE */
+ "Not a typewriter", /* 25 - ENOTTY */
+ "Text file busy", /* 26 - ETXTBSY */
+ "File too large", /* 27 - EFBIG */
+ "No space left on device", /* 28 - ENOSPC */
+ "Illegal seek", /* 29 - ESPIPE */
+ "Read-only file system", /* 30 - EROFS */
+ "Too many links", /* 31 - EMLINK */
+ "Broken pipe", /* 32 - EPIPE */
+
+/* math software */
+ "Argument too large", /* 33 - EDOM */
+ "Result too large", /* 34 - ERANGE */
+
+/* non-blocking and interrupt i/o */
+ "Operation would block", /* 35 - EWOULDBLOCK */
+ "Operation now in progress", /* 36 - EINPROGRESS */
+ "Operation already in progress", /* 37 - EALREADY */
+
+/* ipc/network software */
+
+ /* argument errors */
+ "Socket operation on non-socket", /* 38 - ENOTSOCK */
+ "Destination address required", /* 39 - EDESTADDRREQ */
+ "Message too long", /* 40 - EMSGSIZE */
+ "Protocol wrong type for socket", /* 41 - EPROTOTYPE */
+ "Protocol not available", /* 42 - ENOPROTOOPT */
+ "Protocol not supported", /* 43 - EPROTONOSUPPORT */
+ "Socket type not supported", /* 44 - ESOCKTNOSUPPORT */
+ "Operation not supported on socket", /* 45 - EOPNOTSUPP */
+ "Protocol family not supported", /* 46 - EPFNOSUPPORT */
+ "Address family not supported by protocol family",
+ /* 47 - EAFNOSUPPORT */
+ "Address already in use", /* 48 - EADDRINUSE */
+ "Can't assign requested address", /* 49 - EADDRNOTAVAIL */
+
+ /* operational errors */
+ "Network is down", /* 50 - ENETDOWN */
+ "Network is unreachable", /* 51 - ENETUNREACH */
+ "Network dropped connection on reset", /* 52 - ENETRESET */
+ "Software caused connection abort", /* 53 - ECONNABORTED */
+ "Connection reset by peer", /* 54 - ECONNRESET */
+ "No buffer space available", /* 55 - ENOBUFS */
+ "Socket is already connected", /* 56 - EISCONN */
+ "Socket is not connected", /* 57 - ENOTCONN */
+ "Can't send after socket shutdown", /* 58 - ESHUTDOWN */
+ "Too many references: can't splice", /* 59 - ETOOMANYREFS */
+ "Connection timed out", /* 60 - ETIMEDOUT */
+ "Connection refused", /* 61 - EREFUSED */
+ "Too many levels of symbolic links", /* 62 - ELOOP */
+ "File name too long", /* 63 - ENAMETOOLONG */
+ "Host is down", /* 64 - EHOSTDOWN */
+ "Host is unreachable", /* 65 - EHOSTUNREACH */
+ "Directory not empty", /* 66 - ENOTEMPTY */
+ "Too many processes", /* 67 - EPROCLIM */
+ "Too many users", /* 68 - EUSERS */
+ "Disc quota exceeded", /* 69 - EDQUOT */
+ "Stale NFS file handle", /* 70 - ESTALE */
+ "Too many levels of remote in path", /* 71 - EREMOTE */
+};
+
+int sys_nerr = { sizeof sys_errlist/sizeof sys_errlist[0] };
+
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c 5.6 (Berkeley) 6/27/88";
+#endif /* LIBC_SCCS and not lint */
+
+#include <s_types.h>
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static u_char charmap[] = {
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+ '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+ '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+ '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+ '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+ '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+ '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+ '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+ '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+ '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+strcasecmp(s1, s2)
+ char *s1, *s2;
+{
+ register u_char *cm = charmap,
+ *us1 = (u_char *)s1,
+ *us2 = (u_char *)s2;
+
+ while (cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return(0);
+ return(cm[*us1] - cm[*--us2]);
+}
+
+strncasecmp(s1, s2, n)
+ char *s1, *s2;
+ register int n;
+{
+ register u_char *cm = charmap,
+ *us1 = (u_char *)s1,
+ *us2 = (u_char *)s2;
+
+ while (--n >= 0 && cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return(0);
+ return(n < 0 ? 0 : cm[*us1] - cm[*--us2]);
+}
diff --git a/network/netmanag/README b/network/netmanag/README
new file mode 100644
index 00000000..6724170b
--- /dev/null
+++ b/network/netmanag/README
@@ -0,0 +1,9 @@
+In order to use the NCBI network services in conjunction with the NetManage
+Software development kit, it is necessary to copy the following files
+from the NEWT-SDK developer disks into this "netmanag" directory.
+
+nmpcip.h
+nmpcip.lib
+
+These files are copyrighted by NetManage, so it is not possible for NCBI
+to distribute them in its software tree.
diff --git a/network/nsclilib/lbapi.c b/network/nsclilib/lbapi.c
new file mode 100644
index 00000000..c9bcb000
--- /dev/null
+++ b/network/nsclilib/lbapi.c
@@ -0,0 +1,240 @@
+/* $Id: lbapi.c,v 1.9 1998/12/07 19:01:50 shavirin Exp $
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: $RCSfile: lbapi.c,v $
+*
+* Author: Sergei Shavirin
+*
+* Initial Version Creation Date: 03/24/1997
+*
+* $Revision: 1.9 $
+*
+* File Description:
+* Utilities for the load balancing client library
+*
+* $Log: lbapi.c,v $
+* Revision 1.9 1998/12/07 19:01:50 shavirin
+* Added complience with little-big endian platforms.
+*
+* Revision 1.8 1998/09/22 17:22:57 yaschenk
+* LBCalculateStatus: changed additive constant 1 which is very high to 0.01
+*
+* Revision 1.7 1998/05/08 15:26:57 vakatov
+* [LB_DIRECT] now can skip IP addresses(for the dispatcher hosts) which
+* were already offered by the load-balancing daemon but failed by some reason
+*
+* Revision 1.6 1998/04/23 14:26:18 shavirin
+* Added include #include <sys/ipc.h>
+*
+* Revision 1.5 1998/04/07 14:17:27 vakatov
+* Skip all code(#ifdef'd) if LB_DIRECT is not defined or if compiled on
+* any platform but Solaris and IRIX
+*
+* Revision 1.4 1998/04/03 21:50:08 shavirin
+* Added include file for TCP/IP address define
+*
+* Revision 1.3 1998/04/03 21:16:47 vakatov
+* Cleaned up the code and prepared "lbapi.[ch]" to be moved to "netcli" lib
+*
+* Revision 1.2 1998/04/02 17:36:04 yaschenk
+* Adding dispd-ncbid shortcut when they are on the same server, adding preference to same server in stateless mode
+*
+* Revision 1.1 1998/03/06 18:54:25 shavirin
+* Initial revision
+* ==========================================================================
+*/
+
+#include <lbapi.h>
+
+#ifdef LB_DIRECT
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#define SHM_FLAGS ((SHM_R >> 6) | (SHM_R >> 3) | SHM_R)
+#define MAX_RAND_NUMBER 0x7FFF
+
+
+typedef struct LBUserInfo {
+ LB_MessagePtr lbtable;
+ int shmemid;
+} LBUserInfo, *LBUserInfoPtr;
+
+typedef struct LBStatus {
+ int index;
+ float status;
+ int skip;
+} LBStatus, *LBStatusPtr;
+
+
+static LBUserInfo theinfo;
+
+static float LBCalculateStatus(LB_MessagePtr msgp)
+{
+ return (0.01 + 25600*ntohl(msgp->load[1]) /
+ (float)(ntohl(msgp->load[0])*ntohl(msgp->load[2]) + 1));
+}
+
+static int LBClientInit(void)
+{
+ /* setting it completely random */
+ srand(time(NULL));
+
+ if ((theinfo.shmemid = shmget(LB_SHARED_KEY,
+ sizeof(LB_Message) * MAX_NUM_HOSTS,
+ SHM_FLAGS)) < 0)
+ return -1;
+
+ if ((theinfo.lbtable = (LB_MessagePtr)
+ shmat(theinfo.shmemid, (void *)0, SHM_RDONLY)) == (LB_MessagePtr)-1)
+ return -1;
+
+ return 0;
+}
+
+
+extern int LBPrintTable(void)
+{
+ int i, j;
+ struct sockaddr_in sin;
+ struct hostent *hp;
+ float status;
+ LB_MessagePtr lbtable;
+
+ if((lbtable = theinfo.lbtable) == NULL) {
+ if(LBClientInit() < 0)
+ return -1;
+ lbtable = theinfo.lbtable;
+ }
+
+ for(j = 0; j < MAX_NUM_HOSTS; j++) {
+ if(lbtable[j].address != 0) {
+ sin.sin_addr.s_addr = lbtable[j].address;
+
+ hp = gethostbyaddr((char *)&sin.sin_addr,
+ sizeof (sin.sin_addr), AF_INET);
+ printf("%-15s: ",
+ hp == NULL? inet_ntoa(sin.sin_addr) : hp->h_name);
+
+ status = LBCalculateStatus(&lbtable[j]);
+ printf("%-10.2f ", status);
+
+ for(i = 0; i < NUM_LOAD_PARAMETERS; i++)
+ printf("%5d ", ntohl(lbtable[j].load[i]));
+
+ for(i = 0; i < MAX_NUM_SERVICES; i++) {
+ if(*lbtable[j].service[i] != '\0')
+ printf("%s ", lbtable[j].service[i]);
+ }
+ printf("\n");
+ fflush(stdout);
+ }
+ }
+ printf("----\n");
+
+ return 0;
+}
+
+
+extern unsigned LBGetIPAddress(const char *service, unsigned int pref_ip,
+ unsigned *skip_ip, size_t n_skip)
+{
+ int i, j, k;
+ LBStatus trace[MAX_NUM_HOSTS];
+ int count;
+ float status, all_status, point;
+ LB_MessagePtr lbtable;
+
+ if (!theinfo.lbtable && LBClientInit() < 0)
+ return 0;
+
+ lbtable = theinfo.lbtable;
+
+ memset(trace, '\0', sizeof(trace));
+
+ /* the hosts to be skipped */
+ for (j = 0; j < MAX_NUM_HOSTS; j++) {
+ size_t m;
+ for (m = 0; m < n_skip; m++)
+ if (lbtable[j].address == skip_ip[m]) {
+ trace[j].skip = 1;
+ break;
+ }
+ }
+
+ /* first try to find the preferred address */
+ if ( pref_ip ) {
+ for (j = 0, i = 0; j < MAX_NUM_HOSTS; j++) {
+ if (pref_ip == lbtable[j].address) {
+ if ( trace[j].skip )
+ break;
+ for (k = 0; k < MAX_NUM_SERVICES; k++) {
+ if ( !strcmp(lbtable[j].service[k], service) )
+ return pref_ip;
+ }
+ break;
+ }
+ }
+ }
+
+ all_status = 0;
+ for (j = 0, i = 0; j < MAX_NUM_HOSTS; j++) {
+ if ( trace[j].skip )
+ continue;
+
+ for (k = 0; k < MAX_NUM_SERVICES; k++) {
+ if(!strcmp(lbtable[j].service[k], service)) {
+ status = LBCalculateStatus(&lbtable[j]);
+ all_status += status;
+ trace[i].status = all_status;
+ trace[i].index = j;
+ i++;
+ break;
+ }
+ }
+ }
+ if ( !i )
+ return 0;
+
+ count = i;
+ point = (float)(trace[count-1].status * rand()) / (float)MAX_RAND_NUMBER;
+
+ for (i = 0; i < count; i++) {
+ if (point < trace[i].status)
+ break;
+ }
+
+ return lbtable[trace[i].index].address;
+}
+
+#endif /* LB_DIRECT */
diff --git a/network/nsclilib/lbapi.h b/network/nsclilib/lbapi.h
new file mode 100644
index 00000000..9cc3f30b
--- /dev/null
+++ b/network/nsclilib/lbapi.h
@@ -0,0 +1,120 @@
+#include <ncbilcl.h>
+
+#if defined(LB_DIRECT) && !defined(OS_UNIX_SOL) && !defined(OS_UNIX_IRIX)
+#undef LB_DIRECT
+#endif
+
+#ifndef LB_DIRECT
+#define LBAPI__H
+#endif
+
+#ifndef LBAPI__H
+#define LBAPI__H
+
+/* $Id: lbapi.h,v 1.9 1999/01/22 22:02:38 vakatov Exp $
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: $RCSfile: lbapi.h,v $
+*
+* Author: Sergei Shavirin
+*
+* Initial Version Creation Date: 03/24/1997
+*
+* $Revision: 1.9 $
+*
+* File Description:
+* Definitions for the load-balancing API.
+*
+* $Log: lbapi.h,v $
+* Revision 1.9 1999/01/22 22:02:38 vakatov
+* Added important NOTE for LBGetIPAddress()
+*
+* Revision 1.8 1998/05/08 15:26:58 vakatov
+* [LB_DIRECT] now can skip IP addresses(for the dispatcher hosts) which
+* were already offered by the load-balancing daemon but failed by some reason
+*
+* Revision 1.7 1998/04/30 19:57:22 vakatov
+* included <ncbilcl.h> to get #OS_UNIX_SOL and #OS_UNIX_IRIX
+*
+* Revision 1.6 1998/04/30 16:27:14 vakatov
+* [IRIX] fixed a typo that(erroneously) did not allow LB_DIRECT on IRIX
+*
+* Revision 1.5 1998/04/07 14:40:32 vakatov
+* added missing #endif
+*
+* Revision 1.4 1998/04/07 14:17:28 vakatov
+* Skip all code(#ifdef'd) if LB_DIRECT is not defined or if compiled on
+* any platform but Solaris and IRIX
+*
+* Revision 1.3 1998/04/03 21:16:48 vakatov
+* Cleaned up the code and prepared "lbapi.[ch]" to be moved to "netcli" lib
+*
+* Revision 1.2 1998/04/02 17:36:06 yaschenk
+* Adding dispd-ncbid shortcut when they are on the same server, adding preference to same server in stateless mode
+*
+* Revision 1.1 1998/03/06 18:55:01 shavirin
+* Initial revision
+* ==========================================================================
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_NUM_HOSTS 100
+#define NUM_LOAD_PARAMETERS 4
+#define MAX_NUM_SERVICES 16
+#define MAX_SERVICE_LEN 32
+#define LB_SHARED_KEY 34523
+#define LB_SEMA_KEY 8766564
+
+typedef struct LB_Message {
+ unsigned int address; /* actually, char[4], but for UNIXes... it is okay */
+ int load[NUM_LOAD_PARAMETERS];
+ char service[MAX_NUM_SERVICES][MAX_SERVICE_LEN];
+} LB_Message, *LB_MessagePtr;
+
+extern int LBPrintTable(void);
+
+/* Using the info from the local load-balancing daemon,
+ * get IP address of the host where the specified "service" is running.
+ * Return "preferred_ip" if the specified "service" is available on the
+ * host with IP address = "preferred_ip".
+ * Do not consider first "n_skip" hosts enlisted in the "skip_ip" array.
+ * On any error, return zero.
+ * NOTE: all IP addresses here are in the network byte order
+ */
+extern unsigned LBGetIPAddress
+(const char* service,
+ unsigned preferred_ip,
+ unsigned* skip_ip,
+ size_t n_skip
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LBAPI__H */
diff --git a/network/nsclilib/ncbibuf.c b/network/nsclilib/ncbibuf.c
new file mode 100644
index 00000000..f91a522f
--- /dev/null
+++ b/network/nsclilib/ncbibuf.c
@@ -0,0 +1,299 @@
+/* $RCSfile: ncbibuf.c,v $ $Revision: 6.1 $ $Date: 1998/04/14 15:34:22 $
+* ==========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ==========================================================================
+*
+* Author: Denis Vakatov
+*
+* File Description:
+* Memory-resided FIFO storage area(to be used e.g. in I/O buffering)
+*
+* --------------------------------------------------------------------------
+* $Log: ncbibuf.c,v $
+* Revision 6.1 1998/04/14 15:34:22 vakatov
+* Initial revision
+*
+* ==========================================================================
+*/
+
+#include <ncbi.h>
+#include <ncbibuf.h>
+
+#define MIN_CHUNK_SIZE 512
+
+typedef struct BufChunkTag {
+ struct BufChunkTag* next;
+ Uint4 size; /* of data */
+ Uint4 alloc_size; /* maximum avail.(allocated) size of "data" */
+ Char data[1];
+} BufChunk;
+
+typedef struct Nlm_BufferTag {
+ BufChunk* list;
+ Uint4 n_skip; /* # of bytes already "removed" from the 1st data chunk */
+} Nlm_Buffer;
+
+
+NLM_EXTERN Uint4 BUF_Size(BUF buf)
+{
+ Uint4 size;
+ BufChunk *pChunk;
+ if ( !buf )
+ return 0;
+
+ for (size = 0, pChunk = buf->list; pChunk; pChunk = pChunk->next) {
+ size += pChunk->size;
+ }
+ ASSERT((size > buf->n_skip) || (size == buf->n_skip && !buf->list && !size));
+ size -= buf->n_skip;
+
+ return size;
+}
+
+
+NLM_EXTERN Boolean BUF_Write(BUF* pBuf, const void* data, Uint4 size)
+{
+ BufChunk *pChunk, *pTail;
+ if ( !size )
+ return TRUE;
+
+ /* create the buffer internals, if not created yet */
+ if ( !*pBuf ) {
+ *pBuf = (Nlm_Buffer*)MemNew(sizeof(Nlm_Buffer));
+ if ( !*pBuf )
+ return FALSE;
+ }
+
+ /* find the last allocated chunk */
+ for (pTail = (*pBuf)->list; pTail && pTail->next; pTail = pTail->next);
+
+ /* write to an unfilled space of the last allocated chunk, if any */
+ if (pTail && pTail->size != pTail->alloc_size) {
+ Uint4 n_avail = pTail->alloc_size - pTail->size;
+ Uint4 n_write = (size <= n_avail) ? size : n_avail;
+ ASSERT( pTail->size < pTail->alloc_size );
+ MemCpy(pTail->data + pTail->size, data, n_write);
+ pTail->size += n_write;
+ size -= n_write;
+ data = (char*)data + n_write;
+ }
+
+ /* allocate and write to the new chunk, if necessary */
+ if ( size ) {
+ Uint4 alloc_size =
+ ((size + MIN_CHUNK_SIZE - 1) / MIN_CHUNK_SIZE) * MIN_CHUNK_SIZE;
+ pChunk = (BufChunk*)MemNew(sizeof(BufChunk) - 1 + alloc_size);
+ if ( !pChunk )
+ return FALSE;
+ pChunk->alloc_size = alloc_size;
+ MemCpy(pChunk->data, data, size);
+ pChunk->size = size;
+
+ /* add the new chunk to the buffer list */
+ if ( pTail )
+ pTail->next = pChunk;
+ else
+ (*pBuf)->list = pChunk;
+ }
+ return TRUE;
+}
+
+
+NLM_EXTERN Uint4 BUF_Peek(BUF buf, void* data, Uint4 size)
+{
+ Uint4 n_todo = size;
+ Uint4 n_skip;
+ BufChunk *pChunk;
+
+ if (!data || !size || !buf || !buf->list)
+ return 0;
+
+ n_skip = buf->n_skip;
+ for (pChunk = buf->list, n_skip = buf->n_skip;
+ n_todo && pChunk;
+ pChunk = pChunk->next, n_skip = 0) {
+ Uint4 n_copy = pChunk->size - n_skip;
+ if (n_copy > n_todo)
+ n_copy = n_todo;
+
+ ASSERT( n_skip < pChunk->size );
+ MemCpy(data, (char*)pChunk->data + n_skip, n_copy);
+ data = (char*)data + n_copy;
+ n_todo -= n_copy;
+ }
+
+ return (Uint4)(size - n_todo);
+}
+
+
+NLM_EXTERN Uint4 BUF_Read(BUF buf, void* data, Uint4 size)
+{
+ Uint4 n_todo;
+ if (!buf || !size)
+ return 0;
+
+ /* peek to the callers data buffer, if non-NULL */
+ if ( data )
+ size = BUF_Peek(buf, data, size);
+
+ /* remove the read data from the buffer */
+ n_todo = size;
+ while (n_todo && buf->list) {
+ Uint4 n_avail = buf->list->size - buf->n_skip;
+ if (n_todo >= n_avail) { /* discard the whole chunk */
+ BufChunk *pChunk = buf->list;
+ buf->list = pChunk->next;
+ MemFree(pChunk);
+ n_todo -= n_avail;
+ buf->n_skip = 0;
+ } else { /* discard some of the chunk data */
+ buf->n_skip += n_todo;
+ n_todo = 0;
+ }
+ }
+
+ return (Uint4)(size - n_todo);
+}
+
+
+NLM_EXTERN BUF BUF_Destroy(BUF buf)
+{
+ if ( !buf )
+ return 0;
+
+ while ( buf->list ) {
+ BufChunk *pChunk = buf->list;
+ buf->list = pChunk->next;
+ MemFree(pChunk);
+ }
+
+ MemFree(buf);
+ return 0;
+}
+
+
+#ifdef TEST_MODULE__NCBIBUF
+
+static Uint4 s_Rand(void)
+{ /* a uniform random number generator */
+ static Uint4 s_Random = 1;
+ s_Random = s_Random * 1103515245 + 12345;
+ return (Uint4)(s_Random / 65536) % 32768;
+}
+
+
+Int2 Main()
+{ /* test application */
+#define X_MAX_N_IO 3
+#define X_MAX_READ MIN_CHUNK_SIZE * 3
+#define X_TIMES ((Uint4)(s_Rand() % X_MAX_N_IO))
+#define X_BYTES ((Uint4)(s_Rand() % X_MAX_READ))
+
+ BUF buf = 0;
+ Boolean do_loop = TRUE;
+
+ FILE *fin = FileOpen("stdin", "rb");
+ FILE *fout = FileOpen("stdout", "wb");
+
+ /* setup the error posting */
+ Nlm_ErrSetOpts(ERR_TEE, ERR_LOG_ON);
+ ErrSetLogLevel(SEV_INFO);
+ ErrSetMessageLevel(SEV_INFO);
+ VERIFY( Nlm_ErrSetLog("ncbibuf.log") );
+
+ /* read up to the very end of input stream */
+ while ( do_loop ) {
+ Char charbuf[X_MAX_READ];
+ Uint4 i;
+ Uint4 n_times;
+
+ /* read from the input stream, write to the NCBI IO-buf */
+ n_times = X_TIMES;
+ for (i = 0; i < n_times; i++) {
+ Uint4 n_bytes = X_BYTES;
+ if ( !n_bytes )
+ continue;
+ n_bytes = (Uint4)FileRead(charbuf, 1, (size_t)n_bytes, fin);
+ ErrPostEx(SEV_INFO, 0, 0, "[FileRead] %lu", (unsigned long)n_bytes);
+ if ( !n_bytes ) {
+ do_loop = FALSE; /* end of the input stream */
+ break;
+ }
+ VERIFY( BUF_Write(&buf, charbuf, n_bytes) );
+ ErrPostEx(SEV_INFO, 0, 0, "[BUF_Write] %lu", (unsigned long)n_bytes);
+ }
+
+ /* peek & read from the NCBI IO-buf, write to the output stream */
+ n_times = X_TIMES;
+ for (i = 0; i < n_times && BUF_Size(buf); i++) {
+ Boolean do_peek = (Boolean)(s_Rand() % 2 == 0);
+ Uint4 n_peek;
+ Uint4 n_bytes = X_BYTES;
+ if ( !n_bytes )
+ continue;
+
+ /* peek from the NCBI IO-buf */
+ if ( do_peek ) {
+ Uint4 j, n_peek_times = s_Rand() % 3 + 1;
+ for (j = 0; j < n_peek_times; j++) {
+ n_peek = BUF_Peek(buf, charbuf, n_bytes);
+ ErrPostEx(SEV_INFO, 0, 0, "[BUF_Peek] %lu", (unsigned long)n_peek);
+ }
+ }
+
+ /* read(or just discard) the data */
+ if (do_peek && s_Rand() % 2 == 0)
+ n_bytes = BUF_Read(buf, 0, n_bytes);
+ else
+ n_bytes = BUF_Read(buf, charbuf, n_bytes);
+
+ ErrPostEx(SEV_INFO, 0, 0, "[BUF_Read] %lu", (unsigned long)n_bytes);
+ ASSERT( !do_peek || n_bytes == n_peek );
+
+ /* write the read data to the output stream */
+ VERIFY( n_bytes == (Uint4)FileWrite(charbuf, 1, (size_t)n_bytes, fout) );
+ ErrPostEx(SEV_INFO, 0, 0, "[FileWrite] %lu", (unsigned long)n_bytes);
+ }
+ }
+
+ /* flush the IO-buf to the output stream */
+ while ( BUF_Size(buf) ) {
+ Char charbuf[1024];
+ Uint4 n_bytes = BUF_Read(buf, charbuf, sizeof(charbuf));
+ ErrPostEx(SEV_INFO, 0, 0, "[BUF_Read/flush] %lu", (unsigned long)n_bytes);
+ ASSERT( n_bytes );
+ VERIFY( n_bytes == (Uint4)FileWrite(charbuf, 1, (size_t)n_bytes, fout) );
+ ErrPostEx(SEV_INFO, 0, 0, "[FileWrite/flush] %lu", (unsigned long)n_bytes);
+ }
+
+ /* cleanup */
+ BUF_Destroy(buf);
+ FileClose(fout);
+ FileClose(fin);
+
+ return 0;
+}
+#endif /* TEST_MODULE__NCBIBUF */
+
+/* EOF */
+
diff --git a/network/nsclilib/ncbibuf.h b/network/nsclilib/ncbibuf.h
new file mode 100644
index 00000000..1b462892
--- /dev/null
+++ b/network/nsclilib/ncbibuf.h
@@ -0,0 +1,115 @@
+#ifndef NCBIBUF__H
+#define NCBIBUF__H
+
+/* $RCSfile: ncbibuf.h,v $ $Revision: 6.1 $ $Date: 1998/04/14 15:34:23 $
+* ==========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ==========================================================================
+*
+* Author: Denis Vakatov
+*
+* File Description:
+* Memory-resided FIFO storage area(to be used e.g. in I/O buffering)
+*
+* --------------------------------------------------------------------------
+* $Log: ncbibuf.h,v $
+* Revision 6.1 1998/04/14 15:34:23 vakatov
+* Initial revision
+*
+* ==========================================================================
+*/
+
+#include <ncbistd.h>
+
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define BUF Nlm_BUF
+#define BUF_Size Nlm_BUF_Size
+#define BUF_Write Nlm_BUF_Write
+#define BUF_Peek Nlm_BUF_Peek
+#define BUF_Read Nlm_BUF_Read
+#define BUF_Destroy Nlm_BUF_Destroy
+
+
+struct Nlm_BufferTag;
+typedef struct Nlm_BufferTag* BUF; /* handle of the NCBI buffer */
+
+
+/* Return the number of bytes stored in "buf".
+ * NOTE: return 0 if "buf" == NULL
+ */
+NLM_EXTERN Nlm_Uint4 BUF_Size(BUF buf);
+
+
+/* Add new data to "*pBuf".
+ * NOTE: if "*pBuf" == NULL then create it
+ */
+NLM_EXTERN Nlm_Boolean BUF_Write(BUF* pBuf, const void* data, Nlm_Uint4 size);
+
+
+/* Copy up to "size" bytes stored in "buf" to "data".
+ * Return the # of copied bytes(can be less than "size").
+ * NOTE: "buf" and "data" can be NULL; in both cases, do nothing
+ * and return 0.
+ */
+NLM_EXTERN Nlm_Uint4 BUF_Peek(BUF buf, void* data, Nlm_Uint4 size);
+
+
+/* Copy up to "size" bytes stored in "buf" to "data" and remove
+ * copied data from the "buf".
+ * Return the # of copied-and/or-removed bytes(can be less than "size")
+ * NOTE: if "buf" == NULL then do nothing and return 0
+ * if "data" == NULL then do not copy data anywhere(still, remove it)
+ */
+NLM_EXTERN Nlm_Uint4 BUF_Read(BUF buf, void* data, Nlm_Uint4 size);
+
+
+/* Destroy all internal data; return NULL
+ * NOTE: do nothing if "buf" == NULL
+ */
+NLM_EXTERN BUF BUF_Destroy(BUF buf);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif /* NCBIBUF__H */
diff --git a/network/nsclilib/ncbicli.c b/network/nsclilib/ncbicli.c
new file mode 100644
index 00000000..60a268ba
--- /dev/null
+++ b/network/nsclilib/ncbicli.c
@@ -0,0 +1,570 @@
+/* $RCSfile: ncbicli.c,v $ $Revision: 4.14 $ $Date: 1999/01/22 22:04:58 $
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* Author: Denis Vakatov
+*
+* File Description:
+* API to open(using HTTPD-based dispatcher) and handle socket-based
+* connection to an NCBI service
+*
+* --------------------------------------------------------------------------
+* $Log: ncbicli.c,v $
+* Revision 4.14 1999/01/22 22:04:58 vakatov
+* Uint4toInaddr() to take address in the network byte order
+*
+* Revision 4.13 1998/12/15 17:26:53 vakatov
+* + Handle the case of connecting through a CERN-like non-transparent proxy
+*
+* Revision 4.12 1998/10/13 20:51:14 vakatov
+* Added to HTTP header: &platform=<Nlm_PlatformName()> -- to report
+* the client's platform
+*
+* Revision 4.11 1998/09/08 17:59:03 vakatov
+* Added WWW/Firewall network interface
+*
+* Revision 4.10 1998/08/05 20:19:17 vakatov
+* [eNIC_WWWClient] NIC_GetService(): send the bytestore contents to
+* server rather than to dispatcher
+*
+* Revision 4.9 1998/05/08 15:22:33 vakatov
+* NIC_GetService(): added more detailed error diagnostics
+*
+* Revision 4.8 1998/05/05 22:31:08 vakatov
+* Redesigned some code for the sake of simplicity
+*
+* Revision 4.7 1998/04/30 22:07:25 vakatov
+* NIC_GetService(): set the regular connection timeout to infinite
+*
+* Revision 4.6 1998/04/03 16:08:37 vakatov
+* s_NIC_DispConnectRequest(): minor fix in retrieving client host name
+*
+* Revision 4.5 1998/04/02 20:21:09 vakatov
+* Added possibility to printout service reply headers
+*
+* Revision 4.4 1998/03/30 17:50:08 vakatov
+* Ingrafted to the main NCBI CVS tree
+*
+* ==========================================================================
+*/
+
+#include <ncbi.h>
+#include <ncbicli.h>
+
+#define ENIC_DEFAULT eNIC_WWWClient
+
+
+/***********************************************************************
+ * INTERNAL
+ ***********************************************************************/
+
+typedef struct Nlm_NICtag
+{
+ SOCK sock;
+ CharPtr client_host;
+ Uint4 server_host; /* local byte-order */
+ Uint2 server_port; /* local byte-order */
+ Uint4 ticket; /* network byte-order */
+} Nlm_NICstruct;
+
+
+/* Compose and send an HTTP header-request
+ */
+static Boolean s_SendHeaderWWW
+(SOCK sock,
+ const Char* service_name,
+ const Char* disp_path,
+ const Char* client_agent,
+ const Char* client_host,
+ Uint4 content_length)
+{
+ static char X_POST_1[] = "POST ";
+ static char X_POST_2[] = "?service=";
+ static char X_POST_3[] = "&address=";
+ static char X_POST_4[] = "&platform=";
+ static char X_POST_E[] = " HTTP/1.0\n";
+ static char X_AGENT_1[] = "User-Agent: ";
+ static char X_AGENT_2[] = " from ";
+
+ Char buffer[128];
+ if (SOCK_Write(sock, (const void *)X_POST_1, StrLen(X_POST_1 ), 0)
+ != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)disp_path,
+ StrLen(disp_path), 0) != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)X_POST_2, StrLen(X_POST_2 ), 0)
+ != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)service_name,
+ StrLen(service_name), 0) != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)X_POST_3, StrLen(X_POST_3 ), 0)
+ != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)client_host,
+ StrLen(client_host), 0) != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)X_POST_4, StrLen(X_POST_4 ), 0)
+ != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)Nlm_PlatformName(),
+ StrLen(Nlm_PlatformName()), 0) != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)X_POST_E, StrLen(X_POST_E ), 0)
+ != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)X_AGENT_1, StrLen(X_AGENT_1), 0)
+ != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)client_agent,
+ StrLen(client_agent), 0)
+ != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)X_AGENT_2, StrLen(X_AGENT_2), 0)
+ != eSOCK_ESuccess ||
+ SOCK_Write(sock, (const void *)client_host,
+ StrLen(client_host), 0)
+ != eSOCK_ESuccess ||
+ sprintf(buffer, "\nContent-type: application/x-www-form-urlencoded"
+ "\nContent-Length: %lu\n\n", (unsigned long)content_length)
+ <= 0 ||
+ SOCK_Write(sock, (const void *)buffer, StrLen(buffer ), 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, NIC_ERROR, 4,
+ "[NIC_GetService] Error sending HTTP header");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/* Send the bytestore content
+ */
+static Boolean s_SendBS(SOCK sock, const ByteStore *service_query)
+{
+ const Nlm_BSUnit *bsup;
+ for (bsup = service_query->chain; bsup && bsup->len; bsup = bsup->next) {
+ const void *ptr = Nlm_HandLock(bsup->str);
+ ESOCK_ErrCode err_code = SOCK_Write(sock, ptr, (Uint4)bsup->len, 0);
+ Nlm_HandUnlock(bsup->str);
+ if (err_code != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, NIC_ERROR, 5,
+ "[NIC_GetService] Error sending service query (%s)",
+ SOCK_ErrCodeStr(err_code));
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+/* Skip "n_skip" bytes in the socket;
+ * on error, return non-zero value(number of bytes that could not be skipped)
+ */
+static Uint4 s_NIC_SockSkip(SOCK sock, Uint4 n_skip)
+{
+ ESOCK_ErrCode err_code = eSOCK_ESuccess;
+ while (n_skip && err_code == eSOCK_ESuccess) {
+ Char buffer[1024];
+ Uint4 n_io, n_io_done;
+
+ n_io = MIN(sizeof(buffer), n_skip);
+ err_code = SOCK_Read(sock, buffer, n_io, &n_io_done);
+ n_skip -= n_io_done;
+ }
+
+ if ( n_skip )
+ ErrPostEx(SEV_ERROR, NIC_ERROR, 0,
+ "[s_NIC_SockSkip] Cannot dummy-read requested # of bytes");
+
+ return n_skip;
+}
+
+
+/* Get and process reply from dispatcher(WWW Special-Client agent)
+ */
+static Boolean s_ProcessReply_WWWClient(NIC nic, const STimeout *timeout,
+ Boolean debug_printout,
+ Boolean cern_nontransparent_proxy)
+{
+ Uint4 buf_read;
+ Char buffer[1024];
+ ESOCK_ErrCode err_code;
+
+ buf_read = 0;
+ for (;;) {{ /* TRY */
+ static const Char X_TAG[] = "SERVICE_ENGINE_HOST=";
+ Char *str;
+ Uint4 n_read;
+
+ /* read the next piece of data */
+ err_code = SOCK_Read(nic->sock, buffer + buf_read,
+ sizeof(buffer) - buf_read - 1, &n_read);
+ if (err_code != eSOCK_ESuccess) {
+ ErrPostEx(SEV_WARNING, NIC_ERROR, 6,
+ "[WWW Special] Error in reading reply from the dispatcher"
+ " (%s)", SOCK_ErrCodeStr(err_code));
+ break;
+ }
+ buf_read += n_read;
+ ASSERT( buf_read < sizeof(buffer) );
+ buffer[buf_read] = '\0';
+
+ if ( debug_printout ) {
+ fprintf(stderr, "[WWW Special Client, reply %lu:%lu]: \"%s\"",
+ (unsigned long)buf_read, (unsigned long)(buf_read + n_read),
+ buffer + buf_read - n_read);
+ }
+
+ /* parse for the reply tag and read info on the "real" server */
+ str = StrStr(buffer, X_TAG);
+ if ( str ) { /* read info after the tag */
+ unsigned long server_host, server_port, ticket, dummy;
+ if (sscanf(str + StrLen(X_TAG), "%lx %lx %lx %lx",
+ &server_host, &server_port, &ticket, &dummy) != 4) {
+ buf_read = StrLen(str);
+ MemMove(buffer, str, (size_t)(buf_read + 1));
+ continue; /* yet incomplete... -- continue reading */
+ }
+
+ /* the dispatcher's reply has been parsed successfully */
+ if ( cern_nontransparent_proxy ) { /* substitute server host */
+ SOCK_Address(nic->sock, &server_host, 0, FALSE);
+ }
+ nic->server_host = server_host;
+ nic->server_port = (Uint2)server_port;
+ nic->ticket = Nlm_htonl((Uint4)ticket);
+ break;
+ }
+
+ /* avoid the read-buffer overflow */
+#define SHIFT_SIZE (sizeof(buffer) / 2)
+ if (buf_read > SHIFT_SIZE + sizeof(X_TAG)) {
+ buf_read -= SHIFT_SIZE;
+ MemMove(buffer, buffer + SHIFT_SIZE, (size_t)(buf_read + 1));
+ }
+#undef SHIFT_SIZE
+ }} /* end-of-TRY */
+
+ SOCK_Close(nic->sock); /* dont need the dispatcher anymore... */
+ nic->sock = 0;
+
+ if ( !nic->server_host )
+ return FALSE; /* i.e. the reply is bad or missing */
+
+ {{ /* Connect to the "real" server and send back the ticket */
+ VERIFY( Uint4toInaddr(Nlm_htonl(nic->server_host),
+ buffer, sizeof(buffer)) );
+ if (SOCK_Create(buffer, nic->server_port, &nic->sock) != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, NIC_ERROR, 7,
+ "[WWW Special] Cannot connect to server \"%s\", port %u",
+ buffer, (unsigned int)nic->server_port);
+ return FALSE;
+ }
+
+ VERIFY( SOCK_SetTimeout(nic->sock, eSOCK_OnReadWrite, timeout, 0, 0)
+ == eSOCK_ESuccess );
+
+ if (SOCK_Write(nic->sock, (const void*)&nic->ticket, sizeof(nic->ticket),
+ 0) != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, NIC_ERROR, 8,
+ "[WWW Special] Cannot send the ticket back to server");
+ return FALSE;
+ }
+ }}
+
+ return TRUE;
+}
+
+
+/* Get and process reply from dispatcher(WWW Direct agent for stateless conn.)
+ */
+static Boolean s_ProcessReply_WWWDirect(NIC nic, Boolean debug_printout)
+{
+ /* (just skip all data up to the first '\0') */
+ for (;;) {
+ Char buffer[1024];
+ Uint4 n_read, i_null;
+ Uint4 n_total = 0;
+ ESOCK_ErrCode err_code;
+
+ err_code = SOCK_Peek(nic->sock, buffer, sizeof(buffer)-1, &n_read);
+ if (err_code != eSOCK_ESuccess) {
+ ErrPostEx(SEV_WARNING, NIC_ERROR, 6,
+ "[WWW Direct] Error in reading reply from the dispatcher"
+ " (%s)", SOCK_ErrCodeStr(err_code));
+ return FALSE;
+ }
+ buffer[n_read] = '\0';
+
+ if ( debug_printout ) {
+ fprintf(stderr,
+ "[WWW Direct Client, reply %lu:%lu]: \"%s\"",
+ (unsigned long)n_total, (unsigned long)(n_total + n_read),
+ buffer);
+ }
+ n_total += n_read;
+
+ if ( !n_read ) {
+ ASSERT( 0 );
+ return FALSE;
+ }
+
+ for (i_null = 0; buffer[i_null] && i_null < n_read; i_null++)
+ continue;
+
+ if (i_null == n_read)
+ i_null = n_read - 1;
+
+ if (s_NIC_SockSkip(nic->sock, i_null+1) != 0)
+ return FALSE;
+
+ if ( !buffer[i_null] )
+ break; /* success */
+ }
+
+ return TRUE;
+}
+
+
+
+/***********************************************************************
+ * EXTERNAL
+ ***********************************************************************/
+
+NLM_EXTERN NIC NIC_GetService
+(const Char *service_name,
+ const Char *disp_host,
+ Uint2 disp_port,
+ const Char *disp_path,
+ const STimeout *timeout,
+ ENIC_Agent client_agent,
+ const Char *client_host,
+ const ByteStore *service_query,
+ Uint4 flags)
+{
+ NIC nic = (NIC)MemNew(sizeof(Nlm_NICstruct));
+
+ /* use the default agent, if specified */
+ if (client_agent == eNIC_Default)
+ client_agent = ENIC_DEFAULT;
+
+ for (;;) {{ /* TRY to establish a connection */
+ /* connect to dispatcher(or server) */
+ if (SOCK_Create(disp_host, disp_port, &nic->sock) != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, NIC_ERROR, 1,
+ "[NIC_GetService] Cannot connect to host \"%s\", port %d;",
+ disp_host, (int)disp_port);
+ break;
+ }
+
+ /* retrieve the local host name */
+ if (client_host && *client_host) {
+ nic->client_host = StringSave(client_host);
+ } else {
+ Char buffer[64];
+ if ( !GetHostName(buffer, sizeof(buffer)) ) {
+ ErrPostEx(SEV_WARNING, NIC_ERROR, 3,
+ "[NIC_GetService] Cannot get the local host name");
+ buffer[0] = '\0';
+ }
+ nic->client_host = StringSave(buffer);
+ }
+
+ /* setup the connection i/o timeout(for the handshake stage only) */
+ if (SOCK_SetTimeout(nic->sock, eSOCK_OnReadWrite, timeout, 0, 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, NIC_ERROR, 2,
+ "[NIC_GetService] Cannot setup timeout for the connection"
+ " handshake with host \"%s\", port %d",
+ disp_host, (int)disp_port);
+ break;
+ }
+
+ /* send HTTP header, get reply from dispatcher and process it */
+ if (client_agent == eNIC_WWWClient) {
+ /* send HTTP header */
+ if ( !s_SendHeaderWWW(nic->sock, service_name, disp_path,
+ (flags & NIC_FIREWALL) ?
+ "NCBISpecialFWClient" : "NCBISpecialClient",
+ nic->client_host, 0) )
+ break;
+
+ /* process reply from the dispatcher */
+ if ( !s_ProcessReply_WWWClient
+ (nic, timeout,
+ (Boolean)(flags & NIC_DEBUG_PRINTOUT),
+ (Boolean)(flags & NIC_CERN_PROXY)) )
+ break;
+ } else { /* i.e. eNIC_WWWDirect */
+ /* send HTTP header(along with the bytestore content, if any) */
+ if ( !s_SendHeaderWWW(nic->sock, service_name, disp_path,
+ "NCBIDirectClient", nic->client_host,
+ (Uint4)BSLen((ByteStorePtr)service_query)) )
+ break;
+
+ if (service_query && !s_SendBS(nic->sock, service_query))
+ break;
+
+ /* process reply from the dispatcher */
+ if (!s_ProcessReply_WWWDirect
+ (nic, (Boolean)(flags & NIC_DEBUG_PRINTOUT)) )
+ break;
+ }
+
+ /* set back to infinite timeout for the regular connection i/o */
+ if (SOCK_SetTimeout(nic->sock, eSOCK_OnReadWrite, 0, 0, 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, NIC_ERROR, 9,
+ "[NIC_GetService] Cannot set an infinite timeout for the"
+ " regular client-server socket connection");
+ break;
+ }
+
+ /* for "eNIC_WWWClient", send the bytestore content(query) now */
+ if (client_agent == eNIC_WWWClient && service_query &&
+ !s_SendBS(nic->sock, service_query))
+ break;
+
+ /* success */
+ return nic;
+ }} /* end-of-TRY */
+
+ /* error */
+ ErrPostEx(SEV_ERROR, NIC_ERROR, 10,
+ "[NIC_GetService] Failed to establish connection to dispatcher "
+ " %s:%d/%s, for service\"%s\"",
+ disp_host, (int)disp_port, disp_path, service_name);
+ NIC_CloseService(nic);
+ return 0;
+}
+
+
+NLM_EXTERN SOCK NIC_GetSOCK(NIC nic)
+{
+ return nic->sock;
+}
+
+
+NLM_EXTERN Boolean NIC_CloseService(NIC nic)
+{
+ if (nic->sock && SOCK_Close(nic->sock) != eSOCK_ESuccess)
+ return FALSE;
+
+ MemFree(nic->client_host);
+ MemFree(nic);
+ return TRUE;
+}
+
+
+
+#ifdef TEST_MODULE__NCBICLI
+/***********************************************************************
+ * TEST
+ ***********************************************************************/
+
+#define TEST_ENGINE_HOST "www.ncbi.nlm.nih.gov"
+#define TEST_ENGINE_PORT 80
+#define TEST_ENGINE_URL "/Service/nph-dispd.cgi"
+
+#define ASS_RET(expr,retcode) \
+if ( !(expr) ) { ASSERT( 0 ); return retcode; } else {;}
+
+
+static Nlm_Int2 TEST__ncbicli_1(SOCK sock)
+{
+#ifdef __TODO
+ ESOCK_ErrCode err_code;
+ Char buf[1234];
+ Uint4 n_io = sizeof(buf);
+ Uint4 n_io_done;
+
+ err_code = SOCK_Write(sock, buf, n_io, &n_io_done);
+ ASS_RET((err_code == eSOCK_ESuccess), 11);
+
+ err_code = SOCK_Read(sock, buf, n_io, &n_io_done);
+ ASS_RET((err_code == eSOCK_ESuccess), 12);
+#endif /* __TODO */
+
+ return 0;
+}
+
+static Nlm_Int2 TEST__ncbicli(ENIC_Agent agent)
+{
+ static Char *service_name = "Entrez";
+ Char *service_query = service_name;
+
+ NIC nic;
+ SOCK sock;
+ STimeout timeout;
+ Int2 ret_code;
+ ByteStorePtr service_query_bsp;
+
+ timeout.sec = 10;
+ timeout.usec = 0;
+
+ service_query_bsp = BSNew(StrLen(service_query) + 1);
+ BSWrite(service_query_bsp, service_query, StrLen(service_query)+1);
+ nic = NIC_GetService(service_name,
+ TEST_ENGINE_HOST, TEST_ENGINE_PORT, TEST_ENGINE_URL,
+ &timeout, agent, 0, service_query_bsp,
+ NIC_DEBUG_PRINTOUT);
+ ASS_RET(nic, 1);
+ BSFree(service_query_bsp);
+
+ sock = NIC_GetSOCK(nic);
+ ASS_RET(sock, 2);
+
+ ret_code = TEST__ncbicli_1(sock);
+ ASS_RET((ret_code == 0), ret_code);
+
+ ASS_RET(NIC_CloseService(nic), 9);
+ return 0;
+}
+
+
+extern Nlm_Int2 Nlm_Main(void)
+{
+ Int2 status;
+
+#ifdef WIN16
+ {{ /* a kludge to make sure the "vibwndws.c"(MainProc) get linked */
+ extern void Nlm_Metronome(Nlm_VoidPtr actn); Nlm_Metronome(0);
+ }}
+#endif
+
+ Nlm_ErrSetOpts(ERR_TEE, ERR_LOG_ON);
+ ErrSetLogLevel(SEV_INFO);
+ ErrSetMessageLevel(SEV_INFO);
+ VERIFY( Nlm_ErrSetLog("ncbicli.log") );
+
+ Nlm_ErrPostEx(SEV_INFO, 2, 3, "NCBICLI test started...\n");
+
+ status = TEST__ncbicli(eNIC_WWWClient);
+ ASS_RET((status == 0), 1);
+
+ status = TEST__ncbicli(eNIC_WWWDirect);
+ ASS_RET((status == 0), 2);
+
+ status = TEST__ncbicli(eNIC_Default);
+ ASS_RET((status == 0), 3);
+
+ VERIFY( SOCK_Destroy() == eSOCK_ESuccess );
+
+ return status;
+}
+
+#endif /* TEST_MODULE__NCBICLI */
+
+/* EOF */
diff --git a/network/nsclilib/ncbicli.h b/network/nsclilib/ncbicli.h
new file mode 100644
index 00000000..56111b2a
--- /dev/null
+++ b/network/nsclilib/ncbicli.h
@@ -0,0 +1,138 @@
+#ifndef NCBICLI__H
+#define NCBICLI__H
+
+/* $RCSfile: ncbicli.h,v $ $Revision: 4.4 $ $Date: 1998/12/15 17:24:58 $
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* Author: Denis Vakatov
+*
+* File Description:
+* API to open(using HTTPD-based dispatcher) and handle socket-based
+* connection to an NCBI service
+*
+* --------------------------------------------------------------------------
+* $Log: ncbicli.h,v $
+* Revision 4.4 1998/12/15 17:24:58 vakatov
+* +NIC_CERN_PROXY flag(to indicate the use of CERN-like non-transparent proxy)
+*
+* Revision 4.3 1998/09/08 17:59:05 vakatov
+* Added WWW/Firewall network interface
+*
+* Revision 4.2 1998/04/02 20:21:10 vakatov
+* Added possibility to printout service reply headers
+*
+* Revision 4.1 1998/03/30 17:50:09 vakatov
+* Ingrafted to the main NCBI CVS tree
+*
+* ==========================================================================
+*/
+
+#include <ncbisock.h>
+
+#define NIC_ERROR 888
+
+#define NIC Nlm_NIC
+#define ENIC_Agent Nlm_ENIC_Agent
+#define NIC_GetService Nlm_NIC_GetService
+#define NIC_GetSOCK Nlm_NIC_GetSOCK
+#define NIC_CloseService Nlm_NIC_CloseService
+
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Nlm_NICtag; /* internal storage */
+typedef struct Nlm_NICtag *NIC; /* handle */
+
+
+/* Open read/write connection to the service specified by "service_name"
+ * using dispatcher located at URL "http://disp_host:disp_port/disp_path".
+ * If both "timeout_sec" and "timeout_usec" are equal to zero then wait
+ * ad infinitum; otherwise, fail if the specified timeout expires.
+ * Return handle to the opened connection; NULL on error.
+ */
+
+typedef enum {
+ eNIC_WWWClient = 0,
+ eNIC_WWWDirect,
+
+ eNIC_Default /* use default agent */
+} ENIC_Agent;
+
+/* the "flags" arg for NIC_GetService()
+ */
+/* printout reply from dispatcher */
+#define NIC_DEBUG_PRINTOUT 0x1
+/* use an NCBI firewall daemon to make a connection */
+#define NIC_FIREWALL 0x2
+/* non-transparent CERN-like proxy */
+#define NIC_CERN_PROXY 0x4
+
+
+NLM_EXTERN NIC NIC_GetService
+(const Nlm_Char *service_name,
+ const Nlm_Char *disp_host,
+ Nlm_Uint2 disp_port,
+ const Nlm_Char *disp_path,
+ const STimeout *timeout,
+ ENIC_Agent client_agent,
+ const Char *client_host,
+ const ByteStore *service_query,
+ Uint4 flags
+ );
+
+/* Get SOCK structure associated with the connection
+ */
+NLM_EXTERN SOCK NIC_GetSOCK
+(NIC nic
+ );
+
+/* Close the connection, destroy relevant internal data
+ */
+NLM_EXTERN Nlm_Boolean NIC_CloseService
+(NIC nic
+ );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif /* NCBI_CLI__H */
diff --git a/network/nsclilib/ncbinet.h b/network/nsclilib/ncbinet.h
new file mode 100644
index 00000000..6403b99c
--- /dev/null
+++ b/network/nsclilib/ncbinet.h
@@ -0,0 +1,188 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ncbinet.h
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.3 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* $Log: ncbinet.h,v $
+* Revision 6.3 1998/08/05 20:22:11 vakatov
+* [OS_UNIX] Dont declare "errno" as extern if it's #define'd(e.g. on
+* the MT platforms it can be #define'd to a function)
+*
+* Revision 6.2 1998/03/30 17:58:44 vakatov
+* Included <ni_lib_.h> (some function protos were moved to there)
+*
+* Revision 3.1 1998/03/17 20:39:52 vakatov
+* <save> [UNIX] +compiled OK with "ni_www_.[ch]" and "ni_lib_.[ch]" and
+* modified "ni_types.h" and "ncbinet.h"
+*
+* Revision 6.1 1997/11/18 21:14:12 epstein
+* special handling for Linux/Alpha
+*
+* Revision 5.2 1997/07/01 19:12:41 vakatov
+* [WIN32] DLL'd "netcli.lib"
+*
+* Revision 5.1 1996/10/02 18:18:42 epstein
+* add function NI_FqdnToIpaddr()
+*
+* Revision 4.1 1995/11/27 20:59:09 epstein
+* add client support for direct-connection services
+*
+* 01/21/94 Schuler Replaced
+*/
+
+#ifndef _NCBINET_
+#define _NCBINET_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ni_types.h" /* include <ncbi.h> */
+#include "ni_defin.h"
+#include "ni_error.h"
+#include "ni_encr.h"
+#include <ni_lib_.h>
+
+#ifdef NETP_INET_MACTCP
+#include "macsockd.h"
+#define __TYPES__ /* avoid Mac <Types.h> */
+#define __MEMORY__ /* avoid Mac <Memory.h> */
+#define ipBadLapErr /* avoid Mac <MacTCPCommonTypes.h> */
+#define APPL_SOCK_DEF
+#ifdef __NI_LIB__
+#define DONT_DEFINE_INET
+#else
+#define SOCK_DEFS_ONLY
+#endif
+
+#include "sock_ext.h"
+extern void bzero PROTO((CharPtr target, long numbytes));
+
+#endif /* NETP_INET_MACTCP */
+
+
+/* GLOBAL VARIABLES */
+
+#if defined(OS_UNIX) || defined(NETP_INET_MACTCP)
+#if !defined (OS_UNIX_LINUX) || !defined(PROC_ALPHA)
+extern CharPtr sys_errlist[];
+#endif
+#ifndef errno
+extern int errno;
+#endif
+#endif
+
+#ifdef NETP_INET_MACTCP
+extern long errno_long;
+#endif
+
+
+/* CLIENT FUNCTIONS */
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+NLM_EXTERN Boolean NI_FqdnToIpaddr PROTO((CharPtr fqdn, CharPtr ipbuf, Int2 ipbuflen));
+
+NLM_EXTERN Int2 NI_InitServices PROTO((NI_DispatcherPtr disp, CharPtr user, CharPtr group, CharPtr password, NI_DispInfoPtr PNTR dip));
+
+NLM_EXTERN Int4 NI_SetDispConfig PROTO((NI_DispInfoPtr PNTR dip, CharPtr dispatcher, Int2 dispLen));
+
+NLM_EXTERN NICatalogPtr NI_GetCatalog PROTO((NI_DispatcherPtr disp));
+
+NLM_EXTERN ReqPtr NI_SVCRequestBuild PROTO((NI_DispatcherPtr disp));
+
+NLM_EXTERN void NI_SVCRequestDestroy PROTO((ReqPtr reqp));
+
+NLM_EXTERN NI_HandPtr NI_ServiceGet PROTO((NI_DispatcherPtr disp, CharPtr svc, Uint2 svcvermin, Uint2 svcvermax, CharPtr res, CharPtr restype, Uint2 resvermin, Uint2 resvermax));
+
+NLM_EXTERN NI_HandPtr NI_ServiceRequest PROTO((ReqPtr req));
+
+NLM_EXTERN int NI_ServiceGetReadFd PROTO((NI_HandPtr mhp));
+
+NLM_EXTERN int NI_ServiceGetWriteFd PROTO((NI_HandPtr mhp));
+
+NLM_EXTERN Int2 NI_RequestSetService PROTO((ReqPtr req, CharPtr name, Uint2 vermin, Uint2 vermax));
+
+NLM_EXTERN Int2 NI_RequestAddResource PROTO((ReqPtr req, CharPtr name, CharPtr type, Uint2 vermin, Uint2 vermax));
+
+NLM_EXTERN Int2 NI_GetPlatform PROTO((void));
+
+
+/* SERVER FUNCTIONS */
+
+NLM_EXTERN int NI_ServerACK PROTO((void));
+
+NLM_EXTERN int NI_ServerNACK PROTO((CharPtr err_text));
+
+NLM_EXTERN NI_HandPtr NI_OpenASNIO PROTO((void));
+
+NLM_EXTERN Int2 NI_CloseASNIO PROTO((NI_HandPtr hp));
+
+/* TIMER MANAGEMENT */
+
+NLM_EXTERN void NI_ProcessTimers PROTO((void));
+NLM_EXTERN time_t NI_GetNextWakeup PROTO((void));
+NLM_EXTERN NodePtr NI_SetTimer PROTO((time_t timeout, NI_TimeoutHook hook, Pointer hookParam));
+NLM_EXTERN void NI_CancelTimer PROTO((NodePtr timerId));
+
+/* MISC. FUNCTIONS */
+
+NLM_EXTERN void NI_SetActivityHook PROTO((NI_NetServHook hook));
+
+/* for internal network services use only */
+NLM_EXTERN NI_NetServHook NI_ActivityHook PROTO((void));
+NLM_EXTERN void WriteConFile PROTO((Uint4 conid));
+
+NLM_EXTERN void NI_LogSocket PROTO((int sok, Boolean opening, CharPtr filename, int lineno));
+NLM_EXTERN Int2 NI_SocketsOpen PROTO((void));
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/network/nsclilib/ncbisock.c b/network/nsclilib/ncbisock.c
new file mode 100644
index 00000000..ec48cb57
--- /dev/null
+++ b/network/nsclilib/ncbisock.c
@@ -0,0 +1,1491 @@
+/* $RCSfile: ncbisock.c,v $ $Revision: 4.12 $ $Date: 1999/01/22 22:04:59 $
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* Author: Denis Vakatov
+*
+* File Description:
+* Plain portable socket API
+*
+* --------------------------------------------------------------------------
+* $Log: ncbisock.c,v $
+* Revision 4.12 1999/01/22 22:04:59 vakatov
+* Uint4toInaddr() to take address in the network byte order
+*
+* Revision 4.11 1998/12/15 17:22:22 vakatov
+* + SOCK_Address() -- to get the socket peer's host and port
+*
+* Revision 4.10 1998/08/12 13:12:42 kans
+* moved high level query functions to ncbiurl.[ch]
+*
+* Revision 4.9 1998/08/10 23:24:24 kans
+* added SOCK_SendURLQuery and SOCK_CheckURLQuery from Sequin
+*
+* Revision 4.8 1998/05/01 19:13:55 vakatov
+* [OS_UNIX] Ignore SIGPIPE signal
+*
+* Revision 4.7 1998/04/14 20:04:25 vakatov
+* Added a "hand-made" data buffering on the socket read(#SOCK_NCBI_PEEK)
+* in order to implement MSG_PEEK functionality
+* [OS_MAC] #define SOCK_NCBI_PEEK as MSG_PEEK was not implemented on Mac
+* [OS_UNIX] LSOCK_Create(): use SO_REUSEADDR(see the comments)
+*
+* Revision 4.6 1998/04/07 17:39:13 kans
+* comment out mac definition of TEST_MODULE__NCBISOCK and DO_CLIENT
+*
+* Revision 4.5 1998/03/30 17:50:11 vakatov
+* Ingrafted to the main NCBI CVS tree
+*
+* ==========================================================================
+*/
+
+#include <ncbi.h>
+#include <ncbithr.h>
+
+#if defined(OS_UNIX)
+#include <ncbiwin.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <signal.h>
+
+#elif defined(OS_MSWIN)
+#include <ncbiwin.h>
+#include <winsock.h>
+
+#elif defined(OS_MAC)
+#include "ncbinet.h"
+#include "ni_net.h"
+#include <ncbiwin.h>
+/* cannot write more than SLICE_SIZE at once on Mac, and we have to split
+ * big output buffers into smaller(<SLICE_SIZE) slices before writing it to
+ * socket */
+#define SOCK_WRITE_SLICED
+#define SLICE_SIZE 2048
+/* MSG_PEEK is not implemented(ignored) on Mac, and we have to implement
+ * this feature ourselves */
+#define SOCK_NCBI_PEEK
+
+#endif /* platform-specific #include's (UNIX, MSWIN, MAC) */
+
+
+#include <ncbisock.h>
+
+#ifdef SOCK_NCBI_PEEK
+#include <ncbibuf.h>
+#endif
+
+
+/* patch to old SunOS/Solaris proto(cut&paste from Solaris 2.6 "unistd.h") */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(OS_UNIX_SOL) || defined(OS_UNIX_SUN)
+#if defined(_XPG4_2)
+extern int gethostname(char *, size_t);
+#elif defined(__EXTENSIONS__) || \
+ (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE))
+extern int gethostname(char *, int);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/***********************************************************************
+ * INTERNAL
+ ***********************************************************************/
+
+#define SOCK_MAX_TIMEOUT 99999999
+
+#ifdef SOCK_NCBI_PEEK
+#define SOCK_RECV(s,b,l,f) s_NCBI_Recv(s, (char *)b, l, f)
+#else
+#define SOCK_RECV(s,b,l,f) recv(s->sock, (char *)b, l, f)
+#endif /* SOCK_NCBI_PEEK */
+
+#define SOCK_WRITE(s,b,l) send(s, (char *)b, l, 0)
+
+
+#if defined(OS_MSWIN)
+
+typedef SOCKET Nlm_Socket;
+#define SOCK_INVALID INVALID_SOCKET
+#define SOCK_ERRNO WSAGetLastError()
+#define SOCK_EINTR WSAEINTR
+#define SOCK_EWOULDBLOCK WSAEWOULDBLOCK
+#define SOCK_ECONNRESET WSAECONNRESET
+#define SOCK_EPIPE WSAESHUTDOWN
+#define SOCK_EAGAIN WSAEINPROGRESS
+#define SOCK_NFDS(s) 0
+#define SOCK_CLOSE(s) closesocket(s)
+
+#ifdef WIN16
+#ifndef MAKEWORD
+#define MAKEWORD(a,b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) <<8))
+#endif
+#endif
+/* OS_MSWIN */
+
+#elif defined(OS_UNIX)
+
+typedef int Nlm_Socket;
+#define SOCK_INVALID (-1)
+#define SOCK_ERRNO errno
+#define SOCK_EINTR EINTR
+#define SOCK_EWOULDBLOCK EWOULDBLOCK
+#define SOCK_ECONNRESET ECONNRESET
+#define SOCK_EPIPE EPIPE
+#define SOCK_EAGAIN EAGAIN
+#define SOCK_NFDS(s) (s + 1)
+#define SOCK_CLOSE(s) close(s)
+
+#ifndef INADDR_NONE
+#define INADDR_NONE (Nlm_Uint4)(-1)
+#endif
+/* OS_UNIX */
+
+#elif defined(OS_MAC)
+
+typedef int Nlm_Socket;
+#define SOCK_INVALID (-1)
+#ifndef SOCK_ERRNO
+#define SOCK_ERRNO errno
+#endif
+#define SOCK_EINTR EINTR
+#define SOCK_EWOULDBLOCK EWOULDBLOCK
+#define SOCK_ECONNRESET ECONNRESET
+#define SOCK_EPIPE EPIPE
+#define SOCK_EAGAIN EAGAIN
+#define SOCK_NFDS(s) (s + 1)
+#define SOCK_CLOSE(s) close(s)
+
+extern int gethostname(char *machname, long buflen);
+/* but see ni_lib.c line 2508 for gethostname substitute for Mac */
+
+#endif /* !OS_MSWIN!OS_UNIX!OS_MAC */
+
+
+/* Listening socket */
+typedef struct Nlm_LSOCKtag
+{
+ Nlm_Socket sock;
+} Nlm_LSOCKstruct;
+
+/* Socket */
+typedef struct Nlm_SOCKtag
+{
+ Nlm_Socket sock;
+ struct timeval *r_timeout;
+ struct timeval *w_timeout;
+ struct timeval rr_timeout;
+ struct timeval ww_timeout;
+ Nlm_Uint4 host; /* peer host (in the network byte order) */
+ Nlm_Uint2 port; /* peer port (in the network byte order) */
+#ifdef SOCK_NCBI_PEEK
+ BUF buf;
+#endif
+} Nlm_SOCKstruct;
+
+
+/* STimeout <--> struct timeval conversions
+ */
+static void s_tv2to(const struct timeval *tv, STimeout *to) {
+ if ( tv ) {
+ to->sec = tv->tv_sec;
+ to->usec = tv->tv_usec;
+ }
+ else {
+ to->sec = SOCK_MAX_TIMEOUT;
+ to->usec = 999999;
+ }
+}
+
+static void s_to2tv(const STimeout *to, struct timeval *tv) {
+ if ( to ) {
+ tv->tv_sec = (to->sec < SOCK_MAX_TIMEOUT) ? to->sec : SOCK_MAX_TIMEOUT;
+ tv->tv_usec = to->usec % 1000000;
+ } else {
+ tv->tv_sec = SOCK_MAX_TIMEOUT;
+ tv->tv_usec = 999999;
+ }
+}
+
+
+/* Initialize the API internal data and/or underlying network code
+ */
+#if defined(OS_MSWIN)
+static TNlmMutex s_InitMutex;
+static Nlm_Boolean s_Initialized = FALSE;
+#endif
+
+static ESOCK_ErrCode s_Initialize(void)
+{
+ ESOCK_ErrCode err_code = eSOCK_ESuccess;
+
+#if defined(OS_MSWIN)
+ if ( s_Initialized )
+ return eSOCK_ESuccess;
+
+ NlmMutexLockEx(&s_InitMutex);
+ if ( !s_Initialized ) {
+ WSADATA wsadata;
+ int x_errno = WSAStartup(MAKEWORD(1,1), &wsadata);
+ if (x_errno != 0) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 0,
+ "[s_Initialize] WSAStartup() failed, errno = %d",(int)x_errno);
+ err_code = eSOCK_EUnknown;
+ }
+ s_Initialized = TRUE;
+ }
+ NlmMutexUnlock(s_InitMutex);
+
+#elif defined(OS_UNIX)
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
+ return err_code;
+}
+
+
+/* Switch the specified socket i/o between blocking and non-blocking mode
+ */
+static Nlm_Boolean s_SetNonblock(Nlm_Socket sock, Nlm_Boolean nonblock)
+{
+#if defined(OS_MSWIN)
+ unsigned long argp = nonblock ? 1 : 0;
+ return (Nlm_Boolean)(ioctlsocket(sock, FIONBIO, &argp) == 0);
+#elif defined(OS_UNIX)
+ return (Nlm_Boolean)(fcntl(sock, F_SETFL,
+ nonblock ?
+ fcntl(sock, F_GETFL, 0) | O_NONBLOCK :
+ fcntl(sock, F_GETFL, 0) & (int)~O_NONBLOCK)
+ != -1);
+#elif defined(OS_MAC)
+ return (Nlm_Boolean)(fcntl(sock, F_SETFL,
+ nonblock ?
+ fcntl(sock, F_GETFL, 0) | O_NDELAY :
+ fcntl(sock, F_GETFL, 0) & (int)~O_NDELAY)
+ != -1);
+#else
+ return FALSE;
+#endif /* else!OS_MSWIN!OS_UNIX */
+}
+
+
+/* Select on the socket i/o
+ */
+static ESOCK_ErrCode s_Select(Nlm_Socket sock,
+ ESOCK_Mode mode,
+ const struct timeval *timeout)
+{
+ int n_dfs;
+ fd_set fds, *r_fds, *w_fds;
+
+ /* setup i/o descriptor to select */
+ r_fds = (mode == eSOCK_OnRead || mode == eSOCK_OnReadWrite) ? &fds : 0;
+ w_fds = (mode == eSOCK_OnWrite || mode == eSOCK_OnReadWrite) ? &fds : 0;
+
+ do { /* auto-resume if interrupted by a signal */
+ fd_set e_fds;
+ struct timeval tmout;
+ if ( timeout )
+ tmout = *timeout;
+ FD_ZERO(&fds); FD_ZERO(&e_fds);
+ FD_SET(sock, &fds); FD_SET(sock, &e_fds);
+ n_dfs = select(SOCK_NFDS(sock), r_fds, w_fds, &e_fds,
+ timeout ? &tmout : 0);
+ ASSERT ( -1 <= n_dfs && n_dfs <= 2 );
+ if ((n_dfs < 0 && SOCK_ERRNO != SOCK_EINTR) || FD_ISSET(sock, &e_fds))
+ return eSOCK_EUnknown;
+ } while (n_dfs < 0);
+
+ /* timeout has expired */
+ if (n_dfs == 0)
+ return eSOCK_ETimeout;
+
+ /* success; can i/o now */
+ ASSERT ( FD_ISSET(sock, &fds) );
+ return eSOCK_ESuccess;
+}
+
+
+#ifdef SOCK_NCBI_PEEK
+/* Emulate "peek" using the NCBI data buffering
+ */
+static int s_NCBI_Recv(SOCK sock,
+ Nlm_CharPtr buffer,
+ Nlm_Uint4 size,
+ int flags)
+{
+ Nlm_Uint4 n_readbuf;
+ int n_readsock;
+
+ /* read(or peek)from the internal buffer */
+ n_readbuf = (flags & MSG_PEEK) ?
+ BUF_Peek(sock->buf, buffer, size) : BUF_Read(sock->buf, buffer, size);
+ if (n_readbuf == size)
+ return (int)n_readbuf;
+ buffer += n_readbuf;
+ size -= n_readbuf;
+
+ /* read(dont peek) from the socket */
+ n_readsock = recv(sock->sock, buffer, size, 0);
+ if (n_readsock <= 0)
+ return (int)(n_readbuf ? n_readbuf : n_readsock);
+
+ /* if "peek" -- store the new read data in the internal buffer */
+ if (flags & MSG_PEEK)
+ VERIFY ( BUF_Write(&sock->buf, buffer, n_readsock) );
+
+ return (int)(n_readbuf + n_readsock);
+}
+#endif /* SOCK_NCBI_PEEK */
+
+
+/* Read/Peek data from the socket
+ */
+static ESOCK_ErrCode s_Recv(SOCK sock,
+ Nlm_VoidPtr buf,
+ Nlm_Uint4 size,
+ Nlm_Uint4 *n_read,
+ Nlm_Boolean peek)
+{
+ int x_errno;
+
+ if ( n_read )
+ *n_read = 0;
+
+ for (;;) {
+ /* try to read */
+ int buf_read = SOCK_RECV(sock, buf, (int)size, peek ? MSG_PEEK : 0);
+ if (buf_read > 0) {
+ if ( n_read )
+ *n_read = buf_read;
+ return eSOCK_ESuccess; /* success */
+ }
+
+ x_errno = SOCK_ERRNO;
+
+ if (buf_read == 0) {
+ /* NOTE: empty message may cause the same effect, and it does */
+ /* not (!) get discarded from the input queue; therefore, the */
+ /* subsequent attemts to read will cause just the same effect) */
+ return eSOCK_EClosed; /* the connection must have been closed by peer */
+ }
+
+ /* wait for a data to come(or exit on timeout/error) */
+ if (x_errno == SOCK_EWOULDBLOCK || x_errno == SOCK_EAGAIN) {
+ ESOCK_ErrCode err_code = s_Select(sock->sock,
+ eSOCK_OnRead, sock->r_timeout);
+ if (err_code != eSOCK_ESuccess)
+ return err_code;
+ continue;
+ }
+
+ /* retry if interrupted by a signal */
+ if (x_errno == SOCK_EINTR)
+ continue;
+
+ /* forcibly closed by peer, or shut down */
+ if (x_errno == SOCK_ECONNRESET || x_errno == SOCK_EPIPE)
+ return eSOCK_EClosed;
+
+ /* dont want to handle all possible errors... let it be "unknown" */
+ break;
+ }
+ return eSOCK_EUnknown;
+}
+
+
+/* Write data to the socket "as is"(the whole buffer at once)
+ */
+static ESOCK_ErrCode s_WriteWhole(SOCK sock,
+ const void *buf,
+ Nlm_Uint4 size,
+ Nlm_Uint4 *n_written)
+{
+ const Nlm_Char *x_buf = (const Nlm_Char *)buf;
+ int x_size = (int)size;
+ int x_errno;
+
+ if ( n_written )
+ *n_written = 0;
+ if ( !size )
+ return eSOCK_ESuccess;
+
+ for (;;) {
+ /* try to write */
+ int buf_written = SOCK_WRITE(sock->sock, x_buf, x_size);
+ if (buf_written >= 0) {
+ if ( n_written )
+ *n_written += buf_written;
+ if (buf_written == x_size)
+ return eSOCK_ESuccess; /* all data has been successfully sent */
+ x_buf += buf_written;
+ x_size -= buf_written;
+ ASSERT ( x_size > 0 );
+ continue; /* there is unsent data */
+ }
+ x_errno = SOCK_ERRNO;
+
+ /* blocked; retry if unblocked before the timeout is expired */
+ if (x_errno == SOCK_EWOULDBLOCK || x_errno == SOCK_EAGAIN) {
+ ESOCK_ErrCode err_code = s_Select(sock->sock,
+ eSOCK_OnWrite, sock->w_timeout);
+ if (err_code != eSOCK_ESuccess)
+ return err_code;
+ continue;
+ }
+
+ /* retry if interrupted by a signal */
+ if (x_errno == SOCK_EINTR)
+ continue;
+
+ /* forcibly closed by peer, or shut down */
+ if (x_errno == SOCK_ECONNRESET || x_errno == SOCK_EPIPE)
+ return eSOCK_EClosed;
+
+ /* dont want to handle all possible errors... let it be "unknown" */
+ break;
+ }
+ return eSOCK_EUnknown;
+}
+
+
+#ifdef SOCK_WRITE_SLICED
+/* Split output buffer by slices(of size <= SLICE_SIZE) before writing
+ * to the socket
+ */
+static ESOCK_ErrCode s_WriteSliced(SOCK sock,
+ const void *buf,
+ Nlm_Uint4 size,
+ Nlm_Uint4 *n_written)
+{
+ ESOCK_ErrCode err_code = eSOCK_ESuccess;
+ Nlm_Uint4 x_written = 0;
+
+ while (size && err_code == eSOCK_ESuccess) {
+ Nlm_Uint4 n_io = (size > SLICE_SIZE) ? SLICE_SIZE : size;
+ Nlm_Uint4 n_io_done;
+ err_code = s_WriteWhole(sock, (char*)buf + x_written, n_io, &n_io_done);
+ if ( n_io_done ) {
+ x_written += n_io_done;
+ size -= n_io_done;
+ }
+ }
+
+ if ( n_written )
+ *n_written = x_written;
+ return err_code;
+}
+#endif
+
+
+/***********************************************************************
+ * EXTERNAL
+ ***********************************************************************/
+
+NLM_EXTERN const Nlm_Char *SOCK_ErrCodeStr(ESOCK_ErrCode err_code)
+{
+ static const Nlm_Char *s_ErrCodeStr[eSOCK_EUnknown+1] = {
+ "Success",
+ "Timeout",
+ "Closed",
+ "Unknown"
+ };
+
+ return s_ErrCodeStr[err_code];
+}
+
+
+NLM_EXTERN ESOCK_ErrCode SOCK_Destroy(void)
+{
+#if defined(OS_MSWIN)
+ if ( s_Initialized ) {
+ if (WSACleanup() != 0) {
+ ErrPostEx(SEV_WARNING, SOCK_ERRCODE, 0,
+ "[SOCK_Destroy] WSACleanup() failed, errno = %d",
+ (int)SOCK_ERRNO);
+ return eSOCK_EUnknown;
+ }
+
+ NlmMutexDestroy(s_InitMutex);
+ s_InitMutex = 0;
+ s_Initialized = FALSE;
+ }
+#endif
+
+ return eSOCK_ESuccess;
+}
+
+
+NLM_EXTERN ESOCK_ErrCode LSOCK_Create(Nlm_Uint2 port,
+ Nlm_Uint2 n_listen,
+ LSOCK *lsock)
+{
+ Nlm_Socket sock;
+ struct sockaddr_in addr;
+
+ /* Initialize internals */
+ VERIFY ( s_Initialize() == eSOCK_ESuccess );
+
+ /* Create new(listening) socket */
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == SOCK_INVALID) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 1,
+ "[LSOCK_Create] Cannot create listening socket, errno = %d",
+ (int)SOCK_ERRNO);
+ return eSOCK_EUnknown;
+ }
+
+#ifdef OS_UNIX
+ {{
+ /* Let more than one "bind()" to use the same address.
+ * It was affirmed(?) that under Solaris 2.5 this precaution:
+ * 1) makes the address to be released immediately after the process
+ * termination
+ * 2) still issue EADDINUSE error on the attempt to bind() to the
+ * same address being in-use by a living process(if SOCK_STREAM)
+ */
+ int reuse_addr = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (const char *)&reuse_addr, sizeof(reuse_addr)) != 0) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 2,
+ "[LSOCK_Create] setsockopt(): errno = %d", (int)SOCK_ERRNO);
+ SOCK_CLOSE(sock);
+ return eSOCK_EUnknown;
+ }
+ }}
+#endif
+
+ /* Bind */
+ Nlm_MemSet(&addr, '\0', sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(port);
+ if (bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr)) != 0) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 3,
+ "[LSOCK_Create] bind(): errno = %d", (int)SOCK_ERRNO);
+ SOCK_CLOSE(sock);
+ return eSOCK_EUnknown;
+ }
+
+ /* Listen */
+ if (listen(sock, n_listen) != 0) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 4,
+ "[LSOCK_Create] listen(): errno = %d", (int)SOCK_ERRNO);
+ SOCK_CLOSE(sock);
+ return eSOCK_EUnknown;
+ }
+
+ /* Set to non-blocking mode */
+ if ( !s_SetNonblock(sock, TRUE) ) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 4,
+ "[LSOCK_Create] Cannot set to non-blocking mode");
+ SOCK_CLOSE(sock);
+ return eSOCK_EUnknown;
+ }
+
+ /* Success... */
+ *lsock = (LSOCK)Nlm_MemGet(sizeof(Nlm_LSOCKstruct), 0);
+ (*lsock)->sock = sock;
+ return eSOCK_ESuccess;
+}
+
+
+NLM_EXTERN ESOCK_ErrCode LSOCK_Accept(LSOCK lsock,
+ const STimeout *timeout,
+ SOCK *sock)
+{
+ Nlm_Socket x_sock;
+ Nlm_Uint4 x_host;
+ Nlm_Uint2 x_port;
+
+ {{ /* wait for the connection(up to timeout) */
+ ESOCK_ErrCode code;
+ struct timeval tv;
+ if ( timeout )
+ s_to2tv(timeout, &tv);
+
+ code = s_Select(lsock->sock, eSOCK_OnRead, timeout ? &tv : 0);
+ if (code != eSOCK_ESuccess)
+ return code;
+ }}
+
+ {{ /* accept next connection */
+ struct sockaddr addr;
+ struct sockaddr_in *x_addr = (struct sockaddr_in *)&addr;
+#ifdef OS_MAC
+ long addrlen = sizeof(addr);
+#else
+ int addrlen = sizeof(addr);
+#endif
+ if ((x_sock = accept(lsock->sock, &addr, &addrlen))== SOCK_INVALID) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 1,
+ "[LSOCK_Accept] accept(): errno = %d", (int)SOCK_ERRNO);
+ return eSOCK_EUnknown;
+ }
+ x_host = x_addr->sin_addr.s_addr;
+ x_port = x_addr->sin_port;
+ }}
+
+ /* success: create new SOCK structure */
+ *sock = (SOCK)Nlm_MemNew(sizeof(Nlm_SOCKstruct));
+ (*sock)->sock = x_sock;
+ VERIFY ( SOCK_SetTimeout(*sock, eSOCK_OnReadWrite, 0, 0, 0)
+ == eSOCK_ESuccess );
+ (*sock)->host = x_host;
+ (*sock)->port = x_port;
+ return eSOCK_ESuccess;
+}
+
+
+NLM_EXTERN ESOCK_ErrCode LSOCK_Close(LSOCK lsock)
+{
+ int code;
+
+ /* Set the socket back to blocking mode */
+ if ( !s_SetNonblock(lsock->sock, FALSE) ) {
+ ErrPostEx(SEV_WARNING, SOCK_ERRCODE, 1,
+ "[LSOCK_Close] Cannot set socket back to blocking mode");
+ }
+
+ do { /* auto-resume if interrupted by a signal */
+ code = SOCK_CLOSE(lsock->sock);
+ if (code != 0 && SOCK_ERRNO != SOCK_EINTR) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 2,
+ "[LSOCK_Close] close(): errno = %d", (int)SOCK_ERRNO);
+ return eSOCK_EUnknown;
+ }
+ } while (code != 0);
+
+ Nlm_MemFree(lsock);
+ return eSOCK_ESuccess;
+}
+
+
+NLM_EXTERN ESOCK_ErrCode SOCK_Create(const Nlm_Char *host,
+ Nlm_Uint2 port,
+ SOCK *sock)
+{
+ Nlm_Socket x_sock;
+ Nlm_Uint4 x_host;
+ Nlm_Uint2 x_port;
+
+ struct sockaddr_in server;
+ Nlm_MemSet(&server, '\0', sizeof(server));
+
+ /* Initialize internals */
+ VERIFY ( s_Initialize() == eSOCK_ESuccess );
+
+ /* Get address of the remote host */
+ x_host = inet_addr(host);
+ if (x_host == INADDR_NONE) {
+ struct hostent *hp;
+#ifdef OS_UNIX_SOL
+ struct hostent x_hp;
+ char x_buf[1024];
+ int x_err;
+ hp = gethostbyname_r(host, &x_hp, x_buf, sizeof(x_buf), &x_err);
+#else
+ hp = gethostbyname(host);
+#endif
+ if ( !hp ) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 1,
+ "[SOCK_Create] Cannot resolve network address(\"%s\")",
+ host);
+ return eSOCK_EUnknown;
+ }
+ Nlm_MemCpy((void *)&x_host, (void *)hp->h_addr, sizeof(x_host));
+ }
+ x_port = htons(port);
+
+ /* Fill out the "server" struct */
+ Nlm_MemCpy((void *)&server.sin_addr, (void *)&x_host, sizeof(x_host));
+ server.sin_family = AF_INET;
+ server.sin_port = x_port;
+
+ /* Create new socket */
+ if ((x_sock = socket(AF_INET, SOCK_STREAM, 0)) == SOCK_INVALID) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 2,
+ "[SOCK_Create] Cannot create socket, errno = %d",
+ (int)SOCK_ERRNO);
+ return eSOCK_EUnknown;
+ }
+
+ /* Establish connection to the server */
+ if (connect(x_sock, (struct sockaddr *)&server, sizeof(server)) != 0) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 3,
+ "[SOCK_Create] Cannot connect to host \"%s\", port %d",
+ host, (int)port);
+ SOCK_CLOSE(x_sock);
+ return eSOCK_EUnknown;
+ }
+
+ /* Set the socket i/o to non-blocking mode */
+ if ( !s_SetNonblock(x_sock, TRUE) ) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 4,
+ "[SOCK_Create] Cannot set socket i/o to non-blocking mode");
+ SOCK_CLOSE(x_sock);
+ return eSOCK_EUnknown;
+ }
+
+ /* Success */
+ *sock = (SOCK)Nlm_MemNew(sizeof(Nlm_SOCKstruct));
+ (*sock)->sock = x_sock;
+ VERIFY ( SOCK_SetTimeout(*sock, eSOCK_OnReadWrite, 0, 0, 0)
+ == eSOCK_ESuccess );
+ (*sock)->host = x_host;
+ (*sock)->port = x_port;
+
+ return eSOCK_ESuccess;
+}
+
+
+NLM_EXTERN ESOCK_ErrCode SOCK_Close(SOCK sock)
+{
+ int code;
+
+ /* Set the socket back to blocking mode */
+ if ( !s_SetNonblock(sock->sock, FALSE) ) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 1,
+ "[SOCK_Close] Cannot set socket back to blocking mode");
+ }
+
+ /* Set the linger period according to the write timeout */
+ if ( sock->w_timeout ) {
+ struct linger lgr;
+ lgr.l_onoff = 1;
+ lgr.l_linger = sock->w_timeout->tv_sec ? sock->w_timeout->tv_sec : 1;
+ if (setsockopt(sock->sock, SOL_SOCKET, SO_LINGER,
+ (char *)&lgr, sizeof(lgr)) != 0) {
+ ErrPostEx(SEV_WARNING, SOCK_ERRCODE, 1,
+ "[SOCK_Close] setsockopt(): errno = %d", (int)SOCK_ERRNO);
+ }
+ }
+
+ do {
+ code = SOCK_CLOSE(sock->sock);
+ if (code != 0 && SOCK_ERRNO != SOCK_EINTR) {
+ ErrPostEx(SEV_WARNING, SOCK_ERRCODE, 2,
+ "[SOCK_Close] close(): errno = %d", (int)SOCK_ERRNO);
+ return (SOCK_ERRNO == SOCK_ECONNRESET || SOCK_ERRNO == SOCK_EPIPE) ?
+ eSOCK_EClosed : eSOCK_EUnknown;
+ }
+ /* auto-resume if interrupted by a signal */
+ } while (code != 0);
+
+#ifdef SOCK_NCBI_PEEK
+ BUF_Destroy(sock->buf);
+#endif
+ Nlm_MemFree(sock);
+ return eSOCK_ESuccess;
+}
+
+
+NLM_EXTERN ESOCK_ErrCode SOCK_Select(SOCK sock,
+ ESOCK_Mode mode,
+ const STimeout *timeout)
+{
+ struct timeval tv;
+ if ( timeout )
+ s_to2tv(timeout, &tv);
+
+ return s_Select(sock->sock, mode, timeout ? &tv : 0);
+}
+
+
+NLM_EXTERN ESOCK_ErrCode SOCK_SetTimeout(SOCK sock,
+ ESOCK_Mode mode,
+ const STimeout *new_timeout,
+ STimeout *r_timeout,
+ STimeout *w_timeout)
+{
+ if ( r_timeout )
+ s_tv2to(sock->r_timeout, r_timeout);
+ if ( w_timeout )
+ s_tv2to(sock->w_timeout, w_timeout);
+
+ if (new_timeout == SOCK_GET_TIMEOUT)
+ return eSOCK_ESuccess;
+
+ switch ( mode )
+ {
+ case eSOCK_OnRead:
+ if ( new_timeout ) {
+ sock->r_timeout = &sock->rr_timeout;
+ s_to2tv(new_timeout, sock->r_timeout);
+ } else {
+ sock->r_timeout = 0;
+ }
+ break;
+
+ case eSOCK_OnWrite:
+ if ( new_timeout ) {
+ sock->w_timeout = &sock->ww_timeout;
+ s_to2tv(new_timeout, sock->w_timeout);
+ } else {
+ sock->w_timeout = 0;
+ }
+ break;
+
+ case eSOCK_OnReadWrite:
+ if ( new_timeout ) {
+ sock->r_timeout = &sock->rr_timeout;
+ s_to2tv(new_timeout, sock->r_timeout);
+ sock->w_timeout = &sock->ww_timeout;
+ s_to2tv(new_timeout, sock->w_timeout);
+ } else {
+ sock->r_timeout = 0;
+ sock->w_timeout = 0;
+ }
+ break;
+
+ default:
+ ASSERT ( 0 ); return eSOCK_EUnknown;
+ }
+
+ return eSOCK_ESuccess;
+}
+
+
+NLM_EXTERN ESOCK_ErrCode SOCK_Read(SOCK sock,
+ Nlm_VoidPtr buf,
+ Nlm_Uint4 size,
+ Nlm_Uint4 *n_read)
+{
+ return s_Recv(sock, buf, size, n_read, FALSE);
+}
+
+
+NLM_EXTERN ESOCK_ErrCode SOCK_Peek(SOCK sock,
+ Nlm_VoidPtr buf,
+ Nlm_Uint4 size,
+ Nlm_Uint4 *n_read)
+{
+ return s_Recv(sock, buf, size, n_read, TRUE);
+}
+
+
+NLM_EXTERN ESOCK_ErrCode SOCK_Write(SOCK sock,
+ const void *buf,
+ Nlm_Uint4 size,
+ Nlm_Uint4 *n_written)
+{
+#ifdef SOCK_WRITE_SLICED
+ return s_WriteSliced(sock, buf, size, n_written);
+#else
+ return s_WriteWhole (sock, buf, size, n_written);
+#endif
+}
+
+
+NLM_EXTERN void SOCK_Address(SOCK sock,
+ Nlm_Uint4 *host,
+ Nlm_Uint2 *port,
+ Nlm_Boolean network_byte_order) {
+ if ( host )
+ *host = network_byte_order ? sock->host : (Nlm_Uint4)ntohl(sock->host);
+ if ( port )
+ *port = network_byte_order ? sock->port : (Nlm_Uint2)ntohs(sock->port);
+}
+
+
+NLM_EXTERN Nlm_Boolean GetHostName(Nlm_Char *name,
+ Nlm_Uint4 namelen)
+{
+ int x_errno;
+ ASSERT ( namelen > 0 );
+ VERIFY ( s_Initialize() == eSOCK_ESuccess );
+ name[0] = name[namelen-1] = '\0';
+ x_errno = gethostname(name, (int)namelen);
+ if (x_errno || name[namelen-1]) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 0,
+ "[GetHostName] Cannot get local host name; errno = %d",
+ (int)x_errno);
+ name[0] = '\0';
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+NLM_EXTERN Nlm_Boolean Uint4toInaddr(Nlm_Uint4 ui4_addr,
+ Nlm_CharPtr buf, Nlm_Uint4 buf_len)
+{
+ struct in_addr addr_struct;
+ char *addr_string;
+
+ if ( !buf )
+ return FALSE;
+
+ addr_struct.s_addr = ui4_addr;
+ addr_string = inet_ntoa(addr_struct);
+ if (!addr_string || StrLen(addr_string) >= buf_len) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 0,
+ "[Uint4toInaddr] Cannot convert %lx", (unsigned long)ui4_addr);
+ buf[0] = '\0';
+ return FALSE;
+ }
+
+ StrCpy(buf, addr_string);
+ return TRUE;
+}
+
+extern Nlm_Uint4 Nlm_htonl(Nlm_Uint4 value)
+{
+ return (Nlm_Uint4)htonl((Nlm_Uint4)value);
+}
+
+
+
+
+
+
+
+/*
+#ifdef OS_MAC
+#define TEST_MODULE__NCBISOCK
+#define DO_CLIENT
+#endif
+*/
+
+#ifdef TEST_MODULE__NCBISOCK
+/***********************************************************************
+ * TEST
+ ***********************************************************************/
+
+/* [WIN16] NOTE: make sure that STACKSIZE in your *.def file is set, and
+ * it is big enough(I would recommend 32K; see also N_FIELD * N_FIELD)
+ */
+#define TEST_BUFSIZE 8192
+
+/* exit server before sending the data expected by client(Test 1) */
+/*#define TEST_SRV1_SHUTDOWN*/
+
+#ifndef TEST_SRV1_SHUTDOWN
+/* exit server immediately after its first client is served(Test 1) */
+/*#define TEST_SRV1_ONCE*/
+#endif
+
+
+#define ASS_RET(expr,retcode) \
+if ( !(expr) ) { ASSERT ( 0 ); return retcode; } else {;}
+
+
+/* The simplest randezvous(short request-reply) test functions
+ * "TEST__client_1(SOCK sock)"
+ * "TEST__server_1(SOCK sock)"
+ */
+
+static const Nlm_Char s_C1[] = "C1";
+static const Nlm_Char s_S1[] = "S1";
+
+static Nlm_Int2 TEST__client_1(SOCK sock)
+{ /* reserved ret.codes [110-119] */
+ ESOCK_ErrCode err_code;
+ Nlm_Uint4 n_io, n_io_done;
+ Nlm_Char buf[TEST_BUFSIZE];
+
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 110, "TC1()");
+
+ n_io = Nlm_StrLen(s_C1) + 1;
+ err_code = SOCK_Write(sock, s_C1, n_io, &n_io_done);
+ ASS_RET((err_code == eSOCK_ESuccess && n_io == n_io_done), 101);
+
+ n_io = Nlm_StrLen(s_S1) + 1;
+ err_code = SOCK_Read(sock, buf, n_io, &n_io_done);
+ if (err_code == eSOCK_EClosed) {
+ ErrPostEx(SEV_WARNING, SOCK_ERRCODE, 103, "TC1(): connection closed");
+ return 103;
+ }
+ ASS_RET((err_code == eSOCK_ESuccess && n_io == n_io_done), 104);
+ ASS_RET((Nlm_StrCmp(buf, s_S1) == 0), 105);
+
+ return 0;
+}
+
+
+static Nlm_Int2 TEST__server_1(SOCK sock)
+{ /* reserved ret.codes [210-219] */
+ ESOCK_ErrCode err_code;
+ Nlm_Uint4 n_io, n_io_done;
+ Nlm_Char buf[TEST_BUFSIZE];
+
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 210, "TS1()");
+
+ n_io = Nlm_StrLen(s_C1) + 1;
+ err_code = SOCK_Read(sock, buf, n_io, &n_io_done);
+ ASS_RET((err_code == eSOCK_ESuccess && n_io == n_io_done), 210);
+ ASS_RET((Nlm_StrCmp(buf, s_C1) == 0), 211);
+
+#ifdef TEST_SRV1_SHUTDOWN
+ return 212;
+#endif
+
+ n_io = Nlm_StrLen(s_S1) + 1;
+ err_code = SOCK_Write(sock, s_S1, n_io, &n_io_done);
+ ASS_RET((err_code == eSOCK_ESuccess && n_io == n_io_done), 213);
+
+ return 0;
+}
+
+
+/* More complicated randezvous test functions
+ * "TEST__client_2(SOCK sock)"
+ * "TEST__server_2(SOCK sock)"
+ */
+
+static void s_DoubleTimeout(STimeout *to) {
+ if (!to->sec && !to->usec) {
+ to->usec = 1;
+ } else {
+ to->sec = 2 * to->sec + (2 * to->usec) / 1000000;
+ to->usec = (2 * to->usec) % 1000000;
+ }
+}
+
+static Nlm_Int2 TEST__client_2(SOCK sock)
+{ /* reserved ret.codes [120-139] */
+ ESOCK_ErrCode err_code;
+ Nlm_Uint4 n_io, n_io_done, i;
+#define W_FIELD 10
+#define N_FIELD 1000
+#define N_REPEAT 10
+ Nlm_Char buf[W_FIELD * N_FIELD + 1];
+
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 110, "TC2()");
+
+ /* fill out a buffer to send to server */
+ Nlm_MemSet(buf, '\0', sizeof(buf));
+ for (i = 0; i < N_FIELD; i++) {
+ sprintf(buf + i * W_FIELD, "%10lu", (unsigned long)i);
+ }
+
+ /* send the buffer to server, then get it back */
+ for (i = 0; i < N_REPEAT; i++)
+ {
+ Nlm_Char buf1[sizeof(buf)];
+ STimeout w_to, r_to;
+ Nlm_Boolean w_timeout_on = (Nlm_Boolean)(i%2); /* if to start from */
+ Nlm_Boolean r_timeout_on = (Nlm_Boolean)(i%3); /* zero or inf. timeout */
+ Nlm_CharPtr x_buf;
+
+ /* send */
+ w_to.sec = 0;
+ w_to.usec = 0;
+ err_code = SOCK_SetTimeout(sock, eSOCK_OnWrite,
+ (w_timeout_on ? &w_to : 0), 0, 0);
+ ASS_RET((err_code == eSOCK_ESuccess), 111);
+
+ x_buf = buf;
+ n_io = sizeof(buf);
+ do {
+#if defined(OS_UNIX)
+ sleep(1);
+#elif defined(WIN32)
+ Sleep(1000);
+#endif
+ err_code = SOCK_Write(sock, x_buf, n_io, &n_io_done);
+ if (err_code == eSOCK_EClosed) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 112,
+ "TC2:write: connection closed");
+ return 112;
+ }
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 113,
+ "TC2:write: i=%d, err_code=%d, n_io=%5lu, n_io_done=%5lu"
+ "\ntimeout(%d): %5lu sec, %6lu msec",
+ (int)i, (int)err_code,
+ (unsigned long)n_io, (unsigned long)n_io_done,
+ (int)w_timeout_on,
+ (unsigned long)w_to.sec, (unsigned long)w_to.usec);
+ if ( !w_timeout_on ) {
+ ASS_RET((err_code == eSOCK_ESuccess && n_io_done == n_io), 113);
+ } else {
+ STimeout x_to;
+ ASS_RET((err_code == eSOCK_ESuccess || err_code == eSOCK_ETimeout),
+ 114);
+ ASS_RET((SOCK_SetTimeout(sock, eSOCK_OnWrite, SOCK_GET_TIMEOUT,
+ 0, &x_to) == eSOCK_ESuccess &&
+ w_to.sec == x_to.sec && w_to.usec == x_to.usec), 115);
+ }
+ n_io -= n_io_done;
+ x_buf += n_io_done;
+ if (err_code == eSOCK_ETimeout)
+ s_DoubleTimeout(&w_to);
+ err_code = SOCK_SetTimeout(sock, eSOCK_OnWrite, &w_to, 0, 0);
+ ASS_RET((err_code == eSOCK_ESuccess), 116);
+ w_timeout_on = TRUE;
+ } while ( n_io );
+
+ /* get back the just sent data */
+ r_to.sec = 0;
+ r_to.usec = 0;
+ err_code = SOCK_SetTimeout(sock, eSOCK_OnRead,
+ (r_timeout_on ? &r_to : 0), 0, 0);
+ ASS_RET((err_code == eSOCK_ESuccess), 121);
+
+ x_buf = buf1;
+ n_io = sizeof(buf1);
+ do {
+ if (i%2 == 0)
+ { /* peek a little piece twice and compare */
+ Nlm_Char xx_buf1[128], xx_buf2[128];
+ Nlm_Uint4 xx_io_done1, xx_io_done2;
+ if (SOCK_Peek(sock, xx_buf1, sizeof(xx_buf1), &xx_io_done1)
+ == eSOCK_ESuccess &&
+ SOCK_Peek(sock, xx_buf2, xx_io_done1, &xx_io_done2)
+ == eSOCK_ESuccess) {
+ ASSERT ( xx_io_done1 >= xx_io_done2 );
+ VERIFY ( !Nlm_MemCmp(xx_buf1, xx_buf2, xx_io_done2) );
+ }
+ }
+ err_code = SOCK_Read(sock, x_buf, n_io, &n_io_done);
+ if (err_code == eSOCK_EClosed) {
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 122,
+ "TC2:read: connection closed");
+ return 122;
+ }
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 123,
+ "TC2:read: i=%d, err_code=%d, n_io=%5lu, n_io_done=%5lu"
+ "\ntimeout(%d): %5lu sec, %6lu msec",
+ (int)i, (int)err_code,
+ (unsigned long)n_io, (unsigned long)n_io_done,
+ (int)r_timeout_on,
+ (unsigned long)r_to.sec, (unsigned long)r_to.usec);
+ if ( !r_timeout_on ) {
+ ASS_RET((err_code == eSOCK_ESuccess && n_io_done > 0), 124);
+ } else {
+ STimeout x_to;
+ ASS_RET((err_code == eSOCK_ESuccess || err_code == eSOCK_ETimeout),
+ 125);
+ ASS_RET((SOCK_SetTimeout(sock, eSOCK_OnRead, SOCK_GET_TIMEOUT,
+ &x_to, 0) == eSOCK_ESuccess &&
+ r_to.sec == x_to.sec && r_to.usec == x_to.usec), 126);
+ }
+
+ n_io -= n_io_done;
+ x_buf += n_io_done;
+ if (err_code == eSOCK_ETimeout)
+ s_DoubleTimeout(&r_to);
+ err_code = SOCK_SetTimeout(sock, eSOCK_OnRead, &r_to, 0, 0);
+ ASS_RET((err_code == eSOCK_ESuccess), 127);
+ r_timeout_on = TRUE;
+ } while ( n_io );
+
+ ASS_RET((!Nlm_MemCmp(buf, buf1, sizeof(buf))), 120);
+ }
+
+ return 0;
+}
+
+
+static Nlm_Int2 TEST__server_2(SOCK sock)
+{ /* reserved ret.codes [220-229] */
+ ESOCK_ErrCode err_code;
+ Nlm_Uint4 n_io, n_io_done;
+ Nlm_Char buf[TEST_BUFSIZE];
+ STimeout r_to, w_to;
+ Nlm_Uint4 i;
+
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 220, "TS2()");
+
+ r_to.sec = 0;
+ r_to.usec = 0;
+ w_to = r_to;
+ err_code = SOCK_SetTimeout(sock, eSOCK_OnReadWrite, &r_to, 0, 0);
+ ASS_RET((err_code == eSOCK_ESuccess), 221);
+
+ for (i = 0; ; i++) {
+ Nlm_CharPtr x_buf;
+
+ /* read data from socket */
+ n_io = sizeof(buf);
+ err_code = SOCK_Read(sock, buf, n_io, &n_io_done);
+ switch ( err_code )
+ {
+ case eSOCK_ESuccess:
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 222,
+ "TS2:read:[%lu], err_code=%d, n_io=%5lu, n_io_done=%5lu",
+ (unsigned long)i, (int)err_code,
+ (unsigned long)n_io, (unsigned long)n_io_done);
+ ASS_RET((n_io_done > 0), 222);
+ break;
+ case eSOCK_EClosed:
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 223,
+ "TS2:read: connection closed");
+ return 0;
+ case eSOCK_ETimeout:
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 224,
+ "TS2:read:[%lu] timeout expired: %5lu sec, %6lu msec",
+ (unsigned long)i,
+ (unsigned long)r_to.sec, (unsigned long)r_to.usec);
+ ASS_RET((n_io_done == 0), 224);
+ s_DoubleTimeout(&r_to);
+ err_code = SOCK_SetTimeout(sock, eSOCK_OnRead, &r_to, 0, 0);
+ ASS_RET((err_code == eSOCK_ESuccess), 225);
+ break;
+ default:
+ ASS_RET(0, 226);
+ }
+
+ /* write(just the same) data back to client */
+ n_io = n_io_done;
+ x_buf = buf;
+ while ( n_io ) {
+ err_code = SOCK_Write(sock, buf, n_io, &n_io_done);
+ switch ( err_code )
+ {
+ case eSOCK_ESuccess:
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 231,
+ "TS2:write:[%lu], err_code=%d, n_io=%5lu, n_io_done=%5lu",
+ (unsigned long)i, (int)err_code,
+ (unsigned long)n_io, (unsigned long)n_io_done);
+ ASS_RET((n_io_done > 0), 231);
+ break;
+ case eSOCK_EClosed:
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 232,
+ "TS2:write: connection closed");
+ return 230;
+ case eSOCK_ETimeout:
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 233,
+ "TS2:write:[%lu] timeout expired: %5lu sec, %6lu msec",
+ (unsigned long)i,
+ (unsigned long)w_to.sec, (unsigned long)w_to.usec);
+ ASS_RET((n_io_done == 0), 233);
+ s_DoubleTimeout(&w_to);
+ err_code = SOCK_SetTimeout(sock, eSOCK_OnWrite, &w_to, 0, 0);
+ ASS_RET((err_code == eSOCK_ESuccess), 234);
+ break;
+ default:
+ ASS_RET(0, 235);
+ }
+
+ n_io -= n_io_done;
+ x_buf += n_io_done;
+ }
+ }
+
+ return 0;
+}
+
+
+/* Skeletons for the socket i/o test:
+ * TEST__client(...)
+ * TEST__server(...)
+ * establish and close connection; call test i/o functions like
+ * TEST__[client|server]_[1|2|...] (...)
+ */
+static Nlm_Int2 TEST__client(const Nlm_Char *server_host,
+ Nlm_Uint2 server_port)
+{ /* reserved ret.codes [100-109] */
+ SOCK sock;
+ ESOCK_ErrCode err_code;
+ Nlm_Int2 ret_code;
+
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 101,
+ "TEST__client(host = \"%s\", port = %u)",
+ server_host, (unsigned)server_port);
+
+ /* Connect to server */
+ err_code = SOCK_Create(server_host, server_port, &sock);
+ ASS_RET((err_code == eSOCK_ESuccess), 100);
+
+ /* Test the simplest randezvous(short request-reply)
+ * The two peer functions are:
+ * "TEST__[client|server]_1(SOCK sock)"
+ */
+ ret_code = TEST__client_1(sock);
+ ASS_RET((ret_code == 0), 101);
+
+ /* Test a more complex case
+ * The two peer functions are:
+ * "TEST__[client|server]_2(SOCK sock)"
+ */
+ ret_code = TEST__client_2(sock);
+ ASS_RET((ret_code == 0), 102);
+
+ /* Close connection and exit */
+ err_code = SOCK_Close(sock);
+ ASS_RET((err_code == eSOCK_ESuccess || err_code == eSOCK_EClosed), 109);
+ return 0;
+}
+
+
+static Nlm_Int2 TEST__server(Nlm_Uint2 port)
+{ /* reserved ret.codes [200-209] */
+ LSOCK lsock;
+ ESOCK_ErrCode err_code;
+
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 201,
+ "TEST__server(port = %u)", (unsigned)port);
+
+ /* Create listening socket */
+ err_code = LSOCK_Create(port, 1, &lsock);
+ ASS_RET((err_code == eSOCK_ESuccess), 200);
+
+ /* Accept connections from clients and run test sessions */
+ for (;;)
+ {
+ Nlm_Int2 ret_code;
+
+ /* Accept connection */
+ SOCK sock;
+ err_code = LSOCK_Accept(lsock, NULL, &sock);
+ ASS_RET((err_code == eSOCK_ESuccess), 208);
+
+ /* Test the simplest randezvous(short request-reply)
+ * The two peer functions are:
+ * "TEST__[client|server]_1(SOCK sock)"
+ */
+ ret_code = TEST__server_1(sock);
+ ASS_RET((ret_code == 0), 201);
+
+ /* Test a more complex case
+ * The two peer functions are:
+ * "TEST__[client|server]_2(SOCK sock)"
+ */
+ ret_code = TEST__server_2(sock);
+ ASS_RET((ret_code == 0), 202);
+
+ /* Close connection */
+ err_code = SOCK_Close(sock);
+ ASS_RET((err_code == eSOCK_ESuccess || err_code == eSOCK_EClosed), 209);
+
+#ifdef TEST_SRV1_ONCE
+ /* finish after the first session */
+ break;
+#endif
+ }
+
+ /* Close listening socket */
+ err_code = LSOCK_Close(lsock);
+ ASS_RET((err_code == eSOCK_ESuccess), 204);
+ return 0;
+}
+
+
+/* Main function
+ * Parse command-line options, initialize and cleanup API internals;
+ * run client or server test
+ */
+extern Nlm_Int2 Nlm_Main(void)
+{
+#define MIN_PORT 5001
+ Nlm_Int4 argc = Nlm_GetArgc();
+ Nlm_CharPtr *argv = Nlm_GetArgv();
+
+#ifdef WIN16
+ {{ /* a kludge to make sure the "vibwndws.c"(MainProc) get linked */
+ extern void Nlm_Metronome(Nlm_VoidPtr actn); Nlm_Metronome(0);
+ }}
+#endif
+
+ Nlm_ErrSetOpts(ERR_TEE, ERR_LOG_ON);
+ ErrSetLogLevel(SEV_INFO);
+ ErrSetMessageLevel(SEV_INFO);
+ VERIFY ( Nlm_ErrSetLog("ncbisock.log") );
+
+ {{
+ Nlm_Char local_host[64];
+ VERIFY ( GetHostName(local_host, sizeof(local_host)) );
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 200,
+ "\nRunning NCBISOCK test on host \"%s\"", local_host);
+ }}
+
+#ifdef DO_SERVER
+ argc = 2;
+#endif
+#ifdef DO_CLIENT
+ argc = 3;
+#endif
+
+ switch ( argc )
+ {
+ case 2:
+ { /* Server */
+#ifdef DO_SERVER
+ short port = 5555;
+#else
+ short port;
+ if (sscanf(argv[1], "%hd", &port) != 1 ||
+ port < MIN_PORT)
+ break;
+#endif
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 200,
+ "Starting NCBISOCK server test...");
+ VERIFY ( Nlm_ErrSetLog("ncbisock.srv") );
+
+ {{
+ Nlm_Int2 ret_code = TEST__server((Nlm_Uint2)port);
+ VERIFY ( SOCK_Destroy() == eSOCK_ESuccess );
+ return ret_code;
+ }}
+ }
+
+ case 3:
+ { /* Client */
+#ifdef DO_CLIENT
+ Nlm_CharPtr server_host = "peony";
+ short server_port = 5555;
+#else
+ Nlm_CharPtr server_host = argv[1];
+ short server_port;
+ if (sscanf(argv[2], "%hd", &server_port) != 1 ||
+ server_port < MIN_PORT)
+ break;
+#endif
+ ErrPostEx(SEV_INFO, SOCK_ERRCODE, 100,
+ "Starting NCBISOCK client test... ");
+ VERIFY ( Nlm_ErrSetLog("ncbisock.cli") );
+
+ {{
+ Nlm_Int2 ret_code= TEST__client(server_host, (Nlm_Uint2)server_port);
+ VERIFY ( SOCK_Destroy() == eSOCK_ESuccess );
+ return ret_code;
+ }}
+ }
+ }
+
+ /* Bad cmd-line arguments; Usage */
+ ErrPostEx(SEV_ERROR, SOCK_ERRCODE, 666,
+ "Usage:\n"
+ " Client: %s <srv_host> <port>\n"
+ " Server: %s <port>\n"
+ " where <port> not less than %hd",
+ argv[0], argv[0], (short)MIN_PORT);
+ return 1;
+}
+
+#endif /* TEST_MODULE__NCBISOCK */
+
+/* EOF */
+
diff --git a/network/nsclilib/ncbisock.h b/network/nsclilib/ncbisock.h
new file mode 100644
index 00000000..294e43f7
--- /dev/null
+++ b/network/nsclilib/ncbisock.h
@@ -0,0 +1,288 @@
+#ifndef NCBISOCK__H
+#define NCBISOCK__H
+
+/* $RCSfile: ncbisock.h,v $ $Revision: 4.7 $ $Date: 1999/01/22 22:05:00 $
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* Author: Denis Vakatov
+*
+* File Description:
+* Plain portable socket API
+*
+* --------------------------------------------------------------------------
+* $Log: ncbisock.h,v $
+* Revision 4.7 1999/01/22 22:05:00 vakatov
+* Uint4toInaddr() to take address in the network byte order
+*
+* Revision 4.6 1998/12/15 17:22:24 vakatov
+* + SOCK_Address() -- to get the socket peer's host and port
+*
+* Revision 4.5 1998/08/12 13:12:43 kans
+* moved high level query functions to ncbiurl.[ch]
+*
+* Revision 4.4 1998/08/10 23:24:25 kans
+* added SOCK_SendURLQuery and SOCK_CheckURLQuery from Sequin
+*
+* Revision 4.3 1998/03/30 17:50:13 vakatov
+* Ingrafted to the main NCBI CVS tree
+*
+* ==========================================================================
+*/
+
+#include <ncbistd.h>
+
+/* for ErrPost */
+#define SOCK_ERRCODE 777
+
+#define LSOCK Nlm_LSOCK
+#define SOCK Nlm_SOCK
+
+#define ESOCK_ErrCode Nlm_ESOCK_ErrCode
+#define ESOCK_Mode Nlm_ESOCK_Mode
+#define STimeout Nlm_STimeout
+
+#define SOCK_ErrCodeStr Nlm_SOCK_ErrCodeStr
+
+#define SOCK_Initialize Nlm_SOCK_Initialize
+#define SOCK_Destroy Nlm_SOCK_Destroy
+
+#define LSOCK_Create Nlm_LSOCK_Create
+#define LSOCK_Accept Nlm_LSOCK_Accept
+#define LSOCK_Close Nlm_LSOCK_Close
+
+#define SOCK_Create Nlm_SOCK_Create
+#define SOCK_SetTimeout Nlm_SOCK_SetTimeout
+#define SOCK_Select Nlm_SOCK_Select
+#define SOCK_Read Nlm_SOCK_Read
+#define SOCK_Write Nlm_SOCK_Write
+#define SOCK_Close Nlm_SOCK_Close
+
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Nlm_LSOCKtag; /* listening socket: internal storage */
+typedef struct Nlm_LSOCKtag *LSOCK; /* listening socket: handle */
+
+struct Nlm_SOCKtag; /* socket: internal storage */
+typedef struct Nlm_SOCKtag *SOCK; /* socket: handle */
+
+typedef enum
+{
+ eSOCK_ESuccess = 0, /* everything is fine, no errors occured */
+ eSOCK_ETimeout, /* timeout expired before the data could be i/o'd */
+ eSOCK_EClosed, /* peer has closed the connection */
+
+ eSOCK_EUnknown /* unknown(most probably -- fatal) error */
+} ESOCK_ErrCode;
+
+
+typedef enum {
+ eSOCK_OnRead,
+ eSOCK_OnWrite,
+ eSOCK_OnReadWrite
+} ESOCK_Mode;
+
+typedef struct {
+ Nlm_Uint4 sec; /* seconds(get truncated to platform-dep. max. limit) */
+ Nlm_Uint4 usec; /* microseconds(always get truncated to 10**6) */
+} STimeout;
+
+
+/* Return (const) verbal description for the passed error code
+ */
+NLM_EXTERN const Nlm_Char *SOCK_ErrCodeStr
+(ESOCK_ErrCode err_code
+ );
+
+
+/* [SERVER-side] Create and initialize the server-side(listening) socket
+ * (socket() + bind() + listen())
+ */
+NLM_EXTERN ESOCK_ErrCode LSOCK_Create
+(Nlm_Uint2 port, /* [in] the port to listen at */
+ Nlm_Uint2 n_listen, /* [in] maximal # of pending connections */
+ LSOCK *lsock /* [out] handle of the created listening socket */
+ );
+
+
+/* [SERVER-side] Accept connection from a client
+ * NOTE: the "*timeout" is for this accept() only; to set i/o timeout,
+ * use SOCK_Timeout(); (by default -- infinite)
+ */
+NLM_EXTERN ESOCK_ErrCode LSOCK_Accept
+(LSOCK lsock, /* [in] handle of a listening socket */
+ const STimeout *timeout, /* [in] timeout(infinite if NULL) */
+ SOCK *sock /* [out] handle of the created socket */
+ );
+
+
+/* [SERVER-side] Close the listening socket, destroy relevant internal data
+ */
+NLM_EXTERN ESOCK_ErrCode LSOCK_Close
+(LSOCK lsock
+ );
+
+
+/* [CLIENT-side] Connect client to another(server-side, listening) socket
+ * (socket() + connect())
+ */
+NLM_EXTERN ESOCK_ErrCode SOCK_Create
+(const Nlm_Char *host, /* [in] server host */
+ Nlm_Uint2 port, /* [in] server port */
+ SOCK *sock /* [out] handle of the created socket */
+ );
+
+
+/* [CLIENT-side] Close the connection, destroy relevant internal data
+ * NOTE: if write timeout is specified then it blocks until either all
+ * unsent data are sent or until the timeout expires
+ * NOTE: whatever error code is returned, this function cannot be
+ * called more than once for the same socket
+ */
+NLM_EXTERN ESOCK_ErrCode SOCK_Close
+(SOCK sock
+ );
+
+
+/* Block on the socket until either read/write(dep. on "mode") is
+ * available or timeout expires(if "timeout" is NULL then assume it infinite)
+ */
+NLM_EXTERN ESOCK_ErrCode SOCK_Select
+(SOCK sock,
+ ESOCK_Mode mode,
+ const STimeout *timeout
+ );
+
+
+/* Specify timeout for the connection i/o(see SOCK_[Read|Write|Close] funcs).
+ * NOTE: set the timeout to the maximum if "new_timeout" is NULL
+ * NOTE: the default timeout is the maximum possible(wait "ad infinitum")
+ */
+#define SOCK_GET_TIMEOUT ((const STimeout *)~0)
+NLM_EXTERN ESOCK_ErrCode SOCK_SetTimeout
+(SOCK sock,
+ ESOCK_Mode mode,
+ const STimeout *new_timeout, /* (dont set if equal to SOCK_GET_TIMEOUT) */
+ STimeout *r_timeout, /* if non-NULL, return previous read */
+ STimeout *w_timeout /* and(or) write timeout values */
+ );
+
+
+/* Read up to "size" bytes from "sock" to the mem.buffer pointed by "buf".
+ * In "*n_read", return the number of succesfully read bytes.
+ * If there is no data available to read and the timeout(see
+ * SOCK_Timeout()) is expired then return eSOCK_ETimeout.
+ * NOTE: eSOCK_Closed may indicate an empty message rather than a
+ * a real closure of connection
+ */
+NLM_EXTERN ESOCK_ErrCode SOCK_Read
+(SOCK sock,
+ Nlm_VoidPtr buf,
+ Nlm_Uint4 size,
+ Nlm_Uint4 *n_read
+ );
+
+/* Operate just like SOCK_Read() but dont remove the read data from the
+ * input queue
+ */
+NLM_EXTERN ESOCK_ErrCode SOCK_Peek
+(SOCK sock,
+ Nlm_VoidPtr buf,
+ Nlm_Uint4 size,
+ Nlm_Uint4 *n_read
+ );
+
+
+/* Write "size" bytes from the mem.buffer "buf" to "sock".
+ * In "*n_written", return the number of successfully written bytes.
+ * If cannot write all data and the timeout(see SOCK_Timeout()) is expired
+ * then return eSOCK_ETimeout.
+ */
+NLM_EXTERN ESOCK_ErrCode SOCK_Write
+(SOCK sock,
+ const void *buf,
+ Nlm_Uint4 size,
+ Nlm_Uint4 *n_written
+ );
+
+
+/* Get host address and port of the socket peer
+ * If "network_byte_order" is true then return them in the network byte order
+ * NOTE: "host" or "port" can be NULL
+ */
+NLM_EXTERN void SOCK_Address
+(SOCK sock,
+ Nlm_Uint4 *host,
+ Nlm_Uint2 *port,
+ Nlm_Boolean network_byte_order
+ );
+
+
+/* Destroy internal data used by this module
+ * NOTE: no function from this API can be used after the call to SOCK_Destroy
+ */
+NLM_EXTERN ESOCK_ErrCode SOCK_Destroy(void);
+
+
+/* To be moved from this module to... somewhere else; later... maybe ;-)
+ */
+#define GetHostName Nlm_GetHostName
+NLM_EXTERN Nlm_Boolean GetHostName
+(Nlm_Char *name,
+ Nlm_Uint4 namelen
+ );
+
+#define Uint4toInaddr Nlm_Uint4toInaddr
+NLM_EXTERN Nlm_Boolean Uint4toInaddr
+(Nlm_Uint4 ui4_addr, /* NOTE: must be in the network byte-order */
+ Nlm_CharPtr buf, /* to be filled by smth. like "123.45.67.89\0" */
+ Nlm_Uint4 buf_len
+ );
+
+/* KLUDGE(dont use this beast, please) */
+extern Nlm_Uint4 Nlm_htonl(Nlm_Uint4 value);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif /* NCBISOCK__H */
diff --git a/network/nsclilib/ncbiurl.c b/network/nsclilib/ncbiurl.c
new file mode 100644
index 00000000..1050f845
--- /dev/null
+++ b/network/nsclilib/ncbiurl.c
@@ -0,0 +1,499 @@
+/* ncbiurl.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information (NCBI)
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government do not place any restriction on its use or reproduction.
+* We would, however, appreciate having the NCBI and the author cited in
+* any work or product based on this material
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* ===========================================================================
+*
+* File Name: ncbiurl.c
+*
+* Author: Jonathan Kans
+*
+* Version Creation Date: 8/12/98
+*
+* $Revision: 6.9 $
+*
+* File Description:
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* $Log: ncbiurl.c,v $
+* Revision 6.9 1999/01/07 17:52:36 kans
+* added programName and mydata parameters, fixed bad userAgentName code that Alexey caught and CodeWarrior missed
+*
+* Revision 6.8 1999/01/05 21:35:40 kans
+* pass program name as User-Agent
+*
+* Revision 6.7 1998/11/19 22:51:45 kans
+* name is supplemental_input
+*
+* Revision 6.6 1998/11/19 21:49:34 kans
+* switching from GET to POST
+*
+* Revision 6.5 1998/11/18 20:42:39 kans
+* if still needs question mark before arguments, then does not need ampersand
+*
+* Revision 6.4 1998/11/09 19:16:05 vakatov
+* Added "NLM_EXTERN" to function prototypes
+*
+* ==========================================================================
+*/
+
+#include <ncbiurl.h>
+
+/*****************************************************************************
+*
+* SOCK_SendURLQuery is passed the host machine (without http://), the port
+* (80 is the conventional public port), and a path. The path can include
+* the full query (including a question mark to separate path from query),
+* or a separate query string (without a question mark) can be passed in.
+* An additional arguments parameter can also be passed in, and an ampersand
+* is used to separate the query and arguments parameters.
+*
+* SOCK_CheckURLQuery returns the number of pending URL queries. Call this
+* function at least once every few seconds. This function polls the sockets,
+* and calls the designated result procedure (written by the user) to handle
+* the resulting data file.
+*
+*****************************************************************************/
+
+#define URL_QUERY_BUFLEN 2048
+
+typedef struct querydata {
+ Nlm_Uint4 timeoutsec;
+ URLResultProc resultproc;
+ SOCK sock;
+ Nlm_Boolean receiveBinary;
+ Nlm_VoidPtr mydata;
+} QueryData, PNTR QueryPtr;
+
+static ValNodePtr urlquerylist = NULL;
+
+static Nlm_Boolean HasNoText (Nlm_CharPtr str)
+
+{
+ Nlm_Char ch;
+
+ if (str != NULL) {
+ ch = *str;
+ while (ch != '\0') {
+ if (ch > ' ') {
+ return FALSE;
+ }
+ str++;
+ ch = *str;
+ }
+ }
+ return TRUE;
+}
+
+NLM_EXTERN Nlm_Boolean SOCK_SendURLQuery (Nlm_CharPtr host_machine, Nlm_Uint2 host_port,
+ Nlm_CharPtr host_path, Nlm_CharPtr query,
+ Nlm_CharPtr arguments, Nlm_CharPtr data_file,
+ URLResultProc resultproc, Nlm_Uint4 timeoutsec,
+ Nlm_Boolean sendBinary, Nlm_Boolean receiveBinary,
+ Nlm_CharPtr programName, Nlm_VoidPtr mydata)
+
+{
+ Nlm_Boolean needsAmpsnd = TRUE;
+ Nlm_Boolean needsQmark = TRUE;
+ Nlm_Boolean ok;
+ Nlm_CharPtr buffer;
+ ESOCK_ErrCode err_code;
+ SOCK sock;
+ FILE *fp = (FILE*)0;
+ size_t ct;
+ Nlm_Int4 len;
+ Nlm_Uint4 cnt;
+ Nlm_Uint4 n_written;
+ Nlm_Char path [PATH_MAX];
+ QueryPtr qp;
+ STimeout timeout;
+ Nlm_CharPtr userAgentName = NULL;
+ Nlm_CharPtr mode;
+
+ if (HasNoText (host_machine) || HasNoText (host_path)) return FALSE;
+
+ /* Connect to the server */
+ if (SOCK_Create(host_machine, host_port, &sock) != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Cannot connect to server \"%s\", port %d;",
+ host_machine, (int)host_port);
+ return FALSE;
+ }
+
+ /* Setup the connection's i/o timeout */
+ timeout.sec = timeoutsec;
+ timeout.usec = 0;
+ if (SOCK_SetTimeout(sock, eSOCK_OnWrite, &timeout, 0, 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Cannot setup the connection timeout to "
+ "server \"%s\", port %d",
+ host_machine, (int)host_port);
+ SOCK_Close(sock);
+ return FALSE;
+ }
+
+ /* Allocate heap buffer */
+ buffer = MemNew (URL_QUERY_BUFLEN + 1);
+ if (buffer == NULL) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Cannot allocate buffer");
+ SOCK_Close(sock);
+ return FALSE;
+ }
+ MemSet ((Nlm_VoidPtr) buffer, 0, (size_t) (URL_QUERY_BUFLEN + 1));
+
+ /* allow the user to specify a program name, otherwise get from ProgramPath */
+ if (! HasNoText (programName)) {
+ userAgentName = programName;
+ } else {
+ Nlm_ProgramPath (path, sizeof (path));
+ userAgentName = StringRChr (path, DIRDELIMCHR);
+ if (userAgentName != NULL) {
+ userAgentName++;
+ }
+ }
+ if (HasNoText (userAgentName)) {
+ userAgentName = "?";
+ }
+
+ /* Sockets are connected; now compose and send request */
+ ok = FALSE;
+ do {{ /* TRY */
+ /*
+ static char X_GET[] = "GET ";
+ */
+ static char X_GET[] = "POST ";
+ static char X_HTTP[] = " HTTP/1.0\n";
+ static char X_QUERY[] = "?";
+ static char X_AMPRSND[] = "&";
+
+ needsQmark = TRUE;
+ needsAmpsnd = TRUE;
+ /* write HTTP header */
+ if (SOCK_Write(sock, (const void *)X_GET, StrLen(X_GET ), 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error sending HTTP header");
+ break;
+ }
+
+ if (SOCK_Write(sock, (const void *)host_path,
+ StrLen(host_path), 0) != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error sending HTTP header");
+ break;
+ }
+ if (StringStr (host_path, X_QUERY) != NULL) {
+ needsQmark = FALSE;
+ }
+
+ if (! HasNoText (query)) {
+ if (needsQmark) {
+ if (SOCK_Write(sock, (const void *)X_QUERY, StrLen(X_QUERY ), 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error sending HTTP header");
+ break;
+ }
+ }
+ needsQmark = FALSE;
+ if (SOCK_Write(sock, (const void *)query,
+ StrLen(query), 0) != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error sending HTTP header");
+ break;
+ }
+ }
+
+ if (! HasNoText (arguments)) {
+ if (needsQmark) {
+ if (SOCK_Write(sock, (const void *)X_QUERY, StrLen(X_QUERY ), 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error sending HTTP header");
+ break;
+ }
+ needsQmark = FALSE;
+ needsAmpsnd = FALSE;
+ }
+ if (needsAmpsnd) {
+ if (SOCK_Write(sock, (const void *)X_AMPRSND, StrLen(X_AMPRSND ), 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error sending HTTP header");
+ break;
+ }
+ }
+ if (SOCK_Write(sock, (const void *)arguments,
+ StrLen(arguments), 0) != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error sending HTTP header");
+ break;
+ }
+ }
+
+ if (sendBinary) {
+ mode = "rb";
+ } else {
+ mode = "r";
+ }
+ if (sendBinary) {
+ len = FileLength (data_file);
+ } else {
+ /* get actual length after cr/lf pair conversion to newline on PCs in text mode */
+ len = 0;
+ fp = FileOpen (data_file, mode);
+ if (fp != NULL) {
+ while ((ct = FileRead(buffer, 1, URL_QUERY_BUFLEN, fp)) > 0) {
+ len += ct;
+ }
+ }
+ FileClose (fp);
+ }
+
+ if (SOCK_Write(sock, (const void *)X_HTTP, StrLen(X_HTTP ), 0)
+ != eSOCK_ESuccess ||
+ /*
+ sprintf(buffer, "Content-type: application/x-www-form-urlencoded"
+ "\nContent-Length: %ld\n\n",
+ (long) (len + 1))
+ */
+ sprintf(buffer, "Content-type: multipart/form-data"
+ "\nContent-Disposition: form-data; name=supplemental_input"
+ "\nUser-Agent: %s"
+ "\nContent-Length: %ld\n\n",
+ userAgentName, (long) (len + 1))
+ <= 0
+ ||
+ SOCK_Write(sock, (const void *)buffer, StrLen(buffer), 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error sending HTTP header");
+ break;
+ }
+
+ /* send the service query */
+ if ( data_file ) {
+ fp = FileOpen (data_file, mode);
+ if (fp == NULL) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error opening data file");
+ break;
+ }
+
+ err_code = eSOCK_ESuccess;
+ cnt = 0;
+ while ((ct = FileRead(buffer, 1, URL_QUERY_BUFLEN, fp)) > 0) {
+ err_code = SOCK_Write(sock, (const void *)buffer, ct, &n_written);
+ cnt += n_written;
+ }
+ err_code = SOCK_Write(sock, (const void *)"\0", 1, 0);
+ cnt++;
+
+ FileClose(fp);
+
+ if (err_code != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[SendURLQuery] Error sending service query (%s)",
+ SOCK_ErrCodeStr(err_code));
+ break;
+ }
+ }
+
+ ok = TRUE;
+ }} while ( !ok ); /* end-of-TRY */
+
+ /* Free heap buffer */
+ MemFree (buffer);
+
+
+ /* check for success and return */
+ if ( !ok ) {
+ SOCK_Close(sock);
+ return FALSE;
+ }
+
+ qp = (QueryPtr) MemNew (sizeof (QueryData));
+ if (qp == NULL) return FALSE;
+
+ qp->timeoutsec = timeoutsec;
+ qp->resultproc = resultproc;
+ qp->sock = sock;
+ qp->receiveBinary = receiveBinary;
+ qp->mydata = mydata;
+
+ /* add to polling queue */
+ ValNodeAddPointer (&urlquerylist, 0, (Nlm_VoidPtr) qp);
+ return TRUE;
+}
+
+#define URL_FORMAT_LEN 128
+
+static Nlm_Boolean PollURLQuery (QueryPtr qp)
+
+{
+ Nlm_Char buffer[URL_QUERY_BUFLEN + 1];
+ ESOCK_ErrCode err_code;
+ SOCK sock;
+ FILE *fp = (FILE*)0;
+ size_t ct;
+ STimeout timeout;
+ Nlm_Uint4 n_io_done;
+ Nlm_CharPtr ptr;
+ Nlm_Char ch;
+ Nlm_Boolean inHeader;
+ Nlm_Char path [PATH_MAX];
+ Nlm_Boolean gotIntoLoop = FALSE;
+ Nlm_CharPtr mode;
+ Nlm_Char format [URL_FORMAT_LEN + 1];
+
+ if (qp == NULL) return FALSE;
+ sock = qp->sock;
+
+ timeout.sec = 0;
+ timeout.usec = 0;
+ err_code = eSOCK_ESuccess;
+ if (SOCK_SetTimeout(sock, eSOCK_OnRead, &timeout, 0, 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[PollURLQuery] Cannot setup the connection timeout");
+ SOCK_Close(sock);
+ return FALSE;
+ }
+
+ inHeader = TRUE;
+ fp = NULL;
+ path [0] = '\0';
+ format [0] = '\0';
+ err_code = eSOCK_ESuccess;
+ while ((err_code = SOCK_Read(sock, buffer, URL_QUERY_BUFLEN, &n_io_done))
+ == eSOCK_ESuccess) {
+ static char X_GET_3[] = "Content-Type: text/html";
+ static char X_GET_4[] = "NCBI-tools-type:";
+ gotIntoLoop = TRUE;
+ if (fp == NULL) {
+ TmpNam (path);
+ if (qp->receiveBinary) {
+ mode = "wb";
+ } else {
+ mode = "w";
+ }
+ fp = FileOpen(path, mode);
+ if (fp == NULL) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[PollURLQuery] Error opening FASTA file");
+ return FALSE;
+ }
+ timeout.sec = qp->timeoutsec;
+ timeout.usec = 0;
+ if (SOCK_SetTimeout(sock, eSOCK_OnRead, &timeout, 0, 0)
+ != eSOCK_ESuccess) {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "[PollURLQuery] Cannot reset the connection timeout");
+ SOCK_Close(sock);
+ return FALSE;
+ }
+ }
+ if (inHeader) {
+ ptr = StringStr(buffer, X_GET_4);
+ if (ptr != NULL) {
+ ptr += StrLen (X_GET_4);
+ ch = *ptr;
+ while (ch == ' ') {
+ ptr++;
+ ch = *ptr;
+ }
+ ct = 0;
+ while (ct < URL_FORMAT_LEN && ch != '\0' && ch != '\n' && ch != '\r') {
+ format [ct] = ch;
+ ct++;
+ ptr++;
+ ch = *ptr;
+ }
+ format [ct] = '\0';
+ }
+ ptr = StringStr(buffer, X_GET_3);
+ if (ptr != NULL) {
+ ptr += StrLen (X_GET_3);
+ ch = *ptr;
+ while (ch != '\0' && ch != '\n' && ch != '\r') {
+ ptr++;
+ ch = *ptr;
+ }
+ while (ch == '\n' || ch == '\r') {
+ ptr++;
+ ch = *ptr;
+ }
+ ct = FileWrite(ptr, 1, n_io_done - (ptr - buffer), fp);
+ ASSERT ( ct == n_io_done - (ptr - buffer) );
+ inHeader = FALSE;
+ }
+ } else {
+ ct = FileWrite(buffer, 1, n_io_done, fp);
+ ASSERT ( ct == n_io_done );
+ }
+ }
+
+ if (gotIntoLoop) {
+ FileClose(fp);
+
+ if (qp->resultproc != NULL) {
+ qp->resultproc (path, format, qp->mydata);
+ }
+ FileRemove (path);
+ }
+
+ /* return (Nlm_Boolean)(err_code != eSOCK_ETimeout); */
+ return gotIntoLoop; /* must remove from queue, even if incomplete - but how to warn? */
+}
+
+NLM_EXTERN Nlm_Int4 SOCK_CheckURLQuery (void)
+
+{
+ Nlm_Int4 count = 0;
+ ValNodePtr next;
+ ValNodePtr PNTR prev;
+ QueryPtr qp;
+ ValNodePtr vnp;
+
+ prev = &urlquerylist;
+ vnp = urlquerylist;
+ while (vnp != NULL) {
+ next = vnp->next;
+ qp = (QueryPtr) vnp->data.ptrvalue;
+ if (qp != NULL && PollURLQuery (qp)) {
+ *(prev) = next;
+ vnp->next = NULL;
+ ValNodeFreeData (vnp);
+ vnp = next;
+ /* Beep (); */ /* announce retrieval of URL query results */
+ } else {
+ prev = &(vnp->next);
+ vnp = next;
+ count++;
+ }
+ }
+ return count;
+}
+
diff --git a/network/nsclilib/ncbiurl.h b/network/nsclilib/ncbiurl.h
new file mode 100644
index 00000000..c85fd825
--- /dev/null
+++ b/network/nsclilib/ncbiurl.h
@@ -0,0 +1,100 @@
+/* ncbiurl.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information (NCBI)
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government do not place any restriction on its use or reproduction.
+* We would, however, appreciate having the NCBI and the author cited in
+* any work or product based on this material
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* ===========================================================================
+*
+* File Name: ncbiurl.h
+*
+* Author: Jonathan Kans
+*
+* Version Creation Date: 8/12/98
+*
+* $Revision: 6.4 $
+*
+* File Description:
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+*
+* ==========================================================================
+*/
+
+#ifndef _NCBIURL_
+#define _NCBIURL_
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ncbi.h>
+#include <ncbisock.h>
+
+/*****************************************************************************
+*
+* SOCK_SendURLQuery is passed the host machine (without http://), the port
+* (80 is the conventional public port), and a path. The path can include
+* the full query (including a question mark to separate path from query),
+* or a separate query string (without a question mark) can be passed in.
+* An additional arguments parameter can also be passed in, and an ampersand
+* is used to separate the query and arguments parameters.
+*
+* SOCK_CheckURLQuery returns the number of pending URL queries. Call this
+* function at least once every few seconds. This function polls the sockets,
+* and calls the designated result procedure (written by the user) to handle
+* the resulting data file.
+*
+*****************************************************************************/
+
+typedef Nlm_Boolean (LIBCALLBACK *URLResultProc) (Nlm_CharPtr filename, Nlm_CharPtr format, Nlm_VoidPtr mydata);
+
+NLM_EXTERN Nlm_Boolean SOCK_SendURLQuery (Nlm_CharPtr host_machine, Nlm_Uint2 host_port,
+ Nlm_CharPtr host_path, Nlm_CharPtr query,
+ Nlm_CharPtr arguments, Nlm_CharPtr data_file,
+ URLResultProc resultproc, Nlm_Uint4 timeoutsec,
+ Nlm_Boolean sendBinary, Nlm_Boolean receiveBinary,
+ Nlm_CharPtr programName, Nlm_VoidPtr mydata);
+
+NLM_EXTERN Nlm_Int4 SOCK_CheckURLQuery (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif /* _NCBIURL_ */
diff --git a/network/nsclilib/ni_debug.c b/network/nsclilib/ni_debug.c
new file mode 100644
index 00000000..38b9acfc
--- /dev/null
+++ b/network/nsclilib/ni_debug.c
@@ -0,0 +1,222 @@
+/* $RCSfile: ni_debug.c,v $ $Revision: 6.1 $ $Date: 1998/05/05 22:23:35 $
+* ==========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ==========================================================================
+*
+* Author: Denis Vakatov
+*
+* File Description:
+* Basic client code for the debug NCBI client that connects
+* directly to the standalone server(bypasses NCBI dispatchers)
+*
+* --------------------------------------------------------------------------
+* $Log: ni_debug.c,v $
+* Revision 6.1 1998/05/05 22:23:35 vakatov
+* Initial revision
+*
+* ==========================================================================
+*/
+
+#include <ncbi.h>
+#include <ncbinet.h>
+#include <ncbicli.h>
+
+
+/*********************************
+ * INTERNALS
+ */
+
+/* Hard-coded constants, environment parameter names & defaults
+ */
+
+#define ENV_DEBUG_HOST "NI_DEBUG_HOST"
+#define ENV_DEBUG_PORT "NI_DEBUG_PORT"
+
+#define ENV_DEBUG_TRY "NI_DEBUG_TRY"
+#define DEF_DEBUG_TRY 2
+
+
+/* Static functions
+ */
+
+static Int2 LIBCALLBACK s_AsnRead(Pointer p, CharPtr buff, Uint2 len)
+{
+ Uint4 n_read = 0;
+ SOCK_Read((SOCK)p, buff, len, &n_read);
+ return (Int2)n_read;
+}
+
+
+static Int2 LIBCALLBACK s_AsnWrite(Pointer p, CharPtr buff, Uint2 len)
+{
+ Uint4 n_written = 0;
+ SOCK_Write((SOCK)p, buff, len, &n_written);
+ return (Int2)n_written;
+}
+
+
+static void LIBCALLBACK s_AsnErrorFunc(Int2 type, CharPtr message)
+{
+ ErrPostEx(SEV_ERROR, 77, type, message);
+}
+
+
+/* The interface implementaion functions
+ */
+
+static NI_DispatcherPtr s_GenericInit
+(CharPtr configFile, CharPtr configSection, Boolean showMonitor,
+ CharPtr lastDispatcher, Int2 lastDispLen)
+{
+ NI_DispatcherPtr disp = (NI_DispatcherPtr)MemNew(sizeof(NI_Dispatcher));
+ disp->interface = eNII_Debug;
+
+ if ( lastDispatcher )
+ StringNCpy_0(lastDispatcher, "Debug NCBI Network Client", lastDispLen);
+
+ disp->motd = StringSave("Makes a direct connection to the specified server");
+ disp->adminInfo = StringSave("Denis V. Vakatov "
+ "(vakatov@ncbi.nlm.nih.gov)");
+ disp->referenceCount = 1;
+ return disp;
+}
+
+
+static NI_DispatcherPtr s_SetDispatcher
+(NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
+ Int4 dispserialnum, ValNodePtr encryption, Boolean useOutServ)
+{
+ return s_GenericInit(0, 0, 0, 0, 0);
+}
+
+
+static NI_HandPtr s_GenericGetService
+(NI_DispatcherPtr disp, CharPtr configFile, CharPtr configSection,
+ CharPtr defService, Boolean hasResource)
+{
+ NI_HandPtr result;
+ SOCK sock;
+ Char srv_host[64];
+ Uint2 srv_port;
+ Uint4 conn_try;
+
+ /* get the server host name */
+ NI_GetEnvParam(configFile, configSection, ENV_DEBUG_HOST,
+ srv_host, sizeof(srv_host), "");
+ if ( !srv_host[0] ) {
+ ErrPostEx(SEV_ERROR, 0, 0, ENV_DEBUG_HOST ": undefined");
+ return 0;
+ }
+
+ {{ /* get the server port */
+ Char str[32];
+ int val;
+ NI_GetEnvParam(configFile, configSection, ENV_DEBUG_PORT,
+ str, sizeof(str), "");
+ val = atoi(str);
+ if (val <= 0) {
+ ErrPostEx(SEV_ERROR, 0, 0, ENV_DEBUG_PORT ": bad(%d) or undefined", val);
+ return 0;
+ }
+ srv_port = (Uint2)val;
+ }}
+
+ {{ /* alternate the max. number of attemts to establish a connection */
+ Char str[32];
+ int val;
+ NI_GetEnvParam(configFile, configSection, ENV_DEBUG_TRY,
+ str, sizeof(str), "");
+ val = atoi(str);
+ conn_try = (Uint4)((val > 0) ? val : DEF_DEBUG_TRY);
+ }}
+
+ /* establish connection to the server */
+ for (sock = 0; !sock && conn_try; conn_try--) {
+ if (SOCK_Create(srv_host, srv_port, &sock) != eSOCK_ESuccess) {
+ ErrPostEx(SEV_WARNING, 0, 1,
+ "[Debug NI Client] Cannot connect to host \"%s\", port %d;",
+ srv_host, (int)srv_port);
+ }
+ }
+ if ( !sock ) {
+ ErrPostEx(SEV_ERROR, 0, 1,
+ "[Debug NI Client] Failed to connect to host \"%s\", port %d;",
+ srv_host, (int)srv_port);
+ return 0;
+ }
+
+ /* open ASN i/o, etc. */
+ result = (NI_HandPtr)MemNew(sizeof(NI_Handle));
+ result->extra_proc_info = sock;
+ result->raip = AsnIoNew((ASNIO_BIN | ASNIO_IN), (FILE *)0,
+ (void *)sock, s_AsnRead, (IoFuncType)0);
+ result->waip = AsnIoNew((ASNIO_BIN | ASNIO_OUT), (FILE *)0,
+ (void *)sock, (IoFuncType)0, s_AsnWrite);
+
+ AsnIoSetErrorMsg(result->raip, s_AsnErrorFunc);
+ AsnIoSetErrorMsg(result->waip, s_AsnErrorFunc);
+ result->hostname = StringSave("");
+ result->disp = disp;
+ disp->referenceCount++;
+
+ return result;
+}
+
+
+static Int2 s_EndServices(NI_DispatcherPtr disp)
+{
+ ASSERT ( disp->referenceCount > 0 );
+ if (--disp->referenceCount == 0) {
+ MemFree(disp->adminInfo);
+ MemFree(disp->motd);
+ MemFree(disp);
+ }
+ return 0;
+}
+
+
+static Int2 s_ServiceDisconnect(NI_HandPtr mhp)
+{
+ s_EndServices(mhp->disp);
+ SOCK_Close((SOCK)mhp->extra_proc_info);
+ AsnIoClose(mhp->raip);
+ AsnIoClose(mhp->waip);
+ MemFree(mhp->hostname);
+ MemFree(mhp);
+ return 0;
+}
+
+
+/* Exported table of interface functions
+ */
+
+static const NIInterface s_NII_Debug = {
+ s_GenericInit,
+ s_SetDispatcher,
+ s_GenericGetService,
+ s_ServiceDisconnect,
+ s_EndServices
+};
+const NIInterface *g_NII_Debug = &s_NII_Debug;
+
+/* EOF */
diff --git a/network/nsclilib/ni_defin.h b/network/nsclilib/ni_defin.h
new file mode 100644
index 00000000..a165e885
--- /dev/null
+++ b/network/nsclilib/ni_defin.h
@@ -0,0 +1,388 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_defin.h
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 5/12/92 Epstein Converted tabs to spaces
+* 5/06/92 Epstein Added conditionally-compiled option for use with the
+* "purify" tool
+* 01-21-94 Schuler Added NETP_INET_MACTCP symbol
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_defin.h,v $
+* Revision 6.0 1997/08/25 18:38:29 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/08/13 13:37:15 epstein
+* remove stray semicolons from #defines
+*
+* Revision 5.1 1996/06/11 20:14:14 epstein
+* use O_NONBLOCK instead of O_NDELAY per a suggestion by Sergei Shavirin
+*
+ * Revision 5.0 1996/05/28 14:11:55 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.1 1995/12/18 21:58:06 epstein
+ * correction for SGI build
+ *
+ * Revision 4.0 1995/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.24 1995/05/17 17:51:56 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NI_DEFIN_
+#define _NI_DEFIN_
+
+#define STDIN 0
+#define STDOUT 1
+#define STDERR STDOUT + 1
+
+/* if the "purify" tool is in use, it will seize the file descriptor which */
+/* we had wanted; this is O.K., but the difference must be taken into account */
+/* here */
+#ifndef _PURIFY
+#define STDPIPE STDERR + 1
+#else
+#define STDPIPE STDERR + 2
+#endif
+
+#define NI_Handle MHandle /* for API use */
+#define NI_HandPtr MHandPtr /* for API use */
+#define NI_Request Request /* for API use */
+#define NI_ReqPtr ReqPtr /* for API use */
+
+#define ERRTEXT_BUFSIZ 512 /* size of supplied error text buffer */
+#define HOSTNAME_SIZ 64
+#define INETADDR_SIZ 16 /* of the form 255.255.255.255 */
+#define SVC_HOST_SIZ 64 /* size of addr or name of host */
+#define SVC_NAME_SIZ 64 /* size of name of service */
+#define RES_NAME_SIZ 64 /* size of name of resource */
+#define RESTYP_NAME_SIZ 64 /* size of type of resource */
+#define USERNAME_SIZ 64 /* kerberos principle */
+#define GROUPNAME_SIZ 64 /* kerberos instance */
+#define DOMAINNAME_SIZ 64 /* kerberos realm */
+#define PASSWORD_SIZ 32 /* must be encrypted */
+
+#define MATCHES_ANY_TYPE "*" /* string which matches any resource type */
+
+#define NI_LAST_RESERVED_PORT 1024 /* ports above this MAY be legal */
+
+#define NI_DEFAULT_TIMEOUT 60
+#define NI_SELECT_TIMEOUT 60
+#define NI_READ_TIMEOUT NI_DEFAULT_TIMEOUT
+#define NI_WRITE_TIMEOUT NI_DEFAULT_TIMEOUT
+
+#define PIPE_TOKEN "\003"
+#define PIPE_MSG_FMT "%d\003%s\003"
+
+#define READ_AIP raip
+#define WRITE_AIP waip
+
+#define NI_DEFAULT_DOMAIN "ncbi.nlm.nih.gov" /* default domain */
+#define NI_DEFAULT_HOST "dispatcher" /* default host for dispatcher */
+#define NI_DEFAULT_SERVICE "disp_port" /* default name of service (port) */
+#define NI_DFLT_SVC_PORT 5557 /* default port for service */
+
+#define NI_CLIENT_PORT_LO_NAME "ncbi_begin" /* beginning of client port range */
+#define NI_DFLT_CLILO_PORT 5601 /* default beginning of client port range */
+#define NI_CLIENT_PORT_HI_NAME "ncbi_end" /* end of client port range */
+#define NI_DFLT_CLIHI_PORT 32767 /* default end of client port range */
+
+
+/* instrumentation is enabled by default */
+#ifdef NI_NOSOCK_LOGGING
+#define LOG_SOCKET(x,y)
+#else
+#define LOG_SOCKET(x,y) NI_LogSocket(x,y,__FILE__,__LINE__)
+#endif /* NI_NOSOCK_LOGGING */
+
+
+#ifdef NETP_INET_WSOCK
+/* ** the following was extracted from <winsock.h> ** */
+/*
+ * Windows Sockets errors redefined as regular Berkeley error constants.
+ * These are commented out in Windows NT to avoid conflicts with errno.h.
+ * Use the WSA constants instead.
+ */
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#define EINPROGRESS WSAEINPROGRESS
+#define EALREADY WSAEALREADY
+#define ENOTSOCK WSAENOTSOCK
+#define EDESTADDRREQ WSAEDESTADDRREQ
+#define EMSGSIZE WSAEMSGSIZE
+#define EPROTOTYPE WSAEPROTOTYPE
+#define ENOPROTOOPT WSAENOPROTOOPT
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+#define EOPNOTSUPP WSAEOPNOTSUPP
+#define EPFNOSUPPORT WSAEPFNOSUPPORT
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define EADDRINUSE WSAEADDRINUSE
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#define ENETDOWN WSAENETDOWN
+#define ENETUNREACH WSAENETUNREACH
+#define ENETRESET WSAENETRESET
+#define ECONNABORTED WSAECONNABORTED
+#define ECONNRESET WSAECONNRESET
+#define ENOBUFS WSAENOBUFS
+#define EISCONN WSAEISCONN
+#define ENOTCONN WSAENOTCONN
+#define ESHUTDOWN WSAESHUTDOWN
+#define ETOOMANYREFS WSAETOOMANYREFS
+#define ETIMEDOUT WSAETIMEDOUT
+#define ECONNREFUSED WSAECONNREFUSED
+#define ELOOP WSAELOOP
+//#define ENAMETOOLONG WSAENAMETOOLONG
+#define EHOSTDOWN WSAEHOSTDOWN
+#define EHOSTUNREACH WSAEHOSTUNREACH
+//#define ENOTEMPTY WSAENOTEMPTY
+#define EPROCLIM WSAEPROCLIM
+#define EUSERS WSAEUSERS
+#define EDQUOT WSAEDQUOT
+#define ESTALE WSAESTALE
+#define EREMOTE WSAEREMOTE
+#endif /* NETP_INET_WSOCK */
+
+
+/* MACROS */
+
+/* BLOCKSIG, UNBLOCKSIG, and BZERO are for dispatcher and ncbid only */
+#if defined(OS_UNIX_SYSV) && !defined(BSD_COMPAT)
+/* for System V we cheat and use the caller's "mask" variable to store */
+/* the signal; note that these macros won't work if dealing with more than */
+/* one signal */
+#define NI_BLOCKSIG(_sig, _mask) { _mask = _sig; sighold(_sig); }
+#define NI_UNBLOCKSIG(_sig) sigrelse(_sig)
+#define NI_BZERO(buf, bufsize) Nlm_MemFill(buf, 0, bufsize)
+#else
+#define NI_BLOCKSIG(_sig, _mask) _mask = sigblock(sigmask(_sig))
+#define NI_UNBLOCKSIG(_mask) sigsetmask(_mask)
+#define NI_BZERO(buf, bufsize) bzero(buf, bufsize)
+#endif
+
+
+#ifdef NETP_INET_NEWT
+#define NI_READSOCKET(rsok, rbuf, rlen) recv(rsok, rbuf, rlen, 0)
+#define NI_WRITESOCKET(wsok, wbuf, wlen) send(wsok, wbuf, wlen, 0)
+#define NI_CLOSESOCKET(sok) close_socket(sok)
+#define NI_select(s, r, w, x, t) NI_poll_select(s, r, w, x, t)
+#define NI_SETBLOCKING(fd) ioctl(fd, FIONBIO, "1")
+#define NI_SETNONBLOCKING(fd) ioctl(fd, FIONBIO, "0")
+#endif /* NETP_INET_NEWT */
+
+#ifdef NETP_INET_PCNFS
+#define NI_READSOCKET(rsok, rbuf, rlen) recv(rsok, rbuf, rlen, 0)
+#define NI_WRITESOCKET(wsok, wbuf, wlen) send(wsok, wbuf, wlen, 0)
+#define NI_CLOSESOCKET(sok) close(sok)
+#define NI_select(s, r, w, x, t) select(s, r, w, x, t)
+#define NI_SETBLOCKING(fd) NI_SetBlocking (fd)
+#define NI_SETNONBLOCKING(fd) NI_SetNonBlocking (fd)
+#define NI_BLOCK_WITH_FUNCTION
+#endif /* NETP_INET_PCNFS */
+
+/* Windows Sockets */
+#ifdef NETP_INET_WSOCK
+#define NI_READSOCKET(rsok, rbuf, rlen) recv(rsok, rbuf, rlen, 0)
+#define NI_WRITESOCKET(wsok, wbuf, wlen) send(wsok, wbuf, wlen, 0)
+#define NI_CLOSESOCKET(sok) closesocket(sok)
+#define NI_select(s, r, w, x, t) NI_poll_select(s, r, w, x, t)
+#define NI_SETBLOCKING(fd) NI_SetBlocking (fd)
+#define NI_SETNONBLOCKING(fd) NI_SetNonBlocking (fd)
+#define errno WSAGetLastError()
+#define _INVALID_SOCKET_DEFINED_
+#define NI_BLOCK_WITH_FUNCTION
+#define SOCK_INDEX_ERRNO ((errno <= WSABASEERR || errno >= sys_nerr + WSABASEERR) ? 0 : (errno - WSABASEERR))
+#endif /* NETP_INET_WINSOCK */
+
+/* TGV's Multinet TCP/IP suite for OpenVMS */
+#ifdef NETP_INET_TGV
+#define NI_READSOCKET(rsok, rbuf, rlen) recv(rsok, rbuf, rlen, 0)
+#define NI_WRITESOCKET(wsok, wbuf, wlen) send(wsok, wbuf, wlen, 0)
+#define NI_CLOSESOCKET(sok) socket_close(sok)
+#define NI_select(s, r, w, x, t) select(s, r, w, x, t)
+#define NI_SETBLOCKING(fd) NI_SetBlocking (fd)
+#define NI_SETNONBLOCKING(fd) NI_SetNonBlocking (fd)
+#define NI_BLOCK_WITH_FUNCTION
+#define SOCK_ERRNO socket_errno
+#endif
+
+/* Wollongong TCP/IP suite for OpenVMS */
+#ifdef NETP_INET_TWG
+#define NI_READSOCKET(rsok, rbuf, rlen) recv(rsok, rbuf, rlen, 0)
+#define NI_WRITESOCKET(wsok, wbuf, wlen) send(wsok, wbuf, wlen, 0)
+#define NI_CLOSESOCKET(sok) netclose(sok)
+#define NI_select(s, r, w, x, t) select(s, r, w, x, t)
+#define NI_SETBLOCKING(fd) NI_SetBlocking (fd)
+#define NI_SETNONBLOCKING(fd) NI_SetNonBlocking (fd)
+#define NI_BLOCK_WITH_FUNCTION
+/* from UCX */
+#define FD_SETSIZE 32
+#define fd_set int
+#define FD_SET(n, p) *(p) |= 1 << (n)
+#define FD_CLR(n,p) *(p) &= ~(1 << (n))
+#define FD_ISSET(n,p) ((*p) & (1 << (n)))
+#define FD_ZERO(p) *(p) = 0
+#endif
+
+/* Wollongong PathWay API 1.0 suite for OpenVMS */
+#ifdef NETP_INET_WPW
+#define NI_READSOCKET(rsok, rbuf, rlen) recv(rsok, rbuf, rlen, 0)
+#define NI_WRITESOCKET(wsok, wbuf, wlen) send(wsok, wbuf, wlen, 0)
+#define NI_CLOSESOCKET(sok) netclose(sok)
+#define NI_select(s, r, w, x, t) select(s, r, w, x, t)
+#define NI_SETBLOCKING(fd) NI_SetBlocking (fd)
+#define NI_SETNONBLOCKING(fd) NI_SetNonBlocking (fd)
+#define NI_BLOCK_WITH_FUNCTION
+#endif
+
+/* DEC TCP/IP for OpenVMS (UCX) */
+#ifdef NETP_INET_UCX
+#define NI_READSOCKET(rsok, rbuf, rlen) recv(rsok, rbuf, rlen, 0)
+#define NI_WRITESOCKET(wsok, wbuf, wlen) send(wsok, wbuf, wlen, 0)
+#define NI_CLOSESOCKET(sok) close(sok)
+#define NI_select(s, r, w, x, t) select(s, r, w, x, t)
+#define NI_SETBLOCKING(fd) NI_SetBlocking (fd)
+#define NI_SETNONBLOCKING(fd) NI_SetNonBlocking (fd)
+#define NI_BLOCK_WITH_FUNCTION
+#define FD_SETSIZE 32
+#define fd_set int
+#define FD_SET(n, p) *(p) |= 1 << (n)
+#define FD_CLR(n,p) *(p) &= ~(1 << (n))
+#define FD_ISSET(n,p) ((*p) & (1 << (n)))
+#define FD_ZERO(p) *(p) = 0
+#endif
+
+
+/* Macintosh */
+#if defined(OS_MAC) && !defined(NETP_defined)
+#define NETP_INET_MACTCP
+#endif
+
+#ifdef NETP_INET_MACTCP
+#define NI_READSOCKET(rsok, rbuf, rlen) read(rsok, rbuf, rlen)
+#define NI_WRITESOCKET(wsok, wbuf, wlen) write(wsok, wbuf, wlen)
+#define NI_CLOSESOCKET(sok) close(sok)
+#define NI_select(s, r, w, x, t) select(s, r, w, x, t)
+#define NI_SETBLOCKING(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY) /* set blocking */
+#define NI_SETNONBLOCKING(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NDELAY) /* set nonblocking */
+
+/* The errno_long mechanism is used for interoperability between the */
+/* network services library and the NCSA socket library, which need not have */
+/* been compiled with the same integer size (2 byte vs. 4 byte) */
+#define SOCK_ERRNO errno_long
+#endif /* NETP_INET_MACTCP */
+
+
+#ifndef NI_READSOCKET /* for now, fall back on UNIX as default */
+#define NI_READSOCKET(rsok, rbuf, rlen) read(rsok, rbuf, rlen)
+#define NI_WRITESOCKET(wsok, wbuf, wlen) write(wsok, wbuf, wlen)
+#define NI_CLOSESOCKET(sok) close(sok)
+#define NI_select(s, r, w, x, t) select(s, r, w, x, t)
+
+#ifdef OS_UNIX_BSD
+#define NI_SETBLOCKING(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~FNDELAY) /* set blocking */
+#define NI_SETNONBLOCKING(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | FNDELAY) /* set nonblocking */
+#else
+#define NI_SETBLOCKING(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK) /* set blocking */
+#define NI_SETNONBLOCKING(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) /* set nonblocking */
+#endif /* OS_UNIX_BSD */
+
+#endif /* NI_READSOCKET */
+
+/* MSDOS */
+
+#ifdef COMP_MSC
+#ifndef NETP_INET_MACTCP
+#ifdef FD_SETSIZE
+#undef FD_SETSIZE
+#endif
+#define FD_SETSIZE 32
+#include <io.h>
+
+#ifndef NETP_INET_NEWT
+#ifndef NETP_INET_PCNFS
+#ifndef NETP_INET_WSOCK
+/* copied from Sun version of this file 6-11-91 and modified */
+#define NFDBITS 32
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) MemFill((char *)(p), '\0', sizeof(*(p)))
+#endif
+#endif
+#endif
+
+#endif /* NETP_INET_MACTCP */
+#endif /* COMP_MSC */
+
+#ifndef SOCK_ERRNO
+#define SOCK_ERRNO errno
+#endif /* SOCK_ERRNO */
+
+#ifndef SOCK_INDEX_ERRNO
+#define SOCK_INDEX_ERRNO SOCK_ERRNO
+#endif /* SOCK_INDEX_ERRNO */
+
+#ifndef _INVALID_SOCKET_DEFINED_
+#define INVALID_SOCKET -1
+#endif /* INVALID_SOCKET */
+
+#ifdef NETP_SOCKS
+#define NI_ACCEPT(sok,addr,addrlen) Raccept(sok,addr,addrlen)
+#define NI_BIND(sok,name,namelen,bindaddr) Rbind(sok,name,namelen,bindaddr)
+#define NI_CONNECT(sok,name,namelen) Rconnect(sok,name,namelen)
+#define NI_GETSOCKNAME(sok,name,namelen) Rgetsockname(sok,name,namelen)
+#define NI_LISTEN(sok,backlog) Rlisten(sok,backlog)
+#else
+#define NI_ACCEPT(sok,addr,addrlen) accept(sok,addr,addrlen)
+#define NI_BIND(sok,name,namelen,bindaddr) bind(sok,name,namelen)
+#define NI_CONNECT(sok,name,namelen) connect(sok,name,namelen)
+#define NI_GETSOCKNAME(sok,name,namelen) getsockname(sok,name,namelen)
+#define NI_LISTEN(sok,backlog) listen(sok,backlog)
+#endif
+
+
+#endif /* _NI_DEFIN_ */
+
+
diff --git a/network/nsclilib/ni_disp.c b/network/nsclilib/ni_disp.c
new file mode 100644
index 00000000..eb1e09b0
--- /dev/null
+++ b/network/nsclilib/ni_disp.c
@@ -0,0 +1,3838 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_disp.c (originally -- "ni_lib.c")
+*
+* Author: Beatty, Gish, Epstein, Vakatov
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 4.4 $
+*
+* File Description:
+* This file is a library of functions to be used by server application
+* and client software, using the NCBI "network services" paradigm.
+* It was slightly redesigned in order to fit the new "multiple NCBI
+* protocols" paradigm
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 4/27/92 Epstein Added extensive in-line commentary, and removed all tabs.
+* 5/11/92 Epstein Removed unused function NI_SVCRequestGet(); added support
+* for the connection ID to be written to a CONID file each
+* time that the value of conid is updated; in practice,
+* only dispatcher will update a CONID file.
+* 6/22/92 Epstein For UNIX signals, catch the SIGPIPE error which can
+* occur when writing to a socket which is no longer
+* connected.
+* 7/06/92 Epstein Changed sokselectw() to examine the SO_ERROR socket option
+* after select()-ing a socket to which we were attempting a
+* connection. This eliminates "false connects", i.e.,
+* unsuccessful connection attempts which look successful
+* because the select() call returns 1.
+* 7/14/92 Epstein Changed NI_SetDispatcher() and NI_InitServices() to use
+* a configurable timeout parameter, and in the process
+* also changed sokselectw() to have a timeout parameter,
+* 1/21/93 Epstein Add dispatcher-list support, and add dispatcher-list
+* parameter to NI_InitServices().
+* 2/12/93 Epstein Use new boolean parameter to MsgMakeHandle(), indicating
+* whether or not it should create a socket. This was
+* an attempted fix for a Mac problem ... it later
+* turned out to be an incorrect problem-fix, but also
+* does no harm.
+* 2/24/93 Epstein Fix long-standing Mac bug, by correctly destroying
+* services handle and hence closing an open socket.
+* 3/02/93 Epstein Add functions to write dispatcher-configuration info
+* to a config file. This provides a standardized
+* mechanisms which applications may use for net services
+* configuration. Also added platform functions, so
+* that dispatcher/server complex can know what type
+* of platform a client is running on, assuming that the
+* client is telling the truth.
+* 3/03/93 Epstein Cleanup variable initialization.
+* 3/08/93 Epstein Improve error messages & cleanup to NI_InitServices,
+* include reason in login failure message, and add
+* client platform to service request.
+* 3/09/93 Epstein Add HaltServices() function to simplify cleanup.
+* 3/22/93 Epstein Fix typecast for getsockopt(), and, more importantly,
+* remember to return the computed value in NI_GetPlatform.
+* 3/23/93 Epstein Support VMS/TGV, and add NETP_INET_ prefixes to
+* conditional-compilation symbols.
+* 3/24/93 Epstein Clear the caller's pointer in NI_SetDispConfig().
+* 3/31/93 Epstein Add dispatcher pointer as context for all network
+* services operations; this allows an application
+* to use more than one dispatcher at a time, at the
+* expense of slightly greater complexity. Also add
+* a "Generic Init" function, which can be used by
+* an application to obtain network-services in a
+* simplified, standardized manner.
+* 3/31/93 Epstein Move debug and module variables to their correct home.
+* 4/02/93 Epstein Add WinSock support.
+* 4/12/93 Schuler Add MAKEWORD macro.
+* 4/21/93 Schuler Removed function prototypes for NI_AsnRead, NI_AsnWrite
+* 5/07/93 Epstein Move WSAStartup() code to a better place, add workaround
+* for connection attempt on a non-blocking socket in PC-NFS
+* 4.0, add more platform definitions.
+* 5/24/93 Epstein Add separate error codes for TCP/IP initialization
+* failure and inability to resolve local host name.
+* 5/25/93 Epstein Add configuration-file workaround for PC-NFS 5.0 bug,
+* where NIS sometimes fails on the PC's own host name.
+* 5/27/93 Epstein Incorporate pragmatic "Gestalt" code for Vibrant
+* scrolling workaround for WinSock under Windows 3.1,
+* add add SOCK_INDEX_ERRNO macro to workaround another
+* WinSock pecularity.
+* 6/02/93 Schuler Change "Handle" to "MonitorPtr" for Monitors.
+* 6/07/93 Epstein Added generic timer functions.
+* Also add missing revision history, derived from
+* RCS file.
+* 6/09/93 Epstein Added activity hook to report network activity back
+* to an application.
+* 6/14/93 Epstein Changed "Generic" logic to cause UNIX/VMS loginname
+* to override loginname, rather than vice versa. Also
+* setup DispatchConnect() logic to set client's declared
+* IP address to 0.0.0.0, rather than causing an error,
+* in the case where the client cannot resolve its own
+* host name. In this case, the dispatcher will set its
+* own opinion of the client address based upon
+* getpeername().
+* 6/15/93 Epstein Eliminate "Gestalt" code for Vibrant scrolling
+* workaround for WinSock under Windows 3.1, since the
+* solution for this problem does not require its use.
+* 6/25/93 Epstein Fix activity-hook action for service disconnection (had
+* erroneously announced dispatcher-disconnection), and
+* add logic to try to avoid getservbyname() by looking
+* up dispatcher port # and (loport,hiport) in NCBI
+* configuration file instead of in NIS. As a last resort,
+* look up the name in NIS if the entry in the NCBI
+* config. file is non-numeric. Also, change the client
+* port lookup mechanism for Macintoshes to add a configured
+* "delta" value to the low port number. This results in
+* allowing several Network Services applications to run
+* concurrently on a Mac without port conflicts.
+* 7/08/93 Epstein Fix list traversal error in NI_ProcessTimers()
+* 7/08/93 Epstein Added a counter as a failsafe mechanism in
+* NI_ProcessTimers(), since previous fix attempt failed.
+* 7/09/93 Epstein Changed a few #define names to avoid Alpha compilation
+* warnings, and added reference count to dispatcher data
+* structure.
+* 8/09/93 Epstein Improve diagnostics when a listen() call fails
+* 8/23/93 Epstein Add currentDisp variable so that the currently-attached
+* dispatcher is used when the parameter to NI_SetDispatcher
+* is NULL.
+* 8/31/93 Epstein Fix host vs. network order when comparing port numbers.
+* 9/08/93 Epstein Added new stackDescription variable, to be able to
+* report to the dispatcher the identity of the vendor
+* of the WinSock stack
+* 9/09/93 Epstein Fix use of currentDisp variable to correctly compare
+* new dispatcher request again current dispatcher.
+*11/24/93 Epstein Added code to support standalone servers and clients
+* which communicate with standalone servers or "service
+* brokers", which listen on a specific port (to be
+* augmented later).
+*11/30/93 Epstein Made standalone server code UNIX-only, to avoid
+* possible compilation errors on other platforms. However,
+* it should be possible in principle to run and test a
+* standalone server on a non-UNIX host. Also, added
+* limited security to standalone servers.
+*12/08/93 Epstein Fixed service connection activity hook, per discussion
+* with Kyle Hart.
+*01/19/94 Schuler Post error (SEV_INFO) on WinSock initialization
+* failure showing WinSock's error code.
+*01/28/94 Schuler Replace "NETP_INET_MACTCP" with "NETP_INET_MACTCP"
+*01/28/94 Schuler Defined THIS_MODULE and THIS_FILE
+*02/14/94 Epstein Add preliminary RSAREF encryption support
+*02/22/94 Epstein Add DISP_RECONN_ACTION logic to allow users to breakout
+* or quit if unable to contact primary dispatcher.
+*02/24/94 Epstein Make use of new NI_DupPubKey function, and insert
+* newlines in macros to make editing easier.
+*03/03/94 Epstein Reduce memory leaks, suppress non-printing characters
+* in winsock.dll.
+*04/22/94 Epstein Change error handling to use SEV_ERROR and SEV_WARNING
+* (ErrPostEx). Also do a better job of detecting
+* inability to connect to dispatcher in DispatchConnect(),
+* because under Solaris getsockopt() doesn't correctly
+* detect an error.
+*04/25/94 Epstein Cosmetic change for error when NACK received from
+* Dispatcher.
+*05/04/94 Epstein Add logic to allow a mixture of encrypted and
+* unencrypted services, determined by ENCRYPTION=FALSE
+* fields in the appropriate sections in the config.
+* files.
+*06/08/94 Epstein Add SOCKS support (probably not correct yet) by
+* asking Dispatcher to provide a SVC_PRE_RESPONSE message
+* which contains the server's IP address.
+*06/10/94 Epstein More SOCKS refinement, plus added tracing for SOCKS
+*06/15/94 Epstein Produce working SOCKS version, by changing the protocol
+* so that a SOCKSified client uses two service request
+* messages; one to learn the IP address of the server
+* to which it will be assigned, and the second "real"
+* service request after it has bound the 'listen' port
+* on the SOCKS daemon.
+*07/01/94 Epstein Determine at runtime whether or not to use SOCKS,
+* methodology, based upon presence or absence of
+* SOCKS_CONF file.
+*07/07/94 Epstein Updated commentary.
+*09/22/94 Epstein Improved standalone server code by using SO_REUSEADDR
+* option, making it possible for identical servers to
+* run consecutively without waiting for sockets to
+* shutdown.
+*12/02/94 Epstein Changed NI_GenericGetService() to have environment
+* variables override configuration file for SERVICE_NAME
+* and RESOURCE_TYPE. This is mostly just a convenience
+* for internal NCBI use, allowing the use of a single
+* config. file while using scripts to force the use
+* of a different service.
+*12/06/94 Epstein Added connectDelay, adminInfo and motd fields.
+* The client reports the time which it took to
+* establish a connection in their connectDelay field.
+* The Dispatcher provides the name of the Network
+* administrator and a secondary message-of-the-day in
+* the other two fields.
+*12/21/94 Epstein Added instrumentation for socket management
+*01/11/95 Epstein Change socket instrumentation to suppress some
+* errors for WinSock 1.1.
+*01/13/95 Epstein Add new GetLAPType() function to report Mac clients'
+* TCP/IP implementation ("Ethernet", "PPP", etc.) to
+* the Dispatcher.
+*03/20/95 Epstein Fix InitServices/EndServices logic to correctly only
+* establish a single Dispatcher connection for multiple
+* services.
+*03/29/95 Epstein Reduce calls to Message() in favor of ErrPostEx().
+*06/02/95 Epstein Fix bindPort() to address host/network byte ordering;
+* this should correct a byte-ordering problem on little-
+* endian hosts which use SOCKS.
+*06/06/95 Epstein For UNIX, try to get the user's name from the USER
+* environment variable before inquiring getlogin();
+* this can save CPU time and contention on some systems,
+* since access to utmp can be slow.
+*06/12/95 Epstein Another byte-ordering fix for SOCKS for the SOCKS
+* proxy's port number.
+*10/19/95 Epstein Bug fix to accomodate logic correct in Nlm_StringCmp()
+*
+*11/15/95 Shavirin Added new ability of clients to get direct connection
+* to the server.
+* Created new function: NI_DirectServiceRequest to connect
+ to the server directly and to send SVC_REQUEST
+* Added new parameter in configuration file - DIRECT_SVC_CON
+* This parameter updates new field in dispatcher stucture:
+* disp->useOutServ. If this parameter set to FALSE - old style
+* communication will be used. TRUE is set for direct
+* connection.
+* To handle direct connection protocol of the service request
+* function was changed. In the case of old style everything
+* remained the same (except reconnect switch option - to
+* try direct connection if old style failed - currently disabled)
+* In the case when disp->useOutServ is set client sends
+* service request with field svcreq->want_ticket = TRUE.
+* Dispatcher will sent back SVC_REQUEST with the prepared ticket
+* or NACK in the case of error. Client will send SVC_REQUEST
+* directly to the server and will wait until SVC_RESPONCE or
+* NACK will be received from the dispatcher. After SVC_RESPONCE
+* received communication transfers to the upper layers.
+*01/17/96 Epstein Add protection for DIRECT_SVC_CON mode; this comes into
+* play with Mac OpenTransport (OT)
+*02/02/96 Epstein Add PROXY_SERV_OVERRIDE GetAppParam() flag for
+* DIRECT_SVC_CON mode. This makes it easier for a
+* machine behind a firewall to get through the firewall,
+* although it assumes a priori knowledge of the IP
+* address of the server, and the port numbers on the
+* server.
+*02/21/96 Epstein Fix brokered-services for little-endian clients
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_disp.c,v $
+* Revision 4.4 1998/03/30 17:50:15 vakatov
+* Ingrafted to the main NCBI CVS tree
+*
+* Revision 4.3 1998/03/30 17:17:03 vakatov
+* Renamed from "ni_lib.c" to "ni_disp.c"
+*
+* Revision 4.2 1998/03/25 17:41:02 vakatov
+* Fix for the "gethostname()" proto under Solaris
+*
+* Revision 6.6 1998/03/17 18:55:42 shavirin
+* Rolling back to version 6.3
+*
+* Revision 6.3 1997/11/18 21:14:42 epstein
+* identify Linux Alpha client
+*
+* Revision 6.2 1997/10/06 21:21:50 shavirin
+* Fixed memory leak and uninitiolized memory read errors
+*
+* Revision 6.1 1997/09/11 18:08:24 epstein
+* add output of uname -a to Unix clients' self-identifying string
+*
+* Revision 5.5 1997/07/01 19:12:49 vakatov
+* [WIN32] DLL'd "netcli.lib"
+*
+* Revision 5.4 1997/06/17 18:52:17 epstein
+* fix numerous memory problems associated with timers
+*
+* Revision 5.3 1997/04/24 12:53:33 ostell
+* fixed typo in call to AsnTypeStringToHex
+*
+* Revision 5.2 1997/04/24 12:44:36 ostell
+* changed calls to AsnTypeStringToHex to match new arguments and returns
+*
+* Revision 5.1 1996/10/02 18:18:20 epstein
+* add function NI_FqdnToIpaddr() to simplify layering of netcnfg.c
+*
+* Revision 4.15 1996/05/22 15:12:54 epstein
+* adopt more reasonable semantics for brokered services: by default, only first service is brokered
+*
+* Revision 4.14 1996/04/29 15:29:19 epstein
+* add disp to NI_HandPtr so that service-handle can encapsulate greater context
+*
+* Revision 4.13 1996/02/21 15:50:07 epstein
+* Fix brokered-services for little-endian clients
+*
+* Revision 4.12 1996/02/02 14:53:41 epstein
+* add PROXY_SERV_OVERRIDE setting for DIRECT_SVC_CON mode
+*
+* Revision 4.11 1996/01/17 20:33:09 epstein
+* Add protection for DIRECT_SVC_CON mode; this comes into play with Mac OpenTransport
+*
+* Revision 4.10 1995/12/21 19:55:47 epstein
+* make socket non-blocking for brokered services
+*
+* Revision 4.9 1995/11/30 19:58:08 epstein
+* make NI_DirectServiceRequest() function static
+*
+* Revision 4.8 1995/11/29 17:50:24 epstein
+* fix byte-ordering for direct-service connection
+*
+* Revision 4.7 1995/11/28 21:39:06 epstein
+* remove unneeded sleep() call from non-UNIX platforms
+*
+* Revision 4.6 1995/11/28 20:18:41 epstein
+* fix leaky-socket problem for non-direct-connection services
+*
+* Revision 4.5 1995/11/27 20:59:17 epstein
+* add client support for direct-connection services
+*
+* Revision 4.2 95/10/19 20:29:06 epstein
+* Bug fix to accomodate logic correct in Nlm_StringCmp()
+*
+* Revision 4.1 1995/08/01 13:48:33 epstein
+* remember to initialize someBrokered
+*
+* Revision 1.74 1995/07/12 14:53:28 epstein
+* Another byte-ordering fix for SOCKS
+*
+* Revision 1.73 1995/06/06 10:04:52 epstein
+* use USER environment variable in lieu of getlogin()
+*
+* Revision 1.72 95/06/02 16:58:43 epstein
+* fix bindPort() using htonl() to correct byte-ordering problem on little-endian clients which use SOCKS
+*/
+
+#define _NCBINET_LOCAL_VARS
+#define THIS_MODULE g_nsclient_module
+#define THIS_FILE _this_file
+#define __NI_LIB__
+#include "ncbinet.h"
+#include "ni_lib.h"
+#include "ni_msg.h"
+
+/* missing prototypes */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* patch to old SunOS/Solaris proto(cut&paste from Solaris 2.6 "unistd.h") */
+#if defined(OS_UNIX_SOL) || defined(OS_UNIX_SUN)
+#if defined(_XPG4_2)
+ extern int gethostname(char *, size_t);
+#elif defined(__EXTENSIONS__) || \
+ (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE))
+ extern int gethostname(char *, int);
+#endif
+#endif
+
+#ifdef OS_UNIX
+ extern char *getlogin(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+char * g_nsclient_module = "nsclient";
+static char *_this_file = __FILE__;
+
+
+#define ERR_KEY_MISMATCH "The public encryption key received from the dispatcher does\n\
+not match what is on file. There is a slight security risk\n\
+that this key is being presented by a \"spoofer\" rather than\n\
+the real dispatcher. You may wish to contact the NCBI by\n\
+other means to determine whether this new key is valid. Do\n\
+you wish to accept this as the new key and continue?"
+#define ERR_KEY_NOPREVKEY "A public encryption key was just received from the dispatcher,\n\
+but no key is currently on file. There is a slight security\n\
+risk that this key is being presented by a \"spoofer\" rather\n\
+than the real dispatcher. You may wish to contact the NCBI by\n\
+other means to determine whether this new key is valid. Do\n\
+you wish to accept this as the new key and continue?"
+
+#ifdef NETP_INET_NEWT
+
+#define SIN_ADDR sin_addr.S_un.S_addr
+#define H_ADDR_TYPE Uint4Ptr
+#else
+#define SIN_ADDR sin_addr
+#define H_ADDR_TYPE struct in_addr *
+#endif
+
+#ifdef WIN16
+#ifndef MAKEWORD
+#define MAKEWORD(a,b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) <<8))
+#endif
+#endif
+
+#define NULL_TIMER 0
+
+
+typedef struct NI_Timer {
+ time_t timeout;
+ NI_TimeoutHook hook;
+ Pointer hookParam;
+} NI_Timer, PNTR NI_TimerPtr;
+
+
+/* GLOBALS */
+static FILE *conid_fp = NULL; /* File pointer for CONID */
+static NodePtr timerHead = NULL; /* list of timers */
+static NI_NetServHook activityHook = NULL;
+static NI_DispatcherPtr currentDisp = NULL;
+static CharPtr stackDescription = NULL;
+static fd_set openfds;
+
+
+#ifdef NETP_INET_WSOCK
+static Int4 wsaStartupCount = 0;
+#endif
+
+NILoginPtr NI_MakeMsgLogin PROTO((void));
+
+static Int2 s_EndServices(NI_DispatcherPtr disp);
+static Int2 SetIdentity PROTO((NI_DispatcherPtr disp, CharPtr user, CharPtr group, CharPtr domain));
+static void HaltServices PROTO((NI_DispatcherPtr disp));
+static NI_HandPtr DispatchConnect PROTO((NI_DispatcherPtr disp, CharPtr host, CharPtr name, int timeout));
+static Uint2 bindPort PROTO((int sok, struct sockaddr_in PNTR sokadr, Int2 loport, Int2 hiport, Uint4 remoteHost));
+static Int2 CopyIdentity PROTO((NI_DispatcherPtr disp, NI_UidPtr uid));
+static NI_HandPtr NI_DirectServiceRequest PROTO((NIMsgPtr imp, NI_HandPtr sconnhp));
+
+
+int sokselectr PROTO((int fd));
+int sokselectw PROTO((int fd, int timeout));
+
+int getAsnError PROTO((char * str));
+void SetConFilePtr PROTO((FILE *fp));
+void CloseConFile PROTO((void));
+
+
+
+/*
+ * Purpose: Specify which dispatcher a client should try to connect to
+ *
+ * Parameters:
+ * disp Usually NULL, the pointer to a pre-existing Dispatcher
+ * structure
+ * host Name of the host (Fully Qualified Domain Name) to use
+ * svc Name of the "service" to try to use on that host
+ * dispserialnum Serial number of dispatcher-list. Use -1 if no response
+ * list is desired, or 0 if the serial number is not known.
+ *
+ *
+ * Description:
+ * Set up the dispatcher name which should be used, and the
+ * name of the service on that dispatcher. If other parameters
+ * have been specified previously, free the memory associated
+ * with those names.
+ *
+ * Note:
+ * There are useful defaults for "svc". When in doubt, call
+ * this function with a second arguement of NULL.
+ */
+
+static NI_DispatcherPtr s_SetDispatcher
+(NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
+ Int4 dispserialnum, ValNodePtr encryption, Boolean useOutServ)
+{
+ if (disp == NULL) {
+ if (currentDisp != NULL && !currentDisp->someBrokered)
+ { /* use current dispatcher if it matches what the caller wants */
+ if ((svc == NULL ||
+ StringCmp(svc, currentDisp->dispServiceName) == 0 ) &&
+ StringCmp(host, currentDisp->dispHostName) == 0) {
+ return currentDisp;
+ }
+ }
+
+ disp = (NI_DispatcherPtr) MemNew(sizeof(NI_Dispatcher));
+ if (disp == NULL)
+ return NULL;
+ disp->useOutServ = useOutServ; /* value from configfile */
+ disp->reqResponse = NULL;
+ disp->dispHostName = NULL;
+ disp->dispServiceName = NULL;
+ disp->dispSerialNo = 0;
+ disp->localHostAddr[0] = '\0';
+ disp->dispHP = NULL;
+ disp->svcsHP = NULL;
+ disp->clientPort = 0;
+ disp->identity = NULL;
+ disp->dispTimeout = 0;
+ disp->referenceCount = 0;
+ disp->someBrokered = FALSE;
+ disp->brokeredDummy = FALSE;
+ disp->encryptInfo = encryption;
+ disp->useSocks = FALSE;
+#ifdef SOCKS_CONF
+ {
+ FILE *fp;
+
+ if ((fp = FileOpen(SOCKS_CONF, "r")) != NULL)
+ {
+ disp->useSocks = TRUE;
+ FileClose(fp);
+ }
+ }
+#endif /* SOCKS_CONF */
+ }
+ if (disp->dispHostName != NULL) {
+ MemFree(disp->dispHostName);
+ disp->dispHostName = NULL;
+ }
+ if (disp->dispServiceName != NULL) {
+ MemFree(disp->dispServiceName);
+ disp->dispServiceName = NULL;
+ }
+ if (host != NULL)
+ disp->dispHostName = StringSave(host);
+ if (svc != NULL)
+ disp->dispServiceName = StringSave(svc);
+
+ disp->dispSerialNo = dispserialnum;
+ disp->dispTimeout = timeout;
+
+ return disp;
+} /* NI_SetDispatcher */
+
+
+/*
+ * Purpose: Try to establish a connection to the dispatcher
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * user User name to try on the dispatcher
+ * group Group name to try on the dispatcher
+ * password Password for this user name
+ * dip A pointer to the caller's list of dispatchers; this should
+ * be used by the caller to update its information
+ * regarding which dispatchers to try in the future
+ * (if dip == NULL, then no retries will be made to get
+ * alternate dispatchers)
+ *
+ * Returns:
+ * -1, if something failed (ni_errno indicates the nature of
+ * the problem)
+ * 0, if everything was successful
+ * 1, if we are connected to the dispatcher which we requested,
+ * but the list of current dispatchers has changed
+ * 2, if we are connected to a dispatcher, but not the one
+ * which we requested
+ *
+ *
+ * Description:
+ * Perform any WinSock and/or SOCKS initialization as necessary
+ * Connect to the dispatcher
+ * Set-up a socket for an incoming connection from a server
+ * application process (non-SOCKS clients only)
+ * Send a LOGIN message to the dispatcher
+ * Wait for an ACK or NACK response from the dispatcher (or for
+ * a timeout to occur)
+ * If the response was a NACK due to the dispatcher being a
+ * backup dispatcher, then try the dispatcher which it
+ * directs us to
+ */
+
+NLM_EXTERN Int2 NI_InitServices(NI_DispatcherPtr disp, CharPtr user, CharPtr group, CharPtr password, NI_DispInfoPtr PNTR dip)
+{
+ NIMsgPtr mp, imp;
+ NILoginPtr loginp;
+ struct sockaddr_in svcsAddr;
+ struct timeval timeout;
+ int ready;
+ NIDispInfoPtr dispinfo = NULL;
+ Boolean newDispToTry;
+ Int2 altDispTries = 0;
+ Int2 retval = 0;
+ int status;
+ fd_set readfds;
+ NI_PubKeyPtr pubKey = NULL;
+ Boolean failed;
+#ifdef NETP_INET_WSOCK
+ WSADATA wsaData;
+#endif /* NETP_INET_WSOCK */
+#if defined(OS_MAC) && defined(NETP_INET_MACTCP)
+ extern char * GetLAPType(void);
+ char *lapType = GetLAPType();
+#endif /* OS_MAC && NETP_INET_MACTCP */
+
+ if (disp == NULL)
+ {
+ ni_errno = NIE_MISC;
+ return -1;
+ }
+
+ if (disp->referenceCount > 0 && disp->dispHP != NULL)
+ { /* already connected */
+ disp->referenceCount++;
+ return 0;
+ }
+
+#ifdef NETP_INET_WSOCK
+ status = WSAStartup(MAKEWORD(1,1),&wsaData);
+ if (status != 0)
+ ErrPostEx(SEV_ERROR,0,0,"WinSock 1.1 initialization failure, code %d", status-WSABASEERR);
+ /* Try WinSock 1.1 and 1.0 in that order of preference */
+ if (status != 0 && (status = WSAStartup(MAKEWORD(1,0),&wsaData)) != 0)
+ {
+ ErrPostEx(SEV_ERROR,0,0,"WinSock 1.0 initialization failure, code %d", status-WSABASEERR);
+ ni_errno = NIE_TCPINITFAIL;
+ return -1;
+ }
+ TRACE("%s\n", wsaData.szDescription);
+ if (stackDescription != NULL)
+ {
+ MemFree(stackDescription);
+ }
+ stackDescription = StringSave(wsaData.szDescription);
+ for (status = StrLen(stackDescription) - 1; status >= 0; status--)
+ {
+ /* convert characters which are incompatible with VisibleString */
+ if (stackDescription[status] < ' ' || stackDescription[status] > '~')
+ stackDescription[status] = '#';
+ }
+ wsaStartupCount++;
+
+#endif
+#if defined(OS_MAC) && defined(NETP_INET_MACTCP)
+ if (lapType != NULL)
+ {
+ stackDescription = StringSave(lapType);
+ }
+#endif /* OS_MAC && NETP_INET_MACTCP */
+#ifdef OS_UNIX
+ {
+ FILE *fp;
+ char buffer[128];
+ int status;
+
+ MemSet(&buffer, 0, sizeof(buffer));
+
+ if ((fp = popen("uname -a","r")) != NULL)
+ {
+ FileRead (buffer, 1, sizeof (buffer), fp);
+ stackDescription = StringSave(buffer);
+ pclose(fp);
+ for (status = StrLen(stackDescription) - 1; status >= 0; status--)
+ {
+ /* convert characters which are incompatible with VisibleString */
+ if (stackDescription[status] < ' ' || stackDescription[status] > '~')
+ stackDescription[status] = '#';
+ }
+
+ }
+ }
+#endif /* OS_UNIX */
+#ifdef NETP_SOCKS
+ if (disp->useSocks)
+ {
+ char path[128];
+
+ Nlm_ProgramPath(path, sizeof path);
+
+ SOCKSinit(path);
+ TRACE("Performed SOCKSinit(%s)\n", path);
+ }
+#endif /* NETP_SOCKS */
+
+ if (disp->dispHostName == NULL)
+ disp->dispHostName = StringSave(NI_DEFAULT_HOST);
+ if (disp->dispServiceName == NULL)
+ disp->dispServiceName = StringSave(NI_DEFAULT_SERVICE);
+
+ do {
+ newDispToTry = FALSE;
+ disp->svcsHP = NULL;
+ if ((disp->dispHP = DispatchConnect(disp, disp->dispHostName, disp->dispServiceName, disp->dispTimeout))
+ == NULL) {
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx(SEV_WARNING,0,0, "NI_InitServices: Unable to connect to host <%s>, error <%s>", disp->dispHostName, ni_errlist[ni_errno]);
+ return -1; /* ni_errno remains set */
+ }
+
+ if ((disp->svcsHP = MsgMakeHandle(TRUE)) == NULL) {
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: Unable to allocate resources to communicate with %s", disp->dispHostName);
+ return -1;
+ }
+
+ if (disp->dispTimeout > 0)
+ {
+ MsgSetReadTimeout(disp->svcsHP, disp->dispTimeout);
+ }
+
+ if (!disp->useOutServ)
+ { /* we need no listening if we are using direct connection */
+ if ((disp->clientPort = bindPort(disp->svcsHP->sok, &svcsAddr, disp->loport, disp->hiport, 0)) == 0) {
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ ni_errno = NIE_NOBIND; /* can't bind a free application socket */
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+ if ((status = NI_LISTEN(disp->svcsHP->sok, 5)) < 0) {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(status);
+#endif
+ StringCpy(ni_errtext, sys_errlist[SOCK_INDEX_ERRNO]);
+ ni_errno = NIE_NOLISTEN;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s> <port %d, errno %d>", ni_errlist[ni_errno], (int) disp->clientPort, (int) SOCK_ERRNO);
+ return -1;
+ }
+ }
+
+ SetIdentity(disp, user, group, NI_DEFAULT_DOMAIN);
+
+ loginp = NI_MakeMsgLogin();
+ NI_DestroyUid(loginp->uid);
+ loginp->uid = NI_MakeUid();
+ loginp->seqno = disp->dispHP->seqno++;
+ loginp->dispserialno = disp->dispSerialNo;
+ loginp->connectDelay = disp->dispHP->connectDelay;
+ if (disp->encryptInfo != NULL && NI_EncrAvailable())
+ {
+ loginp->encryptionDesired = TRUE;
+ if (disp->encryptInfo->data.ptrvalue != NULL)
+ {
+ pubKey = (NI_PubKeyPtr) disp->encryptInfo->data.ptrvalue;
+ loginp->pubKey = (NIPubKeyPtr) NI_PubKeyDup(pubKey);
+ }
+ }
+ CopyIdentity(disp, loginp->uid);
+ if (password != NULL)
+ loginp->password = StringSave(password);
+ mp = MsgBuild(NI_LOGIN, disp->dispHP->conid, (VoidPtr) loginp);
+
+ if (MsgWrite(disp->dispHP, mp, FALSE) < 0) {
+ if (getAsnError(ni_errtext) == ECONNRESET)
+ ni_errno = NIE_MAXCONNS;
+ else
+ ni_errno = NIE_MSGWRITE;
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+
+ /* blocks until ACK or ERROR from dispatcher or TIMEOUT */
+
+ timeout.tv_sec = (Uint4) NI_TIMEOUT_SECS;
+ timeout.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(disp->dispHP->sok, &readfds);
+ while ((ready = NI_select(FD_SETSIZE, &readfds, NULL, NULL, &timeout)) < 0) {
+ if (SOCK_ERRNO == EINTR)
+ ; /* repeat while interrupted */
+ else {
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ ni_errno = NIE_SELECT; /* select error */
+ NI_DestroyDispInfo(dispinfo);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+ }
+
+ if (FD_ISSET(disp->dispHP->sok, &readfds) != 0) {
+ if ((imp = MsgRead(disp->dispHP, FALSE)) == NULL) {
+ if (getAsnError(ni_errtext) == ECONNRESET)
+ ni_errno = NIE_MAXCONNS;
+ else
+ ni_errno = NIE_MSGREAD;
+
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+ switch (imp->type) {
+ case NI_ACK:
+ /************************************************************/
+ /* even though we connected successfully to the dispatcher, */
+ /* it may have given us more up-to-date information on the */
+ /* latest list of dispatchers which should be tried; if so, */
+ /* pass the updated list back to the caller */
+ /************************************************************/
+ if (imp->msun.ack->dispinfo != NULL) {
+ if (dispinfo != NULL)
+ {
+ NI_DestroyDispInfo(dispinfo);
+ dispinfo = NULL;
+ }
+ dispinfo = imp->msun.ack->dispinfo;
+ imp->msun.ack->dispinfo = NULL; /* for clean free */
+ }
+ if (disp->encryptInfo != NULL && NI_EncrAvailable())
+ {
+ if (dispinfo != NULL && dispinfo->pubKey != NULL)
+ {
+ failed = FALSE;
+ if (pubKey == NULL)
+ {
+ failed = (Boolean)
+ (Message(MSG_YN, ERR_KEY_NOPREVKEY) == ANS_NO);
+ ni_errno = NIE_NEWKEYNOTACCPT;
+ } else {
+ if (! NI_PubKeysEqual(pubKey, (NI_PubKeyPtr) dispinfo->pubKey))
+ {
+ failed = (Boolean)
+ (Message(MSG_YN, ERR_KEY_MISMATCH) == ANS_NO);
+ ni_errno = NIE_NEWKEYMISMATCH;
+ }
+ }
+ if (failed)
+ {
+ HaltServices(disp);
+ MsgDestroy(imp);
+ return -1;
+ } else {
+ /* replace the key */
+ NI_DestroyPubKey((NIPubKeyPtr) pubKey);
+ pubKey = (NI_PubKeyPtr) dispinfo->pubKey;
+ dispinfo->pubKey = NULL;
+ disp->encryptInfo->data.ptrvalue = (Pointer) pubKey;
+ }
+ }
+ }
+ if (dispinfo != NULL && dip != NULL) {
+ if (*dip != NULL)
+ NI_DestroyDispInfo((NIDispInfoPtr) *dip);
+ *dip = (NI_DispInfoPtr) dispinfo;
+ dispinfo = NULL;
+ retval = 1;
+ }
+ else {
+ NI_DestroyDispInfo(dispinfo);
+ }
+ if (imp->msun.ack->motd != NULL &&
+ imp->msun.ack->motd[0] != NULLB)
+ {
+ disp->motd = imp->msun.ack->motd;
+ imp->msun.ack->motd = NULL; /* for clean free */
+ }
+ if (imp->msun.ack->adminInfo != NULL &&
+ imp->msun.ack->adminInfo[0] != NULLB)
+ {
+ disp->adminInfo = imp->msun.ack->adminInfo;
+ imp->msun.ack->adminInfo = NULL; /* for clean free */
+ }
+#ifdef OS_UNIX
+ signal(SIGPIPE, SIG_IGN); /* catch socket errors */
+#endif /* OS_UNIX */
+ MsgDestroy(imp);
+ disp->referenceCount++;
+ if (currentDisp == NULL)
+ {
+ currentDisp = disp;
+ }
+ return retval; /* only good return */
+
+ case NI_NACK:
+ ni_errno = (enum ni_error) imp->msun.nack->code;
+ if (imp->msun.nack->reason != NULL)
+ {
+ StringCpy(ni_errtext, imp->msun.nack->reason);
+ } else {
+ ni_errtext[0] = '\0';
+ }
+ if (dispinfo != NULL)
+ {
+ NI_DestroyDispInfo(dispinfo);
+ dispinfo = NULL;
+ }
+ dispinfo = imp->msun.nack->dispinfo;
+ imp->msun.nack->dispinfo = NULL; /* for clean free */
+ if (ni_errno == NIE_BACKUPDISP && dispinfo != NULL &&
+ dispinfo->numdispatchers > 0 && dip != NULL &&
+ ++altDispTries < MAX_ALT_DISP_TRIES)
+ {
+ MsgDestroy(imp);
+ HaltServices (disp);
+ s_SetDispatcher(disp, dispinfo->displist[0], disp->dispServiceName,
+ disp->dispTimeout, dispinfo->serialno, disp->encryptInfo,
+ disp->useOutServ);
+ newDispToTry = TRUE;
+ retval = 2;
+ break;
+ }
+ MsgDestroy(imp);
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>\n%s", ni_errlist[ni_errno], ni_errtext);
+ return -1;
+
+ default:
+ MsgDestroy(imp);
+ ni_errno = NIE_MSGUNK;
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+ }
+ } while (newDispToTry);
+
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ ni_errno = NIE_LOGTIMEOUT; /* TIMEOUT */
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+} /* NI_InitServices */
+
+
+/*
+ * Purpose: Init network services based on information in config file
+ *
+ * Parameters:
+ * configFile Name of NCBI-style configuration file. If NULL, defaults
+ * to "NCBI"
+ * configSection Section with NCBI-style configuration file. If NULL,
+ * defaults to "NET_SERV"
+ * showMonitor Boolean; if TRUE, display a monitor while re-trying
+ * for an alternate dispatcher
+ * lastDispatcher Pointer to where this function should store the name
+ * of the dispatcher which was actually used (may be NULL
+ * if the caller does not care about this value)
+ * lastDispLen Maximum length of lastDispatcher
+ *
+ * Returns:
+ * NULL, if unable to contact dispatcher
+ * a pointer to the Dispatcher structure, otherwise
+ *
+ *
+ * Description:
+ * Extracts a dispatcher name and a user name from a configuration
+ * file. If necessary, tries other dispatchers, in order, as
+ * listed in configuration file. Also sets up encryption, if
+ * the client is encryption-capable and encryption is requested
+ * in the configuration file.
+ *
+ *
+ * Note:
+ * This function is provided as a convenience to developers who
+ * wish to use Network Services. Use of this function is not
+ * integral to the use of Network Services ... it is merely a
+ * convenience.
+ */
+
+static NI_DispatcherPtr s_GenericInit
+(CharPtr configFile, CharPtr configSection, Boolean showMonitor,
+CharPtr lastDispatcher, Int2 lastDispLen)
+{
+ char *def_user;
+ char username[64];
+ char groupname[20];
+ char password[20];
+ char dispname[60];
+ char disp_config[10];
+ char disp_msg[110];
+ char buf[60];
+ Boolean more_disps;
+ int alternate = 1;
+ int disp_timeout;
+ Int4 disp_serialno;
+ Monitor *mon = NULL;
+ NI_DispInfoPtr dip = NULL;
+ NI_DispatcherPtr disp = NULL;
+ Boolean someBrokered;
+ Boolean useOutServ;
+ ValNodePtr encryptInfo = NULL;
+ NI_PubKeyPtr keyCopy = NULL;
+ Boolean doEncr = FALSE;
+ Boolean quitOnDispConnFailure = FALSE;
+ Boolean showMessage = FALSE;
+ Int4 numBrokeredServices;
+
+ /******************* open the network connnection *********/
+#define NI_DISP_NAME "dispatch1.nlm.nih.gov"
+#define NI_USER_NAME "anonymous"
+#define NI_GROUP_NAME "GUEST"
+
+ def_user = NI_USER_NAME;
+
+ if (configFile == NULL)
+ configFile = "NCBI";
+ if (configSection == NULL)
+ configSection = "NET_SERV";
+
+ GetAppParam(configFile, configSection, "DISP_USERNAME", NI_USER_NAME, username,
+ sizeof username);
+ /* the user's login name overrides the config file */
+ /* for UNIX or VMS systems (or, for the future, any system where the */
+ /* user name can be determined), use the user's login name as the default */
+ def_user = NULL;
+#ifdef OS_UNIX
+ if ((def_user = getenv("USER")) == NULL)
+ {
+ def_user = getlogin();
+ }
+#endif
+#ifdef OS_VMS
+ def_user = getenv("USER");
+#endif
+ if (def_user != NULL)
+ {
+ StrNCpy(username, def_user, sizeof username);
+ }
+
+ GetAppParam(configFile, configSection, "DISP_GROUPNAME", NI_GROUP_NAME, groupname,
+ sizeof groupname);
+ GetAppParam(configFile, configSection, "DISP_PASSWORD", "", password,
+ sizeof password); /* default = NONE */
+
+ GetAppParam(configFile, configSection, "DISP_TIMEOUT", "0", buf, sizeof buf);
+ disp_timeout = atoi(buf);
+
+ GetAppParam(configFile, configSection, "DISPSERIALNO", "0", buf, sizeof buf);
+ disp_serialno = atoi(buf);
+
+ GetAppParam(configFile, configSection, "DISPATCHER", NI_DISP_NAME, dispname,
+ sizeof dispname);
+
+ GetAppParam(configFile, configSection, "DIRECT_SVC_CON", "FALSE", buf,
+ sizeof(buf));
+ useOutServ = (Boolean)(StrICmp(buf, "TRUE") == 0);
+
+ GetAppParam(configFile, configSection, "SOME_BROKERED", "FALSE", buf, sizeof buf);
+ someBrokered = (Boolean)(StrICmp(buf, "TRUE") == 0);
+ if (someBrokered) {
+ GetAppParam(configFile, configSection, "BROKERED_COUNT", "1", buf, sizeof buf);
+ numBrokeredServices = atoi(buf);
+ if (numBrokeredServices <= 0) {
+ someBrokered = FALSE;
+ } else {
+ sprintf (buf, "%ld", (long) numBrokeredServices - 1);
+ TransientSetAppParam(configFile, configSection, "BROKERED_COUNT", buf);
+ }
+ }
+
+ GetAppParam(configFile, configSection, "DISP_RECONN_ACTION", "CONT", buf, sizeof buf);
+ showMessage = (Boolean)(StrICmp(buf, "ASK") == 0);
+ quitOnDispConnFailure = (Boolean)(StrICmp(buf, "QUIT") == 0);
+
+ GetAppParam(configFile, configSection, "ENCRYPTION_DESIRED", "FALSE", buf, sizeof buf);
+ if (StrICmp(buf, "TRUE") == 0 && NI_EncrAvailable())
+ {
+ doEncr = TRUE;
+ encryptInfo = ValNodeNew(NULL);
+ encryptInfo->data.ptrvalue = (Pointer) NI_ReadPubKeyFromConfig();
+ keyCopy = NI_PubKeyDup((NI_PubKeyPtr) encryptInfo->data.ptrvalue);
+ }
+
+ do {
+ if (alternate == 2 && showMonitor)
+ {
+ mon = MonitorStrNew("Unable to contact primary dispatcher", 35);
+ }
+ if (alternate >= 2)
+ {
+ if (showMessage)
+ {
+ sprintf (disp_msg, "Unable to contact primary dispatcher. Ready to try\ndispatcher #%d <", alternate);
+ StrCat(disp_msg, dispname);
+ StrCat(disp_msg, ">. Continue?");
+ if (Message(MSG_YN, disp_msg) == ANS_NO)
+ break;
+ } else {
+ sprintf(disp_msg, "Trying dispatcher #%d <", alternate);
+ StrCat(disp_msg, dispname);
+ StrCat(disp_msg, ">");
+ if (showMonitor) {
+ MonitorStrValue(mon, disp_msg);
+ }
+ }
+ }
+
+ if (lastDispatcher != NULL) {
+ StrNCpy(lastDispatcher, dispname, lastDispLen);
+ }
+
+ disp = s_SetDispatcher (NULL, dispname, NULL, disp_timeout, disp_serialno, encryptInfo, useOutServ);
+
+ if (someBrokered) {
+ disp->brokeredDummy = TRUE;
+ disp->someBrokered = TRUE;
+ disp->referenceCount++;
+ ValNodeFree (encryptInfo);
+ return disp;
+ }
+
+ if (NI_InitServices(disp, username,
+ groupname[0] == '\0' ? 0 : groupname,
+ password [0] == '\0' ? 0 : password, &dip) >= 0)
+ {
+ if (dip != NULL && dip->serialno != disp_serialno) {
+ NI_SetDispConfig (&dip, dispname, sizeof dispname);
+ }
+ if (mon != NULL)
+ MonitorFree(mon);
+ if (disp->encryptInfo != NULL &&
+ disp->encryptInfo->data.ptrvalue != NULL &&
+ ! NI_PubKeysEqual(keyCopy,
+ (NI_PubKeyPtr) disp->encryptInfo->data.ptrvalue))
+ {
+ NI_WritePubKeyToConfig ((NI_PubKeyPtr) disp->encryptInfo->data.ptrvalue);
+ }
+ NI_DestroyPubKey ((NIPubKeyPtr) keyCopy);
+ return disp;
+ }
+ ErrShow ();
+ s_EndServices (disp);
+ sprintf(disp_config, "DISP_ALT_%d", alternate++);
+ more_disps = (Nlm_Boolean)GetAppParam
+ (configFile, configSection, disp_config, "",
+ dispname, sizeof(dispname));
+ if (doEncr)
+ {
+ encryptInfo = ValNodeNew(NULL);
+ encryptInfo->data.ptrvalue = (Pointer)
+ NI_PubKeyDup((NI_PubKeyPtr) keyCopy);
+ }
+ } while (more_disps && ! quitOnDispConnFailure);
+
+ if (mon != NULL)
+ MonitorFree(mon);
+
+ ValNodeFree (encryptInfo);
+ NI_DestroyPubKey ((NIPubKeyPtr) keyCopy);
+ ErrPostEx(SEV_ERROR,0,0, "NI_InitServices: Unable to connect to any dispatcher");
+ return NULL;
+}
+
+
+/*
+ * Purpose: Get a network service based on information in config file
+ *
+ * Parameters:
+ * disp Pointer to the dispatcher structure obtained from a
+ * previous call to NI_SetDispatcher or NI_GenericInit
+ * configFile Name of NCBI-style configuration file. If NULL, defaults
+ * to "NCBI"
+ * defService The default service/resource/resource-type name, if
+ * not specified otherwise in configuration file.
+ * hasResource Boolean; if TRUE, ask for a resource when requesting
+ * service
+ *
+ * Returns:
+ * NULL, if unable to obtain service
+ * a pointer to the service-structure, otherwise
+ *
+ *
+ * Description:
+ * Extracts a service name and other service data from a
+ * configuration file, and attempts to obtain that service.
+ * As a special case, handle communication with a "brokered
+ * server" (a server which is already listening on a port, where
+ * no communication needs to be performed with the dispatcher).
+ * Also disable data encryption for this service request, if
+ * explicitly specified in the configuration file.
+ *
+ *
+ * Note:
+ * This function is provided as a convenience to developers who
+ * wish to use Network Services. Use of this function is not
+ * integral to the use of Network Services ... it is merely a
+ * convenience.
+ *
+ * For UNIX systems, environment variables can be used to
+ * override the config. file's values for SERVICE_NAME and
+ * RESOURCE_TYPE.
+ */
+
+static NI_HandPtr s_GenericGetService
+(NI_DispatcherPtr disp, CharPtr configFile, CharPtr configSection,
+ CharPtr defService, Boolean hasResource)
+{
+ char buf[40];
+ char service[40];
+ char resource[40];
+ char res_type[40];
+ Uint2 serv_min, serv_max;
+ Uint2 res_min, res_max;
+ char brokeredIpaddr[40];
+ Uint2 port;
+ NI_HandPtr result;
+ ValNodePtr savEncrypt;
+#ifdef OS_UNIX
+ CharPtr envName = (CharPtr)MemNew(StrLen(configSection) + 20);
+ CharPtr envValue;
+#endif
+
+ if (configFile == NULL)
+ configFile = "NCBI";
+
+ GetAppParam(configFile, configSection, "SERVICE_NAME", defService,
+ service, sizeof service);
+#ifdef OS_UNIX
+ /* environment variable overrides config. file */
+ sprintf (envName, "NI_SERVICE_NAME_%s", configSection);
+ if ((envValue = getenv(envName)) != NULL)
+ {
+ StrCpy (service, envValue);
+ }
+#endif /* OS_UNIX */
+ GetAppParam(configFile, configSection, "SERV_VERS_MIN", "1",
+ buf, sizeof buf);
+ serv_min = (Uint2)atoi(buf);
+ GetAppParam(configFile, configSection, "SERV_VERS_MAX", "0",
+ buf, sizeof buf);
+ serv_max = (Uint2)atoi(buf);
+
+ res_min = 1;
+ res_max = 0;
+
+ if (hasResource) {
+ GetAppParam(configFile, configSection, "RESOURCE_NAME", defService,
+ resource, sizeof resource);
+ GetAppParam(configFile, configSection, "RESOURCE_TYPE", defService,
+ res_type, sizeof res_type);
+#ifdef OS_UNIX
+ /* environment variable overrides config. file */
+ sprintf (envName, "NI_RESOURCE_TYPE_%s", configSection);
+ if ((envValue = getenv(envName)) != NULL)
+ {
+ StrCpy (res_type, envValue);
+ }
+#endif /* OS_UNIX */
+ GetAppParam(configFile, configSection, "RES_VERS_MIN", "1",
+ buf, sizeof buf);
+ res_min = (Uint2)atoi(buf);
+ GetAppParam(configFile, configSection, "RES_VERS_MAX", "0",
+ buf, sizeof buf);
+ res_max = (Uint2)atoi(buf);
+ }
+
+#ifdef OS_UNIX
+ MemFree (envName);
+#endif /* OS_UNIX */
+
+ if (disp->someBrokered)
+ {
+ GetAppParam(configFile, configSection, "BROKERED_PORT", "0",
+ buf, sizeof buf);
+ port = htons((unsigned short)atoi(buf));
+ GetAppParam(configFile, configSection, "BROKERED_IPADDR", "",
+ brokeredIpaddr, sizeof brokeredIpaddr);
+ if (port != 0 && brokeredIpaddr[0] != '\0')
+ { /* simulate service request by connecting to that port */
+ struct sockaddr_in serv_addr;
+ NI_HandPtr sHP;
+ int timeout = 30;
+ int status;
+
+ MemFill((VoidPtr) &serv_addr, '\0', sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = inet_addr(brokeredIpaddr);
+ serv_addr.sin_port = port;
+
+ if ((sHP = MsgMakeHandle(TRUE)) == NULL)
+ return NULL;
+ MsgSetLJError(sHP);
+ sHP->hostname = StringSave(brokeredIpaddr);
+
+ if (activityHook != NULL)
+ {
+ activityHook(sHP, NetServHook_svcreq, 0);
+ }
+
+ RETRY:
+#ifndef NETP_INET_NEWT
+ if ((status = NI_CONNECT(sHP->sok, (struct sockaddr PNTR) &serv_addr, sizeof(serv_addr))) < 0) { /* } */
+#else
+ if ((status = NI_CONNECT(sHP->sok, &serv_addr, sizeof(serv_addr))) < 0) {
+ SOCK_ERRNO = ABS(status);
+#endif
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ goto RETRY;
+
+#ifdef NETP_INET_PCNFS
+ /* This is apparently a bug in PC-NFS 4.0 ... a connection attempt */
+ /* on a non-blocking socket yields errno == 0 */
+ case 0:
+#endif /* NETP_INET_PCNFS */
+ case EWOULDBLOCK:
+ case EINPROGRESS:
+ /* if the connect()ion is not established immediately, a */
+ /* select() can be performed where the corresponding "write" */
+ /* file descriptor will be enabled once the connect()ion has been*/
+ /* established */
+ if (sokselectw(sHP->sok, timeout) == 0) {
+ return sHP;
+ }
+ break;
+
+ default:
+ break;
+ }
+ MsgDestroyHandle(sHP);
+ ni_errno = NIE_BROKSVCCONN; /* can't connect to brokered service */
+ return NULL;
+ }
+ {
+ Char buf[16];
+ Char key[8];
+ Int2 len;
+
+ if ((len = GetAppParam("NCBI", "NET_SERV", "DESKEY", "", buf, sizeof buf)) > 0 &&
+ (AsnTypeStringToHex(buf, len, key, NULL) == 0))
+
+ {
+ NI_SetupDESEncryption(sHP, (UcharPtr) key);
+ }
+ }
+ return sHP;
+ } else {
+ if (disp->brokeredDummy)
+ { /* JAE ... establish a true dispatcher connection here */
+ }
+ }
+ }
+
+ savEncrypt = disp->encryptInfo;
+ if (GetAppParam(configFile, configSection, "ENCRYPTION", "TRUE",
+ buf, sizeof buf) > 0 && StrICmp(buf, "FALSE") == 0)
+ {
+ /* temporarily disable encryption */
+ disp->encryptInfo = NULL;
+ }
+ result = NI_ServiceGet(disp, service, serv_min, serv_max,
+ hasResource ? resource : 0, res_type, res_min,
+ res_max);
+ disp->encryptInfo = savEncrypt;
+
+ return result;
+}
+
+
+/*
+ * Purpose: Write dispatcher-configuration information to a config file
+ *
+ * Parameters:
+ * dipp A pointer to the caller's list of dispatchers, obtained
+ * from NI_InitServices()
+ * dispatcher The caller's dispatcher string
+ * dispLen Length of the caller's dispatcher string
+ *
+ * Returns:
+ * 0, if bad parameters were provided
+ * the dispatcher-list serial number, otherwise
+ *
+ *
+ * Description:
+ * Sets up the "NCBI" configuration file with the following
+ * entries in the "NET_SERV" section:
+ * * DISPATCHER is the primary dispatcher name
+ * * DISP_ALT_n for every alternate dispatcher, 1 <= n, a smaller
+ * n indicates a higher priority alternate dispatcher
+ * * DISPSERIALNO is the serial number of the dispatcher list
+ * obtained from a remote dispatcher. This serial number should
+ * be unique for all time ... the dispatcher's serial number
+ * must be changed whenever the master list is modified.
+ *
+ * Note:
+ * This configuration mechanism is only _one_ recommended
+ * mechanism for network services dispatcher configuration. The
+ * application may perform this configuration in any manner
+ * deemed appropriate by the application programmer.
+ *
+ * The value returned by this function is the recommended value
+ * for the dispserialno parameter in a subsequent call to
+ * NI_InitDispatcher().
+ */
+
+NLM_EXTERN Int4 NI_SetDispConfig(NI_DispInfoPtr PNTR dipp, CharPtr dispatcher, Int2 dispLen)
+{
+ int num;
+ Char dispConfig[20];
+ char buf[10];
+ Int4 retval;
+ NI_DispInfoPtr dip;
+
+ if (dipp == NULL || (dip = *dipp) == NULL)
+ {
+ if (dispatcher != NULL)
+ {
+ dispatcher[0] = '\0';
+ }
+ return 0;
+ }
+
+ if (dip->numdispatchers > 0 && dip->displist != NULL)
+ {
+ StringNCpy (dispatcher, dip->displist[0], dispLen);
+ SetAppParam ("NCBI", "NET_SERV", "DISPATCHER", dip->displist[0]);
+ }
+
+ for (num = 1; num < dip->numdispatchers; num++)
+ {
+ sprintf (dispConfig, "DISP_ALT_%d", num);
+ SetAppParam ("NCBI", "NET_SERV", dispConfig, dip->displist[num]);
+ }
+
+ /* wipe out any extraneous old configuration */
+ for (num = dip->numdispatchers; num < 100; num++)
+ {
+ sprintf (dispConfig, "DISP_ALT_%d", num);
+ if (GetAppParam("NCBI", "NET_SERV", dispConfig, "", buf, sizeof buf) <= 0)
+ {
+ break;
+ }
+ SetAppParam ("NCBI", "NET_SERV", dispConfig, NULL);
+ }
+
+ retval = dip->serialno;
+ sprintf (buf, "%ld", (long) dip->serialno);
+ SetAppParam ("NCBI", "NET_SERV", "DISPSERIALNO", buf);
+
+ NI_DestroyDispInfo ((NIDispInfoPtr) dip);
+ *dipp = NULL;
+
+ return retval;
+}
+
+
+/*
+ * Purpose: End use of network services
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ *
+ * Returns:
+ * 0 (always)
+ *
+ *
+ * Description:
+ * Tear down the sockets and data structures associated with
+ * the dispatcher and a server, and free all memory associated
+ * with data structures.
+ */
+
+static Int2 s_EndServices(NI_DispatcherPtr disp)
+{
+ Int2 openSockets;
+
+ if (disp == NULL)
+ return 0;
+
+ if (disp->referenceCount > 0)
+ disp->referenceCount--;
+
+ if (disp->referenceCount <= 0)
+ {
+ if (disp == currentDisp)
+ {
+ currentDisp = NULL;
+ }
+
+ HaltServices (disp);
+ s_SetDispatcher(disp, NULL, NULL, 0, 0, NULL, FALSE); /* free mem */
+
+ if (stackDescription != NULL)
+ {
+ MemFree(stackDescription);
+ stackDescription = NULL;
+ }
+ MemFree(disp->adminInfo);
+ MemFree(disp->motd);
+ MemFree(disp);
+
+ /* For historical reasons pertaining to Network Entrez, a single open
+ socket does not constitute an error in this context. However, at
+ program exit time, a single open socket does constitute a serious
+ problem. */
+ if ((openSockets = NI_SocketsOpen()) > 1)
+ {
+ ErrPostEx(SEV_WARNING,0,0, "At end-services time, %d sockets are still open", openSockets);
+ }
+ }
+
+ return 0;
+} /* NI_EndServices */
+
+
+
+/*
+ * Purpose: Request a catalog from the dispatcher
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ *
+ * Returns:
+ * NULL, if unable to obtain the catalog
+ * a pointer to the received catalog data structure, otherwise
+ *
+ *
+ * Description:
+ * Send a request to the dispatcher, requesting a catalog, and
+ * wait (up to some timeout) for a response. The dispatcher's
+ * response should either be that catalog, or a NACK.
+ */
+
+NLM_EXTERN NICatalogPtr NI_GetCatalog(NI_DispatcherPtr disp)
+{
+ NICatalogPtr catp;
+ NIMsgPtr mp, imp;
+ NICmdPtr cmdp;
+ struct timeval timeout;
+ int ready;
+ fd_set readfds;
+
+ if (disp == NULL)
+ return NULL;
+
+ cmdp = (NICmdPtr) NI_MakeMsgCmd();
+ cmdp->seqno = disp->dispHP->seqno++;
+ cmdp->code = NI_SEND_CATALOG;
+ if ((mp = MsgBuild(NI_COMMAND, disp->dispHP->conid, (VoidPtr) cmdp)) == NULL) {
+ ni_errno = NIE_MISC; /* unable to alloc mem for Msg */
+ return NULL;
+ }
+ if (MsgWrite(disp->dispHP, mp, FALSE) < 0) {
+ ni_errno = NIE_MSGWRITE;
+ return NULL;
+ }
+
+ /* blocks until response from dispatcher or TIMEOUT */
+
+ timeout.tv_sec = (Uint4) NI_TIMEOUT_SECS;
+ timeout.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(disp->dispHP->sok, &readfds);
+ while ((ready = NI_select(FD_SETSIZE, &readfds, NULL, NULL, &timeout)) < 0) {
+ if (SOCK_ERRNO == EINTR)
+ ; /* repeat while interrupted */
+ else {
+ ni_errno = NIE_SELECT; /* select error */
+ return NULL;
+ }
+ }
+
+ if (FD_ISSET(disp->dispHP->sok, &readfds) != 0) {
+ if ((imp = MsgRead(disp->dispHP, FALSE)) == NULL) {
+ LOG_SOCKET(disp->dispHP->sok, FALSE);
+ NI_CLOSESOCKET(disp->dispHP->sok);
+ ni_errno = NIE_MSGREAD;
+ return NULL;
+ }
+ switch (imp->type) {
+ case NI_CATALOG:
+ catp = imp->msun.catalog;
+ imp->msun.catalog = NULL;
+ ni_errno = NIE_NO_ERROR;
+ MsgDestroy(imp);
+ return catp;
+ break;
+
+ case NI_NACK:
+ ni_errno = (enum ni_error) imp->msun.nack->code;
+ if (imp->msun.nack->reason != NULL)
+ StringCpy(ni_errtext, imp->msun.nack->reason);
+ else
+ ni_errtext[0] = '\0';
+ MsgDestroy(imp);
+ return NULL;
+
+ default:
+ MsgDestroy(imp);
+ ni_errno = NIE_MSGUNK; /* Unknown MSG type */
+ return NULL;
+ }
+ }
+ ni_errno = NIE_CMDTIMEOUT; /* TIMEOUT */
+ return NULL;
+} /* NI_GetCatalog */
+
+
+
+/*
+ * Purpose: Create the data structure for a service request
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ *
+ * Returns:
+ * a pointer to the newly created data structure
+ *
+ *
+ * Description:
+ * Allocate the memory for a service request data structure,
+ * and fill in some of the fields.
+ * Note:
+ * There are two ways for a program to issue a service request:
+ * (1) Multi-step, general method (like IRS form 1040)
+ * * Build a request with NI_SVCRequestBuild()
+ * * Populate the request with a specific service request using
+ * NI_RequestSetService()
+ * * Populate the request with zero or more resource requests
+ * calling NI_RequestAddResource() once for every resource
+ * * Send the request with NI_ServiceRequest(), and (hopefully)
+ * obtain a connection to a service provider
+ * * At some later time, delete the request (to save memory)
+ * (2) One-stop shopping, for simple requirement (like form 1040EZ)
+ * * Do everything for a service and up to one resource using
+ * NI_ServiceGet()
+ */
+
+NLM_EXTERN NI_ReqPtr NI_SVCRequestBuild(NI_DispatcherPtr disp)
+{
+ NI_ReqPtr reqp;
+
+ if (disp == NULL)
+ return NULL;
+
+ reqp = (NI_ReqPtr) NI_MakeRequest();
+ reqp->clientPort = (Uint2) disp->clientPort;
+ if (disp->useSocks)
+ {
+ /* tell the Dispatcher that it should use getpeername() to determine */
+ /* the IP address of the SOCKS daemon */
+ reqp->clientAddr = StringSave("0.0.0.0");
+ } else {
+ reqp->clientAddr = StringSave(disp->localHostAddr);
+ }
+ reqp->dispatcher = disp; /* should not be freed when destroying Req */
+
+ return reqp;
+} /* NI_SVCRequestBuild */
+
+
+
+/*
+ * Purpose: Destroy a service request data structure
+ *
+ * Parameters:
+ * reqp A pointer to the data structure to be destroyed
+ *
+ *
+ * Description:
+ * Free all the resources associated with a service request
+ */
+
+NLM_EXTERN void NI_SVCRequestDestroy(NI_ReqPtr reqp)
+{
+ NI_DestroyRequest(reqp);
+} /* NI_SVCRequestDestroy */
+
+
+
+/*
+ * Purpose: Make a service request for a service and up to one resource
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * svc Name of requested service
+ * svcvermin Minimum version number requested for this service
+ * svcvermax Maximum version number requested for this service
+ * res Name of requested resource (possibly NULL)
+ * resvermin Minimum version number requested for this resource
+ * resvermax Maximum version number requested for this resource
+ *
+ * Returns:
+ * The result of the service request
+ *
+ *
+ * Description:
+ * Create and issue a service request for the specified
+ * parameters.
+ */
+
+NLM_EXTERN NI_HandPtr NI_ServiceGet(NI_DispatcherPtr disp, CharPtr svc, Uint2 svcvermin, Uint2 svcvermax, CharPtr res, CharPtr restype, Uint2 resvermin, Uint2 resvermax)
+{
+ NI_ReqPtr reqp;
+
+ if (disp == NULL)
+ return NULL;
+
+ reqp = NI_SVCRequestBuild(disp);
+ NI_RequestSetService(reqp, svc, svcvermin, svcvermax);
+ if (res != NULL)
+ NI_RequestAddResource(reqp, res, restype, resvermin, resvermax);
+
+ return NI_ServiceRequest(reqp);
+} /* NI_ServiceGet */
+
+
+
+/*
+ * Purpose: Issue the specified service request
+ *
+ * Parameters:
+ * req The pre-formatted service request
+ *
+ * Returns:
+ * A message handle to the server which is servicing our request,
+ * if successful
+ * NULL, otherwise (ni_errno will indicate a more precise cause)
+ *
+ *
+ * Description:
+ * Create and issue a service request for the specified
+ * service request, as follows:
+ *
+ * * Create a data structure to which the resulting service
+ * connection can be attached
+ * * Send the service request to the dispatcher
+ *
+ * old - style connection:
+ *
+ * * Wait for the following two events, in either order:
+ * (1) A response from the dispatcher, which is either a
+ * SVC_RESPONSE (good), or a NACK (bad) {or a timeout}
+ * (2) A connection request from the server, which we then
+ * accept()
+ * * If both of the two events occur successfully, return with
+ * success, else, return with failure.
+ *
+ * old-style / direct connection switch
+ * (currently disabled)
+ *
+ * * After NACK was received in old - style connection we don't
+ * worry, set disp->useOutServ to TRUE and return to the beginning
+ * of the function. All service request will be repeated with
+ * direct connection.
+ *
+ * direct connection:
+ *
+ * * Wait for the following events:
+ * (1) A response from the dispatcher, which is either a
+ * SVC_REQUEST (good), or a NACK (bad) {or a timeout}
+ * * In the case of SVC_REQUEST we send this request directly
+ * to the server and wait for next event:
+ * (2) A response from the dispatcher, which is either a
+ * SVC_RESPONSE (good), or a NACK (bad) {or a timeout}
+ * * If both of the two events occur successfully, return with
+ * success, else, return with failure.
+ *
+ * Note:
+ * If the caller's Dispatcher data structure indicates that
+ * encryption should be performed, then a DES key is
+ * pseudorandomly generated prior to issuing the service request,
+ * and is encrypted using public-key encryption. Following
+ * successful establishment of the client<->server session, the
+ * DES key is used to encrypt the ensuing session using
+ * cypher-block-chaining.
+ *
+ * For SOCKSified clients, a different protocol is used where
+ * the client first sends a "pre-service-request", asking the
+ * IP address of the computer to which the Dispatcher will assign
+ * the request. Upon receipt of a NI_SVC_PRE_RESPONSE message
+ * containing that IP address, the client performs a SOCKSified
+ * bind()ing indicating that the specified IP address will
+ * "call back". Having determine the port number which has
+ * been bound on the SOCKS proxy, the client sends the "real"
+ * service request containing the SOCKS proxy's port number
+ * and a reminder as to which IP address the Dispatcher
+ * "promised" would be assigned. After that, processing
+ * proceeds normally, with the server connecting-back (via
+ * the SOCKS proxy) and the Dispatcher sending a SVC_RESPONSE
+ * acknowledgement.
+ *
+ * Note that SOCKS and encryption are completely orthogonal
+ * with respect to each other, and a client may use either, both,
+ * or neither.
+ */
+
+NLM_EXTERN NI_HandPtr NI_ServiceRequest(NI_ReqPtr req)
+{
+ NI_HandPtr sconnhp;
+#ifdef NETP_INET_MACTCP
+ Int4 sconnlen;
+#else
+ int sconnlen;
+#endif
+ struct sockaddr_in sconnaddr;
+ NIMsgPtr mp, imp;
+ NISvcReqPtr svcreqp;
+ struct timeval timeout;
+ Monitor *mon = NULL;
+ int ready;
+ Boolean disp_contact = FALSE, serv_contact = FALSE;
+ Uint4 this_req;
+ fd_set readfds;
+ NI_DispatcherPtr disp = req->dispatcher;
+ Uchar desKey[8];
+#ifdef NETP_SOCKS
+ struct sockaddr_in svcsAddr;
+ Int2 status;
+#endif
+
+NEXTTRY:
+ ni_errtext[0] = '\0';
+ if (disp->useOutServ) {
+ if ((sconnhp = MsgMakeHandle(TRUE)) == NULL) {
+ ni_errno = NIE_MAKEHAND;
+ return NULL;
+ }
+ } else {
+ if ((sconnhp = MsgMakeHandle(FALSE)) == NULL) {
+ ni_errno = NIE_MAKEHAND;
+ return NULL;
+ }
+ }
+
+ svcreqp = NI_MakeMsgSvcreq();
+ svcreqp->seqno = disp->dispHP->seqno++;
+ svcreqp->platform = (Uint4) NI_GetPlatform();
+ if (stackDescription != NULL)
+ {
+ svcreqp->applId = StringSave(stackDescription);
+ }
+ if (disp->encryptInfo != NULL && NI_EncrAvailable())
+ {
+ UcharPtr encryptedDesKey;
+ Int2 encryptedLen;
+
+ NI_GenerateDESKey (desKey);
+ encryptedLen = NI_PubKeyEncrypt((NI_PubKeyPtr) disp->encryptInfo->data.ptrvalue,
+ desKey, sizeof desKey, &encryptedDesKey);
+ if (encryptedLen <= 0)
+ {
+ NI_DestroyRequest(req);
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_PUBKEYENCRFAIL;
+ return NULL;
+ }
+ /* convert the DES key into a ByteStore */
+ svcreqp->desKey = BSNew(encryptedLen);
+ BSWrite (svcreqp->desKey, (VoidPtr) encryptedDesKey, encryptedLen);
+ MemFree (encryptedDesKey);
+ }
+ this_req = svcreqp->seqno;
+ CopyIdentity(disp, svcreqp->uid);
+ NI_DestroyRequest(svcreqp->request);
+ svcreqp->request = req;
+
+ if (disp->useSocks)
+ {
+ svcreqp->wantPreResponse = TRUE;
+ }
+ /* we want to get a ticket for the direct connection */
+ if (disp->useOutServ) {
+ svcreqp->want_ticket = TRUE;
+ }
+
+ if ((mp = MsgBuild(NI_SVC_REQUEST, disp->dispHP->conid, (VoidPtr) svcreqp)) == NULL) {
+ NI_DestroyRequest(req);
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MISC; /* unable to alloc mem for Msg */
+ return NULL;
+ }
+
+ if (MsgWrite(disp->dispHP, mp, disp->useSocks) < 0) {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MSGWRITE;
+ return NULL;
+ }
+
+ /* blocks until SVC_RESPONSE from dispatcher and service or NACK or TIMEOUT */
+ while ( !disp_contact || !serv_contact) {
+ timeout.tv_sec = (Uint4) NI_TIMEOUT_SECS;
+ timeout.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(disp->dispHP->sok, &readfds);
+ if (! disp->useOutServ)
+ FD_SET(disp->svcsHP->sok, &readfds);
+ while ((ready = NI_select(FD_SETSIZE, &readfds, NULL, NULL, &timeout)) < 0) {
+ if (SOCK_ERRNO == EINTR)
+ ; /* repeat while interrupted */
+ else {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_SELECT; /* select error */
+ return NULL;
+ }
+ }
+ if (ready == 0) {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_DSPTIMEOUT; /* TIMEOUT */
+ return NULL;
+ }
+ if (FD_ISSET(disp->dispHP->sok, &readfds) != 0) {
+ if ((imp = MsgRead(disp->dispHP, FALSE)) == NULL) {
+ LOG_SOCKET(disp->dispHP->sok, FALSE);
+ NI_CLOSESOCKET(disp->dispHP->sok);
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MSGREAD;
+ return NULL;
+ }
+ disp_contact = TRUE;
+ switch (imp->type) {
+ case NI_SVC_PRE_RESPONSE:
+#ifdef NETP_SOCKS
+ if (disp->useSocks)
+ {
+ /* must defer binding and listening for SOCKS connection */
+ /* until server's IP address is known */
+
+ TRACE("Processing SOCKS SVC_PRE_RESPONSE\n");
+ /* SOCKS can't deal well with non-blocking connections */
+ NI_SETBLOCKING(disp->svcsHP->sok);
+
+ if ((disp->clientPort = bindPort(disp->svcsHP->sok, &svcsAddr, disp->loport, disp->hiport, imp->msun.preresp->server_ip)) == 0) {
+ TRACE("bindPort failed\n");
+ MsgDestroyHandle(sconnhp);
+ disp->svcsHP = NULL;
+ ni_errno = NIE_NOBIND; /* can't bind a free application socket */
+ ErrPost (CTX_NCBICORE, CORE_UNKNOWN, "NI_ServiceRequest: <%s>", ni_errlist[ni_errno]);
+ return NULL;
+ }
+ TRACE("bindPort succeeded, port = %d\n", disp->clientPort);
+ if (NI_GETSOCKNAME(disp->svcsHP->sok, &svcsAddr, &sconnlen) >= 0)
+ disp->clientPort = ntohs(svcsAddr.sin_port);
+ req->clientPort = disp->clientPort;
+ svcreqp->server_ip = imp->msun.preresp->server_ip;
+ svcreqp->wantPreResponse = FALSE;
+ if (MsgWrite(disp->dispHP, mp, FALSE) < 0) {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MSGWRITE;
+ return NULL;
+ }
+ disp_contact = FALSE; /* now waiting to hear one more msg */
+
+ TRACE("After GETSOCKNAME, port = %d\n", disp->clientPort);
+ if ((status = NI_LISTEN(disp->svcsHP->sok, 5)) < 0) {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(status);
+#endif
+ TRACE("Listen failed, errno = %d\n", SOCK_ERRNO);
+ MsgDestroyHandle(sconnhp);
+ StringCpy(ni_errtext, sys_errlist[SOCK_INDEX_ERRNO]);
+ ni_errno = NIE_NOLISTEN;
+ ErrPost (CTX_NCBICORE, CORE_UNKNOWN, "NI_ServiceRequest: <%s> <port %d, errno %d>", ni_errlist[ni_errno], (int) disp->clientPort, (int) SOCK_ERRNO);
+ return NULL;
+ }
+ }
+#endif
+ /* non-SOCKS clients ignore this message, and should never receive it */
+ TRACE("Listen succeeded\n");
+ MsgDestroy(imp);
+ break;
+
+ case NI_SVC_RESPONSE:
+ if (disp->useSocks)
+ {
+ TRACE("Got SOCKS service response from Dispatcher\n");
+ }
+ ni_errno = NIE_NO_ERROR;
+ NI_DestroyRequest(disp->reqResponse);
+ disp->reqResponse = imp->msun.svcresp->request;
+ sconnhp->hostname = StringSave(disp->reqResponse->clientAddr);
+ imp->msun.svcresp->request = NULL;
+ MsgDestroy(imp);
+ if (mon != NULL) {
+ MonitorStrValue(mon, "Direct connection established");
+#ifdef OS_UNIX
+ sleep(1);
+#endif /* OS_UNIX */
+ MonitorFree(mon);
+ }
+ break;
+
+ case NI_NACK:
+ if (disp->useSocks)
+ {
+ TRACE("Got SOCKS NACK from Dispatcher\n");
+ }
+ ni_errno = (enum ni_error) imp->msun.nack->code;
+ if (imp->msun.nack->reason != NULL)
+ StringCpy(ni_errtext, imp->msun.nack->reason);
+ else
+ ni_errtext[0] = '\0';
+ MsgDestroy(imp);
+
+ /* retry in the case when old style connection failed now is disabled */
+
+ if (FALSE && !disp->useOutServ) {
+ disp->useOutServ = TRUE;
+ mon = MonitorStrNew("Old type of connection failed", 40);
+ MonitorStrValue(mon, "Trying to establish direct connection");
+ serv_contact = FALSE;
+ disp_contact = FALSE;
+ goto NEXTTRY;
+ }
+ else {
+ MsgDestroyHandle(sconnhp);
+ return NULL;
+ }
+ /* Message with direct connection ticket was received */
+ case NI_SVC_REQUEST:
+ if ((sconnhp = NI_DirectServiceRequest(imp, sconnhp)) == NULL) {
+ TRACE("Unable to establish direct connection\n");
+ return NULL;
+ }
+ if (mon != NULL)
+ MonitorStrValue(mon, "Received ticket for direct connection");
+
+ serv_contact = TRUE;
+ disp_contact = FALSE; /* we are looking for SVC_RESPONCE */
+ break;
+
+
+ default:
+ if (disp->useSocks)
+ {
+ TRACE("Got SOCKS unknown message type from Dispatcher\n");
+ }
+ MsgDestroy(imp);
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MSGUNK; /* Unknown MSG type */
+ sprintf(ni_errtext, "%d", imp->type);
+ return NULL;
+ }
+ }
+ if (!disp->useOutServ && (FD_ISSET(disp->svcsHP->sok, &readfds) != 0) && !serv_contact) {
+ sconnlen = sizeof(sconnaddr);
+#ifdef NETP_INET_NEWT
+ sconnhp->sok = NI_ACCEPT(disp->svcsHP->sok, &sconnaddr, &sconnlen);
+#else
+ sconnhp->sok = NI_ACCEPT(disp->svcsHP->sok, (struct sockaddr PNTR) &sconnaddr, &sconnlen);
+#endif /* NETP_INET_NEWT */
+ LOG_SOCKET(sconnhp->sok, TRUE);
+#ifdef NETP_SOCKS
+ if (disp->useSocks)
+ {
+ TRACE("Got connection from server, socket %d\n", sconnhp->sok);
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = MsgMakeHandle(TRUE); /* for next time */
+ }
+#endif /* NETP_SOCKS */
+ if (sconnhp->sok < 0) {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(sconnhp->sok);
+#endif
+ MsgDestroyHandle(sconnhp);
+ StringCpy(ni_errtext, sys_errlist[SOCK_INDEX_ERRNO]);
+ ni_errno = NIE_NOACCEPT; /* application accept error */
+ return NULL;
+ }
+ serv_contact = TRUE;
+ }
+ }
+
+ if (activityHook != NULL)
+ {
+ (*activityHook)(sconnhp, NetServHook_svcreq, 0);
+ }
+
+ if (disp->encryptInfo != NULL && NI_EncrAvailable())
+ {
+ NI_SetupDESEncryption(sconnhp, desKey);
+ }
+
+ if (sconnhp != NULL)
+ {
+ sconnhp->disp = disp;
+ }
+
+ return sconnhp;
+} /* NI_ServiceRequest */
+
+
+
+/*
+ * Purpose: Issue the specified direct service request
+ *
+ * Parameters:
+ *
+ * imp The pre-formatted service request
+ * sconnhp server handle to connect to
+ *
+ * Returns:
+ *
+ * sconnhp A message handle to the server which is servicing our request,
+ * if successful
+ *
+ * Description: This function connects directly to server specified by sconnhp
+ * and sends SVC_REQUEST message imp, formated and completed by
+ * dispatcher and received by NI_ServiceRequest function of the client
+ *
+ *
+ */
+static NI_HandPtr
+NI_DirectServiceRequest(NIMsgPtr imp, NI_HandPtr sconnhp)
+{
+ int timeout = 30;
+ int status;
+ struct sockaddr_in sconnaddr;
+ char buf[20];
+
+ MemFill((VoidPtr) &sconnaddr, '\0', sizeof(sconnaddr));
+ sconnaddr.sin_family = AF_INET;
+ sconnaddr.sin_addr.s_addr = htonl(imp->msun.svcreq->server_ip);
+ if (GetAppParam("NCBI", "NET_SERV", "PROXY_SERV_OVERRIDE", "", buf, sizeof buf) > 0)
+ {
+ sconnaddr.sin_addr.s_addr = inet_addr(buf);
+ }
+ sconnaddr.sin_port = htons(imp->msun.svcreq->server_port);
+
+RETRY1:
+
+
+#ifndef NETP_INET_NEWT
+ status = NI_CONNECT(sconnhp->sok, (struct sockaddr PNTR) &sconnaddr,
+ sizeof(sconnaddr));
+#else
+ status = NI_CONNECT(sconnhp->sok, &sconnaddr, sizeof(sconnaddr));
+#endif
+ if (status < 0) {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(status);
+#endif
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ goto RETRY1;
+
+#ifdef NETP_INET_PCNFS
+ case 0:
+#endif /* NETP_INET_PCNFS */
+ case EWOULDBLOCK:
+ case EINPROGRESS:
+ /* if the connect()ion is not established immediately, a */
+ /* select() can be performed where the corresponding "write" */
+ /* file descriptor will be enabled once the connect()ion has been*/
+ /* established */
+
+ if (sokselectw(sconnhp->sok, timeout) != 0) {
+ MsgDestroyHandle(sconnhp);
+ return NULL;
+ }
+ break;
+
+ default:
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_DIRUNCONNECT; /* cannot establish direct connection */
+ return NULL;
+ }
+ }
+
+ /* Now we are sending service request directly to the server */
+
+ if (MsgWrite(sconnhp, imp, TRUE) < 0) {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_DIRUNCONNECT;
+ return NULL;
+ }
+ return sconnhp;
+}
+
+
+
+/*
+ * Purpose: Disconnect from a service provider
+ *
+ * Parameters:
+ * mhp Message handle for the server
+ *
+ * Returns:
+ * 0, always
+ *
+ *
+ * Description:
+ * Disconnect from a service provider, essentially by just
+ * closing the communication socket to that service provider.
+ */
+
+static Int2 s_ServiceDisconnect(NI_HandPtr mhp)
+{
+ if (activityHook != NULL)
+ {
+ activityHook(mhp, NetServHook_svcdisconn, 0);
+ }
+
+ MsgDestroyHandle(mhp);
+ return 0;
+} /* NI_ServiceDisconnect */
+
+
+
+/*
+ * Purpose: Obtain the read file descriptor from a "message handle"
+ *
+ * Parameters:
+ * handp Message handle
+ *
+ * Returns:
+ * Socket associated with message handle
+ *
+ *
+ * Description:
+ * Get the read file desciptor from a message handle. This
+ * might be useful, for example, when wishing to perform
+ * "direct" I/O to the socket after a connection has been
+ * established with a server/client.
+ */
+
+NLM_EXTERN int NI_ServiceGetReadFd(NI_HandPtr handp)
+{
+ return handp->sok;
+} /* NI_ServiceGetReadFd */
+
+
+
+/*
+ * Purpose: Obtain the write file descriptor from a "message handle"
+ *
+ * Parameters:
+ * handp Message handle
+ *
+ * Returns:
+ * Socket associated with message handle
+ *
+ *
+ * Description:
+ * Get the write file desciptor from a message handle. This
+ * might be useful, for example, when wishing to perform
+ * "direct" I/O to the socket after a connection has been
+ * established with a server/client.
+ */
+
+NLM_EXTERN int NI_ServiceGetWriteFd(NI_HandPtr handp)
+{
+ return handp->sok;
+} /* NI_ServiceGetWriteFd */
+
+
+
+/*
+ * Purpose: Populate a service request with a service name and version #s
+ *
+ * Parameters:
+ * req Service request
+ * name Service name
+ * vermin Minimum version number for this service
+ * vermax Maximum version number for this service
+ *
+ * Returns:
+ * -1, if the name is a NULL pointer
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Populate the service request with the specified service name
+ * and version numbers, dynamically allocating space for the
+ * service name.
+ */
+
+NLM_EXTERN Int2 NI_RequestSetService(NI_ReqPtr req, CharPtr name, Uint2 vermin, Uint2 vermax)
+{
+ if (name == NULL) {
+ ni_errno = NIE_INVAL;
+ return -1;
+ }
+ req->service->name = StringSave(name);
+ req->service->minVersion = vermin;
+ req->service->maxVersion = vermax;
+ req->service->typeL = NULL;
+ return 0;
+} /* NI_RequestSetService */
+
+
+
+/*
+ * Purpose: Populate a service request with an additional resource
+ *
+ * Parameters:
+ * req Service request
+ * name Resource name
+ * type Service type
+ * vermin Minimum version number for this resource
+ * vermax Maximum version number for this resource
+ *
+ * Returns:
+ * -1, if the name is a NULL pointer
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Insert the information for this resource into a list of
+ * resources associated with this service request. This
+ * function may be called one or more times (or, not at all) to
+ * populate a service request with one or more resources.
+ */
+
+NLM_EXTERN Int2 NI_RequestAddResource(NI_ReqPtr req, CharPtr name, CharPtr type, Uint2 vermin, Uint2 vermax)
+
+{
+ NIResPtr resp;
+
+ if (name == NULL) {
+ ni_errno = NIE_INVAL;
+ return -1;
+ }
+ resp = NI_MakeResource();
+ resp->name = StringSave(name);
+ if (type != NULL)
+ resp->type = StringSave(type);
+ resp->minVersion = vermin;
+ resp->maxVersion = vermax;
+ req->resourceL = ListInsertPrev((VoidPtr) resp, req->resourceL); /* add to end of list */
+ return 0;
+} /* NI_RequestAddResource */
+
+
+
+/* THESE FUNCTIONS NOT VISIBLE TO API USER */
+
+/*
+ * Purpose: Partially halt Network Services
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ *
+ * Description:
+ * Halt network services, except refrain from freeing the
+ * parameters which are set by NI_SetDispatcher().
+ */
+
+static void
+HaltServices (NI_DispatcherPtr disp)
+{
+ if (disp == NULL)
+ return;
+
+ if (disp->referenceCount > 0)
+ return;
+
+ if (activityHook != NULL)
+ {
+ activityHook((NI_HandPtr) disp, NetServHook_dispdisconn, 0);
+ }
+
+ MsgDestroyHandle(disp->dispHP);
+ MsgDestroyHandle(disp->svcsHP);
+ NI_DestroyRequest(disp->reqResponse);
+ if (disp->identity != NULL) {
+ MemFree (disp->identity->username);
+ MemFree (disp->identity->group);
+ MemFree (disp->identity->domain);
+ MemFree (disp->identity);
+ disp->identity = NULL;
+ }
+ disp->dispHP = NULL;
+ disp->svcsHP = NULL;
+ disp->reqResponse = NULL;
+ if (disp->encryptInfo != NULL)
+ {
+ if (disp->encryptInfo != NULL)
+ NI_DestroyPubKey((NIPubKeyPtr) disp->encryptInfo->data.ptrvalue);
+ ValNodeFree(disp->encryptInfo);
+ }
+
+#ifdef NETP_INET_WSOCK
+ /* we have an obligation to perform one cleanup call for every Startup */
+ while (wsaStartupCount-- > 0)
+ {
+ WSACleanup();
+ }
+#endif
+}
+
+
+/*
+ * Purpose: Lookup a port # in config file and possible NIS
+ *
+ * Parameters:
+ * service Name of config. file entry
+ * networkOrder Boolean, indicates whether value should be returned in host
+ * order or network order.
+ *
+ * Description:
+ * Look up the specified entry in the NCBI config. file, and
+ * lookup in NIS the name obtained from the config file if it's
+ * non-numeric.
+ *
+ * Note:
+ * The intent of this function is that, in most cases, the
+ * GetAppParam() entry will not be present, and a default value
+ * will be used instead. The getservbyname() call is intended
+ * to be a last resort, because this may be slow on some systems.
+ */
+
+static Uint2
+GetByConfigOrServ(CharPtr service, Boolean networkOrder)
+{
+ struct servent PNTR portEntry;
+ Char buf[50];
+ Uint2 port;
+
+ if (GetAppParam("NCBI", "NET_SERV", service, "", buf, sizeof buf) <= 0)
+ {
+ port = 0;
+ } else {
+ if (StrSpn(buf, "0123456789") == StrLen(buf))
+ { /* all numeric */
+ port = (Uint2)atoi(buf);
+ if (networkOrder)
+ port = htons(port);
+ } else {
+ /* entry from configuration file is name to use in getservbyname */
+ if ((portEntry = getservbyname(buf, "tcp")) == NULL)
+ {
+ port = 0;
+ } else {
+ port = portEntry->s_port;
+ if (! networkOrder)
+ port = ntohs(port);
+ }
+ }
+ }
+
+ return port;
+}
+
+
+/*
+ * Purpose: Connect to the dispatcher
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * host Name of the host on which dispatcher resides
+ * service Name of the "service" (i.e., port) to which we should connect
+ * timeout How long to wait for dispatcher to respond, 0 ==> use default
+ *
+ * Returns:
+ * NULL, if the attempt to connect failed
+ * a pointer to the "Msg" structure for the dispatcher, otherwise
+ *
+ *
+ * Description:
+ * Connect to the dispatcher on the specified hostname on the
+ * specified service (where a service maps to a port number).
+ * This is done by establishing a socket to the dispatcher,
+ * and then connect()ing to that socket; the dispatcher should
+ * be listen()ing on that socket, and should subsequently accept()
+ * the connection request.
+ *
+ * While doing this, also obtain other useful information;
+ * namely, the dotted IP address of the local host, and the
+ * high and low port numbers to be used when attempting
+ * dispatcher connections. This global information is used
+ * elsewhere.
+ */
+
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif /* INADDR_NONE */
+
+static NI_HandPtr
+DispatchConnect(NI_DispatcherPtr disp, CharPtr host, CharPtr service, int timeout)
+{
+ struct hostent PNTR dispHost, PNTR localHost;
+ struct sockaddr_in serv_addr;
+ NI_HandPtr dHP;
+ Uint2 disp_port;
+ Uint4 srvadd;
+ Char servInetAddr[INETADDR_SIZ], localHostName[SVC_HOST_SIZ];
+ Char t_service[64];
+ int status;
+ Int4 connectStartTime;
+
+ if (disp == NULL)
+ return NULL;
+
+
+ serv_addr.sin_family = AF_INET;
+
+ srvadd = inet_addr(host);
+ if ((Int4)srvadd != INADDR_NONE) /* malformed request */
+ MemCopy((VoidPtr) &serv_addr.sin_addr, (VoidPtr) &srvadd, sizeof(srvadd));
+ else {
+ if ((dispHost = gethostbyname(host)) == NULL) {
+ ni_errno = NIE_NOHOSTENT;
+ return NULL;
+ }
+/* MemCopy((VoidPtr)&serv_addr.sin_addr, (VoidPtr)(dispHost->h_addr), dispHost->h_length);*/
+ MemCopy(&serv_addr.sin_addr, dispHost->h_addr, dispHost->h_length);
+ }
+ StringCpy(servInetAddr, inet_ntoa(serv_addr.SIN_ADDR));
+
+ if ((disp_port = GetByConfigOrServ(service, TRUE)) == 0)
+ {
+ if (service)
+ StringCpy(t_service, service); /* because Windows barfs on the pointer */
+ else
+ t_service[0] = 0;
+ if ((disp_port = htons((unsigned short)atoi(t_service))) == 0)
+ disp_port = htons(NI_DFLT_SVC_PORT);
+ }
+ if (ntohs(disp_port) <= NI_LAST_RESERVED_PORT) {
+ ni_errno = NIE_NOSERVENT;
+ return NULL;
+ }
+
+ /* get the Internet address of the "local host" */
+#ifdef NETP_INET_MACTCP
+ /* simpler solution to avoid the hazards of gethostname() */
+ {
+ unsigned long localHostId;
+
+ localHostId = gethostid();
+ StringCpy(disp->localHostAddr, inet_ntoa(* (H_ADDR_TYPE) &localHostId));
+ }
+#else
+ gethostname(localHostName, SVC_HOST_SIZ);
+ if ((localHost = gethostbyname(localHostName)) == NULL) {
+ /* GetAppParam() workaround for PC-NFS 5.0 bug */
+ if (GetAppParam("NCBI", "NET_SERV", "HOST_ADDRESS", "",
+ disp->localHostAddr, sizeof(disp->localHostAddr)) <= 0)
+ { /* use a bogus address which the dispatcher will try to fix */
+ StringCpy(disp->localHostAddr, "0.0.0.0");
+
+ }
+ } else {
+ StringCpy(disp->localHostAddr, inet_ntoa(* (H_ADDR_TYPE) localHost->h_addr));
+ }
+#endif /* NETP_INET_MACTCP */
+
+ if ((disp->loport = GetByConfigOrServ(NI_CLIENT_PORT_LO_NAME, FALSE)) == 0)
+ {
+ if ((disp->loport = (Int2)atoi(NI_CLIENT_PORT_LO_NAME)) == 0)
+ disp->loport = NI_DFLT_CLILO_PORT;
+ }
+ if (disp->loport <= NI_LAST_RESERVED_PORT) {
+ ni_errno = NIE_BADPORT; /* bad low client port */
+ return NULL;
+ }
+
+ if ((disp->hiport = GetByConfigOrServ(NI_CLIENT_PORT_HI_NAME, FALSE)) == 0)
+ {
+ if ((disp->hiport = (Int2)atoi(NI_CLIENT_PORT_HI_NAME)) == 0)
+ disp->hiport = NI_DFLT_CLIHI_PORT;
+ }
+ if (disp->hiport <= NI_LAST_RESERVED_PORT) {
+ ni_errno = NIE_BADPORT; /* bad high client port */
+ return NULL;
+ }
+
+ MemFill((VoidPtr) &serv_addr, '\0', sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = inet_addr(servInetAddr);
+ serv_addr.sin_port = disp_port;
+
+ if ((dHP = MsgMakeHandle(TRUE)) == NULL)
+ return NULL;
+ MsgSetLJError(dHP);
+ if (timeout > 0)
+ MsgSetReadTimeout(dHP, timeout);
+
+ if (activityHook != NULL)
+ {
+ activityHook((NI_HandPtr) disp, NetServHook_dispconn, 0);
+ }
+
+#ifdef NETP_SOCKS
+ if (disp->useSocks)
+ { /* SOCKS can't deal well with blocking connections */
+ NI_SETBLOCKING(dHP->sok);
+ }
+#endif
+
+ connectStartTime = Nlm_GetSecs();
+
+ RETRY:
+#ifndef NETP_INET_NEWT
+ if ((status = NI_CONNECT(dHP->sok, (struct sockaddr PNTR) &serv_addr, sizeof(serv_addr))) < 0) { /* } */
+#else
+ if ((status = NI_CONNECT(dHP->sok, &serv_addr, sizeof(serv_addr))) < 0) {
+ SOCK_ERRNO = ABS(status);
+#endif
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ goto RETRY;
+
+#ifdef NETP_INET_PCNFS
+ /* This is apparently a bug in PC-NFS 4.0 ... a connection attempt */
+ /* on a non-blocking socket yields errno == 0 */
+ case 0:
+#endif /* NETP_INET_PCNFS */
+ case EWOULDBLOCK:
+ case EINPROGRESS:
+ /* if the connect()ion is not established immediately, a */
+ /* select() can be performed where the corresponding "write" */
+ /* file descriptor will be enabled once the connect()ion has been*/
+ /* established */
+ status = sizeof(serv_addr);
+ if (sokselectw(dHP->sok, timeout) == 0
+#ifdef OS_UNIX
+ && getpeername(dHP->sok,(struct sockaddr *) &serv_addr, &status) == 0
+#endif
+ ) {
+ dHP->state = NI_CONNECTED;
+ dHP->connectDelay = (Uint2)(Nlm_GetSecs() - connectStartTime);
+ return dHP;
+ }
+ break;
+
+ default:
+ break;
+ }
+ MsgDestroyHandle(dHP);
+ ni_errno = NIE_DISPCONN; /* can't connect to dispatcher */
+ return NULL;
+ }
+ dHP->state = NI_CONNECTED;
+ dHP->connectDelay = (Uint2)(Nlm_GetSecs() - connectStartTime);
+ return dHP;
+} /* DispatchConnect */
+
+
+/*
+ * Purpose: Convert an FQDN to an IP address
+ *
+ * Parameters:
+ * fqdn A fully-qualified domain name, like "dispatch1.nlm.nih.gov"
+ * ipbuf An output buffer for the dotted-decimal IP address
+ * ipbuflen The length of ipbuf
+ *
+ * Returns:
+ * TRUE, if the address was resolved successfully, FALSE otherwise
+ */
+
+NLM_EXTERN Boolean NI_FqdnToIpaddr(CharPtr fqdn, CharPtr ipbuf, Int2 ipbuflen)
+{
+ struct hostent PNTR dispHost;
+ struct sockaddr_in serv_addr;
+
+ serv_addr.sin_family = AF_INET;
+ if ((dispHost = gethostbyname(fqdn)) != NULL)
+ {
+ MemCopy (&serv_addr.sin_addr, dispHost->h_addr, dispHost->h_length);
+ StringNCpy (ipbuf, inet_ntoa (serv_addr.SIN_ADDR), ipbuflen-1);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+
+
+/*
+ * Purpose: Get the platform on which this client is running
+ *
+ * Parameters:
+ * none
+ *
+ * Returns:
+ * the client's platform, or NI_PLATFORM_UNKNOWN
+ *
+ *
+ * Description:
+ * Calculate what platform this client is running on.
+ *
+ *
+ * Note:
+ * Although the initial implementation of this function
+ * calculates the platform-type at compile-time, it is
+ * legitimate to perform some computation at run time, e.g.,
+ * to determine whether this client is using a particular
+ * low-level driver.
+ *
+ * The dispatcher and servers should not rely on the
+ * information which is received for platform-type, because
+ * the client may be lying, either because of a coding error
+ * or malice on the part of a client developer.
+ */
+
+NLM_EXTERN Int2 NI_GetPlatform (void)
+{
+ static Boolean alreadyInited = FALSE;
+ static Int2 retval;
+
+ if (alreadyInited)
+ {
+ return retval;
+ }
+
+ alreadyInited = TRUE;
+
+ retval = NI_PLATFORM_UNKNOWN;
+
+#ifdef NETP_INET_MACTCP
+ retval = NI_PLATFORM_MAC;
+#endif
+
+#ifdef OS_VMS
+#ifdef NETP_INET_TGV
+ retval = NI_PLATFORM_VMS_TGV;
+#endif
+#ifdef NETP_INET_TWG
+ retval = NI_PLATFORM_VMS_TWG;
+#endif
+#ifdef NETP_INET_WPW
+ retval = NI_PLATFORM_VMS_WPW;
+#endif
+#ifdef NETP_INET_UCX
+ retval = NI_PLATFORM_VMS_UCX;
+#endif
+#ifdef OS_AXP_VMS
+ retval = NI_PLATFORM_AXP_OPENVMS;
+#endif
+#endif /* OS_VMS */
+
+#ifdef OS_UNIX
+ retval = NI_PLATFORM_GENERIC_UNIX;
+#ifdef PROC_IBM370
+ retval = NI_PLATFORM_IBM370AIX;
+#endif
+#ifdef OS_UNIX_SUN
+ retval = NI_PLATFORM_SUN;
+#endif
+#if defined(OS_UNIX_OSF1) && defined(PROC_ALPHA)
+ retval = NI_PLATFORM_ALPHA_OSF1;
+#endif
+#ifdef COMP_AUX
+ retval = NI_PLATFORM_AUX;
+#endif
+#if defined(COMP_CRAY) && defined(PROC_YMP)
+ retval = NI_PLATFORM_CRAY;
+#endif
+#ifdef PROC_CONVEX
+ retval = NI_PLATFORM_CONVEX;
+#endif
+#ifdef PROC_HPPA
+ retval = NI_PLATFORM_HPUX;
+#endif
+#ifdef OS_UNIX_NEXT
+ retval = NI_PLATFORM_NEXT;
+#endif
+#ifdef PROC_MIPS
+ retval = NI_PLATFORM_SGI;
+#endif
+#ifdef OS_UNIX_ULTRIX
+ retval = NI_PLATFORM_ULTRIX;
+#endif
+#if defined(OS_UNIX_SYSV) && defined(PROC_SPARC)
+ retval = NI_PLATFORM_SYSV_ON_SPARC;
+#endif
+#ifdef OS_UNIX_AIX
+ retval = NI_PLATFORM_AIX;
+#endif
+#ifdef OS_UNIX_LINUX
+#ifdef PROC_ALPHA
+ retval = NI_PLATFORM_LINUX_ALPHA;
+#else
+ retval = NI_PLATFORM_LINUX;
+#endif
+#endif
+#endif /* OS_UNIX */
+
+#ifdef OS_DOS
+ retval = NI_PLATFORM_DOS;
+#ifdef WIN16
+ retval = NI_PLATFORM_WIN16;
+#endif
+#ifdef NETP_INET_NEWT
+ retval = NI_PLATFORM_WIN_NEWT;
+#endif
+#ifdef NETP_INET_PCNFS
+ retval = NI_PLATFORM_WIN_PCNFS;
+#endif
+#ifdef WINSOCK
+ retval = NI_PLATFORM_WIN_WINSOCK;
+#endif
+#endif /* OS_DOS */
+
+#ifdef OS_WINNT
+ retval = NI_PLATFORM_WINNT;
+#endif
+
+ return retval;
+}
+
+
+/*
+ * Purpose: Set the "identity" of this client
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * user New Username
+ * group New Groupname
+ * domain New DomainName
+ *
+ * Returns:
+ * 0, always
+ *
+ *
+ * Description:
+ * Allocate the space for the "UID" structure, if not already
+ * allocated, and populate it with the user name, group name,
+ * and domain name.
+ */
+
+static Int2
+SetIdentity(NI_DispatcherPtr disp, CharPtr user, CharPtr group, CharPtr domain)
+{
+ if (disp == NULL)
+ return 0;
+
+ if (disp->identity == NULL)
+ disp->identity = NI_MakeUid();
+
+ if (disp->identity->username != NULL)
+ MemFree(disp->identity->username);
+ disp->identity->username = StringSave(user);
+ if (disp->identity->group != NULL)
+ MemFree(disp->identity->group);
+ if (group != NULL)
+ disp->identity->group = StringSave(group);
+ else
+ disp->identity->group = NULL;
+ if (disp->identity->domain != NULL)
+ MemFree(disp->identity->domain);
+ disp->identity->domain = StringSave(domain);
+ return 0;
+} /* SetIdentity */
+
+
+
+/*
+ * Purpose: Copy from the "identity" UID to the specified UID data struct
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * uid UID structure to be copied into
+ *
+ * Returns:
+ * -1, if invalid arguments
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Copy fields from the "identity" UID data structure into the
+ * UID data structure provided by the caller.
+ */
+
+static Int2
+CopyIdentity(NI_DispatcherPtr disp, NI_UidPtr uid)
+{
+ if (disp == NULL || disp->identity == NULL || uid == NULL)
+ return -1;
+ if (uid->username != NULL)
+ MemFree(uid->username);
+ uid->username = StringSave(disp->identity->username);
+ if (uid->group != NULL)
+ MemFree(uid->group);
+ uid->group = StringSave(disp->identity->group);
+ if (uid->domain != NULL)
+ MemFree(uid->domain);
+ uid->domain = StringSave(disp->identity->domain);
+ return 0;
+} /* CopyIdentity */
+
+
+
+/*
+ * Purpose: Select the next available port within the given range,
+ * and bind a socket to it.
+ *
+ * Parameters:
+ * sok Socket to be bound to a port (INPUT)
+ * sokadr Socket data structure to be populated (OUTPUT)
+ * loport Minimum acceptable port number
+ * hiport Maximum acceptable port number
+ *
+ * Returns:
+ * 0, if unable to bind to a port
+ * the selected ("bound") port number, otherwise
+ *
+ *
+ * Description:
+ * Iterate through the range of acceptable port numbers, until
+ * an unused port number can be selected to which the socket
+ * can be bound.
+ */
+
+static Uint2
+bindPort(int sok, struct sockaddr_in PNTR sokadr, Int2 loport, Int2 hiport, Uint4 remoteHost)
+{
+ int status;
+#ifdef NETP_INET_MACTCP
+ int delta = 0;
+ Char buf[20];
+#endif
+
+ if (hiport == 0)
+ hiport = loport;
+ if (loport > hiport)
+ return 0;
+
+#ifdef NETP_INET_MACTCP
+ /* use a hint from the configuration file to avoid port # conflicts */
+ if (hiport > loport && GetAppParam("NCBI", "NET_SERV", "PORT_DELTA", "0",
+ buf, sizeof buf) > 0)
+ {
+ delta = atoi(buf);
+ loport += delta % (hiport - loport);
+ sprintf (buf, "%d", delta + 1);
+ SetAppParam("NCBI", "NET_SERV", "PORT_DELTA", buf);
+ }
+#endif
+
+ MemFill((VoidPtr) sokadr, '\0', sizeof(struct sockaddr_in));
+ sokadr->sin_family = AF_INET;
+ sokadr->sin_addr.s_addr = INADDR_ANY;
+
+ while (loport <= hiport) {
+ sokadr->sin_port = htons(loport);
+#ifdef NETP_INET_NEWT
+ if ((status = NI_BIND(sok, sokadr, sizeof(struct sockaddr_in), htonl(remoteHost))) == 0)
+#else
+ if ((status = NI_BIND(sok, (struct sockaddr PNTR) sokadr, sizeof(struct sockaddr_in), htonl(remoteHost))) == 0)
+#endif /* NETP_INET_NEWT */
+ return (Uint2) ntohs(sokadr->sin_port);
+ else {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(status);
+#endif
+ loport++;
+ }
+ }
+ return 0;
+} /* bindPort */
+
+
+
+/* SERVER FUNCTIONS */
+
+static int writepipe PROTO((int fd, char *buf, int len));
+
+/*
+ * Purpose: Write a message on the pipe from a child server application
+ * process to its parent NCBID.
+ *
+ * Parameters:
+ * fd Pipe file descriptor
+ * buf Buffer to be written
+ * len Length of buffer
+ *
+ * Returns:
+ * 0, if unable to write because the pipe is full
+ * number of bytes written, otherwise
+ *
+ *
+ * Description:
+ * Write the specified number of bytes to a pipe, and handle
+ * multiple write attempts if necessary, to handle the case where
+ * a write() may be interrupted by a signal.
+ *
+ * Note:
+ * This routine is only used by a child process after it has been
+ * forked and before it has been execed.
+ */
+
+static int
+writepipe(int fd, char *buf, int len)
+{
+ int byteswrit;
+
+ WriteAgain:
+ if ((byteswrit = write(fd, buf, len)) < 0) {
+ switch (errno) {
+ case EINTR:
+ goto WriteAgain;
+
+ case EWOULDBLOCK:
+ default:
+ return 0;
+ }
+ }
+
+ return byteswrit;
+} /* writepipe */
+
+static Int2 StandAlonePort(void)
+{
+#ifdef OS_UNIX
+ CharPtr env;
+ if ((env = getenv("NI_STANDALONE_SERVER")) != NULL)
+ return (Int2)atoi(env);
+#endif
+ return 0;
+}
+
+
+/*
+ * Purpose: Send an "ACK" from a child server application process to its
+ * parent NCBID.
+ *
+ * Returns:
+ * 0, if the ACK was sent successfully
+ * -1, otherwise
+ *
+ *
+ * Description:
+ * Write an "ACK" from a child server application process to its
+ * parent NCBID, on the pipe connecting the two processes.
+ *
+ * Note:
+ * This routine should be called by a child process after it has
+ * determined that it has started successfully. At most one
+ * of NI_ServerACK() and NI_ServerNACK() may be called.
+ */
+
+#define TEMP_BUF_SIZ 256
+
+NLM_EXTERN int NI_ServerACK(void)
+{
+ int wstat;
+ Char temp_buf[TEMP_BUF_SIZ];
+ Int2 port;
+
+ if ((port = StandAlonePort()) == 0)
+ { /* not stand-alone */
+ sprintf(temp_buf, PIPE_MSG_FMT, NIE_SERVACK, "OK");
+ if ((wstat = writepipe(STDPIPE, temp_buf, strlen(temp_buf))) <= 0) {
+ ni_errno = NIE_PIPEIO;
+ strcpy(ni_errtext, (wstat == 0) ? "EWOULDBLOCK" : sys_errlist[errno]);
+ return -1;
+ }
+ } else { /* stand-alone */
+#ifdef OS_UNIX
+ /* non-UNIX platforms currently experience compilation errors */
+ struct sockaddr_in soktAddr;
+ NI_HandPtr hp;
+ int sok;
+ int status;
+ struct sockaddr_in sockaddr;
+ int soktLen;
+ CharPtr security;
+ int one = 1; /* for SO_REUSEADDR */
+
+ hp = MsgMakeHandle(TRUE);
+ NI_SETBLOCKING(hp->sok);
+
+ MemFill(&sockaddr, '\0', sizeof(struct sockaddr_in));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+ sockaddr.sin_port = htons(port);
+
+ if (setsockopt(hp->sok, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
+ sizeof(one)) < 0)
+ {
+ Message (MSG_ERROR, "Unable to set socket re-usability, errno = %d", errno);
+ }
+
+#ifdef NETP_INET_NEWT
+ if ((status = bind(hp->sok, &sockaddr, sizeof(struct sockaddr_in))) == 0)
+#else
+ if ((status = bind(hp->sok, (struct sockaddr PNTR) &sockaddr, sizeof(struct sockaddr_in))) != 0)
+#endif /* NETP_INET_NEWT */
+ { /* error */
+ ErrPostEx(SEV_FATAL,0,0,
+ "Bind failed on socket %d, status = %d, errno = %d",
+ hp->sok, status, errno);
+ return -1;
+ }
+
+ NI_LISTEN(hp->sok, 1);
+ close(0); /* so that accept() will return 0 */
+ soktLen = sizeof(soktAddr);
+
+ /* accept the connection */
+ if ((sok = NI_ACCEPT(hp->sok, (struct sockaddr *) &soktAddr, &soktLen)) < 0)
+ { /* error */
+ ErrPostEx(SEV_FATAL,0,0, "Accept returned bad file descriptor %d, errno = %d",
+ sok, errno);
+ return -1;
+ }
+ LOG_SOCKET(sok, TRUE);
+ NI_SETNONBLOCKING(sok);
+ MsgDestroyHandle(hp);
+ if ((security = getenv("NI_STANDALONE_SECURITY")) != NULL)
+ { /* security must be substring of client address */
+ if (StrNCmp(inet_ntoa(soktAddr.SIN_ADDR), security, StrLen(security)) != 0)
+ {
+ close(sok);
+ ErrPostEx(SEV_FATAL,0,0, "Security violation from IP address %s, security = %s\n",
+ inet_ntoa(soktAddr.SIN_ADDR), security);
+ return -1;
+ }
+ }
+#endif /* OS_UNIX */
+ }
+ return 0;
+} /* NI_ServerACK */
+
+
+
+/*
+ * Purpose: Send an "NACK" from a child server application process to its
+ * parent NCBID.
+ *
+ * Returns:
+ * 0, if the NACK was sent successfully
+ * -1, otherwise
+ *
+ *
+ * Description:
+ * Write an "NACK" from a child server application process to its
+ * parent NCBID, on the pipe connecting the two processes.
+ *
+ * Note:
+ * This routine should be called by a child process after it has
+ * determined that it will be unable to start successfully. In
+ * the event that this routine is not called (or is unable to
+ * perform its function), a timeout mechanism must be relied
+ * upon for the NCBID to realize that a child has started
+ * unsuccessfully.
+ *
+ * At most one of NI_ServerACK() and NI_ServerNACK() may be called.
+ */
+
+NLM_EXTERN int NI_ServerNACK(CharPtr err_text)
+{
+ int wstat;
+ Char temp_buf[TEMP_BUF_SIZ];
+
+ sprintf(temp_buf, PIPE_MSG_FMT, NIE_SERVNACK, err_text);
+ if (StandAlonePort() == 0)
+ { /* not stand-alone */
+ if ((wstat = writepipe(STDPIPE, temp_buf, strlen(temp_buf))) <= 0) {
+ ni_errno = NIE_PIPEIO;
+ strcpy(ni_errtext, (wstat == 0) ? "EWOULDBLOCK" : sys_errlist[errno]);
+ return -1;
+ }
+ } else { /* stand-alone */
+ ErrPostEx(SEV_FATAL,0,0, "Stand-alone server failed startup {%s}", temp_buf);
+ return -1;
+ }
+ return 0;
+} /* NI_ServerNACK */
+
+static Int2 LIBCALLBACK NI_AsnWriteSTDOUT(Pointer p,CharPtr buf,Uint2 len)
+{
+ int bytes = write(STDOUT, buf, len);
+
+ return (Int2)(bytes > 0 ? bytes : 0);
+}
+
+
+/*
+ * Purpose: Open the stream to be used for ASN I/O between a server
+ * application process and its client.
+ *
+ * Returns:
+ * NULL, if something went wrong
+ * a pointer to the Msg structure, otherwise
+ *
+ *
+ * Description:
+ * Create a "Msg" structure for ASN I/O, and associate the Msg's
+ * socket with the standard input file descriptor (STDIN), which is
+ * the communication socket between the server application process
+ * and its client.
+ *
+ * Note:
+ * This routine should only be called by a child application
+ * process (not by a client).
+ */
+
+NLM_EXTERN NI_HandPtr NI_OpenASNIO(void)
+{
+ NI_HandPtr hp;
+ CharPtr agent;
+
+ if ((hp = MsgMakeHandle(FALSE)) == NULL)
+ return NULL;
+
+ MsgSetReadTimeout(hp, NI_SERV_LISTEN_TIMEOUT); /* set default for servers to listen */
+
+ if ((hp->sok = dup(STDIN)) == -1) {
+ MsgDestroyHandle(hp);
+ return NULL;
+ }
+
+ agent = getenv("HTTP_USER_AGENT");
+ if(agent){
+ hp->waip->writefunc=NI_AsnWriteSTDOUT;
+ }
+
+ LOG_SOCKET(hp->sok, TRUE);
+ {
+ CharPtr buf;
+ Char key[8];
+
+ if ((buf = getenv("NI_DESKEY")) != NULL &&
+ (AsnTypeStringToHex(buf, StrLen(buf), key, NULL) == 0))
+ {
+ NI_SetupDESEncryption(hp, (UcharPtr) key);
+ }
+ }
+ return hp;
+} /* NI_OpenASNIO */
+
+
+
+/*
+ * Purpose: Close the ASN stream between a server application process and
+ * its client.
+ *
+ * Returns:
+ * -1 if something went wrong
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Close the stream by closing the socket and deleting the
+ * associated data structures.
+ *
+ * Note:
+ * This routine should only be called by a child application
+ * process (not by a client).
+ */
+
+NLM_EXTERN Int2 NI_CloseASNIO(NI_HandPtr hp)
+{
+ return MsgDestroyHandle(hp);
+} /* NI_CloseANSIO */
+
+
+
+/* MISC FUNCTIONS */
+
+/* sokselectr and sokselectw are not prototyped in ni_lib.h */
+
+/*
+ * Purpose: Wait for a "read" socket to become ready to read, or for
+ * a timeout to occur.
+ *
+ * Returns:
+ * -1 if something went wrong
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Wait for the indicated "read" socket to be marked as
+ * "selected" by a socket() call.
+ *
+ * Note:
+ * This routine is presently unused.
+ *
+ * The timeout mechanism is not exactly enforced, because
+ * received signals could result in a longer timeout period.
+ */
+
+int sokselectr(int fd)
+{
+ fd_set rfds;
+ int ready;
+ struct timeval timeout;
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ timeout.tv_sec = NI_SELECT_TIMEOUT;
+ timeout.tv_usec = 0;
+ while ((ready = select(fd+1, &rfds, NULL, NULL, &timeout)) == -1) {
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ continue;
+
+ default:
+ ni_errno = NIE_MISC;
+ sprintf(ni_errtext, "%s", sys_errlist[SOCK_INDEX_ERRNO]);
+ return -1;
+ }
+ }
+ if (ready == 0) {
+ strcpy(ni_errtext, ni_errlist[ni_errno]);
+ ni_errno = NIE_TIMEOUT;
+ return -1;
+ }
+ if (FD_ISSET(fd, &rfds))
+ return 0;
+ else
+ return -1;
+} /* sokselectr */
+
+
+
+/*
+ * Purpose: Wait for a "write" socket to become ready to write, or for
+ * a timeout to occur.
+ *
+ * Returns:
+ * -1 if something went wrong
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Wait for the indicated "write" socket to be marked as
+ * "selected" by a socket() call.
+ *
+ * Note:
+ * This routine can be used when waiting for a connect() to go
+ * through successfully.
+ *
+ * The timeout mechanism is not exactly enforced, because
+ * received signals could result in a longer timeout period.
+ */
+
+int sokselectw(int fd, int seconds)
+{
+ fd_set wfds;
+ int ready;
+ struct timeval timeout;
+
+ FD_ZERO(&wfds);
+ FD_SET(fd, &wfds);
+ timeout.tv_sec = NI_SELECT_TIMEOUT;
+ if (seconds > 0) /* override default */
+ timeout.tv_sec = seconds;
+ timeout.tv_usec = 0;
+ while ((ready = select(fd+1, NULL, &wfds, NULL, &timeout)) == -1) {
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ continue;
+
+ default:
+ ni_errno = NIE_MISC;
+ sprintf(ni_errtext, "%s", sys_errlist[SOCK_INDEX_ERRNO]);
+ return -1;
+ }
+ }
+ if (ready == 0) {
+ strcpy(ni_errtext, ni_errlist[ni_errno]);
+ ni_errno = NIE_TIMEOUT;
+ return -1;
+ }
+ if (FD_ISSET(fd, &wfds))
+ {
+#ifdef OS_UNIX
+ int err;
+ int optlen;
+
+ optlen = sizeof(int);
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) >= 0 &&
+ err != 0) /* check for an error */
+ return -1; /* got some error */
+#endif /* OS_UNIX */
+ return 0;
+ }
+ else
+ return -1;
+} /* sokselectw */
+
+
+
+/*
+ * Purpose: Parse the error number from an ASN error string which was
+ * formatted at a low level.
+ *
+ * Returns:
+ * -1, if unable to parse the string
+ * the parsed error number, otherwise
+ *
+ *
+ * Description:
+ * Parse the error number from an ASN error string which was
+ * prepared by the ASN tools, and formatted at a low level.
+ *
+ * Note:
+ * The parsing mechanism is dependent upon any future format
+ * changes which may occur in the ASN tools.
+ */
+
+int getAsnError(char *str)
+{
+ int errnum;
+
+ if (sscanf(str, "%*s %*s %*s [-%d]", &errnum) < 1)
+ errnum = -1;
+ return errnum;
+} /* getAsnError */
+
+
+/*
+ * Purpose: Set the Connection ID file pointer
+ *
+ * Parameters:
+ * fp The new value for the file descriptor
+ *
+ *
+ * Description:
+ * Set the Connection ID file pointer. This is used to update
+ * the connection ID each time it is updated, to keep the
+ * value current.
+ *
+ * Note:
+ * In reality, this should only be called by the dispatcher.
+ */
+
+void SetConFilePtr (FILE *fp)
+{
+ conid_fp = fp;
+}
+
+
+/*
+ * Purpose: Update the connection ID file
+ *
+ * Parameters:
+ * conid The new connection ID value
+ *
+ *
+ * Description:
+ * Update the connection ID file, and be sure to flush the stream,
+ * to try to ensure that output really occurs.
+ *
+ * Note:
+ * Should be called every time the "next" connection ID is
+ * modified.
+ */
+
+NLM_EXTERN void WriteConFile (Uint4 conid)
+{
+ if (conid_fp != NULL) {
+ (void) fseek(conid_fp, 0L, SEEK_SET);
+ (void) FileWrite((CharPtr) &conid, 1, sizeof(conid), conid_fp);
+ (void) fflush (conid_fp);
+ }
+}
+
+
+/*
+ * Purpose: Close the connection ID file
+ *
+ *
+ * Description:
+ * Close the connection ID file.
+ * to try to ensure that output really occurs.
+ *
+ * Note:
+ * In reality, this should only be called by the dispatcher.
+ */
+
+void CloseConFile (void)
+{
+ if (conid_fp != NULL) {
+ fclose (conid_fp);
+ conid_fp = NULL;
+ }
+}
+
+
+
+/*
+ * Purpose: Check for expired timers
+ *
+ *
+ * Description:
+ * For every expired timer, call the specified timer
+ * callback function, which is in turn responsible for cancelling
+ * the timer.
+ *
+ * Note:
+ * Timer checks only take place when this function is called.
+ * Therefore, it is the responsibility of an application to
+ * intermitently call this function. This could be done, e.g.
+ * using the UNIX alarm clock mechanism, or inside of an event
+ * loop.
+ *
+ * The order of operations is significant here, because the
+ * hook function must cancel the timer. To perform the linked
+ * list traversal in a less careful manner could result in
+ * illegal memory accesses.
+ *
+ * The timer list in managed in a very unsophisticated manner;
+ * if lots of timers were anticipated, the list would be
+ * maintained sorted by time, and all of the timer functions
+ * would need to maintain and traverse the timer list based
+ * upon this criterion.
+ *
+ * A count is used as a failsafe mechanism against infinite loops.
+ */
+
+#define NI_MAX_TIMERS 1000
+
+NLM_EXTERN void NI_ProcessTimers(void)
+{
+ NodePtr t;
+ NodePtr tnew;
+ NI_TimerPtr timer;
+ NodePtr timersToBeFired = NULL;
+ time_t curtime;
+ int count = NI_MAX_TIMERS;
+
+ if ((t = timerHead) == NULL)
+ {
+ return;
+ }
+
+ curtime = GetSecs();
+
+ do {
+ timer = (NI_TimerPtr) t->elem;
+ tnew = ListGetNext(t);
+ if (timer != NULL && timer->timeout != NULL_TIMER &&
+ timer->timeout <= curtime)
+ { /* note the timer to be fired */
+ timersToBeFired = ListInsert(timer, timersToBeFired);
+ }
+ if (t == tnew)
+ { /* data structure error, time to bail out */
+ break;
+ }
+ t = tnew;
+ } while (t != timerHead && t != NULL && --count > 0);
+
+ if ((t = timersToBeFired) == NULL)
+ return;
+
+ count = NI_MAX_TIMERS;
+
+ do {
+ timer = (NI_TimerPtr) t->elem;
+ tnew = ListGetNext(t);
+
+ /* mark the timer so it won't fire again */
+ timer->timeout = NULL_TIMER;
+ if (timer->hook != NULL)
+ {
+ timer->hook(timer->hookParam);
+ }
+ t = tnew;
+ } while (t != timersToBeFired && t != NULL && --count > 0);
+
+ ListDelete(timersToBeFired);
+}
+
+
+/*
+ * Purpose: Return the time when the next timeout will occur
+ *
+ * Returns: The time, in seconds, when the next scheduled timeout will
+ * occur, or NULL_TIMER, if there are no timers set.
+ *
+ * Description:
+ * Return the time when the next timer timeout will occur.
+ * This information is typically used with the select()
+ * system call, to ensure that a timeout parameter is passed
+ * to select() which is sufficiently short to ensure that
+ * the application will call NI_ProcessTimers() at an
+ * appropriate time.
+ *
+ * Note:
+ * The timer list in managed in a very unsophisticated manner;
+ * if lots of timers were anticipated, the list would be
+ * maintained sorted by time, and all of the timer functions
+ * would need to maintain and traverse the timer list based
+ * upon this criterion.
+ */
+
+NLM_EXTERN time_t NI_GetNextWakeup(void)
+{
+ time_t next_wakeup = NULL_TIMER;
+ NodePtr t;
+ NI_TimerPtr timer;
+
+ NI_ProcessTimers();
+
+ if ((t = timerHead) == NULL)
+ {
+ return NULL_TIMER;
+ }
+
+ do {
+ t = ListGetNext(t);
+ timer = (NI_TimerPtr) t->elem;
+ if (next_wakeup == NULL_TIMER || (timer->timeout != NULL_TIMER &&
+ timer->timeout < next_wakeup))
+ {
+ next_wakeup = timer->timeout;
+ }
+ } while (t != timerHead && t != NULL);
+
+ return next_wakeup;
+}
+
+
+/*
+ * Purpose: Set a timer
+ *
+ * Parameters:
+ * timeout The time in seconds when the timer should expire
+ * hook Callback to be called when (if) the timer expires
+ * hookParam Parameter to be passed to caller's hook when the timer expires
+ *
+ *
+ * Returns: The "timer ID", really a pointer to the timer data structure
+ *
+ *
+ * Description:
+ * Sets a timer with the appropriate parameters.
+ *
+ * Note:
+ * The timer list in managed in a very unsophisticated manner;
+ * if lots of timers were anticipated, the list would be
+ * maintained sorted by time, and all of the timer functions
+ * would need to maintain and traverse the timer list based
+ * upon this criterion.
+ *
+ * It is the responsibility of the application (usually the
+ * hook function) to cancel the timer.
+ */
+
+NodePtr
+NI_SetTimer(time_t timeout, NI_TimeoutHook hook, Pointer hookParam)
+{
+ NodePtr t;
+ NI_TimerPtr timer;
+
+ timer = (NI_TimerPtr) MemNew(sizeof(NI_Timer));
+ timer->timeout = timeout;
+ timer->hook = hook;
+ timer->hookParam = hookParam;
+ t = ListInsert(timer, timerHead);
+ timerHead = t;
+
+ return t;
+}
+
+
+/*
+ * Purpose: Cancel a timer
+ *
+ * Parameters:
+ * timerID The ID of the timer
+ *
+ *
+ * Description:
+ * Cancel the specified timer by deleting the entry and its
+ * associated data structure.
+ *
+ * Note:
+ * The timer list in managed in a very unsophisticated manner;
+ * if lots of timers were anticipated, the list would be
+ * maintained sorted by time, and all of the timer functions
+ * would need to maintain and traverse the timer list based
+ * upon this criterion.
+ */
+
+NLM_EXTERN void NI_CancelTimer(NodePtr timerId)
+{
+ if (timerId != NULL)
+ {
+ MemFree (timerId->elem);
+ timerHead = ListDelete(timerId);
+ }
+}
+
+
+/*
+ * Purpose: Set an activity hook, to inform the application of key events
+ *
+ * Parameters:
+ * hook The hook (callback function)
+ *
+ *
+ * Description:
+ * Setup a hook function which will subsequently be used to
+ * inform the application of various events; these currently
+ * include:
+ * * Connection to dispatcher
+ * * Disconnection from dispatcher
+ * * Service connection
+ * * Service disconnection
+ * * Bytes written
+ * * Bytes read
+ *
+ * Note:
+ * This hook is global for the running application.
+ */
+
+NLM_EXTERN void NI_SetActivityHook (NI_NetServHook hook)
+{
+ activityHook = hook;
+}
+
+
+/*
+ * Purpose: Return the current activity hook
+ *
+ *
+ * Description:
+ * Return the current activity hook. This is only intended
+ * to be used internally by the Network Services library.
+ * This function is used to avoid making activityHook into a
+ * global variable.
+ */
+
+NLM_EXTERN NI_NetServHook NI_ActivityHook (void)
+{
+ return activityHook;
+}
+
+
+/*
+ * Purpose: Initialize socket management
+ *
+ * Description:
+ * If not already initialized, initialize the socket management
+ * data structures
+ */
+
+static void
+InitLogSocket()
+{
+ static Boolean inited = FALSE;
+
+ if (! inited)
+ {
+ FD_ZERO(&openfds);
+ inited = TRUE;
+ }
+}
+
+
+/*
+ * Purpose: Count the number of open sockets
+ */
+
+NLM_EXTERN Int2 NI_SocketsOpen(void)
+{
+ int sok;
+ Int2 count = 0;
+
+ InitLogSocket();
+ for (sok = 0; sok < FD_SETSIZE; sok++)
+ {
+ if (FD_ISSET(sok, &openfds))
+ count++;
+ }
+ return count;
+}
+
+/*
+ * Purpose: Log each socket transaction
+ */
+
+NLM_EXTERN void NI_LogSocket(int sok, Boolean opening, CharPtr filename, int lineno)
+{
+ InitLogSocket();
+
+ if (sok == INVALID_SOCKET || sok < 0 || sok >= FD_SETSIZE)
+ {
+#ifndef NETP_INET_WSOCK
+ /* FD_SETSIZE doesn't accurately describe the socket range for
+ WinSock applications, so don't generate misleading error msgs */
+ ErrPostEx(SEV_WARNING,0,0, "Bad %s operation on socket %d at %s:%d",
+ opening ? "opening" : "closing", sok, filename, lineno);
+#endif /* NETP_INET_WSOCK */
+ return;
+ }
+
+ if (opening)
+ {
+ TRACE("Just opened socket %d at %s:%d\n", sok, filename, lineno);
+ if (FD_ISSET(sok, &openfds))
+ {
+ ErrPostEx(SEV_ERROR,0,0, "Duplicate open of socket %d at %s:%d",
+ sok, filename, lineno);
+ } else {
+ FD_SET(sok, &openfds);
+ }
+ } else {
+ TRACE("Trying to close socket %d at %s:%d\n", sok, filename, lineno);
+ if (FD_ISSET(sok, &openfds))
+ {
+ FD_CLR(sok, &openfds);
+ } else {
+ ErrPostEx(SEV_ERROR,0,0, "Duplicate close of socket %d at %s:%d",
+ sok, filename, lineno);
+ }
+ }
+
+#ifdef _DEBUG
+ {{
+ int localsok;
+ for (localsok = 0; localsok < FD_SETSIZE; localsok++) {
+ if (FD_ISSET(localsok, &openfds)) {
+ TRACE("Socket %d is currently open\n", localsok);
+ }
+ }
+ }}
+#endif /* _DEBUG */
+}
+
+
+/* Exported table of interface functions
+ */
+static const NIInterface s_NII_Dispatcher = {
+ s_GenericInit,
+ s_SetDispatcher,
+ s_GenericGetService,
+ s_ServiceDisconnect,
+ s_EndServices
+};
+const NIInterface *g_NII_Dispatcher = &s_NII_Dispatcher;
+
diff --git a/network/nsclilib/ni_encr.c b/network/nsclilib/ni_encr.c
new file mode 100644
index 00000000..332670a0
--- /dev/null
+++ b/network/nsclilib/ni_encr.c
@@ -0,0 +1,1005 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_encr.c
+*
+* Author: Epstein
+*
+* Version Creation Date: 2/14/94
+*
+* $Revision: 6.2 $
+*
+* File Description:
+* Supports RSAREF-based encryption for NCBI Network Services client-server
+* architecture
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* 02/22/94 Epstein Fix reading of public keys from config. file, and
+* initialization of random data structure for RSA
+* encryption.
+* 03/04/94 Epstein Reduce memory leakage, avoid ErrPost error if unable
+* to open public-key file.
+* 03/09/94 Epstein Add length parameter to NI_LoadPrivKey(), add code
+* which allows {Transient}SetAppParam() to provide
+* some help in providing an unbreakable key. Also
+* use high-granularity timing in generating random
+* key, where available.
+* 07/14/94 Epstein Pad buffer more efficiently in DoDesWrite().
+* 02/22/96 Epstein Correct boundary condition in DoDesRead() to refrain
+* from trying to decrypt a buffer when we don't have
+* at least 8 bytes of input to work with.
+*
+* $Log: ni_encr.c,v $
+* Revision 6.2 1998/06/23 19:45:19 vakatov
+* [WIN32,MSVC++] Made some functions be DLL-exportable
+*
+* Revision 6.1 1997/12/02 16:09:37 epstein
+* fix use of sprintf
+*
+* Revision 4.2 1996/02/22 18:43:03 epstein
+* Correct boundary condition in DoDesRead()
+*
+* Revision 4.1 1995/10/06 12:51:34 epstein
+* cleaned-up port to MS Windows
+* --------------------------------------------------------------------------
+*/
+
+#include <ncbi.h>
+#include <ni_types.h>
+#include <ni_msg.h>
+#include <global.h>
+#include <des.h>
+#include <rsaref.h>
+#ifdef OS_UNIX
+#include <sys/time.h>
+#endif /* OS_UNIX */
+
+#define ENCR_DES_TYPE 1
+
+#define ENCR_DES_STATE_IDLE 0
+#define ENCR_DES_STATE_GOT1LENBYTE 1
+#define ENCR_DES_STATE_INSTREAM 2
+
+
+
+
+/*
+ * Purpose: Encrypts a buffer using DES
+ *
+ * Parameters:
+ * encr Encryption data structure, includes Cypher-block-chaining info
+ * buf Input buffer
+ * len Length of buf
+ * tmpbuf Output buffer
+ *
+ * Returns:
+ * The length of the resulting encrypted data
+ *
+ * Description:
+ * Encodes the specified input buffer using two bytes which contain
+ * the length of the _plaintext_ data which follows, followed by
+ * the encrypted text. Thus, for example, an input buffer of
+ * length 9 will result in 0x0, 0x9, followed by 16 bytes of
+ * encrypted data.
+ *
+ * Note:
+ * For safety, the output buffer must be large enough to accomodate
+ * the two-byte header, plus the length of the input buffer, plus
+ * an additional seven bytes.
+ *
+ * DES cipher-block chaining (CBC) is used, and the CBC information
+ * is encoded in the desWriteContext data structure.
+ */
+
+static Int4
+DoDesWrite(NI_EncrDataPtr encr, CharPtr buf, int len, CharPtr tmpbuf)
+{
+ int encrLen;
+ UcharPtr encrBuf;
+ UcharPtr outbuf = (UcharPtr) tmpbuf;
+
+ outbuf[0] = len / 256; /* high order byte */
+ outbuf[1] = len % 256; /* low order byte */
+
+ encrLen = ((len + 7) / 8) * 8;
+ encrBuf = (UcharPtr) MemNew(encrLen);
+
+ /* pad with zeros */
+ MemSet ((CharPtr) &encrBuf[len], '\0', encrLen - len);
+
+ MemCpy ((CharPtr) encrBuf, buf, len);
+ DES_CBCUpdate ((DES_CBC_CTX PNTR) encr->desWriteContext, &outbuf[2],
+ encrBuf, encrLen);
+ MemFree (encrBuf);
+ return (encrLen + 2);
+}
+
+
+/*
+ * Purpose: Encryption write-filter for DES
+ *
+ * Parameters:
+ * mhvoid Pointer to message handle data structure
+ * buf Input buffer
+ * len Length of buf
+ * tmpbuf Output buffer
+ *
+ * Returns:
+ * The length of the resulting encrypted data
+ *
+ * Description:
+ * Validates the input and then processes the data using
+ * DoDesWrite().
+ */
+
+static Int4 LIBCALL
+DesWriteFilt(VoidPtr mhvoid, CharPtr buf, int len, CharPtr tmpbuf)
+{
+ NI_HandPtr mh = (NI_HandPtr) mhvoid;
+
+ if (len <= 0 || tmpbuf == NULL || buf == NULL || mh == NULL ||
+ mh->encryption == NULL)
+ return 0;
+ return DoDesWrite(mh->encryption, buf, len, tmpbuf);
+}
+
+
+/*
+ * Purpose: Decrypts a buffer using DES
+ *
+ * Parameters:
+ * encr Encryption data structure, includes Cypher-block-chaining info
+ * buf Input buffer containing encrypted data, and output plaintext
+ * bytesRead Length of input data in buf
+ * len Max # of bytes which will fit in buf (requested read length)
+ *
+ * Returns:
+ * The length of the resulting plaintext which has been processed
+ *
+ * Description:
+ * Decodes the specified input buffer, using a protocol which
+ * consists of two bytes of length information (realDataLeft)
+ * followed by bytesToRead bytes of encrypted data, where bytesToRead
+ * is realDataLeft padded out to a multiple of eight bytes.
+ *
+ * The algorithm uses a state machine to process as much of the input
+ * buffer as possible, and to store the remainder of the unprocessed
+ * input data in encr->deferredData.
+ *
+ *
+ * Note:
+ *
+ * DES cipher-block chaining (CBC) is used, and the CBC information
+ * is encoded in the desReadContext data structure. Also note that
+ * the history of the CBC consists of the entire communications
+ * session between client and server up to this point in time.
+ */
+
+static Int4
+DoDesRead(NI_EncrDataPtr encr, CharPtr buf, int bytesRead, int len)
+{
+ UcharPtr scratchInbuf;
+ UcharPtr ip; /* ptr to next byte in scratchInbuf */
+ Int4 retval;
+ Int2 roomInBuffer;
+ Int2 avail;
+ Int2 bytesToDecrypt;
+ Int2 bytesToCopy;
+ UcharPtr scratchOutbuf;
+ Boolean done;
+
+ if (bytesRead <= 0 || buf == NULL || encr == NULL)
+ return 0;
+
+ if (encr->state == ENCR_DES_STATE_IDLE)
+ {
+ encr->numDeferredBytes = 0;
+ encr->realDataLeft = 0;
+ encr->bytesToRead = 0;
+ }
+
+ if ((scratchInbuf = (UcharPtr) MemNew(bytesRead + encr->numDeferredBytes)) ==
+ NULL)
+ return 0;
+ ip = scratchInbuf;
+
+ MemCpy ((CharPtr) scratchInbuf, (CharPtr) encr->deferredData,
+ encr->numDeferredBytes);
+ MemCpy ((CharPtr) &scratchInbuf[encr->numDeferredBytes], buf, bytesRead);
+ bytesRead += encr->numDeferredBytes;
+ encr->numDeferredBytes = 0;
+ retval = 0;
+ done = FALSE;
+
+ while (bytesRead > 0 && ! done)
+ {
+ switch (encr->state) {
+ case ENCR_DES_STATE_IDLE:
+ if (bytesRead == 1)
+ {
+ encr->realDataLeft = *ip++;
+ encr->state = ENCR_DES_STATE_GOT1LENBYTE;
+ done = TRUE;
+ bytesRead--;
+ } else {
+ encr->realDataLeft = ip[0] * 256 + ip[1];
+ encr->bytesToRead = ((encr->realDataLeft + 7) / 8) * 8;
+ encr->numDeferredBytes = 0;
+ ip += 2;
+ bytesRead -= 2;
+ encr->state = ENCR_DES_STATE_INSTREAM;
+ }
+ break;
+ case ENCR_DES_STATE_GOT1LENBYTE:
+ encr->realDataLeft = encr->realDataLeft * 256 + *ip++;
+ encr->bytesToRead = ((encr->realDataLeft + 7) / 8) * 8;
+ encr->numDeferredBytes = 0;
+ bytesRead--;
+ encr->state = ENCR_DES_STATE_INSTREAM;
+ break;
+ case ENCR_DES_STATE_INSTREAM:
+ avail = MIN(encr->bytesToRead, bytesRead);
+ roomInBuffer = (Int2) (len - retval);
+ bytesToDecrypt = (MIN(roomInBuffer, avail) / 8) * 8;
+ if (bytesToDecrypt <= 0)
+ {
+ if (roomInBuffer >= MAX(encr->realDataLeft, 0) && avail >= 8)
+ { /* we can squeeze this in, and there's enough to process */
+ bytesToDecrypt = 8;
+ } else {
+ done = TRUE;
+ break;
+ }
+ }
+ scratchOutbuf = (UcharPtr) MemNew(bytesToDecrypt);
+ DES_CBCUpdate ((DES_CBC_CTX PNTR) encr->desReadContext,
+ scratchOutbuf, ip, bytesToDecrypt);
+ bytesToCopy = MIN(encr->realDataLeft, bytesToDecrypt);
+ MemCpy (buf, (CharPtr) scratchOutbuf, bytesToCopy);
+ MemFree (scratchOutbuf);
+ buf += bytesToCopy;
+ retval += bytesToCopy;
+ ip += bytesToDecrypt;
+ bytesRead -= bytesToDecrypt;
+ encr->bytesToRead -= bytesToDecrypt;
+ encr->realDataLeft -= bytesToDecrypt;
+ if (encr->bytesToRead <= 0)
+ {
+ encr->state = ENCR_DES_STATE_IDLE;
+ encr->numDeferredBytes = 0;
+ encr->realDataLeft = 0;
+ encr->bytesToRead = 0;
+ }
+ break;
+ }
+ }
+
+ if (bytesRead > 0)
+ {
+ encr->numDeferredBytes = bytesRead;
+ if (bytesRead > sizeof(encr->deferredData))
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "Too much deferred decryption data %d bytes", bytesRead);
+ } else {
+ MemCpy ((CharPtr) encr->deferredData, (CharPtr) ip, bytesRead);
+ }
+ }
+
+ MemFree (scratchInbuf);
+
+ return retval;
+}
+
+
+/*
+ * Purpose: DES read filter
+ *
+ * Parameters:
+ * mhvoid Pointer to message handle data structure
+ * buf Input buffer containing encrypted data, and output plaintext
+ * bytesRead Length of input data in buf
+ * len Max # of bytes which will fit in buf (requested read length)
+ * extra_buf unused, but required for NI_ReadFilt declaration
+ * extra_buf_len unused, but required for NI_ReadFilt declaration
+ *
+ * Returns:
+ * The length of the resulting plaintext which has been processed
+ *
+ * Description:
+ * Uses DoDesRead() to process input data, and returns to caller
+ */
+
+static Int4 LIBCALL
+DesReadFilt(VoidPtr mhvoid, CharPtr buf, int bytesRead, int len, CharPtr PNTR extra_buf, Int4Ptr extra_buf_len)
+{
+ NI_HandPtr mh = (NI_HandPtr) mhvoid;
+
+ if (bytesRead <= 0 || buf == NULL || mh == NULL ||
+ mh->encryption == NULL)
+ return 0;
+ return DoDesRead(mh->encryption, buf, bytesRead, len);
+}
+
+
+/*
+ * Purpose: Setup DES encryption for this message handle
+ *
+ * Parameters:
+ * mh Pointer to message handle data structure
+ * desKey DES key to be used for the life of this session
+ *
+ * Returns:
+ * TRUE if setup was successful, FALSE otherwise
+ *
+ * Description:
+ * Allocates an encryption data structure to attach to the message
+ * handle, as well as the RSAREF data structures for both reading
+ * and writing data. Note that the read and write data structures
+ * are each handling an independent half-duplex channel, i.e,
+ * either client->server or server->client data.
+ *
+ * Note:
+ * A caller which uses this function must also call
+ * NI_DestroyEncrStruct() when it is time to destroy the message
+ * handle.
+ */
+
+NLM_EXTERN Boolean LIBCALL
+NI_SetupDESEncryption(NI_HandPtr mh, UcharPtr desKey)
+{
+ Uchar iv[8];
+ NI_EncrDataPtr encr;
+
+ if (mh->encryption != NULL)
+ return FALSE;
+ if ((encr = MemNew(sizeof(*encr))) == NULL)
+ return FALSE;
+ mh->encryption = encr;
+ encr->encrType = ENCR_DES_TYPE; /* the only possibility, for now */
+ encr->state = ENCR_DES_STATE_IDLE;
+ encr->write_filter = DesWriteFilt;
+ encr->read_filter = DesReadFilt;
+ encr->desWriteContext = (DES_CBC_CTX PNTR) MemNew(sizeof(DES_CBC_CTX));
+ MemSet((CharPtr) iv, '\0', sizeof(iv));
+ DES_CBCInit((DES_CBC_CTX PNTR) encr->desWriteContext, desKey, iv, TRUE);
+ encr->desReadContext = (DES_CBC_CTX PNTR) MemNew(sizeof(DES_CBC_CTX));
+ MemSet((CharPtr) iv, '\0', sizeof(iv));
+ DES_CBCInit((DES_CBC_CTX PNTR) encr->desReadContext, desKey, iv, FALSE);
+
+ return TRUE;
+}
+
+
+/*
+ * Purpose: Seed the random number generator if necessary
+ *
+ * Description:
+ * If this function has not previously been called, it seeds the NCBI
+ * random number generator with the best pseudo-random data available
+ * on all systems, namely the current time in seconds, and a notion
+ * of the application's process ID. A high-granularity time is
+ * also included when available.
+ *
+ * Note:
+ * It would be helpful to have another NCBI function which returns
+ * the highest-granularity time available, e.g., many systems have
+ * microsecond and/or ticks available. Any other creative data
+ * available on this system (e.g., for UNIX systems, how many inodes
+ * are in use in the root filesystem of this computer) would also be
+ * helpful to help defeat malicious attempts to crack the security
+ * of this encryption subsystem.
+ */
+
+static void
+SetRandomSeed(void)
+{
+ static Boolean inited = FALSE;
+ Int4 highGranularity = 0;
+#ifdef OS_UNIX
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ highGranularity = tv.tv_usec;
+#endif
+#ifdef OS_MAC
+ highGranularity = clock();
+#endif
+#ifdef WIN_MSWIN
+ highGranularity = (Int4) GetCurrentTime();
+#endif
+
+ if (! inited)
+ {
+ RandomSeed ((long) (GetSecs() | Nlm_GetAppProcessID() | highGranularity));
+ inited = TRUE;
+ }
+}
+
+
+
+/*
+ * Purpose: Initialize an RSAREF random data structure used for RSA encryption
+ *
+ * Parameters:
+ * randomStruct The data structure to be populated
+ *
+ * Description:
+ * Seed the random number generator if necessary, create a random
+ * R_RANDOM_STRUCT data structure, and populate it with
+ * pseudo-random data. When available, data from the NCBI config.
+ * file is exclusive-ORed into each pseudo-random number, so
+ * that an RSA key cannot subsequently be broken by trying all
+ * 2^^32 possible values of the random number generator.
+ */
+
+static void InitRandomStruct (randomStruct)
+R_RANDOM_STRUCT *randomStruct;
+{
+ unsigned int bytesNeeded;
+ long ran;
+ Int4 seednum = 0;
+ Char buf[22];
+ Char moredata[10];
+
+ SetRandomSeed();
+ R_RandomInit (randomStruct);
+
+ while (1) {
+ R_GetRandomBytesNeeded (&bytesNeeded, randomStruct);
+ if (bytesNeeded == 0)
+ break;
+
+ ran = RandomNum();
+ sprintf (buf, "CONFOUND_%ld", (long) seednum);
+ GetAppParam("NCBI", "NET_SERV", buf, "0", moredata, sizeof moredata);
+ ran ^= atoi(moredata);
+ seednum++;
+ R_RandomUpdate (randomStruct, (UcharPtr) &ran, MIN(bytesNeeded, sizeof ran));
+ }
+}
+
+
+
+/*
+ * Purpose: Convert pub encryption key from RSAREF format to internal NCBI fmt
+ *
+ * Parameters:
+ * publicKey Key in RSAREF format
+ *
+ * Returns:
+ * Key in NCBI format, or NULL if an error occurred
+ *
+ * Description:
+ * Convert RSAREF public key data structure into a form which is
+ * suitable for being stored and transmitted in ASN.1
+ */
+
+static NI_PubKeyPtr
+PubKeyToInternalFormat(R_RSA_PUBLIC_KEY PNTR publicKey)
+{
+ NI_PubKeyPtr retval = (NI_PubKeyPtr) MemNew(sizeof(*retval));
+
+ if (retval == NULL || publicKey == NULL)
+ return NULL;
+ retval->bits = publicKey->bits;
+ retval->modulus = BSNew(sizeof(publicKey->modulus));
+ BSWrite(retval->modulus, (VoidPtr) publicKey->modulus, sizeof(publicKey->modulus));
+ retval->exponent = BSNew(sizeof(publicKey->exponent));
+ BSWrite(retval->exponent, (VoidPtr) publicKey->exponent, sizeof(publicKey->exponent));
+ return retval;
+}
+
+
+
+/*
+ * Purpose: Convert pub encryption key from internal NCBI format to RSAREF fmt
+ *
+ * Parameters:
+ * internal Key in NCBI format
+ *
+ * Returns:
+ * Key in RSAREF format, or NULL if an error occurred
+ *
+ * Description:
+ * Produce RSAREF public key data structure from a form which is
+ * suitable for being stored and transmitted in ASN.1
+ */
+
+static R_RSA_PUBLIC_KEY PNTR
+InternalToPubKeyFormat(NI_PubKeyPtr internal)
+{
+ R_RSA_PUBLIC_KEY PNTR retval;
+
+ if (internal == NULL || internal->modulus == NULL ||
+ internal->exponent == NULL)
+ return NULL;
+ retval = (R_RSA_PUBLIC_KEY PNTR) MemNew(sizeof(*retval));
+ retval->bits = internal->bits;
+ BSSeek (internal->modulus, 0, SEEK_SET);
+ BSSeek (internal->exponent, 0, SEEK_SET);
+ BSRead(internal->modulus, retval->modulus, sizeof(retval->modulus));
+ BSRead(internal->exponent, retval->exponent, sizeof(retval->exponent));
+ return retval;
+}
+
+
+/*
+ * Purpose: Compare two public encryption keys for equality
+ *
+ * Parameters:
+ * x Public key #1
+ * y Public key #2
+ *
+ * Returns:
+ * TRUE if keys match, FALSE otherwise
+ *
+ * Description:
+ * Converts keys into RSAREF format, because these are flat data
+ * structures and hence easy to compare.
+ */
+
+NLM_EXTERN Boolean LIBCALL
+NI_PubKeysEqual(NI_PubKeyPtr x, NI_PubKeyPtr y)
+{
+ R_RSA_PUBLIC_KEY PNTR xRsa = InternalToPubKeyFormat(x);
+ R_RSA_PUBLIC_KEY PNTR yRsa = InternalToPubKeyFormat(y);
+ Boolean retval;
+
+ if (xRsa == NULL && yRsa== NULL)
+ return TRUE;
+ if (xRsa == NULL || yRsa== NULL)
+ {
+ retval = FALSE;
+ } else {
+ retval = MemCmp((CharPtr) xRsa, (CharPtr) yRsa, sizeof (*xRsa)) == 0;
+ }
+ MemFree (xRsa);
+ MemFree (yRsa);
+ return retval;
+}
+
+
+
+/*
+ * Purpose: Pseudo-randomly generate an 8-byte DES key
+ *
+ * Parameters:
+ * desKey Resulting DES key
+ *
+ * Description:
+ * Generates 8-byte DES key, grabbing 2 bytes from each of 4 pseudo-
+ * randomly generated long integers.
+ *
+ * Note:
+ * Only 2 bytes are used from the long integer, because it's
+ * conceivable that a machine exists without 4-byte long integers.
+ * In hindsight, sizeof(long) could be used to determine how much to
+ * use, but this is a reasonable implementation.
+ */
+
+NLM_EXTERN void
+NI_GenerateDESKey(UcharPtr desKey)
+{
+ Int2 i;
+ long ran;
+
+ SetRandomSeed();
+ for (i = 0; i < 8;)
+ {
+ ran = RandomNum();
+ desKey[i++] = (Uchar) (ran & 255);
+ desKey[i++] = (Uchar) ((ran >> 8) & 255);
+ }
+}
+
+
+
+/*
+ * Purpose: Generate pub encryption public + private keys, and write to files
+ *
+ * Parameters:
+ * bits Length of key modulus in bits, within a restricted range
+ * pubAip AsnIoPtr to where public-key should be stored
+ * privFp File pointer to where private key should be stored
+ *
+ * Returns:
+ * TRUE if operations were successful, FALSE otherwise
+ *
+ * Description:
+ * Generates public and private keys using RSAREF function, and then
+ * output to AsnIoPtr and file pointer.
+ *
+ * Note:
+ * An AsnIoPtr is used for the public key, because the public key
+ * must be transmittable in a canonical format. Since private keys
+ * are never transmitted, a single block of memory is used for
+ * private keys, and private keys are stored in a single chunk on
+ * disk. This reduces the number of special data structures and
+ * ASN.1 object loaders which needed to be constructed to add
+ * encryption to NCBI Network Services.
+ */
+
+NLM_EXTERN Boolean LIBCALL
+NI_GenAndWritePEMKeys(Int2 bits, AsnIoPtr pubAip, FILE *privFp)
+{
+ R_RSA_PUBLIC_KEY publicKey;
+ R_RSA_PRIVATE_KEY privateKey;
+ R_RSA_PROTO_KEY protoKey;
+ R_RANDOM_STRUCT randomStruct;
+ int retval;
+ AsnModulePtr amp;
+ AsnTypePtr pubAtp;
+ NI_PubKeyPtr internalPub;
+ NI_HandPtr dummyHand;
+
+ if (bits < MIN_RSA_MODULUS_BITS || bits > MAX_RSA_MODULUS_BITS)
+ return FALSE;
+ if (pubAip == NULL || privFp == NULL)
+ return FALSE;
+ /* create a dummy message handle to ensure that ASN.1 is loaded */
+ dummyHand = (NI_HandPtr) MsgMakeHandle(FALSE);
+ MsgDestroyHandle(dummyHand);
+ if ((amp = AsnAllModPtr()) == NULL)
+ return FALSE;
+ if ((pubAtp = AsnTypeFind(amp, "RSA-Pubkey")) == NULL)
+ return FALSE;
+ InitRandomStruct (&randomStruct);
+ protoKey.bits = bits;
+ protoKey.useFermat4 = 1;
+ retval = R_GeneratePEMKeys(&publicKey, &privateKey, &protoKey, &randomStruct);
+ if (retval != 0)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "Error when generating PEM keys %d", retval);
+ }
+ internalPub = PubKeyToInternalFormat(&publicKey);
+ NI_WritePubKey(pubAip, pubAtp, (NIPubKeyPtr) internalPub);
+
+ FileWrite(&privateKey, sizeof(privateKey), 1, privFp);
+
+ return TRUE;
+}
+
+
+
+/*
+ * Purpose: Write a public key to a standard location on client machines
+ *
+ * Parameters:
+ *
+ * pub The public-key to be written to standard file
+ *
+ * Returns:
+ * TRUE if operations were successful, FALSE otherwise
+ *
+ * Description:
+ * Writes public-key to a file in the DATA directory.
+ * Alternatively, the public-key could be stored anywhere ...
+ * originally it was stored in the NCBI configuration file.
+ */
+
+NLM_EXTERN Boolean LIBCALL
+NI_WritePubKeyToConfig (NI_PubKeyPtr pub)
+{
+ Char fname[PATH_MAX];
+ AsnIoPtr aip;
+ AsnModulePtr amp;
+ AsnTypePtr pubAtp;
+ NI_HandPtr dummyHand;
+
+ if (pub == NULL)
+ {
+ return FALSE;
+ }
+
+ /* create a dummy message handle to ensure that ASN.1 is loaded */
+ dummyHand = (NI_HandPtr) MsgMakeHandle(FALSE);
+ MsgDestroyHandle(dummyHand);
+ if ((amp = AsnAllModPtr()) == NULL)
+ return FALSE;
+ if ((pubAtp = AsnTypeFind(amp, "RSA-Pubkey")) == NULL)
+ return FALSE;
+
+ if (! FindPath("ncbi", "ncbi", "data", fname, sizeof (fname)))
+ {
+ ErrPost(CTX_NCBIOBJ, 1, "FindPath failed");
+ return FALSE;
+ }
+
+ StringCat(fname, "pubkey.enc");
+
+ if ((aip = AsnIoOpen(fname, "w")) == NULL)
+ {
+ return FALSE;
+ }
+ NI_WritePubKey(aip, pubAtp, (NIPubKeyPtr) pub);
+ AsnIoClose(aip);
+ return TRUE;
+}
+
+/*
+ * Purpose: Read a public key from a standard configuration location
+ *
+ * Returns:
+ * A pointer to the allocated public-key, or NULL if failed
+ *
+ * Description:
+ * Reads public-key from a file in the DATA directory.
+ * Alternatively, the public-key could be stored anywhere ...
+ * originally it was stored in the NCBI configuration file.
+ */
+
+NLM_EXTERN NI_PubKeyPtr LIBCALL
+NI_ReadPubKeyFromConfig (void)
+{
+ Char fname[PATH_MAX];
+ AsnIoPtr aip;
+ NI_PubKeyPtr pub;
+ NIPubKeyPtr pub2;
+ FILE *fp;
+
+ if (! FindPath("ncbi", "ncbi", "data", fname, sizeof (fname)))
+ {
+ ErrPost(CTX_NCBIOBJ, 1, "FindPath failed");
+ return NULL;
+ }
+
+ StringCat(fname, "pubkey.enc");
+ /* try opening the file first, to suppress AsnIoOpen messages */
+ if ((fp = FileOpen(fname, "r")) == NULL)
+ {
+ return NULL;
+ } else {
+ FileClose(fp);
+ }
+ if ((aip = AsnIoOpen(fname, "r")) == NULL)
+ {
+ FileRemove(fname);
+ return NULL;
+ }
+ /* pub = (NI_PubKeyPtr) NI_MakePubKey(); */
+ pub2 = NI_MakePubKey();
+ pub = (NI_PubKeyPtr) pub2;
+ if (NI_ReadPubKey(aip, NULL, (NIPubKeyPtr) pub) < 0)
+ {
+ NI_DestroyPubKey((NIPubKeyPtr) pub);
+ pub = NULL;
+ }
+ AsnIoClose(aip);
+
+ return pub;
+}
+
+/*
+ * Purpose: Make a copy of a public key
+ *
+ * Parameters:
+ * orig The key to be copied
+ *
+ * Returns:
+ * A pointer to the copy of the public-key, or NULL if failed
+ *
+ * Description:
+ * Makes a copy of a public key
+ */
+
+NLM_EXTERN NI_PubKeyPtr LIBCALL
+NI_PubKeyDup (NI_PubKeyPtr orig)
+{
+ NI_PubKeyPtr dup;
+
+ if (orig == NULL)
+ return NULL;
+ dup = MemNew(sizeof(*dup));
+ dup->bits = orig->bits;
+ dup->modulus = BSDup(orig->modulus);
+ dup->exponent = BSDup(orig->exponent);
+ return dup;
+}
+
+
+/*
+ * Purpose: Load a private-key from the specified file pointer
+ *
+ * Parameters:
+ * fp File pointer from which to read private key
+ * privKeyLenPtr Pointer to where the length of private key may be stored
+ *
+ * Returns:
+ * A pointer to the resulting data structure, or NULL if unsuccessful
+ *
+ * Description:
+ * Reads private key from data file.
+ */
+
+NLM_EXTERN VoidPtr LIBCALL
+NI_LoadPrivKey(FILE *fp, Int2Ptr privKeyLenPtr)
+{
+ R_RSA_PRIVATE_KEY PNTR privKey;
+
+ privKey = (R_RSA_PRIVATE_KEY PNTR) MemNew(sizeof(*privKey));
+
+ FileRead(privKey, sizeof(*privKey), 1, fp);
+
+ if (privKeyLenPtr != NULL)
+ {
+ *privKeyLenPtr = sizeof(*privKey);
+ }
+
+ return privKey;
+}
+
+/*
+ * Purpose: Perform public-key decryption
+ *
+ * Parameters:
+ * pKey Private key
+ * plainText Pointer to resulting plaintext
+ * cipherText Ciphertext to be decrypted
+ * cipherTextLen Length of cipherText
+ *
+ * Returns:
+ * The length of resulting plaintext, or a negative error code
+ *
+ * Description:
+ * Decrypts the specified ciphertext using the specified private
+ * key. Subsequently resizes the resulting plaintext to be only
+ * as large as is needed.
+ *
+ * Note:
+ * The caller must free the pointer to the resulting plaintext.
+ */
+
+NLM_EXTERN Int2 LIBCALL
+NI_PubKeyDecrypt(VoidPtr pKey, UcharPtr PNTR plainText, UcharPtr cipherText, Int2 cipherTextLen)
+{
+ R_RSA_PRIVATE_KEY PNTR privKey = (R_RSA_PRIVATE_KEY PNTR) pKey;
+ int plainTextLen;
+ UcharPtr pText1, pText2;
+
+ if (pKey == NULL || plainText == NULL || cipherText == NULL)
+ return -1;
+
+ *plainText = NULL;
+ /* plain text is certainly shorter than ciphertext */
+ pText1 = (UcharPtr) MemNew(cipherTextLen);
+
+ if (RSAPrivateDecrypt(pText1, &plainTextLen, cipherText, cipherTextLen, privKey) != 0)
+ {
+ MemFree (pText1);
+ return -2;
+ }
+ pText2 = (UcharPtr) MemDup(pText1, plainTextLen);
+ MemFree (pText1);
+ *plainText = pText2;
+ return ((Int2) plainTextLen);
+}
+
+
+/*
+ * Purpose: Perform public-key encryption
+ *
+ * Parameters:
+ * pub Public key
+ * plainText Plaintext to be encrypted
+ * plainTextLen Length of plainText
+ * cipherText Pointer to resulting ciphertext
+ *
+ * Returns:
+ * The length of resulting ciphertext, or a negative error code
+ *
+ * Description:
+ * Encrypts the specified plaintext using the specified public
+ * key. Subsequently resizes the resulting ciphertext to be only
+ * as large as is needed.
+ *
+ * Note:
+ * The caller must free the pointer to the resulting ciphertext.
+ */
+
+NLM_EXTERN Int2 LIBCALL
+NI_PubKeyEncrypt(NI_PubKeyPtr pub, UcharPtr plainText, Int2 plainTextLen, UcharPtr PNTR cipherText)
+{
+ R_RSA_PUBLIC_KEY PNTR pubKeyPtr;
+ R_RANDOM_STRUCT randomStruct;
+ UcharPtr cipher, cipher2;
+ int cipherTextLen = 0;
+
+ if (pub == NULL || plainText == NULL || cipherText == NULL)
+ {
+ return -1;
+ }
+ *cipherText = NULL;
+ if ((pubKeyPtr = InternalToPubKeyFormat(pub)) == NULL)
+ {
+ return -2;
+ }
+ cipher = (UcharPtr) MemNew(plainTextLen * 2 + 64);
+ InitRandomStruct (&randomStruct);
+ if (RSAPublicEncrypt(cipher, &cipherTextLen, plainText, plainTextLen, pubKeyPtr, &randomStruct) != 0)
+ {
+ MemFree (cipher);
+ MemFree (pubKeyPtr);
+ return -3;
+ }
+ MemFree (pubKeyPtr);
+ /* reduce to the proper length */
+ cipher2 = (UcharPtr) MemDup(cipher, cipherTextLen);
+ MemFree (cipher);
+ *cipherText = cipher2;
+ return ((Int2) cipherTextLen);
+}
+
+/*
+ * Purpose: Free an encryption data structure, and erase secret data
+ *
+ * Parameters:
+ * encr Encryption data structure to be destroyed
+ *
+ *
+ * Description:
+ * Frees an encryption data structure, and erases secret data
+ * which could be used by a hostile party to break the encryption.
+ * The caller must free the pointer to the resulting ciphertext.
+ */
+
+NLM_EXTERN void
+NI_DestroyEncrStruct (NI_EncrDataPtr encr)
+{
+ if (encr == NULL)
+ return;
+ if (encr->desReadContext != NULL)
+ {
+ /* clear this memory for security reasons */
+ MemSet(encr->desReadContext, '\0', sizeof(DES_CBC_CTX));
+ MemFree(encr->desReadContext);
+ }
+ if (encr->desWriteContext != NULL)
+ {
+ /* clear this memory for security reasons */
+ MemSet(encr->desWriteContext, '\0', sizeof(DES_CBC_CTX));
+ MemFree(encr->desWriteContext);
+ }
+ MemFree(encr);
+}
+
+/*
+ * Purpose: Indicates whether encryption is available
+ *
+ * Returns: Always TRUE for this file, always FALSE for stub file
+ *
+ *
+ * Description:
+ * Indicates to the caller whether encryption is available, and
+ * whether or not it is safe to call the other encryption
+ * functions.
+ */
+
+NLM_EXTERN Boolean LIBCALL
+NI_EncrAvailable(void)
+{
+ return TRUE;
+}
diff --git a/network/nsclilib/ni_encr.h b/network/nsclilib/ni_encr.h
new file mode 100644
index 00000000..b0b578c9
--- /dev/null
+++ b/network/nsclilib/ni_encr.h
@@ -0,0 +1,102 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_encr.h
+*
+* Author: Epstein
+*
+* Version Creation Date: 2/14/94
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Header for for RSAREF-based encryption support in NCBI network services
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+*
+* RCS Modification History:
+* $Log: ni_encr.h,v $
+* Revision 6.0 1997/08/25 18:38:34 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1997/07/01 19:12:42 vakatov
+* [WIN32] DLL'd "netcli.lib"
+*
+* Revision 5.0 1996/05/28 14:11:55 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.4 1995/05/17 17:52:03 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NI_ENCR_
+#define _NI_ENCR_
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+NLM_EXTERN Boolean LIBCALL NI_SetupDESEncryption PROTO((NI_HandPtr mh, UcharPtr desKey));
+NLM_EXTERN Boolean LIBCALL NI_PubKeysEqual PROTO((NI_PubKeyPtr x, NI_PubKeyPtr y));
+NLM_EXTERN void NI_GenerateDESKey PROTO((UcharPtr desKey));
+NLM_EXTERN Boolean LIBCALL NI_GenAndWritePEMKeys PROTO((Int2 bits, AsnIoPtr pubAip, FILE *privFp));
+NLM_EXTERN Boolean LIBCALL NI_WritePubKeyToConfig PROTO((NI_PubKeyPtr pub));
+NLM_EXTERN NI_PubKeyPtr LIBCALL NI_ReadPubKeyFromConfig PROTO((void));
+NLM_EXTERN NI_PubKeyPtr LIBCALL NI_PubKeyDup PROTO((NI_PubKeyPtr orig));
+NLM_EXTERN VoidPtr LIBCALL NI_LoadPrivKey PROTO((FILE *fp, Int2Ptr privKeyLenPtr));
+NLM_EXTERN Int2 LIBCALL NI_PubKeyDecrypt PROTO((VoidPtr pKey, UcharPtr PNTR plainText, UcharPtr cipherText, Int2 cipherTextLen));
+NLM_EXTERN Int2 LIBCALL NI_PubKeyEncrypt PROTO((NI_PubKeyPtr pub, UcharPtr plainText, Int2 plainTextLen, UcharPtr PNTR cipherText));
+NLM_EXTERN void NI_DestroyEncrStruct PROTO((NI_EncrDataPtr encr));
+NLM_EXTERN Boolean LIBCALL NI_EncrAvailable PROTO((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif /* _NI_ENCR_ */
+
diff --git a/network/nsclilib/ni_encrs.c b/network/nsclilib/ni_encrs.c
new file mode 100644
index 00000000..868de937
--- /dev/null
+++ b/network/nsclilib/ni_encrs.c
@@ -0,0 +1,104 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_encrs.c
+*
+* Author: Epstein
+*
+* Version Creation Date: 2/14/94
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Stub replacement for ni_encr.c. This makes it easy to build NCBI Network
+* Services tools either with or without encryption support.
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 2/15/94 Epstein Replaced nice macro with explicit definitions, due to
+* inconsistency involving C pre-processors.
+*
+*
+* RCS Modification History:
+* $Log: ni_encrs.c,v $
+* Revision 6.0 1997/08/25 18:38:36 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1997/07/01 19:12:43 vakatov
+* [WIN32] DLL'd "netcli.lib"
+*
+* Revision 5.0 1996/05/28 14:11:55 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.5 1995/05/17 17:52:06 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <ncbi.h>
+#include <ni_types.h>
+
+
+/* this is the only function which may be called legally */
+NLM_EXTERN Boolean LIBCALL NI_EncrAvailable (void)
+{ return FALSE; }
+
+NLM_EXTERN Boolean LIBCALL NI_SetupDESEncryption (NI_HandPtr mh, UcharPtr desKey)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_SetupDESEncryption"); return FALSE; }
+
+NLM_EXTERN Boolean LIBCALL NI_PubKeysEqual (NI_PubKeyPtr x, NI_PubKeyPtr y)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_PubKeysEqual"); return FALSE; }
+
+NLM_EXTERN void NI_GenerateDESKey (UcharPtr desKey)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_GenerateDESKey"); }
+
+NLM_EXTERN Boolean LIBCALL NI_GenAndWritePEMKeys (Int2 bits, AsnIoPtr pubAip, FILE *privFp)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_GenAndWritePEMKeys"); return FALSE; }
+
+NLM_EXTERN Boolean LIBCALL NI_WritePubKeyToConfig (NI_PubKeyPtr pub)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_WritePubKeyToConfig"); return FALSE; }
+
+NLM_EXTERN NI_PubKeyPtr LIBCALL NI_ReadPubKeyFromConfig (void)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_ReadPubKeyFromConfig"); return NULL; }
+
+NLM_EXTERN NI_PubKeyPtr LIBCALL NI_PubKeyDup (NI_PubKeyPtr orig)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_PubKeyDup"); return NULL; }
+
+NLM_EXTERN VoidPtr LIBCALL NI_LoadPrivKey (FILE *fp, Int2Ptr privKeyLenPtr)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_LoadPrivKey"); return NULL; }
+
+NLM_EXTERN Int2 LIBCALL NI_PubKeyDecrypt (VoidPtr pKey, UcharPtr PNTR plainText, UcharPtr cipherText, Int2 cipherTextLen)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_PubKeyDecrypt"); return -1; }
+
+NLM_EXTERN Int2 LIBCALL NI_PubKeyEncrypt (NI_PubKeyPtr pub, UcharPtr plainText, Int2 plainTextLen, UcharPtr PNTR cipherText)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_PubKeyDecrypt"); return -1; }
+
+NLM_EXTERN void NI_DestroyEncrStruct (NI_EncrDataPtr encr)
+{ ErrPostEx(SEV_ERROR,0,0,"Invalid call to encryption function NI_DestroyEncrStruct"); }
diff --git a/network/nsclilib/ni_error.c b/network/nsclilib/ni_error.c
new file mode 100644
index 00000000..971f200c
--- /dev/null
+++ b/network/nsclilib/ni_error.c
@@ -0,0 +1,193 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_error.c
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.1 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* $Log: ni_error.c,v $
+* Revision 6.1 1997/11/18 21:14:30 epstein
+* identify Linux Alpha client
+*
+* Revision 6.0 1997/08/25 18:38:38 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1997/07/01 19:12:45 vakatov
+* [WIN32] DLL'd "netcli.lib"
+*
+* Revision 5.0 1996/05/28 14:11:55 ostell
+* Set to revision 5.0
+*
+ * Revision 4.1 1995/11/27 20:59:11 epstein
+ * add client support for direct-connection services
+ *
+ * Revision 4.0 95/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.12 1995/05/17 17:52:10 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include "ni_error.h"
+
+static Char *STATIC__ni_errlist[NIE_N_ERRORS] =
+{
+ "no error",
+ "error",
+ "no entry for user",
+ "no entry for host",
+ "no entry for service",
+ "host address invalid",
+ "port number invalid",
+ "can't open socket",
+ "can't bind socket",
+ "accept socket failed",
+ "listen on socket failed",
+ "can't connect to dispatcher",
+ "can't connect to client",
+ "can't connect to application",
+ "maximum number of connections in use",
+ "select statement failed",
+ "message write failed",
+ "message read failed",
+ "message type unknown",
+ "fork failed",
+ "unable to set user ID",
+ "execute failed",
+ "unknown service",
+ "can't open file",
+ "error in configuration file",
+ "error parsing service entry",
+ "error parsing resource entry",
+ "service is unavailable",
+ "resource is unavailable",
+ "dispatcher disconnected",
+ "service disconnected",
+ "login failed",
+ "login timed out",
+ "dispatcher timed out",
+ "service timed out",
+ "command timed out",
+ "timed out",
+ "unable to make message handle",
+ "user not in group required for access",
+ "version requested not in valid range",
+ "name requested was not found",
+ "requested ID was not found",
+ "select returned unrequested fd",
+ "error using NIS service",
+ "invalid argument",
+ "child process exited abnormally",
+ "already running on this machine",
+ "attempt to set up pipe failed",
+ "i/o error on pipe",
+ "spawned server OK",
+ "spawned server failed",
+ "unable to parse string",
+ "service/resource type mismatch",
+ "dispatcher is acting as backup",
+ "client is not an authorized guest user",
+ "TCP stack initialization failure",
+ "no entry for local host",
+ "ASN.1 specification load failure",
+ "service does not support encryption",
+ "can't connect to brokered service",
+ "failure trying to perform public-key encryption",
+ "failure trying to perform public-key decryption",
+ "new encryption key was not accepted by user",
+ "mismatched new encryption key not accepted by user",
+ "expired ticket",
+ "ticket used from invalid IP address",
+ "bad ticket checksum",
+ "ticket used at invalid server",
+ "unable to connect to server",
+ "unknown error"
+};
+static Char **STATIC__ni_errlist_ptr = &STATIC__ni_errlist[0];
+NLM_EXTERN Char ***x_ni_errlist(void) { return &STATIC__ni_errlist_ptr; }
+
+
+static Char *STATIC__ni_platform[NI_N_PLATFORMS] =
+{
+ "unknown", /* NI_PLATFORM_UNKNOWN */
+ "Macintosh", /* NI_PLATFORM_MAC */
+ "VMS (TGV)", /* NI_PLATFORM_VMS_TGV */
+ "AXP/OpenVMS", /* NI_PLATFORM_AXP_OPENVMS */
+ "Generic UNIX", /* NI_PLATFORM_GENERIC_UNIX */
+ "IBM370 AIX", /* NI_PLATFORM_IBM370AIX */
+ "Sun", /* NI_PLATFORM_SUN */
+ "Alpha+OSF/1", /* NI_PLATFORM_ALPHA_OSF1 */
+ "Mac AU/X", /* NI_PLATFORM_AUX */
+ "Cray", /* NI_PLATFORM_CRAY */
+ "Convex", /* NI_PLATFORM_CONVEX */
+ "HP/UX", /* NI_PLATFORM_HPUX */
+ "NEXT", /* NI_PLATFORM_NEXT */
+ "SGI (MIPS)", /* NI_PLATFORM_SGI */
+ "ULTRIX", /* NI_PLATFORM_ULTRIX */
+ "DOS", /* NI_PLATFORM_DOS */
+ "WIN16", /* NI_PLATFORM_WIN16 */
+ "NEWT", /* NI_PLATFORM_WIN_NEWT */
+ "PC-NFS", /* NI_PLATFORM_WIN_PCNFS */
+ "WINSOCK", /* NI_PLATFORM_WIN_WINSOCK */
+ "WIN NT", /* NI_PLATFORM_WINNT */
+ "System V on Sparc", /* NI_PLATRFOM_SYSV_ON_SPARC */
+ "VMS (UCX)", /* NI_PLATFORM_VMS_UCX */
+ "VMS (TWG)", /* NI_PLATFORM_VMS_TWG */
+ "VMS (WPW)", /* NI_PLATFORM_VMS_WPW */
+ "AIX", /* NI_PLATFORM_AIX */
+ "LINUX", /* NI_PLATFORM_LINUX */
+ "LINUX on ALPHA" /* NI_PLATFORM_LINUX_ALPHA */
+};
+static Char **STATIC__ni_platform_ptr = &STATIC__ni_platform[0];
+NLM_EXTERN Char ***x_ni_platform(void) { return &STATIC__ni_platform_ptr; }
+
+
+/* number of errors */
+static Uint2 STATIC__ni_nerr = (Uint2)NIE_UNKNOWN;
+NLM_EXTERN Uint2 *x_ni_nerr(void) { return &STATIC__ni_nerr; }
+
+/* error level - NOT SET on error */
+static NI_ErrLevel STATIC__ni_errlev;
+NLM_EXTERN NI_ErrLevel *x_ni_errlev(void) { return &STATIC__ni_errlev; }
+
+/* error number set by failing function */
+static NI_Error STATIC__ni_errno;
+NLM_EXTERN NI_Error *x_ni_errno(void) { return &STATIC__ni_errno; }
+
+/* additional error text buffer */
+static Char STATIC__ni_errtext[ERRTEXT_BUFSIZ];
+static Char *STATIC__ni_errtext_ptr = &STATIC__ni_errtext[0];
+NLM_EXTERN Char **x_ni_errtext(void) { return &STATIC__ni_errtext_ptr; }
+
diff --git a/network/nsclilib/ni_error.h b/network/nsclilib/ni_error.h
new file mode 100644
index 00000000..d1d3080d
--- /dev/null
+++ b/network/nsclilib/ni_error.h
@@ -0,0 +1,243 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_error.h
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.1 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 5/12/92 Epstein Converted tabs to spaces
+*
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_error.h,v $
+* Revision 6.1 1997/11/18 21:14:35 epstein
+* identify Linux Alpha client
+*
+* Revision 6.0 1997/08/25 18:38:40 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1997/07/01 19:12:46 vakatov
+* [WIN32] DLL'd "netcli.lib"
+*
+* Revision 5.0 1996/05/28 14:11:55 ostell
+* Set to revision 5.0
+*
+ * Revision 4.1 1995/11/27 20:59:13 epstein
+ * add client support for direct-connection services
+ *
+ * Revision 4.0 95/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.12 1995/05/17 17:52:13 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NI_ERROR_
+#define _NI_ERROR_
+
+#include "ncbinet.h"
+
+#define NI_Platform enum NI_platform
+NI_Platform {
+ NI_PLATFORM_UNKNOWN = 0,
+ NI_PLATFORM_MAC,
+ NI_PLATFORM_VMS_TGV,
+ NI_PLATFORM_AXP_OPENVMS,
+ NI_PLATFORM_GENERIC_UNIX,
+ NI_PLATFORM_IBM370AIX,
+ NI_PLATFORM_SUN,
+ NI_PLATFORM_ALPHA_OSF1,
+ NI_PLATFORM_AUX,
+ NI_PLATFORM_CRAY,
+ NI_PLATFORM_CONVEX,
+ NI_PLATFORM_HPUX,
+ NI_PLATFORM_NEXT,
+ NI_PLATFORM_SGI,
+ NI_PLATFORM_ULTRIX,
+ NI_PLATFORM_DOS,
+ NI_PLATFORM_WIN16,
+ NI_PLATFORM_WIN_NEWT,
+ NI_PLATFORM_WIN_PCNFS,
+ NI_PLATFORM_WIN_WINSOCK,
+ NI_PLATFORM_WINNT,
+ NI_PLATFORM_SYSV_ON_SPARC,
+ NI_PLATFORM_VMS_UCX,
+ NI_PLATFORM_VMS_TWG,
+ NI_PLATFORM_VMS_WPW,
+ NI_PLATFORM_AIX,
+ NI_PLATFORM_LINUX,
+ NI_PLATFORM_LINUX_ALPHA,
+
+ NI_N_PLATFORMS
+#define NI_MAX_PLATFORMS (NI_N_PLATFORMS - 1)
+};
+
+#define NI_ErrLevel enum ni_errlevel
+NI_ErrLevel {
+ NIL_INFORMATION = 1, /* informational */
+ NIL_WARNING, /* small problem */
+ NIL_SEVERE, /* recoverable */
+ NIL_FATAL /* not recoverable */
+};
+
+#define NI_Error enum ni_error
+NI_Error {
+ NIE_NO_ERROR = 0, /* no error */
+ NIE_MISC, /* error */
+ NIE_NOUSERENT, /* no entry for user */
+ NIE_NOHOSTENT, /* no entry for host */
+ NIE_NOSERVENT, /* no entry for service */
+ NIE_BADHOST, /* host address invalid */
+ NIE_BADPORT, /* port number invalid */
+ NIE_SOCKOPEN, /* can't open socket */
+ NIE_NOBIND, /* can't bind socket */
+ NIE_NOACCEPT, /* accept socket failed */
+ NIE_NOLISTEN, /* listen on socket failed */
+ NIE_DISPCONN, /* can't connect to dispatcher */
+ NIE_CLICONN, /* can't connect to client */
+ NIE_APPCONN, /* can't connect to application */
+ NIE_MAXCONNS, /* maximum number of connections in use */
+ NIE_SELECT, /* select statement failed */
+ NIE_MSGWRITE, /* message write failed */
+ NIE_MSGREAD, /* message read failed */
+ NIE_MSGUNK, /* message type unknown */
+ NIE_FORK, /* fork failed */
+ NIE_SETUID, /* unable to set user ID */
+ NIE_EXEC, /* execute failed */
+ NIE_SERVUNK, /* unknown service */
+ NIE_FILOPEN, /* can't open file */
+ NIE_CONFIG, /* error in configuration file */
+ NIE_SVCENT, /* error parsing service entry */
+ NIE_RESENT, /* error parsing resource entry */
+ NIE_SVCUNAVL, /* service is unavailable */
+ NIE_RESUNAVL, /* resource is unavailable */
+ NIE_DSPDCONN, /* dispatcher disconnected */
+ NIE_SVCDCONN, /* service disconnected */
+ NIE_BADLOGIN, /* login failed */
+ NIE_LOGTIMEOUT, /* login timed out */
+ NIE_DSPTIMEOUT, /* dispatcher timed out */
+ NIE_SVCTIMEOUT, /* service timed out */
+ NIE_CMDTIMEOUT, /* command timed out */
+ NIE_TIMEOUT, /* timed out */
+ NIE_MAKEHAND, /* unable to make message handle */
+ NIE_NOTINGRP, /* user not in group required for access */
+ NIE_BADVERS, /* version requested not in valid range */
+ NIE_BADNAME, /* name requested was not found */
+ NIE_BADREQID, /* requested ID was not found */
+ NIE_BADSELFD, /* select returned unrequested fd */
+ NIE_NISERROR, /* error using NIS service */
+ NIE_INVAL, /* invalid argument */
+ NIE_BADEXIT, /* child process exited abnormally */
+ NIE_SEMBUSY, /* already running on this machine */
+ NIE_PIPE, /* attempt to set up pipe failed */
+ NIE_PIPEIO, /* i/o error on pipe */
+ NIE_SERVACK, /* spawned server OK */
+ NIE_SERVNACK, /* spawned server failed */
+ NIE_PARSE, /* unable to parse string */
+ NIE_TYPEMISM, /* service/resource type mismatch */
+ NIE_BACKUPDISP, /* dispatcher is acting as backup */
+ NIE_NOTGUEST, /* client is not an authorized guest user */
+ NIE_TCPINITFAIL, /* TCP stack initialization failure */
+ NIE_NOLOCALHOSTENT, /* no entry for local host */
+ NIE_ASN1SPECFAIL, /* ASN.1 specification load failure */
+ NIE_SVCNOTENCR, /* service does not support encryption */
+ NIE_BROKSVCCONN, /* can't connect to brokered service */
+ NIE_PUBKEYENCRFAIL, /* failure trying to perform public-key encryption */
+ NIE_PUBKEYDECRFAIL, /* failure trying to perform public-key decryption */
+ NIE_NEWKEYNOTACCPT, /* new encryption key was not accepted by user */
+ NIE_NEWKEYMISMATCH, /* mismatched new encryption key not accepted by user */
+ NIE_DIREXPT, /* expired ticket */
+ NIE_DIRINVIPADDR, /* ticket used from invalid IP address */
+ NIE_DIRBADCHECKSUM, /* bad ticket checksum */
+ NIE_DIRINVSERVER, /* ticket used at invalid server */
+ NIE_DIRUNCONNECT, /* unable to connect to server */
+
+ NIE_UNKNOWN, /* unknown error */
+ NIE_N_ERRORS /* do not enumerate after this line! */
+};
+
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* number of errors */
+NLM_EXTERN Uint2 *x_ni_nerr PROTO((void));
+#define ni_nerr (*x_ni_nerr())
+
+/* error level - NOT SET on error */
+NLM_EXTERN NI_ErrLevel *x_ni_errlev PROTO((void));
+#define ni_errlev (*x_ni_errlev())
+
+/* error number set by failing function */
+NLM_EXTERN NI_Error *x_ni_errno PROTO((void));
+#define ni_errno (*x_ni_errno())
+
+/* list of error messages */
+NLM_EXTERN Char ***x_ni_errlist PROTO((void));
+#define ni_errlist (*x_ni_errlist())
+
+/* additional error text buffer */
+NLM_EXTERN Char **x_ni_errtext PROTO((void));
+#define ni_errtext (*x_ni_errtext())
+
+/* list of platform names messages */
+NLM_EXTERN Char ***x_ni_platform PROTO((void));
+#define ni_platform (*x_ni_platform())
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif /* _NI_ERROR_ */
diff --git a/network/nsclilib/ni_lib.c b/network/nsclilib/ni_lib.c
new file mode 100644
index 00000000..12cd1bc2
--- /dev/null
+++ b/network/nsclilib/ni_lib.c
@@ -0,0 +1,3823 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_lib.c
+*
+* Author: Beatty, Gish, Epstein
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.10 $
+*
+* File Description:
+* This file is a library of functions to be used by server application
+* and client software, using the NCBI "network services" paradigm.
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 4/27/92 Epstein Added extensive in-line commentary, and removed all tabs.
+* 5/11/92 Epstein Removed unused function NI_SVCRequestGet(); added support
+* for the connection ID to be written to a CONID file each
+* time that the value of conid is updated; in practice,
+* only dispatcher will update a CONID file.
+* 6/22/92 Epstein For UNIX signals, catch the SIGPIPE error which can
+* occur when writing to a socket which is no longer
+* connected.
+* 7/06/92 Epstein Changed sokselectw() to examine the SO_ERROR socket option
+* after select()-ing a socket to which we were attempting a
+* connection. This eliminates "false connects", i.e.,
+* unsuccessful connection attempts which look successful
+* because the select() call returns 1.
+* 7/14/92 Epstein Changed NI_SetDispatcher() and NI_InitServices() to use
+* a configurable timeout parameter, and in the process
+* also changed sokselectw() to have a timeout parameter,
+* 1/21/93 Epstein Add dispatcher-list support, and add dispatcher-list
+* parameter to NI_InitServices().
+* 2/12/93 Epstein Use new boolean parameter to MsgMakeHandle(), indicating
+* whether or not it should create a socket. This was
+* an attempted fix for a Mac problem ... it later
+* turned out to be an incorrect problem-fix, but also
+* does no harm.
+* 2/24/93 Epstein Fix long-standing Mac bug, by correctly destroying
+* services handle and hence closing an open socket.
+* 3/02/93 Epstein Add functions to write dispatcher-configuration info
+* to a config file. This provides a standardized
+* mechanisms which applications may use for net services
+* configuration. Also added platform functions, so
+* that dispatcher/server complex can know what type
+* of platform a client is running on, assuming that the
+* client is telling the truth.
+* 3/03/93 Epstein Cleanup variable initialization.
+* 3/08/93 Epstein Improve error messages & cleanup to NI_InitServices,
+* include reason in login failure message, and add
+* client platform to service request.
+* 3/09/93 Epstein Add HaltServices() function to simplify cleanup.
+* 3/22/93 Epstein Fix typecast for getsockopt(), and, more importantly,
+* remember to return the computed value in NI_GetPlatform.
+* 3/23/93 Epstein Support VMS/TGV, and add NETP_INET_ prefixes to
+* conditional-compilation symbols.
+* 3/24/93 Epstein Clear the caller's pointer in NI_SetDispConfig().
+* 3/31/93 Epstein Add dispatcher pointer as context for all network
+* services operations; this allows an application
+* to use more than one dispatcher at a time, at the
+* expense of slightly greater complexity. Also add
+* a "Generic Init" function, which can be used by
+* an application to obtain network-services in a
+* simplified, standardized manner.
+* 3/31/93 Epstein Move debug and module variables to their correct home.
+* 4/02/93 Epstein Add WinSock support.
+* 4/12/93 Schuler Add MAKEWORD macro.
+* 4/21/93 Schuler Removed function prototypes for NI_AsnRead, NI_AsnWrite
+* 5/07/93 Epstein Move WSAStartup() code to a better place, add workaround
+* for connection attempt on a non-blocking socket in PC-NFS
+* 4.0, add more platform definitions.
+* 5/24/93 Epstein Add separate error codes for TCP/IP initialization
+* failure and inability to resolve local host name.
+* 5/25/93 Epstein Add configuration-file workaround for PC-NFS 5.0 bug,
+* where NIS sometimes fails on the PC's own host name.
+* 5/27/93 Epstein Incorporate pragmatic "Gestalt" code for Vibrant
+* scrolling workaround for WinSock under Windows 3.1,
+* add add SOCK_INDEX_ERRNO macro to workaround another
+* WinSock pecularity.
+* 6/02/93 Schuler Change "Handle" to "MonitorPtr" for Monitors.
+* 6/07/93 Epstein Added generic timer functions.
+* Also add missing revision history, derived from
+* RCS file.
+* 6/09/93 Epstein Added activity hook to report network activity back
+* to an application.
+* 6/14/93 Epstein Changed "Generic" logic to cause UNIX/VMS loginname
+* to override loginname, rather than vice versa. Also
+* setup DispatchConnect() logic to set client's declared
+* IP address to 0.0.0.0, rather than causing an error,
+* in the case where the client cannot resolve its own
+* host name. In this case, the dispatcher will set its
+* own opinion of the client address based upon
+* getpeername().
+* 6/15/93 Epstein Eliminate "Gestalt" code for Vibrant scrolling
+* workaround for WinSock under Windows 3.1, since the
+* solution for this problem does not require its use.
+* 6/25/93 Epstein Fix activity-hook action for service disconnection (had
+* erroneously announced dispatcher-disconnection), and
+* add logic to try to avoid getservbyname() by looking
+* up dispatcher port # and (loport,hiport) in NCBI
+* configuration file instead of in NIS. As a last resort,
+* look up the name in NIS if the entry in the NCBI
+* config. file is non-numeric. Also, change the client
+* port lookup mechanism for Macintoshes to add a configured
+* "delta" value to the low port number. This results in
+* allowing several Network Services applications to run
+* concurrently on a Mac without port conflicts.
+* 7/08/93 Epstein Fix list traversal error in NI_ProcessTimers()
+* 7/08/93 Epstein Added a counter as a failsafe mechanism in
+* NI_ProcessTimers(), since previous fix attempt failed.
+* 7/09/93 Epstein Changed a few #define names to avoid Alpha compilation
+* warnings, and added reference count to dispatcher data
+* structure.
+* 8/09/93 Epstein Improve diagnostics when a listen() call fails
+* 8/23/93 Epstein Add currentDisp variable so that the currently-attached
+* dispatcher is used when the parameter to NI_SetDispatcher
+* is NULL.
+* 8/31/93 Epstein Fix host vs. network order when comparing port numbers.
+* 9/08/93 Epstein Added new stackDescription variable, to be able to
+* report to the dispatcher the identity of the vendor
+* of the WinSock stack
+* 9/09/93 Epstein Fix use of currentDisp variable to correctly compare
+* new dispatcher request again current dispatcher.
+*11/24/93 Epstein Added code to support standalone servers and clients
+* which communicate with standalone servers or "service
+* brokers", which listen on a specific port (to be
+* augmented later).
+*11/30/93 Epstein Made standalone server code UNIX-only, to avoid
+* possible compilation errors on other platforms. However,
+* it should be possible in principle to run and test a
+* standalone server on a non-UNIX host. Also, added
+* limited security to standalone servers.
+*12/08/93 Epstein Fixed service connection activity hook, per discussion
+* with Kyle Hart.
+*01/19/94 Schuler Post error (SEV_INFO) on WinSock initialization
+* failure showing WinSock's error code.
+*01/28/94 Schuler Replace "NETP_INET_MACTCP" with "NETP_INET_MACTCP"
+*01/28/94 Schuler Defined THIS_MODULE and THIS_FILE
+*02/14/94 Epstein Add preliminary RSAREF encryption support
+*02/22/94 Epstein Add DISP_RECONN_ACTION logic to allow users to breakout
+* or quit if unable to contact primary dispatcher.
+*02/24/94 Epstein Make use of new NI_DupPubKey function, and insert
+* newlines in macros to make editing easier.
+*03/03/94 Epstein Reduce memory leaks, suppress non-printing characters
+* in winsock.dll.
+*04/22/94 Epstein Change error handling to use SEV_ERROR and SEV_WARNING
+* (ErrPostEx). Also do a better job of detecting
+* inability to connect to dispatcher in DispatchConnect(),
+* because under Solaris getsockopt() doesn't correctly
+* detect an error.
+*04/25/94 Epstein Cosmetic change for error when NACK received from
+* Dispatcher.
+*05/04/94 Epstein Add logic to allow a mixture of encrypted and
+* unencrypted services, determined by ENCRYPTION=FALSE
+* fields in the appropriate sections in the config.
+* files.
+*06/08/94 Epstein Add SOCKS support (probably not correct yet) by
+* asking Dispatcher to provide a SVC_PRE_RESPONSE message
+* which contains the server's IP address.
+*06/10/94 Epstein More SOCKS refinement, plus added tracing for SOCKS
+*06/15/94 Epstein Produce working SOCKS version, by changing the protocol
+* so that a SOCKSified client uses two service request
+* messages; one to learn the IP address of the server
+* to which it will be assigned, and the second "real"
+* service request after it has bound the 'listen' port
+* on the SOCKS daemon.
+*07/01/94 Epstein Determine at runtime whether or not to use SOCKS,
+* methodology, based upon presence or absence of
+* SOCKS_CONF file.
+*07/07/94 Epstein Updated commentary.
+*09/22/94 Epstein Improved standalone server code by using SO_REUSEADDR
+* option, making it possible for identical servers to
+* run consecutively without waiting for sockets to
+* shutdown.
+*12/02/94 Epstein Changed NI_GenericGetService() to have environment
+* variables override configuration file for SERVICE_NAME
+* and RESOURCE_TYPE. This is mostly just a convenience
+* for internal NCBI use, allowing the use of a single
+* config. file while using scripts to force the use
+* of a different service.
+*12/06/94 Epstein Added connectDelay, adminInfo and motd fields.
+* The client reports the time which it took to
+* establish a connection in their connectDelay field.
+* The Dispatcher provides the name of the Network
+* administrator and a secondary message-of-the-day in
+* the other two fields.
+*12/21/94 Epstein Added instrumentation for socket management
+*01/11/95 Epstein Change socket instrumentation to suppress some
+* errors for WinSock 1.1.
+*01/13/95 Epstein Add new GetLAPType() function to report Mac clients'
+* TCP/IP implementation ("Ethernet", "PPP", etc.) to
+* the Dispatcher.
+*03/20/95 Epstein Fix InitServices/EndServices logic to correctly only
+* establish a single Dispatcher connection for multiple
+* services.
+*03/29/95 Epstein Reduce calls to Message() in favor of ErrPostEx().
+*06/02/95 Epstein Fix bindPort() to address host/network byte ordering;
+* this should correct a byte-ordering problem on little-
+* endian hosts which use SOCKS.
+*06/06/95 Epstein For UNIX, try to get the user's name from the USER
+* environment variable before inquiring getlogin();
+* this can save CPU time and contention on some systems,
+* since access to utmp can be slow.
+*06/12/95 Epstein Another byte-ordering fix for SOCKS for the SOCKS
+* proxy's port number.
+*10/19/95 Epstein Bug fix to accomodate logic correct in Nlm_StringCmp()
+*
+*11/15/95 Shavirin Added new ability of clients to get direct connection
+* to the server.
+* Created new function: NI_DirectServiceRequest to connect
+ to the server directly and to send SVC_REQUEST
+* Added new parameter in configuration file - DIRECT_SVC_CON
+* This parameter updates new field in dispatcher stucture:
+* disp->useOutServ. If this parameter set to FALSE - old style
+* communication will be used. TRUE is set for direct
+* connection.
+* To handle direct connection protocol of the service request
+* function was changed. In the case of old style everything
+* remained the same (except reconnect switch option - to
+* try direct connection if old style failed - currently disabled)
+* In the case when disp->useOutServ is set client sends
+* service request with field svcreq->want_ticket = TRUE.
+* Dispatcher will sent back SVC_REQUEST with the prepared ticket
+* or NACK in the case of error. Client will send SVC_REQUEST
+* directly to the server and will wait until SVC_RESPONCE or
+* NACK will be received from the dispatcher. After SVC_RESPONCE
+* received communication transfers to the upper layers.
+*01/17/96 Epstein Add protection for DIRECT_SVC_CON mode; this comes into
+* play with Mac OpenTransport (OT)
+*02/02/96 Epstein Add PROXY_SERV_OVERRIDE GetAppParam() flag for
+* DIRECT_SVC_CON mode. This makes it easier for a
+* machine behind a firewall to get through the firewall,
+* although it assumes a priori knowledge of the IP
+* address of the server, and the port numbers on the
+* server.
+*02/21/96 Epstein Fix brokered-services for little-endian clients
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_lib.c,v $
+* Revision 6.10 1998/04/10 19:24:45 vakatov
+* NI_SetInterface(): return the overridden(old) interface value; check
+* for the validity of the new interface
+*
+* Revision 6.9 1998/03/31 23:44:53 vakatov
+* "interface" gets #defined in MS-Win headers; just #undef it
+*
+* Revision 6.8 1998/03/31 21:35:34 vakatov
+* Added stub NI_IsInterfaceSupported(), NI_SetAddress() and
+* NI_SetInterface() for the forward compatibility with "ni_lib_.h"
+*
+* Revision 6.7 1998/03/30 23:05:52 vakatov
+* fixed minor typo
+*
+* Revision 6.6 1998/03/17 18:55:42 shavirin
+* Rolling back to version 6.3
+*
+* Revision 6.3 1997/11/18 21:14:42 epstein
+* identify Linux Alpha client
+*
+* Revision 6.2 1997/10/06 21:21:50 shavirin
+* Fixed memory leak and uninitiolized memory read errors
+*
+* Revision 6.1 1997/09/11 18:08:24 epstein
+* add output of uname -a to Unix clients' self-identifying string
+*
+* Revision 6.0 1997/08/25 18:38:44 madden
+* Revision changed to 6.0
+*
+* Revision 5.5 1997/07/01 19:12:49 vakatov
+* [WIN32] DLL'd "netcli.lib"
+*
+* Revision 5.4 1997/06/17 18:52:17 epstein
+* fix numerous memory problems associated with timers
+*
+* Revision 5.3 1997/04/24 12:53:33 ostell
+* fixed typo in call to AsnTypeStringToHex
+*
+ * Revision 5.2 1997/04/24 12:44:36 ostell
+ * changed calls to AsnTypeStringToHex to match new arguments and returns
+ *
+ * Revision 5.1 1996/10/02 18:18:20 epstein
+ * add function NI_FqdnToIpaddr() to simplify layering of netcnfg.c
+ *
+ * Revision 5.0 1996/05/28 14:11:55 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.15 1996/05/22 15:12:54 epstein
+ * adopt more reasonable semantics for brokered services: by default, only first service is brokered
+ *
+ * Revision 4.14 1996/04/29 15:29:19 epstein
+ * add disp to NI_HandPtr so that service-handle can encapsulate greater context
+ *
+ * Revision 4.13 1996/02/21 15:50:07 epstein
+ * Fix brokered-services for little-endian clients
+ *
+ * Revision 4.12 1996/02/02 14:53:41 epstein
+ * add PROXY_SERV_OVERRIDE setting for DIRECT_SVC_CON mode
+ *
+ * Revision 4.11 1996/01/17 20:33:09 epstein
+ * Add protection for DIRECT_SVC_CON mode; this comes into play with Mac OpenTransport
+ *
+ * Revision 4.10 1995/12/21 19:55:47 epstein
+ * make socket non-blocking for brokered services
+ *
+ * Revision 4.9 1995/11/30 19:58:08 epstein
+ * make NI_DirectServiceRequest() function static
+ *
+ * Revision 4.8 1995/11/29 17:50:24 epstein
+ * fix byte-ordering for direct-service connection
+ *
+ * Revision 4.7 1995/11/28 21:39:06 epstein
+ * remove unneeded sleep() call from non-UNIX platforms
+ *
+ * Revision 4.6 1995/11/28 20:18:41 epstein
+ * fix leaky-socket problem for non-direct-connection services
+ *
+ * Revision 4.5 1995/11/27 20:59:17 epstein
+ * add client support for direct-connection services
+ *
+ * Revision 4.2 95/10/19 20:29:06 epstein
+ * Bug fix to accomodate logic correct in Nlm_StringCmp()
+ *
+ * Revision 4.1 1995/08/01 13:48:33 epstein
+ * remember to initialize someBrokered
+ *
+ * Revision 4.0 1995/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.74 1995/07/12 14:53:28 epstein
+ * Another byte-ordering fix for SOCKS
+ *
+ * Revision 1.73 1995/06/06 10:04:52 epstein
+ * use USER environment variable in lieu of getlogin()
+ *
+ * Revision 1.72 95/06/02 16:58:43 epstein
+ * fix bindPort() using htonl() to correct byte-ordering problem on little-endian clients which use SOCKS
+ *
+ * Revision 1.71 95/05/17 17:52:18 epstein
+ * add RCS log revision history
+ *
+*/
+
+#define _NCBINET_LOCAL_VARS
+#define THIS_MODULE g_nsclient_module
+#define THIS_FILE _this_file
+#define __NI_LIB__
+#include "ncbinet.h"
+#include "ni_lib.h"
+#include "ni_msg.h"
+
+char * g_nsclient_module = "nsclient";
+static char *_this_file = __FILE__;
+
+
+#define ERR_KEY_MISMATCH "The public encryption key received from the dispatcher does\n\
+not match what is on file. There is a slight security risk\n\
+that this key is being presented by a \"spoofer\" rather than\n\
+the real dispatcher. You may wish to contact the NCBI by\n\
+other means to determine whether this new key is valid. Do\n\
+you wish to accept this as the new key and continue?"
+#define ERR_KEY_NOPREVKEY "A public encryption key was just received from the dispatcher,\n\
+but no key is currently on file. There is a slight security\n\
+risk that this key is being presented by a \"spoofer\" rather\n\
+than the real dispatcher. You may wish to contact the NCBI by\n\
+other means to determine whether this new key is valid. Do\n\
+you wish to accept this as the new key and continue?"
+
+#ifdef NETP_INET_NEWT
+
+#define SIN_ADDR sin_addr.S_un.S_addr
+#define H_ADDR_TYPE Uint4Ptr
+#else
+#define SIN_ADDR sin_addr
+#define H_ADDR_TYPE struct in_addr *
+#endif
+
+#ifdef WIN16
+#ifndef MAKEWORD
+#define MAKEWORD(a,b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) <<8))
+#endif
+#endif
+
+#define NULL_TIMER 0
+
+
+typedef struct NI_Timer {
+ time_t timeout;
+ NI_TimeoutHook hook;
+ Pointer hookParam;
+} NI_Timer, PNTR NI_TimerPtr;
+
+
+/* GLOBALS */
+static FILE *conid_fp = NULL; /* File pointer for CONID */
+static NodePtr timerHead = NULL; /* list of timers */
+static NI_NetServHook activityHook = NULL;
+static NI_DispatcherPtr currentDisp = NULL;
+static CharPtr stackDescription = NULL;
+static fd_set openfds;
+
+
+#ifdef NETP_INET_WSOCK
+static Int4 wsaStartupCount = 0;
+#endif
+
+NILoginPtr NI_MakeMsgLogin PROTO((void));
+static Int2 SetIdentity PROTO((NI_DispatcherPtr disp, CharPtr user, CharPtr group, CharPtr domain));
+static void HaltServices PROTO((NI_DispatcherPtr disp));
+static NI_HandPtr DispatchConnect PROTO((NI_DispatcherPtr disp, CharPtr host, CharPtr name, int timeout));
+static Uint2 bindPort PROTO((int sok, struct sockaddr_in PNTR sokadr, Int2 loport, Int2 hiport, Uint4 remoteHost));
+static Int2 CopyIdentity PROTO((NI_DispatcherPtr disp, NI_UidPtr uid));
+static NI_HandPtr NI_DirectServiceRequest PROTO((NIMsgPtr imp, NI_HandPtr sconnhp));
+
+
+int sokselectr PROTO((int fd));
+int sokselectw PROTO((int fd, int timeout));
+
+int getAsnError PROTO((char * str));
+void SetConFilePtr PROTO((FILE *fp));
+void CloseConFile PROTO((void));
+
+
+/* Added for the forward compatibility with "ni_lib_.h":
+ * NI_IsInterfaceSupported()
+ * NI_SetAddress()
+ * NI_SetInterface()
+ */
+NLM_EXTERN Boolean NI_IsInterfaceSupported(ENIInterface ni_interface) {
+ return (Boolean)(ni_interface == eNII_Dispatcher);
+}
+NLM_EXTERN void NI_SetAddress(const Char *address) {;}
+NLM_EXTERN ENIInterface NI_SetInterface(ENIInterface ni_interface) {
+ return eNII_Dispatcher;
+}
+
+
+
+
+/*
+ * Purpose: Specify which dispatcher a client should try to connect to
+ *
+ * Parameters:
+ * disp Usually NULL, the pointer to a pre-existing Dispatcher
+ * structure
+ * host Name of the host (Fully Qualified Domain Name) to use
+ * svc Name of the "service" to try to use on that host
+ * dispserialnum Serial number of dispatcher-list. Use -1 if no response
+ * list is desired, or 0 if the serial number is not known.
+ *
+ *
+ * Description:
+ * Set up the dispatcher name which should be used, and the
+ * name of the service on that dispatcher. If other parameters
+ * have been specified previously, free the memory associated
+ * with those names.
+ *
+ * Note:
+ * There are useful defaults for "svc". When in doubt, call
+ * this function with a second arguement of NULL.
+ */
+
+NLM_EXTERN NI_DispatcherPtr NI_SetDispatcher(NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
+ Int4 dispserialnum, ValNodePtr encryption, Boolean useOutServ)
+{
+ if (disp == NULL) {
+ if (currentDisp != NULL && !currentDisp->someBrokered)
+ { /* use current dispatcher if it matches what the caller wants */
+ if ((svc == NULL ||
+ StringCmp(svc, currentDisp->dispServiceName) == 0 ) &&
+ StringCmp(host, currentDisp->dispHostName) == 0) {
+ return currentDisp;
+ }
+ }
+
+ disp = (NI_DispatcherPtr) MemNew(sizeof(NI_Dispatcher));
+ if (disp == NULL)
+ return NULL;
+ disp->useOutServ = useOutServ; /* value from configfile */
+ disp->reqResponse = NULL;
+ disp->dispHostName = NULL;
+ disp->dispServiceName = NULL;
+ disp->dispSerialNo = 0;
+ disp->localHostAddr[0] = '\0';
+ disp->dispHP = NULL;
+ disp->svcsHP = NULL;
+ disp->clientPort = 0;
+ disp->identity = NULL;
+ disp->dispTimeout = 0;
+ disp->referenceCount = 0;
+ disp->someBrokered = FALSE;
+ disp->brokeredDummy = FALSE;
+ disp->encryptInfo = encryption;
+ disp->useSocks = FALSE;
+#ifdef SOCKS_CONF
+ {
+ FILE *fp;
+
+ if ((fp = FileOpen(SOCKS_CONF, "r")) != NULL)
+ {
+ disp->useSocks = TRUE;
+ FileClose(fp);
+ }
+ }
+#endif /* SOCKS_CONF */
+ }
+ if (disp->dispHostName != NULL) {
+ MemFree(disp->dispHostName);
+ disp->dispHostName = NULL;
+ }
+ if (disp->dispServiceName != NULL) {
+ MemFree(disp->dispServiceName);
+ disp->dispServiceName = NULL;
+ }
+ if (host != NULL)
+ disp->dispHostName = StringSave(host);
+ if (svc != NULL)
+ disp->dispServiceName = StringSave(svc);
+
+ disp->dispSerialNo = dispserialnum;
+ disp->dispTimeout = timeout;
+
+ return disp;
+} /* NI_SetDispatcher */
+
+
+
+/*
+ * Purpose: Try to establish a connection to the dispatcher
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * user User name to try on the dispatcher
+ * group Group name to try on the dispatcher
+ * password Password for this user name
+ * dip A pointer to the caller's list of dispatchers; this should
+ * be used by the caller to update its information
+ * regarding which dispatchers to try in the future
+ * (if dip == NULL, then no retries will be made to get
+ * alternate dispatchers)
+ *
+ * Returns:
+ * -1, if something failed (ni_errno indicates the nature of
+ * the problem)
+ * 0, if everything was successful
+ * 1, if we are connected to the dispatcher which we requested,
+ * but the list of current dispatchers has changed
+ * 2, if we are connected to a dispatcher, but not the one
+ * which we requested
+ *
+ *
+ * Description:
+ * Perform any WinSock and/or SOCKS initialization as necessary
+ * Connect to the dispatcher
+ * Set-up a socket for an incoming connection from a server
+ * application process (non-SOCKS clients only)
+ * Send a LOGIN message to the dispatcher
+ * Wait for an ACK or NACK response from the dispatcher (or for
+ * a timeout to occur)
+ * If the response was a NACK due to the dispatcher being a
+ * backup dispatcher, then try the dispatcher which it
+ * directs us to
+ */
+
+NLM_EXTERN Int2 NI_InitServices(NI_DispatcherPtr disp, CharPtr user, CharPtr group, CharPtr password, NI_DispInfoPtr PNTR dip)
+{
+ NIMsgPtr mp, imp;
+ NILoginPtr loginp;
+ struct sockaddr_in svcsAddr;
+ struct timeval timeout;
+ int ready;
+ NIDispInfoPtr dispinfo = NULL;
+ Boolean newDispToTry;
+ Int2 altDispTries = 0;
+ Int2 retval = 0;
+ int status;
+ fd_set readfds;
+ NI_PubKeyPtr pubKey = NULL;
+ Boolean failed;
+#ifdef NETP_INET_WSOCK
+ WSADATA wsaData;
+#endif /* NETP_INET_WSOCK */
+#if defined(OS_MAC) && defined(NETP_INET_MACTCP)
+ extern char * GetLAPType(void);
+ char *lapType = GetLAPType();
+#endif /* OS_MAC && NETP_INET_MACTCP */
+
+ if (disp == NULL)
+ {
+ ni_errno = NIE_MISC;
+ return -1;
+ }
+
+ if (disp->referenceCount > 0 && disp->dispHP != NULL)
+ { /* already connected */
+ disp->referenceCount++;
+ return 0;
+ }
+
+#ifdef NETP_INET_WSOCK
+ status = WSAStartup(MAKEWORD(1,1),&wsaData);
+ if (status != 0)
+ ErrPostEx(SEV_ERROR,0,0,"WinSock 1.1 initialization failure, code %d", status-WSABASEERR);
+ /* Try WinSock 1.1 and 1.0 in that order of preference */
+ if (status != 0 && (status = WSAStartup(MAKEWORD(1,0),&wsaData)) != 0)
+ {
+ ErrPostEx(SEV_ERROR,0,0,"WinSock 1.0 initialization failure, code %d", status-WSABASEERR);
+ ni_errno = NIE_TCPINITFAIL;
+ return -1;
+ }
+ TRACE("%s\n", wsaData.szDescription);
+ if (stackDescription != NULL)
+ {
+ MemFree(stackDescription);
+ }
+ stackDescription = StringSave(wsaData.szDescription);
+ for (status = StrLen(stackDescription) - 1; status >= 0; status--)
+ {
+ /* convert characters which are incompatible with VisibleString */
+ if (stackDescription[status] < ' ' || stackDescription[status] > '~')
+ stackDescription[status] = '#';
+ }
+ wsaStartupCount++;
+
+#endif
+#if defined(OS_MAC) && defined(NETP_INET_MACTCP)
+ if (lapType != NULL)
+ {
+ stackDescription = StringSave(lapType);
+ }
+#endif /* OS_MAC && NETP_INET_MACTCP */
+#ifdef OS_UNIX
+ {
+ FILE *fp;
+ char buffer[128];
+ int status;
+
+ MemSet(buffer, 0, sizeof(buffer));
+
+ if ((fp = popen("uname -a","r")) != NULL)
+ {
+ FileRead (buffer, 1, sizeof (buffer), fp);
+ stackDescription = StringSave(buffer);
+ pclose(fp);
+ for (status = StrLen(stackDescription) - 1; status >= 0; status--)
+ {
+ /* convert characters which are incompatible with VisibleString */
+ if (stackDescription[status] < ' ' || stackDescription[status] > '~')
+ stackDescription[status] = '#';
+ }
+
+ }
+ }
+#endif /* OS_UNIX */
+#ifdef NETP_SOCKS
+ if (disp->useSocks)
+ {
+ char path[128];
+
+ Nlm_ProgramPath(path, sizeof path);
+
+ SOCKSinit(path);
+ TRACE("Performed SOCKSinit(%s)\n", path);
+ }
+#endif /* NETP_SOCKS */
+
+ if (disp->dispHostName == NULL)
+ disp->dispHostName = StringSave(NI_DEFAULT_HOST);
+ if (disp->dispServiceName == NULL)
+ disp->dispServiceName = StringSave(NI_DEFAULT_SERVICE);
+
+ do {
+ newDispToTry = FALSE;
+ disp->svcsHP = NULL;
+ if ((disp->dispHP = DispatchConnect(disp, disp->dispHostName, disp->dispServiceName, disp->dispTimeout))
+ == NULL) {
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx(SEV_WARNING,0,0, "NI_InitServices: Unable to connect to host <%s>, error <%s>", disp->dispHostName, ni_errlist[ni_errno]);
+ return -1; /* ni_errno remains set */
+ }
+
+ if ((disp->svcsHP = MsgMakeHandle(TRUE)) == NULL) {
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: Unable to allocate resources to communicate with %s", disp->dispHostName);
+ return -1;
+ }
+
+ if (disp->dispTimeout > 0)
+ {
+ MsgSetReadTimeout(disp->svcsHP, disp->dispTimeout);
+ }
+
+ if (!disp->useOutServ)
+ { /* we need no listening if we are using direct connection */
+ if ((disp->clientPort = bindPort(disp->svcsHP->sok, &svcsAddr, disp->loport, disp->hiport, 0)) == 0) {
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ ni_errno = NIE_NOBIND; /* can't bind a free application socket */
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+ if ((status = NI_LISTEN(disp->svcsHP->sok, 5)) < 0) {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(status);
+#endif
+ StringCpy(ni_errtext, sys_errlist[SOCK_INDEX_ERRNO]);
+ ni_errno = NIE_NOLISTEN;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s> <port %d, errno %d>", ni_errlist[ni_errno], (int) disp->clientPort, (int) SOCK_ERRNO);
+ return -1;
+ }
+ }
+
+ SetIdentity(disp, user, group, NI_DEFAULT_DOMAIN);
+
+ loginp = NI_MakeMsgLogin();
+ NI_DestroyUid(loginp->uid);
+ loginp->uid = NI_MakeUid();
+ loginp->seqno = disp->dispHP->seqno++;
+ loginp->dispserialno = disp->dispSerialNo;
+ loginp->connectDelay = disp->dispHP->connectDelay;
+ if (disp->encryptInfo != NULL && NI_EncrAvailable())
+ {
+ loginp->encryptionDesired = TRUE;
+ if (disp->encryptInfo->data.ptrvalue != NULL)
+ {
+ pubKey = (NI_PubKeyPtr) disp->encryptInfo->data.ptrvalue;
+ loginp->pubKey = (NIPubKeyPtr) NI_PubKeyDup(pubKey);
+ }
+ }
+ CopyIdentity(disp, loginp->uid);
+ if (password != NULL)
+ loginp->password = StringSave(password);
+ mp = MsgBuild(NI_LOGIN, disp->dispHP->conid, (VoidPtr) loginp);
+
+ if (MsgWrite(disp->dispHP, mp, FALSE) < 0) {
+ if (getAsnError(ni_errtext) == ECONNRESET)
+ ni_errno = NIE_MAXCONNS;
+ else
+ ni_errno = NIE_MSGWRITE;
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+
+ /* blocks until ACK or ERROR from dispatcher or TIMEOUT */
+
+ timeout.tv_sec = (Uint4) NI_TIMEOUT_SECS;
+ timeout.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(disp->dispHP->sok, &readfds);
+ while ((ready = NI_select(FD_SETSIZE, &readfds, NULL, NULL, &timeout)) < 0) {
+ if (SOCK_ERRNO == EINTR)
+ ; /* repeat while interrupted */
+ else {
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ ni_errno = NIE_SELECT; /* select error */
+ NI_DestroyDispInfo(dispinfo);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+ }
+
+ if (FD_ISSET(disp->dispHP->sok, &readfds) != 0) {
+ if ((imp = MsgRead(disp->dispHP, FALSE)) == NULL) {
+ if (getAsnError(ni_errtext) == ECONNRESET)
+ ni_errno = NIE_MAXCONNS;
+ else
+ ni_errno = NIE_MSGREAD;
+
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+ switch (imp->type) {
+ case NI_ACK:
+ /************************************************************/
+ /* even though we connected successfully to the dispatcher, */
+ /* it may have given us more up-to-date information on the */
+ /* latest list of dispatchers which should be tried; if so, */
+ /* pass the updated list back to the caller */
+ /************************************************************/
+ if (imp->msun.ack->dispinfo != NULL) {
+ if (dispinfo != NULL)
+ {
+ NI_DestroyDispInfo(dispinfo);
+ dispinfo = NULL;
+ }
+ dispinfo = imp->msun.ack->dispinfo;
+ imp->msun.ack->dispinfo = NULL; /* for clean free */
+ }
+ if (disp->encryptInfo != NULL && NI_EncrAvailable())
+ {
+ if (dispinfo != NULL && dispinfo->pubKey != NULL)
+ {
+ failed = FALSE;
+ if (pubKey == NULL)
+ {
+ failed = Message(MSG_YN, ERR_KEY_NOPREVKEY) ==
+ ANS_NO;
+ ni_errno = NIE_NEWKEYNOTACCPT;
+ } else {
+ if (! NI_PubKeysEqual(pubKey, (NI_PubKeyPtr) dispinfo->pubKey))
+ {
+ failed = Message(MSG_YN, ERR_KEY_MISMATCH) ==
+ ANS_NO;
+ ni_errno = NIE_NEWKEYMISMATCH;
+ }
+ }
+ if (failed)
+ {
+ HaltServices(disp);
+ MsgDestroy(imp);
+ return -1;
+ } else {
+ /* replace the key */
+ NI_DestroyPubKey((NIPubKeyPtr) pubKey);
+ pubKey = (NI_PubKeyPtr) dispinfo->pubKey;
+ dispinfo->pubKey = NULL;
+ disp->encryptInfo->data.ptrvalue = (Pointer) pubKey;
+ }
+ }
+ }
+ if (dispinfo != NULL && dip != NULL) {
+ if (*dip != NULL)
+ NI_DestroyDispInfo((NIDispInfoPtr) *dip);
+ *dip = (NI_DispInfoPtr) dispinfo;
+ dispinfo = NULL;
+ retval = 1;
+ }
+ else {
+ NI_DestroyDispInfo(dispinfo);
+ }
+ if (imp->msun.ack->motd != NULL &&
+ imp->msun.ack->motd[0] != NULLB)
+ {
+ disp->motd = imp->msun.ack->motd;
+ imp->msun.ack->motd = NULL; /* for clean free */
+ }
+ if (imp->msun.ack->adminInfo != NULL &&
+ imp->msun.ack->adminInfo[0] != NULLB)
+ {
+ disp->adminInfo = imp->msun.ack->adminInfo;
+ imp->msun.ack->adminInfo = NULL; /* for clean free */
+ }
+#ifdef OS_UNIX
+ signal(SIGPIPE, SIG_IGN); /* catch socket errors */
+#endif /* OS_UNIX */
+ MsgDestroy(imp);
+ disp->referenceCount++;
+ if (currentDisp == NULL)
+ {
+ currentDisp = disp;
+ }
+ return retval; /* only good return */
+
+ case NI_NACK:
+ ni_errno = (enum ni_error) imp->msun.nack->code;
+ if (imp->msun.nack->reason != NULL)
+ {
+ StringCpy(ni_errtext, imp->msun.nack->reason);
+ } else {
+ ni_errtext[0] = '\0';
+ }
+ if (dispinfo != NULL)
+ {
+ NI_DestroyDispInfo(dispinfo);
+ dispinfo = NULL;
+ }
+ dispinfo = imp->msun.nack->dispinfo;
+ imp->msun.nack->dispinfo = NULL; /* for clean free */
+ if (ni_errno == NIE_BACKUPDISP && dispinfo != NULL &&
+ dispinfo->numdispatchers > 0 && dip != NULL &&
+ ++altDispTries < MAX_ALT_DISP_TRIES)
+ {
+ MsgDestroy(imp);
+ HaltServices (disp);
+ NI_SetDispatcher(disp, dispinfo->displist[0], disp->dispServiceName,
+ disp->dispTimeout, dispinfo->serialno, disp->encryptInfo,
+ disp->useOutServ);
+ newDispToTry = TRUE;
+ retval = 2;
+ break;
+ }
+ MsgDestroy(imp);
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>\n%s", ni_errlist[ni_errno], ni_errtext);
+ return -1;
+
+ default:
+ MsgDestroy(imp);
+ ni_errno = NIE_MSGUNK;
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+ }
+ }
+ } while (newDispToTry);
+
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = NULL;
+ ni_errno = NIE_LOGTIMEOUT; /* TIMEOUT */
+ NI_DestroyDispInfo(dispinfo);
+ HaltServices (disp);
+ ErrPostEx (SEV_ERROR, CTX_NCBICORE, CORE_UNKNOWN, "NI_InitServices: <%s>", ni_errlist[ni_errno]);
+ return -1;
+} /* NI_InitServices */
+
+
+/*
+ * Purpose: Init network services based on information in config file
+ *
+ * Parameters:
+ * configFile Name of NCBI-style configuration file. If NULL, defaults
+ * to "NCBI"
+ * configSection Section with NCBI-style configuration file. If NULL,
+ * defaults to "NET_SERV"
+ * showMonitor Boolean; if TRUE, display a monitor while re-trying
+ * for an alternate dispatcher
+ * lastDispatcher Pointer to where this function should store the name
+ * of the dispatcher which was actually used (may be NULL
+ * if the caller does not care about this value)
+ * lastDispLen Maximum length of lastDispatcher
+ *
+ * Returns:
+ * NULL, if unable to contact dispatcher
+ * a pointer to the Dispatcher structure, otherwise
+ *
+ *
+ * Description:
+ * Extracts a dispatcher name and a user name from a configuration
+ * file. If necessary, tries other dispatchers, in order, as
+ * listed in configuration file. Also sets up encryption, if
+ * the client is encryption-capable and encryption is requested
+ * in the configuration file.
+ *
+ *
+ * Note:
+ * This function is provided as a convenience to developers who
+ * wish to use Network Services. Use of this function is not
+ * integral to the use of Network Services ... it is merely a
+ * convenience.
+ */
+
+NLM_EXTERN NI_DispatcherPtr NI_GenericInit (CharPtr configFile, CharPtr configSection, Boolean showMonitor, CharPtr lastDispatcher, Int2 lastDispLen)
+{
+ char *def_user;
+ char username[64];
+ char groupname[20];
+ char password[20];
+ char dispname[60];
+ char disp_config[10];
+ char disp_msg[110];
+ char buf[60];
+ Boolean more_disps;
+ int alternate = 1;
+ int disp_timeout;
+ Int4 disp_serialno;
+ Monitor *mon = NULL;
+ NI_DispInfoPtr dip = NULL;
+ NI_DispatcherPtr disp = NULL;
+ Boolean someBrokered;
+ Boolean useOutServ;
+ ValNodePtr encryptInfo = NULL;
+ NI_PubKeyPtr keyCopy = NULL;
+ Boolean doEncr = FALSE;
+ Boolean quitOnDispConnFailure = FALSE;
+ Boolean showMessage = FALSE;
+ Int4 numBrokeredServices;
+#ifdef OS_UNIX
+ char *getlogin PROTO((void));
+#endif
+
+ /******************* open the network connnection *********/
+#define NI_DISP_NAME "dispatch1.nlm.nih.gov"
+#define NI_USER_NAME "anonymous"
+#define NI_GROUP_NAME "GUEST"
+
+ def_user = NI_USER_NAME;
+
+ if (configFile == NULL)
+ configFile = "NCBI";
+ if (configSection == NULL)
+ configSection = "NET_SERV";
+
+ GetAppParam(configFile, configSection, "DISP_USERNAME", NI_USER_NAME, username,
+ sizeof username);
+ /* the user's login name overrides the config file */
+ /* for UNIX or VMS systems (or, for the future, any system where the */
+ /* user name can be determined), use the user's login name as the default */
+ def_user = NULL;
+#ifdef OS_UNIX
+ if ((def_user = getenv("USER")) == NULL)
+ {
+ def_user = getlogin();
+ }
+#endif
+#ifdef OS_VMS
+ def_user = getenv("USER");
+#endif
+ if (def_user != NULL)
+ {
+ StrNCpy(username, def_user, sizeof username);
+ }
+
+ GetAppParam(configFile, configSection, "DISP_GROUPNAME", NI_GROUP_NAME, groupname,
+ sizeof groupname);
+ GetAppParam(configFile, configSection, "DISP_PASSWORD", "", password,
+ sizeof password); /* default = NONE */
+
+ GetAppParam(configFile, configSection, "DISP_TIMEOUT", "0", buf, sizeof buf);
+ disp_timeout = atoi(buf);
+
+ GetAppParam(configFile, configSection, "DISPSERIALNO", "0", buf, sizeof buf);
+ disp_serialno = atoi(buf);
+
+ GetAppParam(configFile, configSection, "DISPATCHER", NI_DISP_NAME, dispname,
+ sizeof dispname);
+
+ GetAppParam(configFile, configSection, "DIRECT_SVC_CON", "FALSE", buf,
+ sizeof(buf));
+ useOutServ = StrICmp(buf, "TRUE") == 0;
+
+ GetAppParam(configFile, configSection, "SOME_BROKERED", "FALSE", buf, sizeof buf);
+ someBrokered = StrICmp(buf, "TRUE") == 0;
+ if (someBrokered) {
+ GetAppParam(configFile, configSection, "BROKERED_COUNT", "1", buf, sizeof buf);
+ numBrokeredServices = atoi(buf);
+ if (numBrokeredServices <= 0) {
+ someBrokered = FALSE;
+ } else {
+ sprintf (buf, "%ld", (long) numBrokeredServices - 1);
+ TransientSetAppParam(configFile, configSection, "BROKERED_COUNT", buf);
+ }
+ }
+
+ GetAppParam(configFile, configSection, "DISP_RECONN_ACTION", "CONT", buf, sizeof buf);
+ showMessage = StrICmp(buf, "ASK") == 0;
+ quitOnDispConnFailure = StrICmp(buf, "QUIT") == 0;
+
+ GetAppParam(configFile, configSection, "ENCRYPTION_DESIRED", "FALSE", buf, sizeof buf);
+ if (StrICmp(buf, "TRUE") == 0 && NI_EncrAvailable())
+ {
+ doEncr = TRUE;
+ encryptInfo = ValNodeNew(NULL);
+ encryptInfo->data.ptrvalue = (Pointer) NI_ReadPubKeyFromConfig();
+ keyCopy = NI_PubKeyDup((NI_PubKeyPtr) encryptInfo->data.ptrvalue);
+ }
+
+ do {
+ if (alternate == 2 && showMonitor)
+ {
+ mon = MonitorStrNew("Unable to contact primary dispatcher", 35);
+ }
+ if (alternate >= 2)
+ {
+ if (showMessage)
+ {
+ sprintf (disp_msg, "Unable to contact primary dispatcher. Ready to try\ndispatcher #%d <", alternate);
+ StrCat(disp_msg, dispname);
+ StrCat(disp_msg, ">. Continue?");
+ if (Message(MSG_YN, disp_msg) == ANS_NO)
+ break;
+ } else {
+ sprintf(disp_msg, "Trying dispatcher #%d <", alternate);
+ StrCat(disp_msg, dispname);
+ StrCat(disp_msg, ">");
+ if (showMonitor) {
+ MonitorStrValue(mon, disp_msg);
+ }
+ }
+ }
+
+ if (lastDispatcher != NULL) {
+ StrNCpy(lastDispatcher, dispname, lastDispLen);
+ }
+
+ disp = NI_SetDispatcher (NULL, dispname, NULL, disp_timeout, disp_serialno, encryptInfo, useOutServ);
+
+ if (someBrokered) {
+ disp->brokeredDummy = TRUE;
+ disp->someBrokered = TRUE;
+ disp->referenceCount++;
+ ValNodeFree (encryptInfo);
+ return disp;
+ }
+
+ if (NI_InitServices(disp, username, groupname[0] == '\0' ? 0 : groupname,
+ password[0] == '\0' ? 0 : password, &dip) >= 0)
+ {
+ if (dip != NULL && dip->serialno != disp_serialno) {
+ NI_SetDispConfig (&dip, dispname, sizeof dispname);
+ }
+ if (mon != NULL)
+ MonitorFree(mon);
+ if (disp->encryptInfo != NULL &&
+ disp->encryptInfo->data.ptrvalue != NULL &&
+ ! NI_PubKeysEqual(keyCopy,
+ (NI_PubKeyPtr) disp->encryptInfo->data.ptrvalue))
+ {
+ NI_WritePubKeyToConfig ((NI_PubKeyPtr) disp->encryptInfo->data.ptrvalue);
+ }
+ NI_DestroyPubKey ((NIPubKeyPtr) keyCopy);
+ return disp;
+ }
+ ErrShow ();
+ NI_EndServices (disp);
+ sprintf(disp_config, "DISP_ALT_%d", alternate++);
+ more_disps = GetAppParam(configFile, configSection, disp_config, "", dispname,
+ sizeof dispname);
+ if (doEncr)
+ {
+ encryptInfo = ValNodeNew(NULL);
+ encryptInfo->data.ptrvalue = (Pointer)
+ NI_PubKeyDup((NI_PubKeyPtr) keyCopy);
+ }
+ } while (more_disps && ! quitOnDispConnFailure);
+
+ if (mon != NULL)
+ MonitorFree(mon);
+
+ ValNodeFree (encryptInfo);
+ NI_DestroyPubKey ((NIPubKeyPtr) keyCopy);
+ ErrPostEx(SEV_ERROR,0,0, "NI_InitServices: Unable to connect to any dispatcher");
+ return NULL;
+}
+
+
+/*
+ * Purpose: Get a network service based on information in config file
+ *
+ * Parameters:
+ * disp Pointer to the dispatcher structure obtained from a
+ * previous call to NI_SetDispatcher or NI_GenericInit
+ * configFile Name of NCBI-style configuration file. If NULL, defaults
+ * to "NCBI"
+ * defService The default service/resource/resource-type name, if
+ * not specified otherwise in configuration file.
+ * hasResource Boolean; if TRUE, ask for a resource when requesting
+ * service
+ *
+ * Returns:
+ * NULL, if unable to obtain service
+ * a pointer to the service-structure, otherwise
+ *
+ *
+ * Description:
+ * Extracts a service name and other service data from a
+ * configuration file, and attempts to obtain that service.
+ * As a special case, handle communication with a "brokered
+ * server" (a server which is already listening on a port, where
+ * no communication needs to be performed with the dispatcher).
+ * Also disable data encryption for this service request, if
+ * explicitly specified in the configuration file.
+ *
+ *
+ * Note:
+ * This function is provided as a convenience to developers who
+ * wish to use Network Services. Use of this function is not
+ * integral to the use of Network Services ... it is merely a
+ * convenience.
+ *
+ * For UNIX systems, environment variables can be used to
+ * override the config. file's values for SERVICE_NAME and
+ * RESOURCE_TYPE.
+ */
+
+NLM_EXTERN NI_HandPtr NI_GenericGetService (NI_DispatcherPtr disp, CharPtr configFile, CharPtr configSection, CharPtr defService, Boolean hasResource)
+{
+ char buf[40];
+ char service[40];
+ char resource[40];
+ char res_type[40];
+ int serv_min;
+ int serv_max;
+ int res_min;
+ int res_max;
+ char brokeredIpaddr[40];
+ Uint2 port;
+ NI_HandPtr result;
+ ValNodePtr savEncrypt;
+#ifdef OS_UNIX
+ CharPtr envName = (CharPtr)MemNew(StrLen(configSection) + 20);
+ CharPtr envValue;
+#endif
+
+ if (configFile == NULL)
+ configFile = "NCBI";
+
+ GetAppParam(configFile, configSection, "SERVICE_NAME", defService,
+ service, sizeof service);
+#ifdef OS_UNIX
+ /* environment variable overrides config. file */
+ sprintf (envName, "NI_SERVICE_NAME_%s", configSection);
+ if ((envValue = getenv(envName)) != NULL)
+ {
+ StrCpy (service, envValue);
+ }
+#endif /* OS_UNIX */
+ GetAppParam(configFile, configSection, "SERV_VERS_MIN", "1",
+ buf, sizeof buf);
+ serv_min = atoi(buf);
+ GetAppParam(configFile, configSection, "SERV_VERS_MAX", "0",
+ buf, sizeof buf);
+ serv_max = atoi(buf);
+
+ res_min = 1;
+ res_max = 0;
+
+ if (hasResource) {
+ GetAppParam(configFile, configSection, "RESOURCE_NAME", defService,
+ resource, sizeof resource);
+ GetAppParam(configFile, configSection, "RESOURCE_TYPE", defService,
+ res_type, sizeof res_type);
+#ifdef OS_UNIX
+ /* environment variable overrides config. file */
+ sprintf (envName, "NI_RESOURCE_TYPE_%s", configSection);
+ if ((envValue = getenv(envName)) != NULL)
+ {
+ StrCpy (res_type, envValue);
+ }
+#endif /* OS_UNIX */
+ GetAppParam(configFile, configSection, "RES_VERS_MIN", "1",
+ buf, sizeof buf);
+ res_min = atoi(buf);
+ GetAppParam(configFile, configSection, "RES_VERS_MAX", "0",
+ buf, sizeof buf);
+ res_max = atoi(buf);
+ }
+
+#ifdef OS_UNIX
+ MemFree (envName);
+#endif /* OS_UNIX */
+
+ if (disp->someBrokered)
+ {
+ GetAppParam(configFile, configSection, "BROKERED_PORT", "0",
+ buf, sizeof buf);
+ port = htons(atoi(buf));
+ GetAppParam(configFile, configSection, "BROKERED_IPADDR", "",
+ brokeredIpaddr, sizeof brokeredIpaddr);
+ if (port != 0 && brokeredIpaddr[0] != '\0')
+ { /* simulate service request by connecting to that port */
+ struct sockaddr_in serv_addr;
+ NI_HandPtr sHP;
+ int timeout = 30;
+ int status;
+
+ MemFill((VoidPtr) &serv_addr, '\0', sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = inet_addr(brokeredIpaddr);
+ serv_addr.sin_port = port;
+
+ if ((sHP = MsgMakeHandle(TRUE)) == NULL)
+ return NULL;
+ MsgSetLJError(sHP);
+ sHP->hostname = StringSave(brokeredIpaddr);
+
+ if (activityHook != NULL)
+ {
+ activityHook(sHP, NetServHook_svcreq, 0);
+ }
+
+ RETRY:
+#ifndef NETP_INET_NEWT
+ if ((status = NI_CONNECT(sHP->sok, (struct sockaddr PNTR) &serv_addr, sizeof(serv_addr))) < 0) { /* } */
+#else
+ if ((status = NI_CONNECT(sHP->sok, &serv_addr, sizeof(serv_addr))) < 0) {
+ SOCK_ERRNO = ABS(status);
+#endif
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ goto RETRY;
+
+#ifdef NETP_INET_PCNFS
+ /* This is apparently a bug in PC-NFS 4.0 ... a connection attempt */
+ /* on a non-blocking socket yields errno == 0 */
+ case 0:
+#endif /* NETP_INET_PCNFS */
+ case EWOULDBLOCK:
+ case EINPROGRESS:
+ /* if the connect()ion is not established immediately, a */
+ /* select() can be performed where the corresponding "write" */
+ /* file descriptor will be enabled once the connect()ion has been*/
+ /* established */
+ if (sokselectw(sHP->sok, timeout) == 0) {
+ return sHP;
+ }
+ break;
+
+ default:
+ break;
+ }
+ MsgDestroyHandle(sHP);
+ ni_errno = NIE_BROKSVCCONN; /* can't connect to brokered service */
+ return NULL;
+ }
+ {
+ Char buf[16];
+ Char key[8];
+ Int2 len;
+
+ if ((len = GetAppParam("NCBI", "NET_SERV", "DESKEY", "", buf, sizeof buf)) > 0 &&
+ (AsnTypeStringToHex(buf, len, key, NULL) == 0))
+
+ {
+ NI_SetupDESEncryption(sHP, (UcharPtr) key);
+ }
+ }
+ return sHP;
+ } else {
+ if (disp->brokeredDummy)
+ { /* JAE ... establish a true dispatcher connection here */
+ }
+ }
+ }
+
+ savEncrypt = disp->encryptInfo;
+ if (GetAppParam(configFile, configSection, "ENCRYPTION", "TRUE",
+ buf, sizeof buf) > 0 && StrICmp(buf, "FALSE") == 0)
+ {
+ /* temporarily disable encryption */
+ disp->encryptInfo = NULL;
+ }
+ result = NI_ServiceGet(disp, service, serv_min, serv_max,
+ hasResource ? resource : 0, res_type, res_min,
+ res_max);
+ disp->encryptInfo = savEncrypt;
+
+ return result;
+}
+
+
+/*
+ * Purpose: Write dispatcher-configuration information to a config file
+ *
+ * Parameters:
+ * dipp A pointer to the caller's list of dispatchers, obtained
+ * from NI_InitServices()
+ * dispatcher The caller's dispatcher string
+ * dispLen Length of the caller's dispatcher string
+ *
+ * Returns:
+ * 0, if bad parameters were provided
+ * the dispatcher-list serial number, otherwise
+ *
+ *
+ * Description:
+ * Sets up the "NCBI" configuration file with the following
+ * entries in the "NET_SERV" section:
+ * * DISPATCHER is the primary dispatcher name
+ * * DISP_ALT_n for every alternate dispatcher, 1 <= n, a smaller
+ * n indicates a higher priority alternate dispatcher
+ * * DISPSERIALNO is the serial number of the dispatcher list
+ * obtained from a remote dispatcher. This serial number should
+ * be unique for all time ... the dispatcher's serial number
+ * must be changed whenever the master list is modified.
+ *
+ * Note:
+ * This configuration mechanism is only _one_ recommended
+ * mechanism for network services dispatcher configuration. The
+ * application may perform this configuration in any manner
+ * deemed appropriate by the application programmer.
+ *
+ * The value returned by this function is the recommended value
+ * for the dispserialno parameter in a subsequent call to
+ * NI_InitDispatcher().
+ */
+
+NLM_EXTERN Int4 NI_SetDispConfig(NI_DispInfoPtr PNTR dipp, CharPtr dispatcher, Int2 dispLen)
+{
+ Int2 num;
+ Char dispConfig[20];
+ char buf[10];
+ Int4 retval;
+ NI_DispInfoPtr dip;
+
+ if (dipp == NULL || (dip = *dipp) == NULL)
+ {
+ if (dispatcher != NULL)
+ {
+ dispatcher[0] = '\0';
+ }
+ return 0;
+ }
+
+ if (dip->numdispatchers > 0 && dip->displist != NULL)
+ {
+ StringNCpy (dispatcher, dip->displist[0], dispLen);
+ SetAppParam ("NCBI", "NET_SERV", "DISPATCHER", dip->displist[0]);
+ }
+
+ for (num = 1; num < dip->numdispatchers; num++)
+ {
+ sprintf (dispConfig, "DISP_ALT_%d", num);
+ SetAppParam ("NCBI", "NET_SERV", dispConfig, dip->displist[num]);
+ }
+
+ /* wipe out any extraneous old configuration */
+ for (num = dip->numdispatchers; num < 100; num++)
+ {
+ sprintf (dispConfig, "DISP_ALT_%d", num);
+ if (GetAppParam("NCBI", "NET_SERV", dispConfig, "", buf, sizeof buf) <= 0)
+ {
+ break;
+ }
+ SetAppParam ("NCBI", "NET_SERV", dispConfig, NULL);
+ }
+
+ retval = dip->serialno;
+ sprintf (buf, "%ld", (long) dip->serialno);
+ SetAppParam ("NCBI", "NET_SERV", "DISPSERIALNO", buf);
+
+ NI_DestroyDispInfo ((NIDispInfoPtr) dip);
+ *dipp = NULL;
+
+ return retval;
+}
+
+
+/*
+ * Purpose: End use of network services
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ *
+ * Returns:
+ * 0 (always)
+ *
+ *
+ * Description:
+ * Tear down the sockets and data structures associated with
+ * the dispatcher and a server, and free all memory associated
+ * with data structures.
+ */
+
+NLM_EXTERN Int2 NI_EndServices(NI_DispatcherPtr disp)
+{
+ Int2 openSockets;
+
+ if (disp == NULL)
+ return 0;
+
+ if (disp->referenceCount > 0)
+ disp->referenceCount--;
+
+ if (disp->referenceCount <= 0)
+ {
+ if (disp == currentDisp)
+ {
+ currentDisp = NULL;
+ }
+
+ HaltServices (disp);
+ NI_SetDispatcher(disp, NULL, NULL, 0, 0, NULL, FALSE); /* free mem */
+
+ if (stackDescription != NULL)
+ {
+ MemFree(stackDescription);
+ stackDescription = NULL;
+ }
+ MemFree(disp->adminInfo);
+ MemFree(disp->motd);
+ MemFree(disp);
+
+ /* For historical reasons pertaining to Network Entrez, a single open
+ socket does not constitute an error in this context. However, at
+ program exit time, a single open socket does constitute a serious
+ problem. */
+ if ((openSockets = NI_SocketsOpen()) > 1)
+ {
+ ErrPostEx(SEV_WARNING,0,0, "At end-services time, %d sockets are still open", openSockets);
+ }
+ }
+
+ return 0;
+} /* NI_EndServices */
+
+
+
+/*
+ * Purpose: Request a catalog from the dispatcher
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ *
+ * Returns:
+ * NULL, if unable to obtain the catalog
+ * a pointer to the received catalog data structure, otherwise
+ *
+ *
+ * Description:
+ * Send a request to the dispatcher, requesting a catalog, and
+ * wait (up to some timeout) for a response. The dispatcher's
+ * response should either be that catalog, or a NACK.
+ */
+
+NLM_EXTERN NICatalogPtr NI_GetCatalog(NI_DispatcherPtr disp)
+{
+ NICatalogPtr catp;
+ NIMsgPtr mp, imp;
+ NICmdPtr cmdp;
+ struct timeval timeout;
+ int ready;
+ fd_set readfds;
+
+ if (disp == NULL)
+ return NULL;
+
+ cmdp = (NICmdPtr) NI_MakeMsgCmd();
+ cmdp->seqno = disp->dispHP->seqno++;
+ cmdp->code = NI_SEND_CATALOG;
+ if ((mp = MsgBuild(NI_COMMAND, disp->dispHP->conid, (VoidPtr) cmdp)) == NULL) {
+ ni_errno = NIE_MISC; /* unable to alloc mem for Msg */
+ return NULL;
+ }
+ if (MsgWrite(disp->dispHP, mp, FALSE) < 0) {
+ ni_errno = NIE_MSGWRITE;
+ return NULL;
+ }
+
+ /* blocks until response from dispatcher or TIMEOUT */
+
+ timeout.tv_sec = (Uint4) NI_TIMEOUT_SECS;
+ timeout.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(disp->dispHP->sok, &readfds);
+ while ((ready = NI_select(FD_SETSIZE, &readfds, NULL, NULL, &timeout)) < 0) {
+ if (SOCK_ERRNO == EINTR)
+ ; /* repeat while interrupted */
+ else {
+ ni_errno = NIE_SELECT; /* select error */
+ return NULL;
+ }
+ }
+
+ if (FD_ISSET(disp->dispHP->sok, &readfds) != 0) {
+ if ((imp = MsgRead(disp->dispHP, FALSE)) == NULL) {
+ LOG_SOCKET(disp->dispHP->sok, FALSE);
+ NI_CLOSESOCKET(disp->dispHP->sok);
+ ni_errno = NIE_MSGREAD;
+ return NULL;
+ }
+ switch (imp->type) {
+ case NI_CATALOG:
+ catp = imp->msun.catalog;
+ imp->msun.catalog = NULL;
+ ni_errno = NIE_NO_ERROR;
+ MsgDestroy(imp);
+ return catp;
+ break;
+
+ case NI_NACK:
+ ni_errno = (enum ni_error) imp->msun.nack->code;
+ if (imp->msun.nack->reason != NULL)
+ StringCpy(ni_errtext, imp->msun.nack->reason);
+ else
+ ni_errtext[0] = '\0';
+ MsgDestroy(imp);
+ return NULL;
+
+ default:
+ MsgDestroy(imp);
+ ni_errno = NIE_MSGUNK; /* Unknown MSG type */
+ return NULL;
+ }
+ }
+ ni_errno = NIE_CMDTIMEOUT; /* TIMEOUT */
+ return NULL;
+} /* NI_GetCatalog */
+
+
+
+/*
+ * Purpose: Create the data structure for a service request
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ *
+ * Returns:
+ * a pointer to the newly created data structure
+ *
+ *
+ * Description:
+ * Allocate the memory for a service request data structure,
+ * and fill in some of the fields.
+ * Note:
+ * There are two ways for a program to issue a service request:
+ * (1) Multi-step, general method (like IRS form 1040)
+ * * Build a request with NI_SVCRequestBuild()
+ * * Populate the request with a specific service request using
+ * NI_RequestSetService()
+ * * Populate the request with zero or more resource requests
+ * calling NI_RequestAddResource() once for every resource
+ * * Send the request with NI_ServiceRequest(), and (hopefully)
+ * obtain a connection to a service provider
+ * * At some later time, delete the request (to save memory)
+ * (2) One-stop shopping, for simple requirement (like form 1040EZ)
+ * * Do everything for a service and up to one resource using
+ * NI_ServiceGet()
+ */
+
+NLM_EXTERN NI_ReqPtr NI_SVCRequestBuild(NI_DispatcherPtr disp)
+{
+ NI_ReqPtr reqp;
+
+ if (disp == NULL)
+ return NULL;
+
+ reqp = (NI_ReqPtr) NI_MakeRequest();
+ reqp->clientPort = (Uint2) disp->clientPort;
+ if (disp->useSocks)
+ {
+ /* tell the Dispatcher that it should use getpeername() to determine */
+ /* the IP address of the SOCKS daemon */
+ reqp->clientAddr = StringSave("0.0.0.0");
+ } else {
+ reqp->clientAddr = StringSave(disp->localHostAddr);
+ }
+ reqp->dispatcher = disp; /* should not be freed when destroying Req */
+
+ return reqp;
+} /* NI_SVCRequestBuild */
+
+
+
+/*
+ * Purpose: Destroy a service request data structure
+ *
+ * Parameters:
+ * reqp A pointer to the data structure to be destroyed
+ *
+ *
+ * Description:
+ * Free all the resources associated with a service request
+ */
+
+NLM_EXTERN void NI_SVCRequestDestroy(NI_ReqPtr reqp)
+{
+ NI_DestroyRequest(reqp);
+} /* NI_SVCRequestDestroy */
+
+
+
+/*
+ * Purpose: Make a service request for a service and up to one resource
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * svc Name of requested service
+ * svcvermin Minimum version number requested for this service
+ * svcvermax Maximum version number requested for this service
+ * res Name of requested resource (possibly NULL)
+ * resvermin Minimum version number requested for this resource
+ * resvermax Maximum version number requested for this resource
+ *
+ * Returns:
+ * The result of the service request
+ *
+ *
+ * Description:
+ * Create and issue a service request for the specified
+ * parameters.
+ */
+
+NLM_EXTERN NI_HandPtr NI_ServiceGet(NI_DispatcherPtr disp, CharPtr svc, Uint2 svcvermin, Uint2 svcvermax, CharPtr res, CharPtr restype, Uint2 resvermin, Uint2 resvermax)
+{
+ NI_ReqPtr reqp;
+
+ if (disp == NULL)
+ return NULL;
+
+ reqp = NI_SVCRequestBuild(disp);
+ NI_RequestSetService(reqp, svc, svcvermin, svcvermax);
+ if (res != NULL)
+ NI_RequestAddResource(reqp, res, restype, resvermin, resvermax);
+
+ return NI_ServiceRequest(reqp);
+} /* NI_ServiceGet */
+
+
+
+/*
+ * Purpose: Issue the specified service request
+ *
+ * Parameters:
+ * req The pre-formatted service request
+ *
+ * Returns:
+ * A message handle to the server which is servicing our request,
+ * if successful
+ * NULL, otherwise (ni_errno will indicate a more precise cause)
+ *
+ *
+ * Description:
+ * Create and issue a service request for the specified
+ * service request, as follows:
+ *
+ * * Create a data structure to which the resulting service
+ * connection can be attached
+ * * Send the service request to the dispatcher
+ *
+ * old - style connection:
+ *
+ * * Wait for the following two events, in either order:
+ * (1) A response from the dispatcher, which is either a
+ * SVC_RESPONSE (good), or a NACK (bad) {or a timeout}
+ * (2) A connection request from the server, which we then
+ * accept()
+ * * If both of the two events occur successfully, return with
+ * success, else, return with failure.
+ *
+ * old-style / direct connection switch
+ * (currently disabled)
+ *
+ * * After NACK was received in old - style connection we don't
+ * worry, set disp->useOutServ to TRUE and return to the beginning
+ * of the function. All service request will be repeated with
+ * direct connection.
+ *
+ * direct connection:
+ *
+ * * Wait for the following events:
+ * (1) A response from the dispatcher, which is either a
+ * SVC_REQUEST (good), or a NACK (bad) {or a timeout}
+ * * In the case of SVC_REQUEST we send this request directly
+ * to the server and wait for next event:
+ * (2) A response from the dispatcher, which is either a
+ * SVC_RESPONSE (good), or a NACK (bad) {or a timeout}
+ * * If both of the two events occur successfully, return with
+ * success, else, return with failure.
+ *
+ * Note:
+ * If the caller's Dispatcher data structure indicates that
+ * encryption should be performed, then a DES key is
+ * pseudorandomly generated prior to issuing the service request,
+ * and is encrypted using public-key encryption. Following
+ * successful establishment of the client<->server session, the
+ * DES key is used to encrypt the ensuing session using
+ * cypher-block-chaining.
+ *
+ * For SOCKSified clients, a different protocol is used where
+ * the client first sends a "pre-service-request", asking the
+ * IP address of the computer to which the Dispatcher will assign
+ * the request. Upon receipt of a NI_SVC_PRE_RESPONSE message
+ * containing that IP address, the client performs a SOCKSified
+ * bind()ing indicating that the specified IP address will
+ * "call back". Having determine the port number which has
+ * been bound on the SOCKS proxy, the client sends the "real"
+ * service request containing the SOCKS proxy's port number
+ * and a reminder as to which IP address the Dispatcher
+ * "promised" would be assigned. After that, processing
+ * proceeds normally, with the server connecting-back (via
+ * the SOCKS proxy) and the Dispatcher sending a SVC_RESPONSE
+ * acknowledgement.
+ *
+ * Note that SOCKS and encryption are completely orthogonal
+ * with respect to each other, and a client may use either, both,
+ * or neither.
+ */
+
+NLM_EXTERN NI_HandPtr NI_ServiceRequest(NI_ReqPtr req)
+{
+ NI_HandPtr sconnhp;
+#ifdef NETP_INET_MACTCP
+ Int4 sconnlen;
+#else
+ int sconnlen;
+#endif
+ struct sockaddr_in sconnaddr;
+ NIMsgPtr mp, imp;
+ NISvcReqPtr svcreqp;
+ struct timeval timeout;
+ Monitor *mon = NULL;
+ int ready;
+ Boolean disp_contact = FALSE, serv_contact = FALSE;
+ Uint4 this_req;
+ fd_set readfds;
+ NI_DispatcherPtr disp = req->dispatcher;
+ Uchar desKey[8];
+#ifdef NETP_SOCKS
+ struct sockaddr_in svcsAddr;
+ Int2 status;
+#endif
+
+NEXTTRY:
+ ni_errtext[0] = '\0';
+ if (disp->useOutServ) {
+ if ((sconnhp = MsgMakeHandle(TRUE)) == NULL) {
+ ni_errno = NIE_MAKEHAND;
+ return NULL;
+ }
+ } else {
+ if ((sconnhp = MsgMakeHandle(FALSE)) == NULL) {
+ ni_errno = NIE_MAKEHAND;
+ return NULL;
+ }
+ }
+
+ svcreqp = NI_MakeMsgSvcreq();
+ svcreqp->seqno = disp->dispHP->seqno++;
+ svcreqp->platform = (Uint4) NI_GetPlatform();
+ if (stackDescription != NULL)
+ {
+ svcreqp->applId = StringSave(stackDescription);
+ }
+ if (disp->encryptInfo != NULL && NI_EncrAvailable())
+ {
+ UcharPtr encryptedDesKey;
+ Int2 encryptedLen;
+
+ NI_GenerateDESKey (desKey);
+ encryptedLen = NI_PubKeyEncrypt((NI_PubKeyPtr) disp->encryptInfo->data.ptrvalue,
+ desKey, sizeof desKey, &encryptedDesKey);
+ if (encryptedLen <= 0)
+ {
+ NI_DestroyRequest(req);
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_PUBKEYENCRFAIL;
+ return NULL;
+ }
+ /* convert the DES key into a ByteStore */
+ svcreqp->desKey = BSNew(encryptedLen);
+ BSWrite (svcreqp->desKey, (VoidPtr) encryptedDesKey, encryptedLen);
+ MemFree (encryptedDesKey);
+ }
+ this_req = svcreqp->seqno;
+ CopyIdentity(disp, svcreqp->uid);
+ NI_DestroyRequest(svcreqp->request);
+ svcreqp->request = req;
+
+ if (disp->useSocks)
+ {
+ svcreqp->wantPreResponse = TRUE;
+ }
+ /* we want to get a ticket for the direct connection */
+ if (disp->useOutServ) {
+ svcreqp->want_ticket = TRUE;
+ }
+
+ if ((mp = MsgBuild(NI_SVC_REQUEST, disp->dispHP->conid, (VoidPtr) svcreqp)) == NULL) {
+ NI_DestroyRequest(req);
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MISC; /* unable to alloc mem for Msg */
+ return NULL;
+ }
+
+ if (MsgWrite(disp->dispHP, mp, disp->useSocks) < 0) {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MSGWRITE;
+ return NULL;
+ }
+
+ /* blocks until SVC_RESPONSE from dispatcher and service or NACK or TIMEOUT */
+ while ( !disp_contact || !serv_contact) {
+ timeout.tv_sec = (Uint4) NI_TIMEOUT_SECS;
+ timeout.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(disp->dispHP->sok, &readfds);
+ if (! disp->useOutServ)
+ FD_SET(disp->svcsHP->sok, &readfds);
+ while ((ready = NI_select(FD_SETSIZE, &readfds, NULL, NULL, &timeout)) < 0) {
+ if (SOCK_ERRNO == EINTR)
+ ; /* repeat while interrupted */
+ else {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_SELECT; /* select error */
+ return NULL;
+ }
+ }
+ if (ready == 0) {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_DSPTIMEOUT; /* TIMEOUT */
+ return NULL;
+ }
+ if (FD_ISSET(disp->dispHP->sok, &readfds) != 0) {
+ if ((imp = MsgRead(disp->dispHP, FALSE)) == NULL) {
+ LOG_SOCKET(disp->dispHP->sok, FALSE);
+ NI_CLOSESOCKET(disp->dispHP->sok);
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MSGREAD;
+ return NULL;
+ }
+ disp_contact = TRUE;
+ switch (imp->type) {
+ case NI_SVC_PRE_RESPONSE:
+#ifdef NETP_SOCKS
+ if (disp->useSocks)
+ {
+ /* must defer binding and listening for SOCKS connection */
+ /* until server's IP address is known */
+
+ TRACE("Processing SOCKS SVC_PRE_RESPONSE\n");
+ /* SOCKS can't deal well with non-blocking connections */
+ NI_SETBLOCKING(disp->svcsHP->sok);
+
+ if ((disp->clientPort = bindPort(disp->svcsHP->sok, &svcsAddr, disp->loport, disp->hiport, imp->msun.preresp->server_ip)) == 0) {
+ TRACE("bindPort failed\n");
+ MsgDestroyHandle(sconnhp);
+ disp->svcsHP = NULL;
+ ni_errno = NIE_NOBIND; /* can't bind a free application socket */
+ ErrPost (CTX_NCBICORE, CORE_UNKNOWN, "NI_ServiceRequest: <%s>", ni_errlist[ni_errno]);
+ return NULL;
+ }
+ TRACE("bindPort succeeded, port = %d\n", disp->clientPort);
+ if (NI_GETSOCKNAME(disp->svcsHP->sok, &svcsAddr, &sconnlen) >= 0)
+ disp->clientPort = ntohs(svcsAddr.sin_port);
+ req->clientPort = disp->clientPort;
+ svcreqp->server_ip = imp->msun.preresp->server_ip;
+ svcreqp->wantPreResponse = FALSE;
+ if (MsgWrite(disp->dispHP, mp, FALSE) < 0) {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MSGWRITE;
+ return NULL;
+ }
+ disp_contact = FALSE; /* now waiting to hear one more msg */
+
+ TRACE("After GETSOCKNAME, port = %d\n", disp->clientPort);
+ if ((status = NI_LISTEN(disp->svcsHP->sok, 5)) < 0) {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(status);
+#endif
+ TRACE("Listen failed, errno = %d\n", SOCK_ERRNO);
+ MsgDestroyHandle(sconnhp);
+ StringCpy(ni_errtext, sys_errlist[SOCK_INDEX_ERRNO]);
+ ni_errno = NIE_NOLISTEN;
+ ErrPost (CTX_NCBICORE, CORE_UNKNOWN, "NI_ServiceRequest: <%s> <port %d, errno %d>", ni_errlist[ni_errno], (int) disp->clientPort, (int) SOCK_ERRNO);
+ return NULL;
+ }
+ }
+#endif
+ /* non-SOCKS clients ignore this message, and should never receive it */
+ TRACE("Listen succeeded\n");
+ MsgDestroy(imp);
+ break;
+
+ case NI_SVC_RESPONSE:
+ if (disp->useSocks)
+ {
+ TRACE("Got SOCKS service response from Dispatcher\n");
+ }
+ ni_errno = NIE_NO_ERROR;
+ NI_DestroyRequest(disp->reqResponse);
+ disp->reqResponse = imp->msun.svcresp->request;
+ sconnhp->hostname = StringSave(disp->reqResponse->clientAddr);
+ imp->msun.svcresp->request = NULL;
+ MsgDestroy(imp);
+ if (mon != NULL) {
+ MonitorStrValue(mon, "Direct connection established");
+#ifdef OS_UNIX
+ sleep(1);
+#endif /* OS_UNIX */
+ MonitorFree(mon);
+ }
+ break;
+
+ case NI_NACK:
+ if (disp->useSocks)
+ {
+ TRACE("Got SOCKS NACK from Dispatcher\n");
+ }
+ ni_errno = (enum ni_error) imp->msun.nack->code;
+ if (imp->msun.nack->reason != NULL)
+ StringCpy(ni_errtext, imp->msun.nack->reason);
+ else
+ ni_errtext[0] = '\0';
+ MsgDestroy(imp);
+
+ /* retry in the case when old style connection failed now is disabled */
+
+ if (FALSE && !disp->useOutServ) {
+ disp->useOutServ = TRUE;
+ mon = MonitorStrNew("Old type of connection failed", 40);
+ MonitorStrValue(mon, "Trying to establish direct connection");
+ serv_contact = FALSE;
+ disp_contact = FALSE;
+ goto NEXTTRY;
+ }
+ else {
+ MsgDestroyHandle(sconnhp);
+ return NULL;
+ }
+ /* Message with direct connection ticket was received */
+ case NI_SVC_REQUEST:
+ if ((sconnhp = NI_DirectServiceRequest(imp, sconnhp)) == NULL) {
+ TRACE("Unable to establish direct connection\n");
+ return NULL;
+ }
+ if (mon != NULL)
+ MonitorStrValue(mon, "Received ticket for direct connection");
+
+ serv_contact = TRUE;
+ disp_contact = FALSE; /* we are looking for SVC_RESPONCE */
+ break;
+
+
+ default:
+ if (disp->useSocks)
+ {
+ TRACE("Got SOCKS unknown message type from Dispatcher\n");
+ }
+ MsgDestroy(imp);
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_MSGUNK; /* Unknown MSG type */
+ sprintf(ni_errtext, "%d", imp->type);
+ return NULL;
+ }
+ }
+ if (!disp->useOutServ && (FD_ISSET(disp->svcsHP->sok, &readfds) != 0) && !serv_contact) {
+ sconnlen = sizeof(sconnaddr);
+#ifdef NETP_INET_NEWT
+ sconnhp->sok = NI_ACCEPT(disp->svcsHP->sok, &sconnaddr, &sconnlen);
+#else
+ sconnhp->sok = NI_ACCEPT(disp->svcsHP->sok, (struct sockaddr PNTR) &sconnaddr, &sconnlen);
+#endif /* NETP_INET_NEWT */
+ LOG_SOCKET(sconnhp->sok, TRUE);
+#ifdef NETP_SOCKS
+ if (disp->useSocks)
+ {
+ TRACE("Got connection from server, socket %d\n", sconnhp->sok);
+ MsgDestroyHandle(disp->svcsHP);
+ disp->svcsHP = MsgMakeHandle(TRUE); /* for next time */
+ }
+#endif /* NETP_SOCKS */
+ if (sconnhp->sok < 0) {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(sconnhp->sok);
+#endif
+ MsgDestroyHandle(sconnhp);
+ StringCpy(ni_errtext, sys_errlist[SOCK_INDEX_ERRNO]);
+ ni_errno = NIE_NOACCEPT; /* application accept error */
+ return NULL;
+ }
+ serv_contact = TRUE;
+ }
+ }
+
+ if (activityHook != NULL)
+ {
+ (*activityHook)(sconnhp, NetServHook_svcreq, 0);
+ }
+
+ if (disp->encryptInfo != NULL && NI_EncrAvailable())
+ {
+ NI_SetupDESEncryption(sconnhp, desKey);
+ }
+
+ if (sconnhp != NULL)
+ {
+ sconnhp->disp = disp;
+ }
+
+ return sconnhp;
+} /* NI_ServiceRequest */
+
+
+
+/*
+ * Purpose: Issue the specified direct service request
+ *
+ * Parameters:
+ *
+ * imp The pre-formatted service request
+ * sconnhp server handle to connect to
+ *
+ * Returns:
+ *
+ * sconnhp A message handle to the server which is servicing our request,
+ * if successful
+ *
+ * Description: This function connects directly to server specified by sconnhp
+ * and sends SVC_REQUEST message imp, formated and completed by
+ * dispatcher and received by NI_ServiceRequest function of the client
+ *
+ *
+ */
+static NI_HandPtr
+NI_DirectServiceRequest(NIMsgPtr imp, NI_HandPtr sconnhp)
+{
+ int timeout = 30;
+ int status;
+ struct sockaddr_in sconnaddr;
+ char buf[20];
+
+ MemFill((VoidPtr) &sconnaddr, '\0', sizeof(sconnaddr));
+ sconnaddr.sin_family = AF_INET;
+ sconnaddr.sin_addr.s_addr = htonl(imp->msun.svcreq->server_ip);
+ if (GetAppParam("NCBI", "NET_SERV", "PROXY_SERV_OVERRIDE", "", buf, sizeof buf) > 0)
+ {
+ sconnaddr.sin_addr.s_addr = inet_addr(buf);
+ }
+ sconnaddr.sin_port = htons(imp->msun.svcreq->server_port);
+
+RETRY1:
+
+
+#ifndef NETP_INET_NEWT
+ status = NI_CONNECT(sconnhp->sok, (struct sockaddr PNTR) &sconnaddr,
+ sizeof(sconnaddr));
+#else
+ status = NI_CONNECT(sconnhp->sok, &sconnaddr, sizeof(sconnaddr));
+#endif
+ if (status < 0) {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(status);
+#endif
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ goto RETRY1;
+
+#ifdef NETP_INET_PCNFS
+ case 0:
+#endif /* NETP_INET_PCNFS */
+ case EWOULDBLOCK:
+ case EINPROGRESS:
+ /* if the connect()ion is not established immediately, a */
+ /* select() can be performed where the corresponding "write" */
+ /* file descriptor will be enabled once the connect()ion has been*/
+ /* established */
+
+ if (sokselectw(sconnhp->sok, timeout) != 0) {
+ MsgDestroyHandle(sconnhp);
+ return NULL;
+ }
+ break;
+
+ default:
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_DIRUNCONNECT; /* cannot establish direct connection */
+ return NULL;
+ }
+ }
+
+ /* Now we are sending service request directly to the server */
+
+ if (MsgWrite(sconnhp, imp, TRUE) < 0) {
+ MsgDestroyHandle(sconnhp);
+ ni_errno = NIE_DIRUNCONNECT;
+ return NULL;
+ }
+ return sconnhp;
+}
+
+
+
+/*
+ * Purpose: Disconnect from a service provider
+ *
+ * Parameters:
+ * mhp Message handle for the server
+ *
+ * Returns:
+ * 0, always
+ *
+ *
+ * Description:
+ * Disconnect from a service provider, essentially by just
+ * closing the communication socket to that service provider.
+ */
+
+NLM_EXTERN Int2 NI_ServiceDisconnect(NI_HandPtr mhp)
+{
+ if (activityHook != NULL)
+ {
+ activityHook(mhp, NetServHook_svcdisconn, 0);
+ }
+
+ MsgDestroyHandle(mhp);
+ return 0;
+} /* NI_ServiceDisconnect */
+
+
+
+/*
+ * Purpose: Obtain the read file descriptor from a "message handle"
+ *
+ * Parameters:
+ * handp Message handle
+ *
+ * Returns:
+ * Socket associated with message handle
+ *
+ *
+ * Description:
+ * Get the read file desciptor from a message handle. This
+ * might be useful, for example, when wishing to perform
+ * "direct" I/O to the socket after a connection has been
+ * established with a server/client.
+ */
+
+NLM_EXTERN int NI_ServiceGetReadFd(NI_HandPtr handp)
+{
+ return handp->sok;
+} /* NI_ServiceGetReadFd */
+
+
+
+/*
+ * Purpose: Obtain the write file descriptor from a "message handle"
+ *
+ * Parameters:
+ * handp Message handle
+ *
+ * Returns:
+ * Socket associated with message handle
+ *
+ *
+ * Description:
+ * Get the write file desciptor from a message handle. This
+ * might be useful, for example, when wishing to perform
+ * "direct" I/O to the socket after a connection has been
+ * established with a server/client.
+ */
+
+NLM_EXTERN int NI_ServiceGetWriteFd(NI_HandPtr handp)
+{
+ return handp->sok;
+} /* NI_ServiceGetWriteFd */
+
+
+
+/*
+ * Purpose: Populate a service request with a service name and version #s
+ *
+ * Parameters:
+ * req Service request
+ * name Service name
+ * vermin Minimum version number for this service
+ * vermax Maximum version number for this service
+ *
+ * Returns:
+ * -1, if the name is a NULL pointer
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Populate the service request with the specified service name
+ * and version numbers, dynamically allocating space for the
+ * service name.
+ */
+
+NLM_EXTERN Int2 NI_RequestSetService(NI_ReqPtr req, CharPtr name, Uint2 vermin, Uint2 vermax)
+{
+ if (name == NULL) {
+ ni_errno = NIE_INVAL;
+ return -1;
+ }
+ req->service->name = StringSave(name);
+ req->service->minVersion = vermin;
+ req->service->maxVersion = vermax;
+ req->service->typeL = NULL;
+ return 0;
+} /* NI_RequestSetService */
+
+
+
+/*
+ * Purpose: Populate a service request with an additional resource
+ *
+ * Parameters:
+ * req Service request
+ * name Resource name
+ * type Service type
+ * vermin Minimum version number for this resource
+ * vermax Maximum version number for this resource
+ *
+ * Returns:
+ * -1, if the name is a NULL pointer
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Insert the information for this resource into a list of
+ * resources associated with this service request. This
+ * function may be called one or more times (or, not at all) to
+ * populate a service request with one or more resources.
+ */
+
+NLM_EXTERN Int2 NI_RequestAddResource(NI_ReqPtr req, CharPtr name, CharPtr type, Uint2 vermin, Uint2 vermax)
+
+{
+ NIResPtr resp;
+
+ if (name == NULL) {
+ ni_errno = NIE_INVAL;
+ return -1;
+ }
+ resp = NI_MakeResource();
+ resp->name = StringSave(name);
+ if (type != NULL)
+ resp->type = StringSave(type);
+ resp->minVersion = vermin;
+ resp->maxVersion = vermax;
+ req->resourceL = ListInsertPrev((VoidPtr) resp, req->resourceL); /* add to end of list */
+ return 0;
+} /* NI_RequestAddResource */
+
+
+
+/* THESE FUNCTIONS NOT VISIBLE TO API USER */
+
+/*
+ * Purpose: Partially halt Network Services
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ *
+ * Description:
+ * Halt network services, except refrain from freeing the
+ * parameters which are set by NI_SetDispatcher().
+ */
+
+static void
+HaltServices (NI_DispatcherPtr disp)
+{
+ if (disp == NULL)
+ return;
+
+ if (disp->referenceCount > 0)
+ return;
+
+ if (activityHook != NULL)
+ {
+ activityHook((NI_HandPtr) disp, NetServHook_dispdisconn, 0);
+ }
+
+ MsgDestroyHandle(disp->dispHP);
+ MsgDestroyHandle(disp->svcsHP);
+ NI_DestroyRequest(disp->reqResponse);
+ if (disp->identity != NULL) {
+ MemFree (disp->identity->username);
+ MemFree (disp->identity->group);
+ MemFree (disp->identity->domain);
+ MemFree (disp->identity);
+ disp->identity = NULL;
+ }
+ disp->dispHP = NULL;
+ disp->svcsHP = NULL;
+ disp->reqResponse = NULL;
+ if (disp->encryptInfo != NULL)
+ {
+ if (disp->encryptInfo != NULL)
+ NI_DestroyPubKey((NIPubKeyPtr) disp->encryptInfo->data.ptrvalue);
+ ValNodeFree(disp->encryptInfo);
+ }
+
+#ifdef NETP_INET_WSOCK
+ /* we have an obligation to perform one cleanup call for every Startup */
+ while (wsaStartupCount-- > 0)
+ {
+ WSACleanup();
+ }
+#endif
+}
+
+
+/*
+ * Purpose: Lookup a port # in config file and possible NIS
+ *
+ * Parameters:
+ * service Name of config. file entry
+ * networkOrder Boolean, indicates whether value should be returned in host
+ * order or network order.
+ *
+ * Description:
+ * Look up the specified entry in the NCBI config. file, and
+ * lookup in NIS the name obtained from the config file if it's
+ * non-numeric.
+ *
+ * Note:
+ * The intent of this function is that, in most cases, the
+ * GetAppParam() entry will not be present, and a default value
+ * will be used instead. The getservbyname() call is intended
+ * to be a last resort, because this may be slow on some systems.
+ */
+
+static Uint2
+GetByConfigOrServ(CharPtr service, Boolean networkOrder)
+{
+ struct servent PNTR portEntry;
+ Char buf[50];
+ Uint2 port;
+
+ if (GetAppParam("NCBI", "NET_SERV", service, "", buf, sizeof buf) <= 0)
+ {
+ port = 0;
+ } else {
+ if (StrSpn(buf, "0123456789") == StrLen(buf))
+ { /* all numeric */
+ port = atoi(buf);
+ if (networkOrder)
+ port = htons(port);
+ } else {
+ /* entry from configuration file is name to use in getservbyname */
+ if ((portEntry = getservbyname(buf, "tcp")) == NULL)
+ {
+ port = 0;
+ } else {
+ port = portEntry->s_port;
+ if (! networkOrder)
+ port = ntohs(port);
+ }
+ }
+ }
+
+ return port;
+}
+
+
+/*
+ * Purpose: Connect to the dispatcher
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * host Name of the host on which dispatcher resides
+ * service Name of the "service" (i.e., port) to which we should connect
+ * timeout How long to wait for dispatcher to respond, 0 ==> use default
+ *
+ * Returns:
+ * NULL, if the attempt to connect failed
+ * a pointer to the "Msg" structure for the dispatcher, otherwise
+ *
+ *
+ * Description:
+ * Connect to the dispatcher on the specified hostname on the
+ * specified service (where a service maps to a port number).
+ * This is done by establishing a socket to the dispatcher,
+ * and then connect()ing to that socket; the dispatcher should
+ * be listen()ing on that socket, and should subsequently accept()
+ * the connection request.
+ *
+ * While doing this, also obtain other useful information;
+ * namely, the dotted IP address of the local host, and the
+ * high and low port numbers to be used when attempting
+ * dispatcher connections. This global information is used
+ * elsewhere.
+ */
+
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif /* INADDR_NONE */
+
+static NI_HandPtr
+DispatchConnect(NI_DispatcherPtr disp, CharPtr host, CharPtr service, int timeout)
+{
+ struct hostent PNTR dispHost, PNTR localHost;
+ struct sockaddr_in serv_addr;
+ NI_HandPtr dHP;
+ Uint2 disp_port;
+ Uint4 srvadd;
+ Char servInetAddr[INETADDR_SIZ], localHostName[SVC_HOST_SIZ];
+ Char t_service[64];
+ int status;
+ Int4 connectStartTime;
+
+ if (disp == NULL)
+ return NULL;
+
+
+ serv_addr.sin_family = AF_INET;
+
+ srvadd = inet_addr(host);
+ if ((Int4)srvadd != INADDR_NONE) /* malformed request */
+ MemCopy((VoidPtr) &serv_addr.sin_addr, (VoidPtr) &srvadd, sizeof(srvadd));
+ else {
+ if ((dispHost = gethostbyname(host)) == NULL) {
+ ni_errno = NIE_NOHOSTENT;
+ return NULL;
+ }
+/* MemCopy((VoidPtr)&serv_addr.sin_addr, (VoidPtr)(dispHost->h_addr), dispHost->h_length);*/
+ MemCopy(&serv_addr.sin_addr, dispHost->h_addr, dispHost->h_length);
+ }
+ StringCpy(servInetAddr, inet_ntoa(serv_addr.SIN_ADDR));
+
+ if ((disp_port = GetByConfigOrServ(service, TRUE)) == 0)
+ {
+ if (service)
+ StringCpy(t_service, service); /* because Windows barfs on the pointer */
+ else
+ t_service[0] = 0;
+ if ((disp_port = htons(atoi(t_service))) == 0)
+ disp_port = htons(NI_DFLT_SVC_PORT);
+ }
+ if (ntohs(disp_port) <= NI_LAST_RESERVED_PORT) {
+ ni_errno = NIE_NOSERVENT;
+ return NULL;
+ }
+
+ /* get the Internet address of the "local host" */
+#ifdef NETP_INET_MACTCP
+ /* simpler solution to avoid the hazards of gethostname() */
+ {
+ unsigned long localHostId;
+
+ localHostId = gethostid();
+ StringCpy(disp->localHostAddr, inet_ntoa(* (H_ADDR_TYPE) &localHostId));
+ }
+#else
+ gethostname(localHostName, SVC_HOST_SIZ);
+ if ((localHost = gethostbyname(localHostName)) == NULL) {
+ /* GetAppParam() workaround for PC-NFS 5.0 bug */
+ if (GetAppParam("NCBI", "NET_SERV", "HOST_ADDRESS", "",
+ disp->localHostAddr, sizeof(disp->localHostAddr)) <= 0)
+ { /* use a bogus address which the dispatcher will try to fix */
+ StringCpy(disp->localHostAddr, "0.0.0.0");
+
+ }
+ } else {
+ StringCpy(disp->localHostAddr, inet_ntoa(* (H_ADDR_TYPE) localHost->h_addr));
+ }
+#endif /* NETP_INET_MACTCP */
+
+ if ((disp->loport = GetByConfigOrServ(NI_CLIENT_PORT_LO_NAME, FALSE)) == 0)
+ {
+ if ((disp->loport = atoi(NI_CLIENT_PORT_LO_NAME)) == 0)
+ disp->loport = NI_DFLT_CLILO_PORT;
+ }
+ if (disp->loport <= NI_LAST_RESERVED_PORT) {
+ ni_errno = NIE_BADPORT; /* bad low client port */
+ return NULL;
+ }
+
+ if ((disp->hiport = GetByConfigOrServ(NI_CLIENT_PORT_HI_NAME, FALSE)) == 0)
+ {
+ if ((disp->hiport = atoi(NI_CLIENT_PORT_HI_NAME)) == 0)
+ disp->hiport = NI_DFLT_CLIHI_PORT;
+ }
+ if (disp->hiport <= NI_LAST_RESERVED_PORT) {
+ ni_errno = NIE_BADPORT; /* bad high client port */
+ return NULL;
+ }
+
+ MemFill((VoidPtr) &serv_addr, '\0', sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = inet_addr(servInetAddr);
+ serv_addr.sin_port = disp_port;
+
+ if ((dHP = MsgMakeHandle(TRUE)) == NULL)
+ return NULL;
+ MsgSetLJError(dHP);
+ if (timeout > 0)
+ MsgSetReadTimeout(dHP, timeout);
+
+ if (activityHook != NULL)
+ {
+ activityHook((NI_HandPtr) disp, NetServHook_dispconn, 0);
+ }
+
+#ifdef NETP_SOCKS
+ if (disp->useSocks)
+ { /* SOCKS can't deal well with blocking connections */
+ NI_SETBLOCKING(dHP->sok);
+ }
+#endif
+
+ connectStartTime = Nlm_GetSecs();
+
+ RETRY:
+#ifndef NETP_INET_NEWT
+ if ((status = NI_CONNECT(dHP->sok, (struct sockaddr PNTR) &serv_addr, sizeof(serv_addr))) < 0) { /* } */
+#else
+ if ((status = NI_CONNECT(dHP->sok, &serv_addr, sizeof(serv_addr))) < 0) {
+ SOCK_ERRNO = ABS(status);
+#endif
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ goto RETRY;
+
+#ifdef NETP_INET_PCNFS
+ /* This is apparently a bug in PC-NFS 4.0 ... a connection attempt */
+ /* on a non-blocking socket yields errno == 0 */
+ case 0:
+#endif /* NETP_INET_PCNFS */
+ case EWOULDBLOCK:
+ case EINPROGRESS:
+ /* if the connect()ion is not established immediately, a */
+ /* select() can be performed where the corresponding "write" */
+ /* file descriptor will be enabled once the connect()ion has been*/
+ /* established */
+ status = sizeof(serv_addr);
+ if (sokselectw(dHP->sok, timeout) == 0
+#ifdef OS_UNIX
+ && getpeername(dHP->sok,(struct sockaddr *) &serv_addr, &status) == 0
+#endif
+ ) {
+ dHP->state = NI_CONNECTED;
+ dHP->connectDelay = Nlm_GetSecs() - connectStartTime;
+ return dHP;
+ }
+ break;
+
+ default:
+ break;
+ }
+ MsgDestroyHandle(dHP);
+ ni_errno = NIE_DISPCONN; /* can't connect to dispatcher */
+ return NULL;
+ }
+ dHP->state = NI_CONNECTED;
+ dHP->connectDelay = Nlm_GetSecs() - connectStartTime;
+ return dHP;
+} /* DispatchConnect */
+
+
+/*
+ * Purpose: Convert an FQDN to an IP address
+ *
+ * Parameters:
+ * fqdn A fully-qualified domain name, like "dispatch1.nlm.nih.gov"
+ * ipbuf An output buffer for the dotted-decimal IP address
+ * ipbuflen The length of ipbuf
+ *
+ * Returns:
+ * TRUE, if the address was resolved successfully, FALSE otherwise
+ */
+
+NLM_EXTERN Boolean NI_FqdnToIpaddr(CharPtr fqdn, CharPtr ipbuf, Int2 ipbuflen)
+{
+ struct hostent PNTR dispHost;
+ struct sockaddr_in serv_addr;
+
+ serv_addr.sin_family = AF_INET;
+ if ((dispHost = gethostbyname(fqdn)) != NULL)
+ {
+ MemCopy (&serv_addr.sin_addr, dispHost->h_addr, dispHost->h_length);
+ StringNCpy (ipbuf, inet_ntoa (serv_addr.SIN_ADDR), ipbuflen-1);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+
+
+/*
+ * Purpose: Get the platform on which this client is running
+ *
+ * Parameters:
+ * none
+ *
+ * Returns:
+ * the client's platform, or NI_PLATFORM_UNKNOWN
+ *
+ *
+ * Description:
+ * Calculate what platform this client is running on.
+ *
+ *
+ * Note:
+ * Although the initial implementation of this function
+ * calculates the platform-type at compile-time, it is
+ * legitimate to perform some computation at run time, e.g.,
+ * to determine whether this client is using a particular
+ * low-level driver.
+ *
+ * The dispatcher and servers should not rely on the
+ * information which is received for platform-type, because
+ * the client may be lying, either because of a coding error
+ * or malice on the part of a client developer.
+ */
+
+NLM_EXTERN Int2 NI_GetPlatform (void)
+{
+ static Boolean alreadyInited = FALSE;
+ static Int2 retval;
+
+ if (alreadyInited)
+ {
+ return retval;
+ }
+
+ alreadyInited = TRUE;
+
+ retval = NI_PLATFORM_UNKNOWN;
+
+#ifdef NETP_INET_MACTCP
+ retval = NI_PLATFORM_MAC;
+#endif
+
+#ifdef OS_VMS
+#ifdef NETP_INET_TGV
+ retval = NI_PLATFORM_VMS_TGV;
+#endif
+#ifdef NETP_INET_TWG
+ retval = NI_PLATFORM_VMS_TWG;
+#endif
+#ifdef NETP_INET_WPW
+ retval = NI_PLATFORM_VMS_WPW;
+#endif
+#ifdef NETP_INET_UCX
+ retval = NI_PLATFORM_VMS_UCX;
+#endif
+#ifdef OS_AXP_VMS
+ retval = NI_PLATFORM_AXP_OPENVMS;
+#endif
+#endif /* OS_VMS */
+
+#ifdef OS_UNIX
+ retval = NI_PLATFORM_GENERIC_UNIX;
+#ifdef PROC_IBM370
+ retval = NI_PLATFORM_IBM370AIX;
+#endif
+#ifdef OS_UNIX_SUN
+ retval = NI_PLATFORM_SUN;
+#endif
+#if defined(OS_UNIX_OSF1) && defined(PROC_ALPHA)
+ retval = NI_PLATFORM_ALPHA_OSF1;
+#endif
+#ifdef COMP_AUX
+ retval = NI_PLATFORM_AUX;
+#endif
+#if defined(COMP_CRAY) && defined(PROC_YMP)
+ retval = NI_PLATFORM_CRAY;
+#endif
+#ifdef PROC_CONVEX
+ retval = NI_PLATFORM_CONVEX;
+#endif
+#ifdef PROC_HPPA
+ retval = NI_PLATFORM_HPUX;
+#endif
+#ifdef OS_UNIX_NEXT
+ retval = NI_PLATFORM_NEXT;
+#endif
+#ifdef PROC_MIPS
+ retval = NI_PLATFORM_SGI;
+#endif
+#ifdef OS_UNIX_ULTRIX
+ retval = NI_PLATFORM_ULTRIX;
+#endif
+#if defined(OS_UNIX_SYSV) && defined(PROC_SPARC)
+ retval = NI_PLATFORM_SYSV_ON_SPARC;
+#endif
+#ifdef OS_UNIX_AIX
+ retval = NI_PLATFORM_AIX;
+#endif
+#ifdef OS_UNIX_LINUX
+#ifdef PROC_ALPHA
+ retval = NI_PLATFORM_LINUX_ALPHA;
+#else
+ retval = NI_PLATFORM_LINUX;
+#endif
+#endif
+#endif /* OS_UNIX */
+
+#ifdef OS_DOS
+ retval = NI_PLATFORM_DOS;
+#ifdef WIN16
+ retval = NI_PLATFORM_WIN16;
+#endif
+#ifdef NETP_INET_NEWT
+ retval = NI_PLATFORM_WIN_NEWT;
+#endif
+#ifdef NETP_INET_PCNFS
+ retval = NI_PLATFORM_WIN_PCNFS;
+#endif
+#ifdef WINSOCK
+ retval = NI_PLATFORM_WIN_WINSOCK;
+#endif
+#endif /* OS_DOS */
+
+#ifdef OS_WINNT
+ retval = NI_PLATFORM_WINNT;
+#endif
+
+ return retval;
+}
+
+
+/*
+ * Purpose: Set the "identity" of this client
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * user New Username
+ * group New Groupname
+ * domain New DomainName
+ *
+ * Returns:
+ * 0, always
+ *
+ *
+ * Description:
+ * Allocate the space for the "UID" structure, if not already
+ * allocated, and populate it with the user name, group name,
+ * and domain name.
+ */
+
+static Int2
+SetIdentity(NI_DispatcherPtr disp, CharPtr user, CharPtr group, CharPtr domain)
+{
+ if (disp == NULL)
+ return 0;
+
+ if (disp->identity == NULL)
+ disp->identity = NI_MakeUid();
+
+ if (disp->identity->username != NULL)
+ MemFree(disp->identity->username);
+ disp->identity->username = StringSave(user);
+ if (disp->identity->group != NULL)
+ MemFree(disp->identity->group);
+ if (group != NULL)
+ disp->identity->group = StringSave(group);
+ else
+ disp->identity->group = NULL;
+ if (disp->identity->domain != NULL)
+ MemFree(disp->identity->domain);
+ disp->identity->domain = StringSave(domain);
+ return 0;
+} /* SetIdentity */
+
+
+
+/*
+ * Purpose: Copy from the "identity" UID to the specified UID data struct
+ *
+ * Parameters:
+ * disp A pointer to the dispatcher structure
+ * uid UID structure to be copied into
+ *
+ * Returns:
+ * -1, if invalid arguments
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Copy fields from the "identity" UID data structure into the
+ * UID data structure provided by the caller.
+ */
+
+static Int2
+CopyIdentity(NI_DispatcherPtr disp, NI_UidPtr uid)
+{
+ if (disp == NULL || disp->identity == NULL || uid == NULL)
+ return -1;
+ if (uid->username != NULL)
+ MemFree(uid->username);
+ uid->username = StringSave(disp->identity->username);
+ if (uid->group != NULL)
+ MemFree(uid->group);
+ uid->group = StringSave(disp->identity->group);
+ if (uid->domain != NULL)
+ MemFree(uid->domain);
+ uid->domain = StringSave(disp->identity->domain);
+ return 0;
+} /* CopyIdentity */
+
+
+
+/*
+ * Purpose: Select the next available port within the given range,
+ * and bind a socket to it.
+ *
+ * Parameters:
+ * sok Socket to be bound to a port (INPUT)
+ * sokadr Socket data structure to be populated (OUTPUT)
+ * loport Minimum acceptable port number
+ * hiport Maximum acceptable port number
+ *
+ * Returns:
+ * 0, if unable to bind to a port
+ * the selected ("bound") port number, otherwise
+ *
+ *
+ * Description:
+ * Iterate through the range of acceptable port numbers, until
+ * an unused port number can be selected to which the socket
+ * can be bound.
+ */
+
+static Uint2
+bindPort(int sok, struct sockaddr_in PNTR sokadr, Int2 loport, Int2 hiport, Uint4 remoteHost)
+{
+ int status;
+#ifdef NETP_INET_MACTCP
+ int delta = 0;
+ Char buf[20];
+#endif
+
+ if (hiport == 0)
+ hiport = loport;
+ if (loport > hiport)
+ return 0;
+
+#ifdef NETP_INET_MACTCP
+ /* use a hint from the configuration file to avoid port # conflicts */
+ if (hiport > loport && GetAppParam("NCBI", "NET_SERV", "PORT_DELTA", "0",
+ buf, sizeof buf) > 0)
+ {
+ delta = atoi(buf);
+ loport += delta % (hiport - loport);
+ sprintf (buf, "%d", delta + 1);
+ SetAppParam("NCBI", "NET_SERV", "PORT_DELTA", buf);
+ }
+#endif
+
+ MemFill((VoidPtr) sokadr, '\0', sizeof(struct sockaddr_in));
+ sokadr->sin_family = AF_INET;
+ sokadr->sin_addr.s_addr = INADDR_ANY;
+
+ while (loport <= hiport) {
+ sokadr->sin_port = htons(loport);
+#ifdef NETP_INET_NEWT
+ if ((status = NI_BIND(sok, sokadr, sizeof(struct sockaddr_in), htonl(remoteHost))) == 0)
+#else
+ if ((status = NI_BIND(sok, (struct sockaddr PNTR) sokadr, sizeof(struct sockaddr_in), htonl(remoteHost))) == 0)
+#endif /* NETP_INET_NEWT */
+ return (Uint2) ntohs(sokadr->sin_port);
+ else {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(status);
+#endif
+ loport++;
+ }
+ }
+ return 0;
+} /* bindPort */
+
+
+
+/* SERVER FUNCTIONS */
+
+static int writepipe PROTO((int fd, char *buf, int len));
+
+/*
+ * Purpose: Write a message on the pipe from a child server application
+ * process to its parent NCBID.
+ *
+ * Parameters:
+ * fd Pipe file descriptor
+ * buf Buffer to be written
+ * len Length of buffer
+ *
+ * Returns:
+ * 0, if unable to write because the pipe is full
+ * number of bytes written, otherwise
+ *
+ *
+ * Description:
+ * Write the specified number of bytes to a pipe, and handle
+ * multiple write attempts if necessary, to handle the case where
+ * a write() may be interrupted by a signal.
+ *
+ * Note:
+ * This routine is only used by a child process after it has been
+ * forked and before it has been execed.
+ */
+
+static int
+writepipe(int fd, char *buf, int len)
+{
+ int byteswrit;
+
+ WriteAgain:
+ if ((byteswrit = write(fd, buf, len)) < 0) {
+ switch (errno) {
+ case EINTR:
+ goto WriteAgain;
+
+ case EWOULDBLOCK:
+ default:
+ return 0;
+ }
+ }
+
+ return byteswrit;
+} /* writepipe */
+
+static Int2 StandAlonePort(void)
+{
+ CharPtr env;
+
+#ifdef OS_UNIX
+ if ((env = getenv("NI_STANDALONE_SERVER")) == NULL)
+ {
+ return 0;
+ }
+
+ return atoi(env);
+#else
+ return 0;
+#endif
+}
+
+
+/*
+ * Purpose: Send an "ACK" from a child server application process to its
+ * parent NCBID.
+ *
+ * Returns:
+ * 0, if the ACK was sent successfully
+ * -1, otherwise
+ *
+ *
+ * Description:
+ * Write an "ACK" from a child server application process to its
+ * parent NCBID, on the pipe connecting the two processes.
+ *
+ * Note:
+ * This routine should be called by a child process after it has
+ * determined that it has started successfully. At most one
+ * of NI_ServerACK() and NI_ServerNACK() may be called.
+ */
+
+#define TEMP_BUF_SIZ 256
+
+NLM_EXTERN int NI_ServerACK(void)
+{
+ int wstat;
+ Char temp_buf[TEMP_BUF_SIZ];
+ Int2 port;
+
+ if ((port = StandAlonePort()) == 0)
+ { /* not stand-alone */
+ sprintf(temp_buf, PIPE_MSG_FMT, NIE_SERVACK, "OK");
+ if ((wstat = writepipe(STDPIPE, temp_buf, strlen(temp_buf))) <= 0) {
+ ni_errno = NIE_PIPEIO;
+ strcpy(ni_errtext, (wstat == 0) ? "EWOULDBLOCK" : sys_errlist[errno]);
+ return -1;
+ }
+ } else { /* stand-alone */
+#ifdef OS_UNIX
+ /* non-UNIX platforms currently experience compilation errors */
+ struct sockaddr_in soktAddr;
+ NI_HandPtr hp;
+ int sok;
+ int status;
+ struct sockaddr_in sockaddr;
+ int soktLen;
+ CharPtr security;
+ int one = 1; /* for SO_REUSEADDR */
+
+ hp = MsgMakeHandle(TRUE);
+ NI_SETBLOCKING(hp->sok);
+
+ MemFill(&sockaddr, '\0', sizeof(struct sockaddr_in));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+ sockaddr.sin_port = htons(port);
+
+ if (setsockopt(hp->sok, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
+ sizeof(one)) < 0)
+ {
+ Message (MSG_ERROR, "Unable to set socket re-usability, errno = %d", errno);
+ }
+
+#ifdef NETP_INET_NEWT
+ if ((status = bind(hp->sok, &sockaddr, sizeof(struct sockaddr_in))) == 0)
+#else
+ if ((status = bind(hp->sok, (struct sockaddr PNTR) &sockaddr, sizeof(struct sockaddr_in))) != 0)
+#endif /* NETP_INET_NEWT */
+ { /* error */
+ ErrPostEx(SEV_FATAL,0,0,
+ "Bind failed on socket %d, status = %d, errno = %d",
+ hp->sok, status, errno);
+ return -1;
+ }
+
+ NI_LISTEN(hp->sok, 1);
+ close(0); /* so that accept() will return 0 */
+ soktLen = sizeof(soktAddr);
+
+ /* accept the connection */
+ if ((sok = NI_ACCEPT(hp->sok, (struct sockaddr *) &soktAddr, &soktLen)) < 0)
+ { /* error */
+ ErrPostEx(SEV_FATAL,0,0, "Accept returned bad file descriptor %d, errno = %d",
+ sok, errno);
+ return -1;
+ }
+ LOG_SOCKET(sok, TRUE);
+ NI_SETNONBLOCKING(sok);
+ MsgDestroyHandle(hp);
+ if ((security = getenv("NI_STANDALONE_SECURITY")) != NULL)
+ { /* security must be substring of client address */
+ if (StrNCmp(inet_ntoa(soktAddr.SIN_ADDR), security, StrLen(security)) != 0)
+ {
+ close(sok);
+ ErrPostEx(SEV_FATAL,0,0, "Security violation from IP address %s, security = %s\n",
+ inet_ntoa(soktAddr.SIN_ADDR), security);
+ return -1;
+ }
+ }
+#endif /* OS_UNIX */
+ }
+ return 0;
+} /* NI_ServerACK */
+
+
+
+/*
+ * Purpose: Send an "NACK" from a child server application process to its
+ * parent NCBID.
+ *
+ * Returns:
+ * 0, if the NACK was sent successfully
+ * -1, otherwise
+ *
+ *
+ * Description:
+ * Write an "NACK" from a child server application process to its
+ * parent NCBID, on the pipe connecting the two processes.
+ *
+ * Note:
+ * This routine should be called by a child process after it has
+ * determined that it will be unable to start successfully. In
+ * the event that this routine is not called (or is unable to
+ * perform its function), a timeout mechanism must be relied
+ * upon for the NCBID to realize that a child has started
+ * unsuccessfully.
+ *
+ * At most one of NI_ServerACK() and NI_ServerNACK() may be called.
+ */
+
+NLM_EXTERN int NI_ServerNACK(CharPtr err_text)
+{
+ int wstat;
+ Char temp_buf[TEMP_BUF_SIZ];
+
+ sprintf(temp_buf, PIPE_MSG_FMT, NIE_SERVNACK, err_text);
+ if (StandAlonePort() == 0)
+ { /* not stand-alone */
+ if ((wstat = writepipe(STDPIPE, temp_buf, strlen(temp_buf))) <= 0) {
+ ni_errno = NIE_PIPEIO;
+ strcpy(ni_errtext, (wstat == 0) ? "EWOULDBLOCK" : sys_errlist[errno]);
+ return -1;
+ }
+ } else { /* stand-alone */
+ ErrPostEx(SEV_FATAL,0,0, "Stand-alone server failed startup {%s}", temp_buf);
+ return -1;
+ }
+ return 0;
+} /* NI_ServerNACK */
+
+
+
+/*
+ * Purpose: Open the stream to be used for ASN I/O between a server
+ * application process and its client.
+ *
+ * Returns:
+ * NULL, if something went wrong
+ * a pointer to the Msg structure, otherwise
+ *
+ *
+ * Description:
+ * Create a "Msg" structure for ASN I/O, and associate the Msg's
+ * socket with the standard input file descriptor (STDIN), which is
+ * the communication socket between the server application process
+ * and its client.
+ *
+ * Note:
+ * This routine should only be called by a child application
+ * process (not by a client).
+ */
+
+NLM_EXTERN NI_HandPtr NI_OpenASNIO(void)
+{
+ NI_HandPtr hp;
+
+ if ((hp = MsgMakeHandle(FALSE)) == NULL)
+ return NULL;
+
+ MsgSetReadTimeout(hp, NI_SERV_LISTEN_TIMEOUT); /* set default for servers to listen */
+
+ if ((hp->sok = dup(STDIN)) == -1) { /* STDOUT points to same socket */
+ MsgDestroyHandle(hp);
+ return NULL;
+ }
+ LOG_SOCKET(hp->sok, TRUE);
+ {
+ CharPtr buf;
+ Char key[8];
+
+ if ((buf = getenv("NI_DESKEY")) != NULL &&
+ (AsnTypeStringToHex(buf, StrLen(buf), key, NULL) == 0))
+ {
+ NI_SetupDESEncryption(hp, (UcharPtr) key);
+ }
+ }
+ return hp;
+} /* NI_OpenASNIO */
+
+
+
+/*
+ * Purpose: Close the ASN stream between a server application process and
+ * its client.
+ *
+ * Returns:
+ * -1 if something went wrong
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Close the stream by closing the socket and deleting the
+ * associated data structures.
+ *
+ * Note:
+ * This routine should only be called by a child application
+ * process (not by a client).
+ */
+
+NLM_EXTERN Int2 NI_CloseASNIO(NI_HandPtr hp)
+{
+ return MsgDestroyHandle(hp);
+} /* NI_CloseANSIO */
+
+
+
+/* MISC FUNCTIONS */
+
+/* sokselectr and sokselectw are not prototyped in ni_lib.h */
+
+/*
+ * Purpose: Wait for a "read" socket to become ready to read, or for
+ * a timeout to occur.
+ *
+ * Returns:
+ * -1 if something went wrong
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Wait for the indicated "read" socket to be marked as
+ * "selected" by a socket() call.
+ *
+ * Note:
+ * This routine is presently unused.
+ *
+ * The timeout mechanism is not exactly enforced, because
+ * received signals could result in a longer timeout period.
+ */
+
+int sokselectr(int fd)
+{
+ fd_set rfds;
+ int ready;
+ struct timeval timeout;
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ timeout.tv_sec = NI_SELECT_TIMEOUT;
+ timeout.tv_usec = 0;
+ while ((ready = select(fd+1, &rfds, NULL, NULL, &timeout)) == -1) {
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ continue;
+
+ default:
+ ni_errno = NIE_MISC;
+ sprintf(ni_errtext, "%s", sys_errlist[SOCK_INDEX_ERRNO]);
+ return -1;
+ }
+ }
+ if (ready == 0) {
+ strcpy(ni_errtext, ni_errlist[ni_errno]);
+ ni_errno = NIE_TIMEOUT;
+ return -1;
+ }
+ if (FD_ISSET(fd, &rfds))
+ return 0;
+ else
+ return -1;
+} /* sokselectr */
+
+
+
+/*
+ * Purpose: Wait for a "write" socket to become ready to write, or for
+ * a timeout to occur.
+ *
+ * Returns:
+ * -1 if something went wrong
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Wait for the indicated "write" socket to be marked as
+ * "selected" by a socket() call.
+ *
+ * Note:
+ * This routine can be used when waiting for a connect() to go
+ * through successfully.
+ *
+ * The timeout mechanism is not exactly enforced, because
+ * received signals could result in a longer timeout period.
+ */
+
+int sokselectw(int fd, int seconds)
+{
+ fd_set wfds;
+ int ready;
+ struct timeval timeout;
+
+ FD_ZERO(&wfds);
+ FD_SET(fd, &wfds);
+ timeout.tv_sec = NI_SELECT_TIMEOUT;
+ if (seconds > 0) /* override default */
+ timeout.tv_sec = seconds;
+ timeout.tv_usec = 0;
+ while ((ready = select(fd+1, NULL, &wfds, NULL, &timeout)) == -1) {
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ continue;
+
+ default:
+ ni_errno = NIE_MISC;
+ sprintf(ni_errtext, "%s", sys_errlist[SOCK_INDEX_ERRNO]);
+ return -1;
+ }
+ }
+ if (ready == 0) {
+ strcpy(ni_errtext, ni_errlist[ni_errno]);
+ ni_errno = NIE_TIMEOUT;
+ return -1;
+ }
+ if (FD_ISSET(fd, &wfds))
+ {
+#ifdef OS_UNIX
+ int err;
+ int optlen;
+
+ optlen = sizeof(int);
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) >= 0 &&
+ err != 0) /* check for an error */
+ return -1; /* got some error */
+#endif /* OS_UNIX */
+ return 0;
+ }
+ else
+ return -1;
+} /* sokselectw */
+
+
+
+/*
+ * Purpose: Parse the error number from an ASN error string which was
+ * formatted at a low level.
+ *
+ * Returns:
+ * -1, if unable to parse the string
+ * the parsed error number, otherwise
+ *
+ *
+ * Description:
+ * Parse the error number from an ASN error string which was
+ * prepared by the ASN tools, and formatted at a low level.
+ *
+ * Note:
+ * The parsing mechanism is dependent upon any future format
+ * changes which may occur in the ASN tools.
+ */
+
+int getAsnError(char *str)
+{
+ int errnum;
+
+ if (sscanf(str, "%*s %*s %*s [-%d]", &errnum) < 1)
+ errnum = -1;
+ return errnum;
+} /* getAsnError */
+
+
+/*
+ * Purpose: Set the Connection ID file pointer
+ *
+ * Parameters:
+ * fp The new value for the file descriptor
+ *
+ *
+ * Description:
+ * Set the Connection ID file pointer. This is used to update
+ * the connection ID each time it is updated, to keep the
+ * value current.
+ *
+ * Note:
+ * In reality, this should only be called by the dispatcher.
+ */
+
+void SetConFilePtr (FILE *fp)
+{
+ conid_fp = fp;
+}
+
+
+/*
+ * Purpose: Update the connection ID file
+ *
+ * Parameters:
+ * conid The new connection ID value
+ *
+ *
+ * Description:
+ * Update the connection ID file, and be sure to flush the stream,
+ * to try to ensure that output really occurs.
+ *
+ * Note:
+ * Should be called every time the "next" connection ID is
+ * modified.
+ */
+
+NLM_EXTERN void WriteConFile (Uint4 conid)
+{
+ if (conid_fp != NULL) {
+ (void) fseek(conid_fp, 0L, SEEK_SET);
+ (void) FileWrite((CharPtr) &conid, 1, sizeof(conid), conid_fp);
+ (void) fflush (conid_fp);
+ }
+}
+
+
+/*
+ * Purpose: Close the connection ID file
+ *
+ *
+ * Description:
+ * Close the connection ID file.
+ * to try to ensure that output really occurs.
+ *
+ * Note:
+ * In reality, this should only be called by the dispatcher.
+ */
+
+void CloseConFile (void)
+{
+ if (conid_fp != NULL) {
+ fclose (conid_fp);
+ conid_fp = NULL;
+ }
+}
+
+
+
+/*
+ * Purpose: Check for expired timers
+ *
+ *
+ * Description:
+ * For every expired timer, call the specified timer
+ * callback function, which is in turn responsible for cancelling
+ * the timer.
+ *
+ * Note:
+ * Timer checks only take place when this function is called.
+ * Therefore, it is the responsibility of an application to
+ * intermitently call this function. This could be done, e.g.
+ * using the UNIX alarm clock mechanism, or inside of an event
+ * loop.
+ *
+ * The order of operations is significant here, because the
+ * hook function must cancel the timer. To perform the linked
+ * list traversal in a less careful manner could result in
+ * illegal memory accesses.
+ *
+ * The timer list in managed in a very unsophisticated manner;
+ * if lots of timers were anticipated, the list would be
+ * maintained sorted by time, and all of the timer functions
+ * would need to maintain and traverse the timer list based
+ * upon this criterion.
+ *
+ * A count is used as a failsafe mechanism against infinite loops.
+ */
+
+#define NI_MAX_TIMERS 1000
+
+NLM_EXTERN void NI_ProcessTimers(void)
+{
+ NodePtr t;
+ NodePtr tnew;
+ NI_TimerPtr timer;
+ NodePtr timersToBeFired = NULL;
+ time_t curtime;
+ int count = NI_MAX_TIMERS;
+
+ if ((t = timerHead) == NULL)
+ {
+ return;
+ }
+
+ curtime = GetSecs();
+
+ do {
+ timer = (NI_TimerPtr) t->elem;
+ tnew = ListGetNext(t);
+ if (timer != NULL && timer->timeout != NULL_TIMER &&
+ timer->timeout <= curtime)
+ { /* note the timer to be fired */
+ timersToBeFired = ListInsert(timer, timersToBeFired);
+ }
+ if (t == tnew)
+ { /* data structure error, time to bail out */
+ break;
+ }
+ t = tnew;
+ } while (t != timerHead && t != NULL && --count > 0);
+
+ if ((t = timersToBeFired) == NULL)
+ return;
+
+ count = NI_MAX_TIMERS;
+
+ do {
+ timer = (NI_TimerPtr) t->elem;
+ tnew = ListGetNext(t);
+
+ /* mark the timer so it won't fire again */
+ timer->timeout = NULL_TIMER;
+ if (timer->hook != NULL)
+ {
+ timer->hook(timer->hookParam);
+ }
+ t = tnew;
+ } while (t != timersToBeFired && t != NULL && --count > 0);
+
+ ListDelete(timersToBeFired);
+}
+
+
+/*
+ * Purpose: Return the time when the next timeout will occur
+ *
+ * Returns: The time, in seconds, when the next scheduled timeout will
+ * occur, or NULL_TIMER, if there are no timers set.
+ *
+ * Description:
+ * Return the time when the next timer timeout will occur.
+ * This information is typically used with the select()
+ * system call, to ensure that a timeout parameter is passed
+ * to select() which is sufficiently short to ensure that
+ * the application will call NI_ProcessTimers() at an
+ * appropriate time.
+ *
+ * Note:
+ * The timer list in managed in a very unsophisticated manner;
+ * if lots of timers were anticipated, the list would be
+ * maintained sorted by time, and all of the timer functions
+ * would need to maintain and traverse the timer list based
+ * upon this criterion.
+ */
+
+NLM_EXTERN time_t NI_GetNextWakeup(void)
+{
+ time_t next_wakeup = NULL_TIMER;
+ NodePtr t;
+ NI_TimerPtr timer;
+
+ NI_ProcessTimers();
+
+ if ((t = timerHead) == NULL)
+ {
+ return NULL_TIMER;
+ }
+
+ do {
+ t = ListGetNext(t);
+ timer = (NI_TimerPtr) t->elem;
+ if (next_wakeup == NULL_TIMER || (timer->timeout != NULL_TIMER &&
+ timer->timeout < next_wakeup))
+ {
+ next_wakeup = timer->timeout;
+ }
+ } while (t != timerHead && t != NULL);
+
+ return next_wakeup;
+}
+
+
+/*
+ * Purpose: Set a timer
+ *
+ * Parameters:
+ * timeout The time in seconds when the timer should expire
+ * hook Callback to be called when (if) the timer expires
+ * hookParam Parameter to be passed to caller's hook when the timer expires
+ *
+ *
+ * Returns: The "timer ID", really a pointer to the timer data structure
+ *
+ *
+ * Description:
+ * Sets a timer with the appropriate parameters.
+ *
+ * Note:
+ * The timer list in managed in a very unsophisticated manner;
+ * if lots of timers were anticipated, the list would be
+ * maintained sorted by time, and all of the timer functions
+ * would need to maintain and traverse the timer list based
+ * upon this criterion.
+ *
+ * It is the responsibility of the application (usually the
+ * hook function) to cancel the timer.
+ */
+
+NodePtr
+NI_SetTimer(time_t timeout, NI_TimeoutHook hook, Pointer hookParam)
+{
+ NodePtr t;
+ NI_TimerPtr timer;
+
+ timer = (NI_TimerPtr) MemNew(sizeof(NI_Timer));
+ timer->timeout = timeout;
+ timer->hook = hook;
+ timer->hookParam = hookParam;
+ t = ListInsert(timer, timerHead);
+ timerHead = t;
+
+ return t;
+}
+
+
+/*
+ * Purpose: Cancel a timer
+ *
+ * Parameters:
+ * timerID The ID of the timer
+ *
+ *
+ * Description:
+ * Cancel the specified timer by deleting the entry and its
+ * associated data structure.
+ *
+ * Note:
+ * The timer list in managed in a very unsophisticated manner;
+ * if lots of timers were anticipated, the list would be
+ * maintained sorted by time, and all of the timer functions
+ * would need to maintain and traverse the timer list based
+ * upon this criterion.
+ */
+
+NLM_EXTERN void NI_CancelTimer(NodePtr timerId)
+{
+ if (timerId != NULL)
+ {
+ MemFree (timerId->elem);
+ timerHead = ListDelete(timerId);
+ }
+}
+
+
+/*
+ * Purpose: Set an activity hook, to inform the application of key events
+ *
+ * Parameters:
+ * hook The hook (callback function)
+ *
+ *
+ * Description:
+ * Setup a hook function which will subsequently be used to
+ * inform the application of various events; these currently
+ * include:
+ * * Connection to dispatcher
+ * * Disconnection from dispatcher
+ * * Service connection
+ * * Service disconnection
+ * * Bytes written
+ * * Bytes read
+ *
+ * Note:
+ * This hook is global for the running application.
+ */
+
+NLM_EXTERN void NI_SetActivityHook (NI_NetServHook hook)
+{
+ activityHook = hook;
+}
+
+
+/*
+ * Purpose: Return the current activity hook
+ *
+ *
+ * Description:
+ * Return the current activity hook. This is only intended
+ * to be used internally by the Network Services library.
+ * This function is used to avoid making activityHook into a
+ * global variable.
+ */
+
+NLM_EXTERN NI_NetServHook NI_ActivityHook (void)
+{
+ return activityHook;
+}
+
+
+/*
+ * Purpose: Initialize socket management
+ *
+ * Description:
+ * If not already initialized, initialize the socket management
+ * data structures
+ */
+
+static void
+InitLogSocket()
+{
+ static Boolean inited = FALSE;
+
+ if (! inited)
+ {
+ FD_ZERO(&openfds);
+ inited = TRUE;
+ }
+}
+
+
+/*
+ * Purpose: Count the number of open sockets
+ */
+
+NLM_EXTERN Int2 NI_SocketsOpen(void)
+{
+ int sok;
+ int count = 0;
+
+ InitLogSocket();
+ for (sok = 0; sok < FD_SETSIZE; sok++)
+ {
+ if (FD_ISSET(sok, &openfds))
+ count++;
+ }
+ return count;
+}
+
+/*
+ * Purpose: Log each socket transaction
+ */
+
+NLM_EXTERN void NI_LogSocket(int sok, Boolean opening, CharPtr filename, int lineno)
+{
+ int localsok;
+
+ InitLogSocket();
+
+ if (sok == INVALID_SOCKET || sok < 0 || sok >= FD_SETSIZE)
+ {
+#ifndef NETP_INET_WSOCK
+ /* FD_SETSIZE doesn't accurately describe the socket range for
+ WinSock applications, so don't generate misleading error msgs */
+ ErrPostEx(SEV_WARNING,0,0, "Bad %s operation on socket %d at %s:%d",
+ opening ? "opening" : "closing", sok, filename, lineno);
+#endif /* NETP_INET_WSOCK */
+ return;
+ }
+
+ if (opening)
+ {
+ TRACE("Just opened socket %d at %s:%d\n", sok, filename, lineno);
+ if (FD_ISSET(sok, &openfds))
+ {
+ ErrPostEx(SEV_ERROR,0,0, "Duplicate open of socket %d at %s:%d",
+ sok, filename, lineno);
+ } else {
+ FD_SET(sok, &openfds);
+ }
+ } else {
+ TRACE("Trying to close socket %d at %s:%d\n", sok, filename, lineno);
+ if (FD_ISSET(sok, &openfds))
+ {
+ FD_CLR(sok, &openfds);
+ } else {
+ ErrPostEx(SEV_ERROR,0,0, "Duplicate close of socket %d at %s:%d",
+ sok, filename, lineno);
+ }
+ }
+
+#ifdef DEBUG
+ for (localsok = 0; localsok < FD_SETSIZE; localsok++)
+ {
+ if (FD_ISSET(localsok, &openfds))
+ {
+ TRACE("Socket %d is currently open\n", localsok);
+ }
+ }
+#endif /* DEBUG */
+}
+
diff --git a/network/nsclilib/ni_lib.h b/network/nsclilib/ni_lib.h
new file mode 100644
index 00000000..05ef2844
--- /dev/null
+++ b/network/nsclilib/ni_lib.h
@@ -0,0 +1,78 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_lib.h
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 5/12/92 Epstein Converted tabs to spaces
+*
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_lib.h,v $
+* Revision 6.0 1997/08/25 18:38:49 madden
+* Revision changed to 6.0
+*
+* Revision 5.0 1996/05/28 14:11:55 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.4 1995/05/17 17:52:23 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NI_LIB_
+#define _NI_LIB_
+
+#include "ncbinet.h"
+#include "ni_net.h"
+
+#include "ni_msg.h"
+
+/* DEFINES */
+
+#define NI_TIMEOUT_SECS 60 /* timeout for connections, requests, etc. */
+#define NI_SERV_LISTEN_TIMEOUT 1800 /* default: servers timeout after 30 minutes */
+#define MAX_ALT_DISP_TRIES 2 /* number of times to try alternate dispatchers */
+
+
+#endif
diff --git a/network/nsclilib/ni_lib_.c b/network/nsclilib/ni_lib_.c
new file mode 100644
index 00000000..27ea08ea
--- /dev/null
+++ b/network/nsclilib/ni_lib_.c
@@ -0,0 +1,334 @@
+/* $RCSfile: ni_lib_.c,v $ $Revision: 4.8 $ $Date: 1998/09/08 17:59:06 $
+* ==========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ==========================================================================
+*
+* Author: Denis Vakatov
+*
+* File Description:
+* Wraparound the old NCBI network client API.
+* Now provides new mechanisms to connect clients to the NCBI network
+* services
+*
+* --------------------------------------------------------------------------
+* $Log: ni_lib_.c,v $
+* Revision 4.8 1998/09/08 17:59:06 vakatov
+* Added WWW/Firewall network interface
+*
+* Revision 4.7 1998/05/05 22:45:37 vakatov
+* Added "eNII_Debug" network interface
+*
+* Revision 4.6 1998/04/15 20:01:20 vakatov
+* [OS_MAC, ALLOW_STATELESS] Stateless mode now available on Mac
+*
+* Revision 4.5 1998/04/10 19:24:47 vakatov
+* NI_SetInterface(): return the overridden(old) interface value; check
+* for the validity of the new interface
+*
+* Revision 4.4 1998/04/03 22:54:46 vakatov
+* Support *stateless* WWW connection only if #ALLOW_STATELESS is defined
+* (thus, disable it by default)
+*
+* Revision 4.3 1998/03/31 00:27:04 kans
+* for Mac, define NI_WWW_SUPPORTED
+*
+* Revision 4.2 1998/03/30 17:50:17 vakatov
+* Ingrafted to the main NCBI CVS tree
+*
+* ==========================================================================
+*/
+
+#include <ncbinet.h>
+#include <ncbithr.h>
+
+/* As for now, the old-fashioned interface is supported for all platforms
+ */
+#define NI_DISP_SUPPORTED
+
+/* As for now, the WWW(HTTPD)-based interfaces are not always supported
+ */
+#if defined(OS_UNIX) || defined(OS_MSWIN) || defined(OS_MAC)
+#define NI_WWW_SUPPORTED
+#define NI_WWWFIREWALL_SUPPORTED
+#ifdef ALLOW_STATELESS
+#define NI_WWWDIRECT_SUPPORTED
+#endif
+#define NI_DEBUG_SUPPORTED
+#endif /* OS_UNIX | OS_MSWIN | OS_MAC */
+
+
+/* Override config-file value by the environment variable's value, if any */
+#if defined(OS_UNIX) || defined(OS_MSWIN)
+#define USE_GETENV
+#endif /* OS_UNIX | OS_MSWIN */
+
+
+/* Hard-coded constants, environment parameter names & defaults
+ */
+
+#define DEF_CONFIG_FILE "NCBI"
+#define DEF_CONFIG_SECTION "NET_SERV"
+#define ENV_CONN_MODE "SRV_CONN_MODE"
+#define DISPATCHER_MODE "DISPATCHER"
+#define WWW_CLIENT_MODE "WWW"
+#define WWW_FIREWALL_MODE "FIREWALL"
+#define WWW_DIRECT_MODE "STATELESS"
+#define DEBUG_MODE "DEBUG"
+
+
+/* Enumerated array of the interface implementation function sets
+ */
+
+static const NIInterface **s_NII[eNII_Default] = {
+#ifdef NI_DISP_SUPPORTED
+ &g_NII_Dispatcher,
+#else
+ 0,
+#endif
+
+#ifdef NI_WWW_SUPPORTED
+ &g_NII_WWW,
+#else
+ 0,
+#endif
+
+#ifdef NI_WWWFIREWALL_SUPPORTED
+ &g_NII_WWWFirewall,
+#else
+ 0,
+#endif
+
+#ifdef NI_WWWDIRECT_SUPPORTED
+ &g_NII_WWWDirect,
+#else
+ 0,
+#endif
+
+#ifdef NI_DEBUG_SUPPORTED
+ &g_NII_Debug
+#else
+ 0
+#endif
+};
+
+
+/* Local typedefs
+ */
+
+typedef struct {
+ ENIInterface interface;
+ CharPtr address;
+} NIOptions;
+
+
+/* Static functions
+ */
+
+static void s_NIOptionsTLS_Cleanup(TNlmTls TLS, VoidPtr old_value)
+{
+ if ( old_value ) {
+ NIOptions *nio = (NIOptions *)old_value;
+ MemFree(nio->address);
+ MemFree(nio);
+ }
+}
+
+static NIOptions* s_GetNIOptions
+(const Char *conf_file, const Char *conf_section)
+{
+ static TNlmTls s_NIOptionsTLS;
+
+ NIOptions *nio;
+ Char conn_mode[64];
+
+ if (NlmTlsGetValue(s_NIOptionsTLS, (VoidPtr *)&nio)
+ && nio && nio->interface != eNII_Default)
+ return nio;
+
+ if ( !nio )
+ nio = (NIOptions *)MemNew(sizeof(NIOptions));
+
+ NI_GetEnvParam(conf_file, conf_section, ENV_CONN_MODE,
+ conn_mode, sizeof(conn_mode), "");
+ if (StringCmp(conn_mode, DISPATCHER_MODE) == 0)
+ nio->interface = eNII_Dispatcher;
+ else if (StringCmp(conn_mode, WWW_CLIENT_MODE) == 0)
+ nio->interface = eNII_WWW;
+ else if (StringCmp(conn_mode, WWW_FIREWALL_MODE) == 0)
+ nio->interface = eNII_WWWFirewall;
+ else if (StringCmp(conn_mode, WWW_DIRECT_MODE) == 0)
+ nio->interface = eNII_WWWDirect;
+ else if (StringCmp(conn_mode, DEBUG_MODE) == 0)
+ nio->interface = eNII_Debug;
+ else
+ nio->interface = NII_DEFAULT;
+
+ if ( !NI_IsInterfaceSupported(nio->interface) )
+ nio->interface = NII_DEFAULT;
+ ASSERT ( NI_IsInterfaceSupported(nio->interface) );
+
+ NlmTlsSetValue(&s_NIOptionsTLS, (VoidPtr)nio, s_NIOptionsTLS_Cleanup);
+ return nio;
+}
+
+
+/*********************************
+ * INTERNAL EXTERNALS(to be used inside the library only; not public)
+ */
+
+extern Uint4 NI_GetEnvParamEx
+(const Char *conf_file, const Char *conf_section,
+ const Char *env_name, const Char *conf_name,
+ Char *buf, Uint4 bufsize, const Char *dflt)
+{
+ ASSERT ( (env_name && *env_name) || (conf_name && *conf_name) );
+ ASSERT ( buf && bufsize );
+ buf[0] = '\0';
+
+#ifdef USE_GETENV
+ if (env_name && *env_name) {
+ const Char *str = getenv(env_name);
+ if (str && *str) {
+ Uint4 len = StrLen(str);
+ if (len >= bufsize)
+ return 0;
+ StrCpy(buf, str);
+ return len;
+ }
+ }
+#endif
+
+ if (conf_name && *conf_name) {
+ if ( !conf_file )
+ conf_file = DEF_CONFIG_FILE;
+ if ( !conf_section )
+ conf_section = DEF_CONFIG_SECTION;
+
+ return GetAppParam
+ ((CharPtr)conf_file, (CharPtr)conf_section, (CharPtr)conf_name,
+ (CharPtr)dflt, buf, (Int2)bufsize);
+ }
+
+ return 0;
+}
+
+extern Uint4 NI_GetEnvParam
+(const Char *conf_file, const Char *conf_section,
+ const Char *env_conf_name,
+ Char *buf, Uint4 bufsize, const Char *dflt)
+{
+ return NI_GetEnvParamEx(conf_file, conf_section,
+ env_conf_name, env_conf_name,
+ buf, bufsize, dflt);
+}
+
+
+/*********************************
+ * EXTERNALS
+ */
+
+NLM_EXTERN Boolean NI_IsInterfaceSupported(ENIInterface ni_interface)
+{
+ switch ( ni_interface ) {
+ case eNII_Dispatcher:
+ case eNII_WWW:
+ case eNII_WWWFirewall:
+ case eNII_WWWDirect:
+ case eNII_Debug:
+ return (Boolean)(s_NII[ni_interface] != 0);
+ case eNII_Default:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+
+NLM_EXTERN void NI_SetAddress(const Char *address)
+{
+ NIOptions *nio = s_GetNIOptions(0,0);
+ if ( nio->address )
+ MemFree(nio->address);
+ nio->address = StringSave(address);
+}
+
+
+NLM_EXTERN ENIInterface NI_SetInterface(ENIInterface ni_interface)
+{
+ NIOptions *nio = s_GetNIOptions(0,0);
+ ENIInterface prev_interface = nio->interface;
+
+ if ( NI_IsInterfaceSupported(ni_interface) )
+ nio->interface = ni_interface;
+ else {
+ ErrPostEx(SEV_ERROR, 0, 0,
+ "NI_SetInterface(): unsupported interface [#%d]",
+ (int)ni_interface);
+ }
+ return prev_interface;
+}
+
+
+NLM_EXTERN NI_DispatcherPtr NI_GenericInit
+(CharPtr configFile, CharPtr configSection, Boolean showMonitor,
+ CharPtr lastDispatcher, Int2 lastDispLen)
+{
+ return
+ (*s_NII[s_GetNIOptions(configFile,configSection)->interface])->generic_init
+ (configFile, configSection, showMonitor, lastDispatcher, lastDispLen);
+}
+
+
+NLM_EXTERN NI_DispatcherPtr NI_SetDispatcher
+(NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
+ Int4 uniqueSeqNo, ValNodePtr encryption, Boolean useOutServ)
+{
+ ENIInterface nii = disp ? disp->interface : s_GetNIOptions(0,0)->interface;
+ return (*s_NII[nii])->set_dispatcher
+ (disp, host, svc, timeout, uniqueSeqNo, encryption, useOutServ);
+}
+
+
+NLM_EXTERN NI_HandPtr NI_GenericGetService
+(NI_DispatcherPtr disp, CharPtr configFile, CharPtr configSection,
+ CharPtr defService, Boolean hasResource)
+{
+ return (*s_NII[disp->interface])->generic_get_service
+ (disp, configFile, configSection, defService, hasResource);
+}
+
+
+NLM_EXTERN Int2 NI_EndServices
+(NI_DispatcherPtr disp)
+{
+ return (*s_NII[disp->interface])->end_services
+ (disp);
+}
+
+NLM_EXTERN Int2 NI_ServiceDisconnect
+(NI_HandPtr mhp)
+{
+ return mhp ? (*s_NII[mhp->disp->interface])->disconnect_service(mhp) : 0;
+}
+
+/* EOF */
diff --git a/network/nsclilib/ni_lib_.h b/network/nsclilib/ni_lib_.h
new file mode 100644
index 00000000..63d54a83
--- /dev/null
+++ b/network/nsclilib/ni_lib_.h
@@ -0,0 +1,178 @@
+#ifndef NI_LIB___H
+#define NI_LIB___H
+
+/* $RCSfile: ni_lib_.h,v $ $Revision: 4.5 $ $Date: 1998/09/08 17:59:06 $
+* ==========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ==========================================================================
+*
+* Author: Denis Vakatov
+*
+* File Description:
+* Wraparound the old NCBI network client API.
+* Now provides new mechanisms to connect clients to the NCBI network
+* services
+*
+* --------------------------------------------------------------------------
+* $Log: ni_lib_.h,v $
+* Revision 4.5 1998/09/08 17:59:06 vakatov
+* Added WWW/Firewall network interface
+*
+* Revision 4.4 1998/05/05 22:45:38 vakatov
+* Added "eNII_Debug" network interface
+*
+* Revision 4.3 1998/04/10 19:24:47 vakatov
+* NI_SetInterface(): return the overridden(old) interface value; check
+* for the validity of the new interface
+*
+* Revision 4.2 1998/03/30 17:50:18 vakatov
+* Ingrafted to the main NCBI CVS tree
+*
+* ==========================================================================
+*/
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* To check whether an interface is supported
+ */
+NLM_EXTERN Boolean NI_IsInterfaceSupported(ENIInterface ni_interface);
+
+
+/* Setup the interface to be used for the dispatcher created in the
+ * next call to NI_GenericInitWWW()
+ * NOTE 1: this interface will be used for this thread only and for
+ * all subsequent calls to NI_GenericInitWWW()
+ * NOTE 2: use "interface" == eNII_Default to try to retrieve the
+ * interface from the environment and config files; if it
+ * cannot be found there as well, then the application will
+ * use "interface" == NII_DEFAULT
+ */
+NLM_EXTERN ENIInterface NI_SetInterface(ENIInterface ni_interface);
+
+
+/* Setup the client host address to be used in the next call to
+ * NI_GenericGetService()
+ * NOTE: the address will be valid for this thread only and for
+ * the only one call to NI_GenericGetService()
+ */
+NLM_EXTERN void NI_SetAddress(const Char *address);
+
+
+/* The set of functions that are capable to work with different
+ * network interfaces(according to NI_SetInterface)
+ */
+NLM_EXTERN NI_DispatcherPtr NI_GenericInit
+(CharPtr configFile, CharPtr configSection, Boolean showMonitor,
+ CharPtr lastDispatcher, Int2 lastDispLen);
+NLM_EXTERN NI_DispatcherPtr NI_SetDispatcher
+(NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
+ Int4 uniqueSeqNo, ValNodePtr encryption, Boolean useOutServ);
+NLM_EXTERN NI_HandPtr NI_GenericGetService
+(NI_DispatcherPtr disp, CharPtr configFile, CharPtr configSection,
+ CharPtr defService, Boolean hasResource);
+NLM_EXTERN Int2 NI_EndServices
+(NI_DispatcherPtr disp);
+NLM_EXTERN Int2 NI_ServiceDisconnect
+(NI_HandPtr mhp);
+
+
+/*******************************************************************
+ * The stuff below is for the NCBI in-library(internal) use
+ *******************************************************************/
+
+/* Type definition of functions comprising an interface
+ */
+
+typedef NI_DispatcherPtr (*F_NIGenericInit)
+ (CharPtr configFile, CharPtr configSection, Boolean showMonitor,
+ CharPtr lastDispatcher, Int2 lastDispLen);
+typedef NI_DispatcherPtr (*F_NISetDispatcher)
+ (NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
+ Int4 dispserialnum, ValNodePtr encryption, Boolean useOutServ);
+typedef NI_HandPtr (*F_NIGenericGetService)
+ (NI_DispatcherPtr disp, CharPtr configFile, CharPtr configSection,
+ CharPtr defService, Boolean hasResource);
+typedef Int2 (*F_NIServiceDisconnect)
+ (NI_HandPtr mhp);
+typedef Int2 (*F_NIEndServices)
+ (NI_DispatcherPtr disp);
+
+
+/* Set of functions describing an interface
+ */
+typedef struct {
+ F_NIGenericInit generic_init;
+ F_NISetDispatcher set_dispatcher;
+ F_NIGenericGetService generic_get_service;
+ F_NIServiceDisconnect disconnect_service;
+ F_NIEndServices end_services;
+} NIInterface;
+
+
+/* These are the only clues exported by the modules that implement
+ * connection interfaces
+ * NOTE: although these are global, however they must *NOT* be referenced
+ * anywhere but in this module!
+ */
+extern const NIInterface *g_NII_Dispatcher; /* "ni_lib.c" */
+extern const NIInterface *g_NII_WWW; /* "ni_www.c" */
+extern const NIInterface *g_NII_WWWFirewall; /* "ni_www.c" */
+extern const NIInterface *g_NII_WWWDirect; /* "ni_www.c" */
+extern const NIInterface *g_NII_Debug; /* "ni_debug.c" */
+
+
+/* Try to extract the specified parameter from the environment or
+ * configuration fife
+ */
+extern Uint4 NI_GetEnvParam
+(const Char *conf_file, const Char *conf_section,
+ const Char *env_conf_name,
+ Char *buf, Uint4 bufsize, const Char *dflt);
+
+extern Uint4 NI_GetEnvParamEx
+(const Char *conf_file, const Char *conf_section,
+ const Char *env_name, const Char *conf_name,
+ Char *buf, Uint4 bufsize, const Char *dflt);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif /* NI_LIB___H */
diff --git a/network/nsclilib/ni_list.c b/network/nsclilib/ni_list.c
new file mode 100644
index 00000000..d49092b2
--- /dev/null
+++ b/network/nsclilib/ni_list.c
@@ -0,0 +1,494 @@
+#ifdef NOWAY_ABOUT_TO_BE_ZOMBIED
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_list.c
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* List and ring management functions.
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 4/23/92 Epstein Added extensive in-line commentary, and removed all tabs
+* 5/11/92 Epstein Changed ListSwapAdj() to provide more rigorous testing
+* that its two arguments are adjacent in the list.
+* 5/14/92 Epstein Added ListStrCopy() and ListStrDel()
+* 7/06/92 Epstein Fixed bug in ListStrCopy(), where the newly created
+* list was not being returned to the caller ... whoops.
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_list.c,v $
+* Revision 6.0 1997/08/25 18:38:51 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1997/01/28 21:23:42 epstein
+* prepare to be zombied; functionality has been moved to ncbimisc.[ch]
+*
+ * Revision 5.0 1996/05/28 14:11:55 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.0 1995/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.2 1995/05/17 17:52:27 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include "ni_list.h"
+
+
+
+/*
+ * Purpose: Insert an item as the next element in a doubly linked list(ring)
+ *
+ * Parameters:
+ * elem Next element to be inserted; this is data only,not a NodePtr
+ * ap Insertion point
+ *
+ * Returns:
+ * The newly allocated NodePtr, containing forward and backward
+ * pointers and a pointer to elem
+ *
+ *
+ * Description:
+ * Allocate the necessary memory for a "Node", attach the
+ * caller's data to that Node, and insert the Node after the
+ * specified node in the list, maintaining the integrity of
+ * a doubly-linked ring. If there are no other items in the
+ * ring, create a "minimal" ring which consists of the single
+ * Node pointing to itself in both directions.
+ *
+ * Note:
+ * Most "list" data is actually stored in a doubly-linked ring, as
+ * shown below. Furthermore, note that each node only contains a
+ * pointer to the actual data in the list, rather than the actual
+ * data itself.
+ *
+ * +------------------------------------------------------------------+
+ * ^ |
+ * | +-------------------------------------------------------+ |
+ * | | ^ |
+ * | V | |
+ * | +-------+ +-------+ +-------+ | |
+ * | | next |------>| next |------> ... ------->| next |-->+ |
+ * | +-------+ +-------+ +-------+ |
+ * +<--| last |<------| last |<------ ... <-------| last |<-----+
+ * +-------+ +-------+ +-------+
+ * | elem | | elem | | elem |
+ * +-------+ +-------+ +-------+
+ * | | |
+ * | | |
+ * V V V
+ * +-------+ +-------+ +-------+
+ * | actual| | actual| | actual|
+ * | data | | data | | data |
+ * +-------+ +-------+ +-------+
+ */
+
+NodePtr
+ListInsert(VoidPtr elem, NodePtr ap) /* ptr to node to insert after */
+{
+ NodePtr np;
+
+ if (elem == NULL)
+ return NULL;
+
+ np = (NodePtr) MemNew(sizeof(Node));
+ np->elem = elem;
+
+ if (ap == NULL) { /* no nodes in list */
+ np->last = np;
+ np->next = np;
+ return np;
+ }
+ else { /* 1 or more nodes in list */
+ np->next = ap->next;
+ ap->next = np;
+ np->next->last = np;
+ np->last = ap;
+ return np;
+ }
+} /* ListInsert */
+
+
+
+/*
+ * Purpose: Insert an item as the previous element in a doubly linked
+ * list(ring)
+ *
+ * Parameters:
+ * elem Next element to be inserted; this is data only,not a NodePtr
+ * ap Insertion point
+ *
+ * Returns:
+ * The newly allocated NodePtr, containing forward and backward
+ * pointers and a pointer to elem
+ *
+ *
+ * Description:
+ * Insert the specified item into the ring, before the specified
+ * insertion point. In the case where the specified insertion
+ * point was NULL, this is equivalent to ListInsert().
+ */
+
+NodePtr
+ListInsertPrev(VoidPtr elem, NodePtr ap) /* ptr to node to insert before */
+{
+ NodePtr np;
+
+ np = ap;
+ if (ap != NULL)
+ ap = ap->last; /* previous node */
+
+ ap = ListInsert(elem, ap);
+ return (np == NULL) ? ap : np;
+} /* ListInsertPrev */
+
+
+
+/*
+ * Purpose: Delete a single node from a list or ring
+ *
+ * Parameters:
+ * np Node to be deleted
+ *
+ * Returns:
+ * A pointer to the "next" node in the list/ring, after the
+ * deleted node.
+ *
+ *
+ * Description:
+ * Delete the specified node from a list or ring. It is the
+ * responsibility of the caller to free the memory associated
+ * with the "elem" (data), if appropriate.
+ */
+
+NodePtr
+ListDelete(NodePtr np)
+{
+ NodePtr nextnode, lastnode;
+
+ if (np == NULL)
+ return NULL;
+
+ nextnode = np->next;
+ lastnode = np->last;
+
+ if (nextnode == NULL && lastnode == NULL) /* only node in a list */
+ ;
+ else if (nextnode == NULL) { /* last in a list */
+ np->last->next = NULL;
+ nextnode = np->last;
+ }
+ else if (lastnode == NULL) { /* first in a list */
+ np->next->last = NULL;
+ nextnode = np->next;
+ }
+ else if (np == nextnode) /* last in a ring */
+ nextnode = NULL;
+ else { /* node with both neighbors */
+ np->last->next = nextnode;
+ np->next->last = np->last;
+ }
+
+ MemFree(np); /* assumes element memory has been freed */
+ return nextnode;
+} /* ListDelete */
+
+
+
+/*
+ * Purpose: Get the next element from a list or ring (non-destructively)
+ *
+ * Parameters:
+ * np Node before the node to be selected
+ *
+ * Returns:
+ * A pointer to the "next" node in the list/ring (or NULL
+ * if the list/ring was NULL). Note that for a list, the
+ * returned value can also be NULL.
+ *
+ *
+ * Description:
+ * Return the "next" node in the list or rin.g
+ */
+
+NodePtr
+ListGetNext(NodePtr np)
+{
+ if (np == NULL)
+ return NULL;
+ return np->next;
+} /* ListGetNext */
+
+
+
+/*
+ * Purpose: Swap two adjacent nodes in a list or ring
+ *
+ * Parameters:
+ * np1 "Prior" node
+ * np2 "Next" node
+ *
+ *
+ * Description:
+ * Swap the two specified elements, provided that they are
+ * adjacent, and np1 precedes np2.
+ */
+
+void
+ListSwapAdj(NodePtr np1, NodePtr np2) /* priornode, nextnode */
+{
+ if (np1 == NULL || np2 == NULL || np1->next->last != np1) /* must be sane */
+ return;
+
+ if (np1->next != np2 || np2->last != np1) /* must be in order */
+ return;
+
+ if (np1->last != NULL)
+ np1->last->next = np2;
+
+ if (np2->next != NULL)
+ np2->next->last = np1;
+
+ np1->next = np2->next;
+ np2->last = np1->last;
+
+ np1->last = np2;
+ np2->next = np1;
+} /* ListSwapAdj */
+
+
+
+/*
+ * Purpose: Sort the specified ring/list
+ *
+ * Parameters:
+ * head Head of the list to be sorted
+ * cmpfunc Comparison function (return values are like memcmp())
+ * order ASCEND or DESCEND
+ *
+ * Returns:
+ * A pointer to the first element of the sorted ring or list
+ *
+ *
+ * Description:
+ * Sort the specified list, in place, using bubble sort, and
+ * the specified comparison function. Determine prior to sorting
+ * whether this is a list or a ring. If it's a ring, break the
+ * ring prior to sorting, and restore it to a ring topology
+ * after sorting has been completed.
+ */
+
+NodePtr
+ListSort(NodePtr head, int (*cmpfunc )PROTO ((NodePtr, NodePtr )), int order) /* 0 if equal, LT 0 if 1st element > 2nd element */
+{
+ NodePtr np;
+ Boolean sorted = FALSE, ring;
+ int result;
+
+ if (head == NULL)
+ return NULL;
+ if (head->last == NULL)
+ ring = FALSE;
+ else
+ ring = TRUE;
+ if (ring)
+ ListBreakRing(head);
+
+ /* just bubble sort for now */
+
+ while (! sorted) {
+ np = head;
+ sorted = TRUE;
+
+ while (np->next != NULL) {
+ result = (*cmpfunc)(np, np->next);
+ if ((result > 0 && order == ASCEND) || (result < 0 && order == DESCEND)) {
+ sorted = FALSE;
+ if (np == head)
+ head = np->next; /* keep head pointing at 1st element */
+ ListSwapAdj(np, np->next);
+ }
+ else
+ np = np->next;
+ }
+ }
+
+ if (ring)
+ ListConnectRing(head);
+ return head; /* ptr to first element */
+} /* ListSort */
+
+
+
+/*
+ * Purpose: Break the specified ring into a non-circular (linear) list
+ *
+ * Parameters:
+ * np Head of the ring to be broken
+ *
+ *
+ * Description:
+ * Break the specified ring between its head and tail.
+ *
+ * Note:
+ * This function may be called safely (without effect) if the
+ * passed parameter is already a list, rather than a ring.
+ */
+
+void
+ListBreakRing(NodePtr np)
+{
+ if (np == NULL)
+ return;
+ if (np->last == NULL)
+ return;
+
+ np->last->next = NULL;
+ np->last = NULL;
+} /* ListBreakRing */
+
+
+
+/*
+ * Purpose: Convert a list into a ring.
+ *
+ * Parameters:
+ * head Head of the list to be connected
+ *
+ *
+ * Description:
+ * Connect the specified list between its head and tail, producing
+ * a ring.
+ *
+ * Note:
+ * This function may be called safely (without effect) if the
+ * passed parameter is already a ring, rather than a list.
+ */
+
+void
+ListConnectRing(NodePtr head)
+{
+ NodePtr np;
+
+ if (head == NULL)
+ return;
+
+ np = head;
+
+ while (np->next != NULL) {
+ np = np->next;
+ if (np == head)
+ return;
+ }
+
+ np->next = head;
+ head->last = np;
+} /* ListConnectRing */
+
+
+/*
+ * Purpose: Copy a list where the list elements are character strings
+ *
+ * Parameters:
+ * strlist List to be copied
+ *
+ * Returns:
+ * A copy of the original list (which may be NULL)
+ *
+ *
+ * Description:
+ * Create a list which is a copy of the original list, and
+ * also make copies of the strings.
+ *
+ * Note:
+ * There is no obvious way to make a generic list copying
+ * routine, because, in general, the length of each list
+ * element is unknown. This is a simple case where it is
+ * easy to copy a list.
+ */
+
+NodePtr
+ListStrCopy (NodePtr strlist)
+{
+ NodePtr newlist = NULL;
+ NodePtr np = strlist;
+ CharPtr stringtext;
+
+ if (strlist == NULL)
+ return NULL;
+
+ do {
+ stringtext = StringSave((CharPtr) np->elem);
+ newlist = ListInsert(stringtext, newlist);
+ np = ListGetNext(np);
+ } while (np != NULL && np != strlist);
+
+ return newlist->next; /* points to 1st element in new list */
+}
+
+
+/*
+ * Purpose: Delete a list where the list elements are character strings
+ *
+ * Parameters:
+ * np List to be deleted
+ *
+ *
+ * Description:
+ * Delete the list nodes and the character string data associated
+ * with each node.
+ *
+ * Note:
+ * This routine will work for any list element which is a single
+ * block of memory. However, it will not work in the more general
+ * case where a list element in turn references other memory
+ * which must also be freed.
+ */
+
+void
+ListStrDel (NodePtr np)
+{
+ while (np != NULL)
+ {
+ MemFree (np->elem);
+ np = ListDelete(np);
+ }
+}
+#endif /* NOWAY_ABOUT_TO_BE_ZOMBIED */
diff --git a/network/nsclilib/ni_list.h b/network/nsclilib/ni_list.h
new file mode 100644
index 00000000..2ddbe113
--- /dev/null
+++ b/network/nsclilib/ni_list.h
@@ -0,0 +1,98 @@
+#ifdef NOWAY_ABOUT_TO_BE_ZOMBIED
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_list.h
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 5/12/92 Epstein Converted tabs to spaces
+*
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_list.h,v $
+* Revision 6.0 1997/08/25 18:38:53 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1997/01/28 21:23:46 epstein
+* prepare to be zombied; functionality has been moved to ncbimisc.[ch]
+*
+ * Revision 5.0 1996/05/28 14:11:55 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.0 1995/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.2 1995/05/17 17:52:30 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NI_LIST_
+#define _NI_LIST_
+
+#include "ncbinet.h"
+
+#define ASCEND 0 /* order for ListSort */
+#define DESCEND 1
+
+
+/* FUNCTIONS */
+
+extern NodePtr ListInsert PROTO((VoidPtr elem, NodePtr after));
+
+extern NodePtr ListInsertPrev PROTO((VoidPtr elem, NodePtr before));
+
+extern NodePtr ListDelete PROTO((NodePtr node));
+
+extern NodePtr ListGetNext PROTO((NodePtr after));
+
+extern void ListSwapAdj PROTO((NodePtr priornode, NodePtr nextnode));
+
+extern NodePtr ListSort PROTO((NodePtr sl, int (*cmpfunc)(NodePtr, NodePtr), int order));
+
+extern void ListBreakRing PROTO((NodePtr np));
+
+extern void ListConnectRing PROTO((NodePtr np));
+extern NodePtr ListStrCopy PROTO((NodePtr strlist));
+extern void ListStrDel PROTO((NodePtr np));
+
+
+#endif
+#endif /* NOWAY_ABOUT_TO_BE_ZOMBIED */
diff --git a/network/nsclilib/ni_macdv.c b/network/nsclilib/ni_macdv.c
new file mode 100644
index 00000000..868b2bb4
--- /dev/null
+++ b/network/nsclilib/ni_macdv.c
@@ -0,0 +1,418 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_macdv.c
+*
+* Author: epstein
+*
+* Version Creation Date: 1/13/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Determine which Macintosh MacTCP device is in-use (e.g., "Ethernet", "PPP")
+*
+* Note: This file is almost entirely based upon source code kindly provided
+* by Robert S. Mah (rmah@panix.com). This in turn is based upon
+* the Apple technical document "MacTCP 2.0 LAP Tech Note".
+*
+* This file is to be used for Macintosh computers only.
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*01/17/95 Kans Add CodeWarrior-compatibility
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_macdv.c,v $
+* Revision 6.0 1997/08/25 18:38:55 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1997/01/29 00:20:48 kans
+* uses <MacTCP.h> instead of obsolete <MacTCPCommonTypes.h>
+*
+ * Revision 5.1 1997/01/28 22:36:06 kans
+ * changed <GestaltEqu.h> to <Gestalt.h>
+ *
+ * Revision 5.0 1996/05/28 14:11:55 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.3 1996/04/30 21:17:40 epstein
+ * add back safety variables to avoid risk of stack corruption
+ *
+ * Revision 4.1 1996/04/30 16:06:54 kans
+ * UsingOpenTransport checks gestalt (JAE)
+ *
+ * Revision 4.0 1995/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.3 1995/05/17 17:52:34 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <ncbi.h>
+#include <ncbiwin.h>
+
+#include <MacTCP.h>
+#include <Files.h>
+#include <Errors.h>
+#include <Resources.h>
+#include <Memory.h>
+#include <Gestalt.h>
+#include <Folders.h>
+
+#ifdef COMP_METRO
+typedef OSErr (*OSErrProcPtr)();
+typedef Ptr (*PtrProcPtr)();
+typedef Boolean (*BooleanProcPtr)();
+typedef void (*voidProcPtr)();
+
+#endif
+
+typedef unsigned char uchar;
+
+extern Boolean ResLoad;
+
+#if GENERATINGPOWERPC
+#pragma options align=mac68k
+#endif
+
+
+/*
+ * Holds IP and LAP-specific configuration information. This is held in the
+ * 'ipln' configuration resource in either the MacTCP driver or the "MacTCP
+ * Prep" files.
+ */
+typedef struct IPConfig {
+ long version;
+ long flags;
+ long dfl_ip_addr;
+ long dfl_net_mask;
+ long dfl_broadcast_mask;
+ long dfl_gateway_addr;
+ b_8 server_lap_address[8];
+ long configIPAddr;
+ long configNetMask;
+ long dfl_dyn_low;
+ long dfl_dyn_high;
+ char dfl_zone[34]; /* ### */
+ Boolean load;
+ Boolean admin;
+ Boolean netLock;
+ Boolean subnetLock;
+ Boolean nodeLock;
+ Boolean filler1;
+ long activeLap;
+ long slot;
+ char filename[33]; /* ### */
+} IPConfig;
+
+
+/*
+ * LAPInfo is allocated during system start-up and holds all of the
+LAP-specific information.
+ */
+struct LAPInfo {
+ b_32 our_ip_addr; /* LAP's IP address =
+*/
+ b_32 our_net_mask; /* LAP's IP net-mask=
+ */
+ b_32 ip_broadcast_addr; /* IP's broadcast
+address */
+ IPConfig lc; /* copy of
+IP LAP configuration resource */
+ OSErrProcPtr lapInit; /* pointer to
+once-only LAP init routine */
+ OSErrProcPtr lapOpen; /* LAP open routine =
+*/
+ OSErrProcPtr lapClose; /* LAP close routine=
+ */
+ voidProcPtr lapUnload; /* LAP
+unload routine, undoes LapInit */
+ OSErrProcPtr lapAttach; /* LAP attach PH
+routine */
+ OSErrProcPtr lapDetach; /* LAP detach=
+ routine */
+ OSErrProcPtr lapOutput; /* LAP output=
+ routine */
+ OSErrProcPtr lapControl; /* LAP control
+routine */
+ voidProcPtr lapFault; /* LAP
+fault isolation routine */
+ OSErrProcPtr lapStatistics; /* LAP statistic reading
+routine */
+ voidProcPtr lapConfigure; /* LAP-specific
+configuration routines */
+ BooleanProcPtr lapProbe; /* send a
+LAP-specific address probe packet */
+ BooleanProcPtr lapRegister; /* register our IP address
+on the network */
+ voidProcPtr lapFindGateway; /* LAP-specific
+means of finding a gateway */
+ BooleanProcPtr lapGwyCheck; /* LAP-specific means of
+verifying gateway up */
+ /* IP parameters */
+ ip_addr dfl_dns_addr; /* address of DNS
+from config protocol */
+ Handle dnslHndl; /* handle
+to DNS configuration resource */
+ Ptr dnsCache; /*
+pointer to space allocated for dns cache */
+ long dnsCacheSize; /* size of cache
+allocated, in bytes */
+ /* LAP parameters */
+ long headerSize; /* LAP
+header space requirements */
+ long trailerSize; /* LAP trailer
+space requirements */
+ long outMaxPacketSize; /* size of maximum
+output packet */
+ long inMaxPacketSize; /* size of maximum
+input packet */
+ long maxDataSize; /* size of maximum
+data packet */
+ long numConnections; /* number of
+separate network connections */
+ unsigned long versionFlags; /* version number flags */
+ voidProcPtr ip_ph; /* pointer
+to IP's protocol handler */
+ Ptr ipGlobals; /*
+pointer to IP's A5 */
+ short link_unit; /* unit
+number of link driver */
+ Boolean addressConflict; /* TRUE if address
+conflict discovered */
+ long lapType; /* IP LAP
+hardware type number */
+ long lapAddrLength; /* size of LAP
+address field */
+ unsigned char *lapAddrPtr; /* pointer to LAP address
+field */
+ unsigned long reserved; /* MacTCP reserved
+field */
+};
+
+
+
+
+#if GENERATINGPOWERPC
+#pragma options align=reset
+#endif
+
+
+
+
+char * GetLAPType( void );
+static char * ParseLAPType(IPConfig **configH );
+static OSErr SearchFolderForRsrc( FSSpec *target, short vRefNum, long dirID,
+ OSType ftype, OSType fcrea, OSType rsrcType );
+
+
+//--------------------------------------------------------------------------
+// Returns the current LAP driver type
+// Note: We should fix this to search the control panels folder for any file
+// of the correct type containing a 'ipln' resource.
+//--------------------------------------------------------------------------
+
+Boolean UsingOpenTransport (void)
+
+{
+ OSErr err;
+ long gval;
+
+ /* gestaltOpenTpt is defined in OpenTransport.h, which is only
+ available in CodeWarrior at present.
+ */
+ /*
+ err = Gestalt (gestaltOpenTpt, &gval);
+ */
+ err = Gestalt ('otan', &gval);
+ if (err == noErr && gval != 0) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+char * GetLAPType( void )
+{
+ IPConfig **configH;
+ long responce;
+ char safety1[100];
+ FSSpec fspec;
+ char safety2[100];
+ short refNum = -1;
+ char *lapType = NULL;
+
+ if( Gestalt( 'mtcp', &responce ) != noErr )
+ return (UsingOpenTransport() ? "OpenTransport" : NULL);
+
+ // First check the MacTCP Prep file
+ if( FindFolder( kOnSystemDisk, kPreferencesFolderType, false,
+ &fspec.vRefNum, &fspec.parID ) != noErr )
+ goto try_mactcp_drvr;
+
+ if( SearchFolderForRsrc( &fspec, fspec.vRefNum, fspec.parID,
+ 'mtpp', 'mtcp', 'ipln' ) != noErr )
+ goto try_mactcp_drvr;
+
+ if( (refNum = FSpOpenResFile( &fspec, fsRdPerm )) == -1 )
+ goto try_mactcp_drvr;
+
+ configH = (IPConfig**) Get1IndResource( 'ipln', 1 );
+ if( configH != NULL && *configH != NULL ){
+ lapType = ParseLAPType( configH );
+ }
+ CloseResFile( refNum );
+
+ if( lapType != NULL )
+ return lapType;
+
+ // Otherwise check the MacTCP driver/control panel
+
+try_mactcp_drvr:
+ if( FindFolder( kOnSystemDisk, 'cntl', false,
+ &fspec.vRefNum, &fspec.parID ) != noErr )
+ goto exit;
+
+ if( SearchFolderForRsrc( &fspec, fspec.vRefNum, fspec.parID,
+ 'cdev', 'ztcp', 'ipln' ) != noErr )
+ goto exit;
+
+ if( (refNum = FSpOpenResFile( &fspec, fsRdPerm )) == -1 )
+ goto exit;
+
+ configH = (IPConfig**) Get1IndResource( 'ipln', 1 );
+ if( configH != NULL && *configH != NULL ){
+ lapType = ParseLAPType( configH );
+ }
+ CloseResFile( refNum );
+
+exit:
+ if(lapType == NULL)
+ return (UsingOpenTransport() ? "OpenTransport" : NULL);
+
+ return lapType;
+}
+
+
+
+//--------------------------------------------------------------------------
+// Takes a 'ipln' resource and tries to figure out which LAP driver we are
+// using.
+//--------------------------------------------------------------------------
+
+static char * ParseLAPType(IPConfig **configH )
+{
+ const IPConfig *ipc;
+ static char laptype[256];
+ uchar hs;
+
+ hs = HGetState( (Handle) configH );
+ HLock( (Handle) configH );
+ ipc = *configH;
+
+ // Check if MacTCP is using LocalTalk or Ethernet
+ if( ipc->activeLap == 128 || ipc->activeLap == 129 ){
+ if (ipc->activeLap == 128)
+ return "LocalTalk";
+ else
+ return "Ethernet";
+ }
+
+ memcpy(laptype, ipc->filename, ipc->filename[0] + 1);
+ p2cstr((unsigned char *)laptype);
+
+ return laptype;
+}
+
+
+
+//--------------------------------------------------------------------------
+// Search a folder for a file of a specific type and creator (specify 0L for
+// any) that contains a resource of a given type.
+// Returns a FSpec to that file.
+//--------------------------------------------------------------------------
+
+static OSErr
+SearchFolderForRsrc( FSSpec *target, short vRefNum, long dirID,
+ OSType ftype, OSType fcrea, OSType rsrcType )
+{
+ FSSpec fspec;
+ HParamBlockRec fi;
+ Handle rsrcH;
+ short refNum;
+ OSErr err;
+ Boolean oldResLoad;
+
+ err = fnfErr;
+#ifdef NEW_UNIVERSAL_HEADERS /* JAE */
+ oldResLoad = LMGetResLoad();
+#else
+ oldResLoad = /* ResLoad */ true;
+#endif /* NEW_UNIVERSAL_HEADERS */
+ SetResLoad( false );
+
+ fspec.vRefNum = vRefNum;
+ fspec.parID = dirID;
+
+ fi.fileParam.ioCompletion = NULL;
+ fi.fileParam.ioNamePtr = fspec.name;
+ fi.fileParam.ioVRefNum = vRefNum;
+ fi.fileParam.ioDirID = dirID;
+ fi.fileParam.ioFDirIndex = 1;
+
+ while( PBHGetFInfoSync( &fi ) == noErr )
+ {
+ // scan folder for resource files of specific type & creator
+ if( (fcrea == 0L || fi.fileParam.ioFlFndrInfo.fdCreator == fcrea)
+ && (ftype == 0L || fi.fileParam.ioFlFndrInfo.fdType == ftype) )
+ {
+ // found the conforming file, try to open it
+ if( (refNum=FSpOpenResFile(&fspec,fsRdPerm)) != -1 )
+ {
+ // see if a resource is there
+ rsrcH = GetIndResource( rsrcType, 1 );
+ CloseResFile( refNum );
+
+ // if there, return noErr
+ if( rsrcH != NULL ){
+ err = noErr;
+ *target = fspec;
+ break;
+ }
+ }
+ }
+ // check next file in folder
+ fi.fileParam.ioFDirIndex++;
+ fi.fileParam.ioDirID = dirID; // PBHGetFInfo() clobbers ioDirID
+ }
+ SetResLoad( oldResLoad );
+ return err;
+}
diff --git a/network/nsclilib/ni_msg.asn b/network/nsclilib/ni_msg.asn
new file mode 100644
index 00000000..d67ee117
--- /dev/null
+++ b/network/nsclilib/ni_msg.asn
@@ -0,0 +1,232 @@
+--$Revision: 6.0 $
+-- ===========================================================================
+--
+-- PUBLIC DOMAIN NOTICE
+-- National Center for Biotechnology Information
+--
+-- This software/database is a "United States Government Work" under the
+-- terms of the United States Copyright Act. It was written as part of
+-- the author's official duties as a United States Government employee and
+-- thus cannot be copyrighted. This software/database is freely available
+-- to the public for use. The National Library of Medicine and the U.S.
+-- Government have not placed any restriction on its use or reproduction.
+--
+-- Although all reasonable efforts have been taken to ensure the accuracy
+-- and reliability of the software and data, the NLM and the U.S.
+-- Government do not and cannot warrant the performance or results that
+-- may be obtained by using this software or data. The NLM and the U.S.
+-- Government disclaim all warranties, express or implied, including
+-- warranties of performance, merchantability or fitness for any particular
+-- purpose.
+--
+-- Please cite the author in any work or product based on this material.
+--
+-- ===========================================================================
+--
+-- File Name: ni_msg.asn
+--
+-- Author: Beatty, Gish, Epstein
+--
+-- Version Creation Date: 1/1/92
+--
+-- File Description:
+-- ASN.1 message header
+--
+-- Modifications:
+-- ==========================================================================
+-- Date Name Description of modification
+-- ======= ========== =====================================================
+-- 5/12/92 Epstein Added type to SVC-Entry
+--
+--
+-- ==========================================================================
+
+
+NCBI-MESSAGE DEFINITIONS ::=
+BEGIN
+
+EXPORTS SVC-Entry, RES-Entry, Toolset, Identity, Request, MSG-ACK, MSG-NACK, MSG-Login, MSG-SVC-List,
+ MSG-SVC-Request, MSG-SVC-Response, MSG-Cmd, MSG-Acct, MSG-Catalog, Message;
+
+SVC-Entry ::= SEQUENCE {
+ name VisibleString, -- name of service
+ minvers INTEGER, -- minimum legal version
+ maxvers INTEGER, -- maximum legal version
+ id INTEGER OPTIONAL, -- ID that is unique on host
+ priority INTEGER OPTIONAL, -- priority of service
+ group VisibleString OPTIONAL, -- group with access to service
+ description VisibleString OPTIONAL, -- description of service
+ types SET OF VisibleString OPTIONAL, -- types of allowed resources
+ priority-timeout INTEGER OPTIONAL, -- priority penalization timeout
+ priority-penalty INTEGER OPTIONAL, -- penalty exacted after timeout
+ encryption-supported BOOLEAN OPTIONAL, -- service supports encryption
+ tracking-period INTEGER OPTIONAL, -- time period (minutes) to track service
+ tracking-count INTEGER OPTIONAL -- # service requests during tracking-period from this IP
+
+}
+
+RES-Entry ::= SEQUENCE {
+ name VisibleString, -- name of resource
+ type VisibleString, -- type of resource
+ minvers INTEGER, -- minimum legal version
+ maxvers INTEGER, -- maximum legal version
+ id INTEGER OPTIONAL, -- ID that is unique on host
+ group VisibleString OPTIONAL, -- group with access to service
+ description VisibleString OPTIONAL -- description of service
+}
+
+Region-Descr ::= SEQUENCE {
+ region-name VisibleString, -- name describing region
+ priority-delta INTEGER OPTIONAL -- priority incentive for client
+}
+
+Toolset ::= SEQUENCE {
+ host VisibleString, -- name of host
+ motd VisibleString OPTIONAL, -- message of the day on host
+ services SET OF SVC-Entry OPTIONAL,
+ resources SET OF RES-Entry OPTIONAL,
+ regions SET OF Region-Descr OPTIONAL
+}
+
+Identity ::= SEQUENCE {
+ username VisibleString, -- kerberos principle
+ group VisibleString OPTIONAL, -- kerberos instance
+ domain VisibleString OPTIONAL -- kerberos realm
+}
+
+RSA-Pubkey ::= SEQUENCE {
+ bits INTEGER,
+ modulus OCTET STRING,
+ exponent OCTET STRING
+}
+
+Dispatcher-Info ::= SEQUENCE {
+ serial-no INTEGER, -- unique ID assoc w/disp list
+ is-alternate-list BOOLEAN, -- is this an alternate dispatcher list?
+ num-dispatchers INTEGER,
+ disp-list SEQUENCE OF VisibleString,
+ pub-key RSA-Pubkey OPTIONAL
+}
+
+Request ::= SEQUENCE {
+ address VisibleString OPTIONAL, -- client internet address
+ port INTEGER OPTIONAL, -- client contact port
+ svcentry SVC-Entry, -- service requested
+ resentry SET OF RES-Entry OPTIONAL -- resources requested
+}
+
+MSG-ACK ::= SEQUENCE {
+ seqno INTEGER, -- sequence number of the acked message
+ disp-info Dispatcher-Info OPTIONAL,
+ admin-info VisibleString OPTIONAL,
+ motd VisibleString OPTIONAL
+}
+
+MSG-NACK ::= SEQUENCE {
+ seqno INTEGER, -- sequence number of the nacked message
+ code INTEGER, -- exception code, (-1) means nonspecific error
+ reason VisibleString OPTIONAL , -- human-readable explanation
+ disp-info Dispatcher-Info OPTIONAL
+}
+
+MSG-Login ::= SEQUENCE {
+ seqno INTEGER, -- sequence number
+ uid Identity,
+ password VisibleString OPTIONAL, -- should be encrypted
+ disp-serial-no INTEGER OPTIONAL, -- unique ID assoc w/disp list
+ encryption-desired BOOLEAN OPTIONAL,
+ pub-key RSA-Pubkey OPTIONAL,
+ des-key OCTET STRING OPTIONAL, -- from ncbid only
+ connect-delay INTEGER OPTIONAL , -- connect delay when contacting Disp
+ server-port INTEGER OPTIONAL -- from ncbid only
+}
+
+MSG-SVC-List ::= SEQUENCE {
+ seqno INTEGER, -- sequence number
+ toollist Toolset, -- one set
+ knows-tracking BOOLEAN OPTIONAL -- aware of tracking-count/periods
+}
+
+MSG-SVC-Request ::= SEQUENCE {
+ seqno INTEGER, -- sequence number
+ conid INTEGER, -- connection number for client accounting
+ uid Identity, -- client user ID struct
+ request Request, -- client address and request
+ platform INTEGER OPTIONAL, -- client's platform
+ appl-id VisibleString OPTIONAL, -- identifies client application
+ des-key OCTET STRING OPTIONAL, -- DES key to be used for session (key is encrypted using RSA)
+ want-pre-response BOOLEAN OPTIONAL, -- If TRUE, requesting MSG-SVC-Pre-Response
+ server-ip INTEGER OPTIONAL, -- IP address of server machine
+ server-port INTEGER OPTIONAL, -- port on server machine
+ want-ticket BOOLEAN OPTIONAL, -- If TRUE, requesting SVC-Request containing ticket
+ ticket Ticket OPTIONAL
+}
+
+Ticket ::= SEQUENCE {
+ seqno INTEGER,
+ -- all fields that follow are encrypted using ncbid's DES key
+ confounding-rand-num OCTET STRING, -- used to confound forgery attempts
+ client-ip-1 OCTET STRING, -- ticket is valid from either of these 2 addrs
+ client-ip-2 OCTET STRING OPTIONAL,
+ server-ip OCTET STRING, -- this ticket is only valid at this server IP
+ client-des-key OCTET STRING OPTIONAL,
+ ticket-expiration OCTET STRING,
+ checksum OCTET STRING
+}
+
+
+MSG-SVC-Response ::= SEQUENCE {
+ seqno INTEGER, -- sequence number
+ request Request -- client address and request
+}
+
+MSG-SVC-Pre-Response ::= SEQUENCE {
+ seqno INTEGER, -- sequence number
+ server-ip INTEGER -- IP address of server machine
+}
+
+MSG-Cmd ::= SEQUENCE {
+ seqno INTEGER, -- sequence number
+ command INTEGER
+}
+
+MSG-Acct ::= SEQUENCE {
+ seqno INTEGER, -- sequence number
+ conid INTEGER, -- connection number of client
+ jobname VisibleString,
+ usertime INTEGER,
+ systemtime INTEGER
+}
+
+MSG-Catalog ::= SEQUENCE {
+ seqno INTEGER, -- sequence number
+ motd VisibleString OPTIONAL, -- message of the day
+ toollists SET OF Toolset OPTIONAL -- one set for each ncbid
+}
+
+MSG-Load-Status ::= SEQUENCE {
+ load REAL, -- current load on this machine
+ power REAL, -- power of this machine
+ light-thresh REAL, -- when load is below this value, machine is considered to be lightly-loaded
+ heavy-thresh REAL, -- when load is above this value, machine is considered to be over-loaded
+ job-penalty REAL -- penalty per outstanding job on this server
+}
+
+Message ::= CHOICE {
+ ack MSG-ACK,
+ nack MSG-NACK,
+ login MSG-Login,
+ svc-list MSG-SVC-List,
+ svc-request MSG-SVC-Request,
+ svc-response MSG-SVC-Response,
+ command MSG-Cmd,
+ acct MSG-Acct,
+ catalog MSG-Catalog,
+ svc-pre-response MSG-SVC-Pre-Response,
+ load-status MSG-Load-Status
+}
+
+END
+
+
+
diff --git a/network/nsclilib/ni_msg.c b/network/nsclilib/ni_msg.c
new file mode 100644
index 00000000..44bfa9be
--- /dev/null
+++ b/network/nsclilib/ni_msg.c
@@ -0,0 +1,4587 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_msg.c
+*
+* Author: Beatty, Gish, Epstein
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* This file consists mostly of functions for creating, destroying, reading,
+* and writing message structures. It also contains the high-level functions
+* for reading or writing a message, as well as the lowest-level functions
+* which are read, write, and error 'hooks' for the ASN library.
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 5/01/92 Epstein Added extensive in-line commentary, and removed all tabs
+* 5/01/92 Epstein Modified to support un-blocked reads, by storing state
+* information and returning to the caller.
+* 5/11/92 Epstein Changed MsgBuild() to free memory in the event of
+* an invalid message type; fixed MsgDestroy() to
+* return -1 rather than NULL (NULL is the wrong type);
+* added logic to allow the dispatcher to update the
+* CONID file when the value of "conid" is incremented
+* 6/18/92 Epstein Added AsnIoSetBufsize() for write socket, to improve
+* network throughput.
+* 6/22/92 Epstein Changed all NI_AsnRead() and NI_AsnWrite() error return
+* codes to be the negative of the absolute value of errno,
+* because errno's can be negative on Macintoshes.
+* 7/10/92 Epstein Changed MsgSaveData() to set the current index
+* (mh->cur_index) to match the number of queued bytes;
+* this avoids unintentional re-reading of queued data
+* unless a read fails.
+* 2/12/93 Epstein Add an argument to MsgMakeHandle() to indicate whether
+* or not a socket should be created.
+* 2/19/93 Epstein Add PC-NFS 4.0 support.
+* 2/24/93 Epstein Fix memory leak
+* 3/08/93 Epstein Add optional client platform to service request
+* 3/11/93 Epstein Add "is-alternate-list" boolean to dispatcher-list,
+* to make it easier for a dispatcher-monitor-client
+* to distinguish between primary and backup dispatchers.
+* 3/23/93 Epstein Change platform conditional-compilation to include
+* the NETP_INET_ prefix, add VMS/TGV support.
+* 4/02/93 Epstein Remember to initialize conid to a known value ... this
+* avoids clients connecting with all sorts of wild conid
+* values.
+* 4/02/93 Epstein Add preliminary WinSock support.
+* 4/13/93 Epstein Add subSet fields to toolset to support catalog
+* filtering by dispatcher.
+* 4/21/93 Schuler Removed (IoFuncType) typecast on calls to AsnIoNew()
+* in order to enable compile-time type checking.
+* 4/21/93 Schuler Changed implementation of NI_AsnNew(), NI_AsnWrite(), and
+* NI_ASNIOError() to use LIBCALLBACK calling convention.
+* 4/21/93 Epstein Fix MsgBuild() return error (was incorrectly returning
+* FALSE instead of NULL).
+* 5/07/93 Epstein Fixup NI_SetBlocking() and NI_SetNonBlocking(), which
+* had been backwards. Also add Wollongong (TWG) support,
+* and use INVALID_SOCKET #define, per WinSock spec.
+* 5/25/93 Epstein Add regional support, and add application ID to
+* service request.
+* 5/27/93 Epstein Provide separate error code for ASN.1 dynamic object
+* loader failure, try to do separate PeekMessage, etc.
+* code for WinSock in the never-ending battle to fix
+* scrollbar behavior under WinSock.
+* 5/28/93 Epstein Re-work Disable-vibrant code to use new pragmatic
+* "Gestalt" functions, rather than making explicit
+* calls into Vibrant. This decouples Network Services
+* from Vibrant.
+* 6/02/93 Epstein Fixup sys_errlist references to correctly use new
+* SOCK_INDEX_ERRNO macro, to accomodate yet another
+* WinSock peculiarity.
+* 6/07/93 Epstein Use new timer mechanism to support "hung timeout";
+* also add new function MsgSetTimeoutHooks().
+* Also add missing revision history, derived from
+* RCS file.
+* 6/09/93 Epstein Added activity hook to report network activity back
+* to an application.
+* 6/15/93 Epstein Fix long-standing WinSock scrolling problem, by changing
+* NI_poll_select() to refrain from processing
+* WM_LBUTTONUP messages. For some reason, reading these
+* messages off the queue and processing them resulted
+* in a failure to correctly interpret the WM_LBUTTONUP
+* message as an "end scrolling" message.
+* Also clean-up Windows compilation warnings.
+* 6/17/93 Epstein Temporarily change NI_SetNonBlocking() to provide
+* incorrect (blocking!) semantics for TWG. This must
+* be fixed at a later date.
+* 6/22/93 Epstein Support UCX, although NI_SetNonBlocking() and
+* NI_SetBlocking() are currently completely unsupported.
+* This should be fixed at a later date if it turns out
+* that UCX actually supports these features.
+* 8/09/93 Epstein Remove annoying cursor modification, except for NEWT,
+* where it may be necessary.
+*01/21/94 Schuler Calls to Yield() bracketed by #ifdef WIN61/#endif
+*01/28/94 Schuler Replaced "OS_MAC" with "NETP_INET_MACTCP"
+*01/28/94 Schuler Defined THIS_MODULE and THIS_FILE
+*02/14/94 Epstein Added encryption support
+*02/16/94 Epstein Replaced Gestalt calls with SetAppProperty()
+*02/24/94 Epstein Move des-key from dispinfo to login to allow ncbid
+* to send a DES key to dispatcher. Also performed some
+* cleanup.
+*06/08/94 Epstein Add messages needed for SOCKS support
+*06/15/94 Epstein Add parameter to MsgWrite(), and add server-ip to
+* service request, both to accomodate SOCKS.
+*12/06/94 Epstein Added connectDelay, adminInfo and motd field to
+* client<->Dispatcher communication. Also populated
+* the priority field in the Catalog.
+*12/21/94 Epstein Make use of new socket instrumentation
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_msg.c,v $
+* Revision 6.0 1997/08/25 18:39:01 madden
+* Revision changed to 6.0
+*
+* Revision 5.3 1997/07/01 19:12:55 vakatov
+* [WIN32] DLL'd "netcli.lib"
+*
+* Revision 5.2 1996/06/28 17:14:21 epstein
+* add job-penalty
+*
+ * Revision 5.1 1996/06/27 17:17:54 epstein
+ * add load-balancing
+ *
+ * Revision 5.0 1996/05/28 14:11:55 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.5 1996/04/30 16:06:54 kans
+ * UsingOpenTransport checks gestalt (JAE)
+ *
+ * Revision 4.4 1996/04/02 13:21:08 epstein
+ * avoid a rare, unexplained condition by zapping a file descriptor
+ *
+ * Revision 4.3 1995/11/28 16:55:14 kans
+ * changed return NULL to return FALSE
+ *
+ * Revision 4.2 1995/11/27 20:59:24 epstein
+ * add client support for direct-connection services
+ *
+ * Revision 4.0 95/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.37 1995/05/24 12:08:54 epstein
+ * add support for tracking of how many times a client IP has used a service within a time interval
+ *
+ * Revision 1.36 95/05/17 17:52:39 epstein
+ * add RCS log revision history
+ *
+*/
+
+extern char * g_nsclient_module;
+#define THIS_MODULE g_nsclient_module
+static char * _this_file = __FILE__;
+#define THIS_FILE _this_file
+
+#include <ncbi.h>
+#include "ni_msg.h"
+#include "ni_asn.h" /* produced by ASNTOOL */
+
+/* macros */
+#if defined(NETP_INET_NEWT) || defined(NETP_INET_WSOCK)
+/* cooperation may be required with Vibrant to avoid runaway scrollbars */
+#define DisabVibrant() { Nlm_SetAppProperty("disable_vibrant", "1"); SetHourGlass(); }
+#define EnabVibrant() { Nlm_RemoveAppProperty("disable_vibrant"); PopHourGlass(); }
+#else
+#define DisabVibrant()
+#define EnabVibrant()
+#endif /* NETP_INET_NEWT */
+
+static NIAckPtr readACK PROTO((void));
+static void writeACK PROTO((NIAckPtr ackp));
+static NINackPtr readNACK PROTO((void));
+static void writeNACK PROTO((NINackPtr nackp));
+static NILoginPtr readLOGIN PROTO ((void));
+static void writeLOGIN PROTO((NILoginPtr loginp));
+static NISvcListPtr readSVC_LIST PROTO ((void));
+static void writeSVC_LIST PROTO((NISvcListPtr svclistp));
+static NISvcReqPtr readSVC_REQUEST PROTO ((void));
+static void writeSVC_REQUEST PROTO((NISvcReqPtr svcreqp));
+static NISvcRespPtr readSVC_RESPONSE PROTO ((void));
+static void writeSVC_RESPONSE PROTO((NISvcRespPtr svcrespp));
+static NICmdPtr readCOMMAND PROTO ((void));
+static void writeCOMMAND PROTO((NICmdPtr cmdp));
+static NIPreRespPtr readPRE_RESPONSE PROTO ((void));
+static void writePRE_RESPONSE PROTO((NIPreRespPtr prp));
+
+extern NITicketPtr NI_DestroyTicket PROTO ((NITicketPtr));
+static NITicketPtr NI_ReadTicket PROTO ((void));
+static Boolean NI_WriteTicket PROTO ((NITicketPtr));
+
+static NIAcctPtr readACCT PROTO ((void));
+static void writeACCT PROTO((NIAcctPtr accp));
+static NICatalogPtr readCATALOG PROTO ((void));
+static void writeCATALOG PROTO((NICatalogPtr catp));
+
+static NIStatusPtr readSTATUS PROTO ((void));
+static void writeSTATUS PROTO((NIStatusPtr statp));
+
+static int readRequest PROTO ((ReqPtr rp));
+static void writeRequest PROTO((ReqPtr reqp));
+static int readUid PROTO ((NI_UidPtr uid));
+static void writeUid PROTO((NI_UidPtr uidp));
+static int readService PROTO ((NISvcPtr svcp));
+static void writeService PROTO((NISvcPtr svcp));
+static int readResource PROTO ((NIResPtr resp));
+static void writeResource PROTO((NIResPtr resp));
+static int readRegion PROTO ((NIRegionPtr regp));
+static void writeRegion PROTO((NIRegionPtr regp));
+static int readToolset PROTO ((NIToolsetPtr tsp));
+static void writeToolset PROTO((NIToolsetPtr tsp));
+static int readPubKey PROTO ((NIPubKeyPtr pubkey));
+static void writePubKey PROTO((NIPubKeyPtr pubkey));
+static int readDispInfo PROTO ((NIDispInfoPtr dip));
+static void writeDispInfo PROTO((NIDispInfoPtr dip));
+
+static Boolean InitMsg PROTO((void));
+static void WriteCleanup PROTO((CharPtr tmpbuf));
+static Boolean MsgHaveSavedData PROTO((MHandPtr mh));
+static void MsgSaveData PROTO((MHandPtr mh, CharPtr buf,
+ Uint2 len));
+static int MsgReadSavedData PROTO((MHandPtr mh,
+ CharPtr buf, Uint2 len));
+static void MsgFreeSavedData PROTO((MHandPtr mh));
+static void SetHourGlass PROTO((void));
+static void PopHourGlass PROTO((void));
+
+
+/* VARS */
+
+Uint4 conid = 1; /* globally unique connection ID counter */
+Jumpbuf ni_env; /* saved environment for LongJump (servers only) */
+
+static AsnTypePtr atp;
+static AsnIoPtr aip;
+
+
+
+/* FUNCTIONS */
+
+/******************************************************************************/
+/* */
+/* Functions for creating, destroying, reading, and writing message structures*/
+/* */
+/******************************************************************************/
+
+
+
+
+/************************************ ACK *************************************/
+
+NLM_EXTERN NIAckPtr NI_MakeMsgAck(void)
+{
+ NIAckPtr ap;
+
+ ap = (NIAckPtr) MemNew(sizeof(NIAck));
+ ap->seqno = 0;
+ ap->dispinfo = NULL;
+ ap->adminInfo = NULL;
+ ap->motd = NULL;
+ return ap;
+} /* NI_MakeMsgAck */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgAck(NIAckPtr mp)
+{
+ if (mp == NULL)
+ return 1;
+ if (mp->dispinfo != NULL)
+ {
+ NI_DestroyDispInfo(mp->dispinfo);
+ }
+ if (mp->adminInfo != NULL)
+ {
+ MemFree(mp->adminInfo);
+ }
+ if (mp->motd != NULL)
+ {
+ MemFree(mp->motd);
+ }
+ MemFree(mp);
+ return 0;
+} /* NI_MakeMsgAck */
+
+
+static NIAckPtr
+readACK(void)
+{
+ DataVal value;
+ NIAckPtr ackp;
+
+ ackp = NI_MakeMsgAck();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* seqno */
+ goto AckFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AckFail;
+ ackp->seqno = value.intvalue;
+ atp = AsnReadId(aip, amp, atp);
+ if (atp == MSG_ACK_disp_info) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AckFail;
+ ackp->dispinfo = NI_MakeDispInfo();
+ if (readDispInfo(ackp->dispinfo) < 0)
+ goto AckFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto AckFail;
+ }
+ if (atp == MSG_ACK_admin_info) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AckFail;
+ ackp->adminInfo = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto AckFail;
+ }
+ if (atp == MSG_ACK_motd) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AckFail;
+ ackp->motd = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto AckFail;
+ }
+ if (atp != MESSAGE_ack)
+ goto AckFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AckFail;
+ return ackp;
+
+ AckFail:
+ NI_DestroyMsgAck(ackp);
+ return NULL;
+} /* readACK */
+
+
+static void
+writeACK(NIAckPtr ackp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_ack);
+ value.intvalue = (Int4) ackp->seqno;
+ AsnWrite(aip, MSG_ACK_seqno, &value);
+ if (ackp->dispinfo != NULL) {
+ AsnStartStruct(aip, MSG_ACK_disp_info);
+ writeDispInfo(ackp->dispinfo);
+ AsnEndStruct(aip, MSG_ACK_disp_info);
+ }
+ if (ackp->adminInfo != NULL) {
+ value.ptrvalue = (Pointer) ackp->adminInfo;
+ AsnWrite(aip, MSG_ACK_admin_info, &value);
+ }
+ if (ackp->motd != NULL) {
+ value.ptrvalue = (Pointer) ackp->motd;
+ AsnWrite(aip, MSG_ACK_motd, &value);
+ }
+
+ AsnEndStruct(aip, MESSAGE_ack);
+} /* writeACK */
+
+
+/************************************ NACK ***********************************/
+
+NLM_EXTERN NINackPtr NI_MakeMsgNack(void)
+{
+ NINackPtr np;
+
+ np = (NINackPtr) MemNew(sizeof(NINack));
+ np->seqno = 0;
+ np->reason = NULL;
+ np->dispinfo = NULL;
+ return np;
+} /* NI_MakeMsgNack */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgNack(NINackPtr mp)
+{
+ if (mp == NULL)
+ return 1;
+ if (mp->reason != NULL)
+ MemFree(mp->reason);
+ if (mp->dispinfo != NULL)
+ NI_DestroyDispInfo(mp->dispinfo);
+ MemFree(mp);
+ return 0;
+} /* NI_DestroyMsgNack */
+
+
+static NINackPtr
+readNACK(void)
+{
+ DataVal value;
+ NINackPtr nackp;
+
+ nackp = NI_MakeMsgNack();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* seqno */
+ goto NackFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto NackFail;
+ nackp->seqno = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* code */
+ goto NackFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto NackFail;
+ nackp->code = (NI_Error) value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == MSG_NACK_reason) { /* reason */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto NackFail;
+ nackp->reason = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto NackFail;
+ }
+ if (atp == MSG_NACK_disp_info) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto NackFail;
+ nackp->dispinfo = NI_MakeDispInfo();
+ if (readDispInfo(nackp->dispinfo) < 0)
+ goto NackFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto NackFail;
+ }
+ if (atp != MESSAGE_nack)
+ goto NackFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto NackFail;
+ return nackp;
+
+ NackFail:
+ NI_DestroyMsgNack(nackp);
+ return NULL;
+} /* readNACK */
+
+
+static void
+writeNACK(NINackPtr nackp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_nack);
+ value.intvalue = (Int4) nackp->seqno;
+ AsnWrite(aip, MSG_NACK_seqno, &value);
+ value.intvalue = (Int4) nackp->code;
+ AsnWrite(aip, MSG_NACK_code, &value);
+
+ if (nackp->reason != NULL) {
+ value.ptrvalue = (Pointer) nackp->reason;
+ AsnWrite(aip, MSG_NACK_reason, &value);
+ }
+ if (nackp->dispinfo != NULL) {
+ AsnStartStruct(aip, MSG_NACK_disp_info);
+ writeDispInfo(nackp->dispinfo);
+ AsnEndStruct(aip, MSG_NACK_disp_info);
+ }
+ AsnEndStruct(aip, MESSAGE_nack);
+}
+
+
+/************************************ LOGIN ***********************************/
+
+NLM_EXTERN NILoginPtr NI_MakeMsgLogin(void)
+{
+ NILoginPtr lp;
+
+ lp = (NILoginPtr) MemNew(sizeof(NILogin));
+ lp->seqno = 0;
+ lp->uid = NI_MakeUid();
+ lp->password = NULL;
+ lp->dispserialno = -1;
+ lp->encryptionDesired = FALSE;
+ lp->pubKey = NULL;
+ lp->desKey = NULL;
+ lp->connectDelay = -1;
+ lp->server_port = 0;
+ return lp;
+} /* NI_MakeMsgLogin() */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgLogin(NILoginPtr lp)
+{
+ if (lp == NULL)
+ return 1;
+ if (lp->uid != NULL)
+ NI_DestroyUid(lp->uid);
+ if (lp->password != NULL)
+ MemFree(lp->password);
+ if (lp->pubKey != NULL)
+ NI_DestroyPubKey(lp->pubKey);
+ if (lp->desKey != NULL)
+ BSFree(lp->desKey);
+ MemFree(lp);
+ return 0;
+} /* NI_DestroyMsgLogin() */
+
+
+static NILoginPtr
+readLOGIN(void)
+{
+ DataVal value;
+ NILoginPtr loginp;
+
+ loginp = NI_MakeMsgLogin();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* seqno */
+ goto LoginFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+ loginp->seqno = value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_LOGIN_uid */
+ goto LoginFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+ if (readUid(loginp->uid) < 0)
+ goto LoginFail;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* password ? */
+ goto LoginFail;
+
+ if (atp == MSG_LOGIN_password) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+ loginp->password = (CharPtr) value.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* disp_serial_no ? */
+ goto LoginFail;
+ }
+
+ if (atp == MSG_LOGIN_disp_serial_no) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+ loginp->dispserialno = value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* encryption desired ? */
+ goto LoginFail;
+ }
+
+ if (atp == MSG_LOGIN_encryption_desired) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+ loginp->encryptionDesired = value.boolvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* pub_key ? */
+ goto LoginFail;
+
+ }
+
+ if (atp == MSG_LOGIN_pub_key) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+ loginp->pubKey = NI_MakePubKey();
+ if (readPubKey(loginp->pubKey) < 0)
+ goto LoginFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* des_key ? */
+ goto LoginFail;
+ }
+
+ if (atp == MSG_LOGIN_des_key) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+ loginp->desKey = (ByteStorePtr) value.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* connect_delay ? */
+ goto LoginFail;
+ }
+
+ if (atp == MSG_LOGIN_connect_delay) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+ loginp->connectDelay = value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* server_port ? */
+ goto LoginFail;
+ }
+
+ if (atp == MSG_LOGIN_server_port) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+
+ loginp->server_port = value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* last message ? */
+ goto LoginFail;
+ }
+ if (atp != MESSAGE_login)
+ goto LoginFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto LoginFail;
+ return loginp;
+
+ LoginFail:
+ NI_DestroyMsgLogin(loginp);
+ return NULL;
+} /* readLOGIN */
+
+
+static void
+writeLOGIN(NILoginPtr loginp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_login);
+ value.intvalue = (Int4) loginp->seqno;
+ AsnWrite(aip, MSG_LOGIN_seqno, &value);
+ AsnStartStruct(aip, MSG_LOGIN_uid);
+ writeUid(loginp->uid);
+ AsnEndStruct(aip, MSG_LOGIN_uid);
+
+ if (loginp->password != NULL) {
+ value.ptrvalue = (Pointer) loginp->password;
+ AsnWrite(aip, MSG_LOGIN_password, &value);
+ }
+ if (loginp->dispserialno >= 0) {
+ value.intvalue = loginp->dispserialno;
+ AsnWrite(aip, MSG_LOGIN_disp_serial_no, &value);
+ }
+ if (loginp->encryptionDesired) {
+ value.boolvalue = loginp->encryptionDesired;
+ AsnWrite(aip, MSG_LOGIN_encryption_desired, &value);
+ }
+ if (loginp->pubKey != NULL) {
+ AsnStartStruct(aip, MSG_LOGIN_pub_key);
+ writePubKey(loginp->pubKey);
+ AsnEndStruct(aip, MSG_LOGIN_pub_key);
+ }
+ if (loginp->desKey != NULL) {
+ value.ptrvalue = (Pointer) loginp->desKey;
+ AsnWrite(aip, MSG_LOGIN_des_key, &value);
+ }
+ if (loginp->connectDelay >= 0) {
+ value.intvalue = loginp->connectDelay;
+ AsnWrite(aip, MSG_LOGIN_connect_delay, &value);
+ }
+
+ if (loginp->server_port > 0) {
+ value.intvalue = loginp->server_port;
+ AsnWrite(aip, MSG_LOGIN_server_port, &value);
+ }
+
+
+ AsnEndStruct(aip, MESSAGE_login);
+} /* writeLOGIN */
+
+
+/************************************ SVC_LIST ********************************/
+
+NLM_EXTERN NISvcListPtr NI_MakeMsgSvclist(void)
+{
+ NISvcListPtr sp;
+
+ sp = (NISvcListPtr) MemNew(sizeof(NISvcList));
+ sp->seqno = 0;
+ sp->toolset = NI_MakeToolset();
+ sp->knowsTracking = FALSE;
+ return sp;
+} /* NI_MakeMsgSvclist */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgSvclist(NISvcListPtr sp)
+{
+ if (sp == NULL)
+ return 1;
+ if (sp->toolset != NULL)
+ NI_DestroyToolset(sp->toolset);
+ MemFree(sp);
+ return 0;
+} /* NI_DestroyMsgSvclist */
+
+
+static NISvcListPtr
+readSVC_LIST(void)
+{
+ DataVal value;
+ NISvcListPtr svclistp;
+
+ svclistp = NI_MakeMsgSvclist();
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_SVC_LIST_seqno */
+ goto SvcListFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcListFail;
+ svclistp->seqno = value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_SVC_LIST_toollist */
+ goto SvcListFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcListFail;
+ if (readToolset(svclistp->toolset) < 0)
+ goto SvcListFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto SvcListFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcListFail;
+
+ if (atp == MSG_SVC_LIST_knows_tracking)
+ {
+ svclistp->knowsTracking = value.boolvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto SvcListFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcListFail;
+ }
+
+ if (atp != MESSAGE_svc_list)
+ goto SvcListFail;
+ return svclistp;
+
+ SvcListFail:
+ NI_DestroyMsgSvclist(svclistp);
+ return NULL;
+} /* readSVC_LIST */
+
+
+static void
+writeSVC_LIST(NISvcListPtr svclistp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_svc_list);
+ value.intvalue = (Int4) svclistp->seqno;
+ AsnWrite(aip, MSG_SVC_LIST_seqno, &value);
+
+ AsnStartStruct(aip, MSG_SVC_LIST_toollist);
+ writeToolset(svclistp->toolset);
+ AsnEndStruct(aip, MSG_SVC_LIST_toollist);
+ if (svclistp->knowsTracking)
+ {
+ value.boolvalue = svclistp->knowsTracking;
+ AsnWrite(aip, MSG_SVC_LIST_knows_tracking, &value);
+ }
+
+ AsnEndStruct(aip, MESSAGE_svc_list);
+} /* writeSVC_LIST */
+
+
+/************************************ SVC_REQUEST *****************************/
+
+NLM_EXTERN NISvcReqPtr NI_MakeMsgSvcreq(void)
+{
+ NISvcReqPtr sp;
+
+ sp = (NISvcReqPtr) MemNew(sizeof(NISvcReq));
+ sp->seqno = 0;
+ sp->uid = NI_MakeUid();
+ sp->request = NI_MakeRequest();
+ sp->platform = NI_PLATFORM_UNKNOWN;
+ sp->applId = NULL;
+ sp->desKey = NULL;
+ sp->wantPreResponse = FALSE;
+ sp->server_ip = 0;
+ sp->server_port = 0;
+ sp->want_ticket = FALSE;
+ sp->ticket = NULL;
+ return sp;
+} /* NI_MakeMsgSvcreq() */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgSvcreq(NISvcReqPtr sp)
+{
+ if (sp == NULL)
+ return 1;
+ if (sp->uid != NULL)
+ NI_DestroyUid(sp->uid);
+ if (sp->request != NULL)
+ NI_DestroyRequest(sp->request);
+ if (sp->applId != NULL)
+ MemFree(sp->applId);
+ if (sp->desKey != NULL)
+ BSFree (sp->desKey);
+ if (sp->ticket != NULL)
+ NI_DestroyTicket (sp->ticket);
+ MemFree(sp);
+ return 0;
+} /* NI_DestroyMsgSvcreq() */
+
+
+static NISvcReqPtr
+readSVC_REQUEST(void)
+{
+ DataVal value;
+ NISvcReqPtr svcreqp;
+
+ svcreqp = NI_MakeMsgSvcreq();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_SVC_REQUEST_seqno */
+ goto SvcReqFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ svcreqp->seqno = value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_SVC_REQUEST_conid */
+ goto SvcReqFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ svcreqp->conid = value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_SVC_REQUEST_uid */
+ goto SvcReqFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ if (readUid(svcreqp->uid) < 0)
+ goto SvcReqFail;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_SVC_REQUEST_request */
+ goto SvcReqFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ if (readRequest(svcreqp->request) < 0)
+ goto SvcReqFail;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == MSG_SVC_REQUEST_platform) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ svcreqp->platform = (Uint4) value.intvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp == MSG_SVC_REQUEST_appl_id) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ svcreqp->applId = (CharPtr) value.ptrvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp == MSG_SVC_REQUEST_des_key) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ svcreqp->desKey = (ByteStorePtr) value.ptrvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp == SVC_REQUEST_want_pre_response) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ svcreqp->wantPreResponse = value.boolvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+
+ if (atp == MSG_SVC_REQUEST_server_ip) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ svcreqp->server_ip = value.intvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+ if (atp == MSG_SVC_REQUEST_server_port) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ svcreqp->server_port = value.intvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+ if (atp == MSG_SVC_REQUEST_want_ticket) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ svcreqp->want_ticket = value.boolvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+ if (svcreqp->want_ticket) {
+
+ if (atp == MSG_SVC_REQUEST_ticket) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ if((svcreqp->ticket = NI_ReadTicket()) == 0)
+ goto SvcReqFail;
+ atp = AsnReadId(aip, amp, atp);
+ }
+ }
+
+ if (atp != MESSAGE_svc_request)
+ goto SvcReqFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcReqFail;
+ return svcreqp;
+
+ SvcReqFail:
+ NI_DestroyMsgSvcreq(svcreqp);
+ return NULL;
+} /* readSVC_REQUEST */
+
+
+static void
+writeSVC_REQUEST(NISvcReqPtr svcreqp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_svc_request);
+ value.intvalue = (Int4) svcreqp->seqno;
+ AsnWrite(aip, MSG_SVC_REQUEST_seqno, &value);
+ value.intvalue = (Int4) svcreqp->conid;
+ AsnWrite(aip, MSG_SVC_REQUEST_conid, &value);
+ AsnStartStruct(aip, MSG_SVC_REQUEST_uid);
+ writeUid(svcreqp->uid);
+ AsnEndStruct(aip, MSG_SVC_REQUEST_uid);
+ AsnStartStruct(aip, MSG_SVC_REQUEST_request);
+ writeRequest(svcreqp->request);
+ AsnEndStruct(aip, MSG_SVC_REQUEST_request);
+ value.intvalue = (Int4) svcreqp->platform;
+ AsnWrite(aip, MSG_SVC_REQUEST_platform, &value);
+
+ if (svcreqp->applId != NULL)
+ {
+ value.ptrvalue = (Pointer) svcreqp->applId;
+ AsnWrite(aip, MSG_SVC_REQUEST_appl_id, &value);
+ }
+
+ if (svcreqp->desKey != NULL)
+ {
+ value.ptrvalue = (Pointer) svcreqp->desKey;
+ AsnWrite(aip, MSG_SVC_REQUEST_des_key, &value);
+ }
+
+ if (svcreqp->wantPreResponse)
+ {
+ value.boolvalue = svcreqp->wantPreResponse;
+ AsnWrite(aip, SVC_REQUEST_want_pre_response, &value);
+ }
+
+ if (svcreqp->server_ip != 0)
+ {
+ value.intvalue = svcreqp->server_ip;
+ AsnWrite(aip, MSG_SVC_REQUEST_server_ip, &value);
+ }
+
+ if (svcreqp->server_port != 0)
+ {
+ value.intvalue = svcreqp->server_port;
+ AsnWrite(aip, MSG_SVC_REQUEST_server_port, &value);
+ }
+
+ if (svcreqp->want_ticket) {
+
+ value.boolvalue = svcreqp->want_ticket;
+ AsnWrite(aip, MSG_SVC_REQUEST_want_ticket, &value);
+
+ if (svcreqp->ticket != NULL) {
+ AsnStartStruct(aip, MSG_SVC_REQUEST_ticket);
+ NI_WriteTicket(svcreqp->ticket);
+ AsnEndStruct(aip, MSG_SVC_REQUEST_ticket);
+ }
+ }
+ AsnEndStruct(aip, MESSAGE_svc_request);
+} /* writeSVC_REQUEST */
+
+/********************************* TICKET *************************************/
+
+NLM_EXTERN NITicketPtr NI_MakeTicket(void)
+{
+ NITicketPtr ptr = MemNew((size_t) sizeof(NITicket));
+ return ptr;
+}
+
+extern NITicketPtr NI_DestroyTicket(NITicketPtr ptr)
+{
+ if (ptr == NULL) {
+ return NULL;
+ }
+ BSFree(ptr -> confounding_rand_num);
+ BSFree(ptr -> client_ip_1);
+ BSFree(ptr -> client_ip_2);
+ BSFree(ptr -> server_ip);
+ BSFree(ptr -> client_des_key);
+ BSFree(ptr -> ticket_expiration);
+ BSFree(ptr -> checksum);
+ return MemFree(ptr);
+}
+
+static NITicketPtr
+NI_ReadTicket(void)
+{
+ DataVal av;
+ NITicketPtr ptr;
+ ptr = NI_MakeTicket();
+
+ if ((atp = AsnReadId(aip,amp, atp)) == NULL)
+ goto TicketFail;
+
+ if (atp == TICKET_seqno) {
+ if ( AsnReadVal(aip, atp, &av) < 0) {
+ goto TicketFail;
+ }
+ ptr -> seqno = av.intvalue;
+ if ((atp = AsnReadId(aip,amp, atp)) == NULL)
+ goto TicketFail;
+ }
+ if (atp == TICKET_confounding_rand_num) {
+ if ( AsnReadVal(aip, atp, &av) < 0) {
+ goto TicketFail;
+ }
+ ptr -> confounding_rand_num = (ByteStorePtr) av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TICKET_client_ip_1) {
+ if ( AsnReadVal(aip, atp, &av) < 0) {
+ goto TicketFail;
+ }
+ ptr -> client_ip_1 = (ByteStorePtr) av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TICKET_client_ip_2) {
+ if ( AsnReadVal(aip, atp, &av) < 0) {
+ goto TicketFail;
+ }
+ ptr -> client_ip_2 = (ByteStorePtr) av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TICKET_server_ip) {
+ if ( AsnReadVal(aip, atp, &av) < 0) {
+ goto TicketFail;
+ }
+ ptr -> server_ip = (ByteStorePtr) av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TICKET_client_des_key) {
+ if ( AsnReadVal(aip, atp, &av) < 0) {
+ goto TicketFail;
+ }
+ ptr -> client_des_key = (ByteStorePtr) av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TICKET_ticket_expiration) {
+ if ( AsnReadVal(aip, atp, &av) < 0) {
+ goto TicketFail;
+ }
+ ptr -> ticket_expiration = (ByteStorePtr) av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TICKET_checksum) {
+ if ( AsnReadVal(aip, atp, &av) < 0) {
+ goto TicketFail;
+ }
+ ptr -> checksum = (ByteStorePtr) av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) < 0) {
+ goto TicketFail;
+ }
+ /* end struct */
+
+ return ptr;
+
+TicketFail:
+
+ NI_DestroyTicket(ptr);
+ return NULL;
+}
+
+static Boolean
+NI_WriteTicket(NITicketPtr ptr)
+{
+ DataVal av;
+ Boolean retval = FALSE;
+
+ av.intvalue = ptr -> seqno;
+ retval = AsnWrite(aip, TICKET_seqno, &av);
+ if (ptr -> confounding_rand_num != NULL) {
+ av.ptrvalue = (Pointer) ptr -> confounding_rand_num;
+ retval = AsnWrite(aip, TICKET_confounding_rand_num, &av);
+ }
+ if (ptr -> client_ip_1 != NULL) {
+ av.ptrvalue = (Pointer) ptr -> client_ip_1;
+ retval = AsnWrite(aip, TICKET_client_ip_1, &av);
+ }
+ if (ptr -> client_ip_2 != NULL) {
+ av.ptrvalue = (Pointer) ptr -> client_ip_2;
+ retval = AsnWrite(aip, TICKET_client_ip_2, &av);
+ }
+ if (ptr -> server_ip != NULL) {
+ av.ptrvalue = (Pointer) ptr -> server_ip;
+ retval = AsnWrite(aip, TICKET_server_ip, &av);
+ }
+ if (ptr -> client_des_key != NULL) {
+ av.ptrvalue = (Pointer) ptr -> client_des_key;
+ retval = AsnWrite(aip, TICKET_client_des_key, &av);
+ }
+ if (ptr -> ticket_expiration != NULL) {
+ av.ptrvalue = (Pointer) ptr -> ticket_expiration;
+ retval = AsnWrite(aip, TICKET_ticket_expiration, &av);
+ }
+ if (ptr -> checksum != NULL) {
+ av.ptrvalue = (Pointer) ptr -> checksum;
+ retval = AsnWrite(aip, TICKET_checksum, &av);
+ }
+
+ if (!retval)
+ goto TicketFail;
+ return retval;
+
+TicketFail:
+
+ NI_DestroyTicket(ptr);
+ return FALSE;
+
+}
+
+
+
+/********************************* SVC_RESPONSE *******************************/
+
+NLM_EXTERN NISvcRespPtr NI_MakeMsgSvcresp(void)
+{
+ NISvcRespPtr sp;
+
+ sp = (NISvcRespPtr) MemNew(sizeof(NISvcResp));
+ sp->seqno = 0;
+ sp->request = NI_MakeRequest();
+ return sp;
+} /* NI_MakeMsgSvcresp() */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgSvcresp(NISvcRespPtr sp)
+{
+ if (sp == NULL)
+ return 1;
+ if (sp->request != NULL)
+ NI_DestroyRequest(sp->request);
+ MemFree(sp);
+ return 0;
+} /* NI_DestroyMsgSvcresp() */
+
+
+static NISvcRespPtr
+readSVC_RESPONSE(void)
+{
+ DataVal value;
+ NISvcRespPtr svcrespp;
+
+ svcrespp = NI_MakeMsgSvcresp();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_SVC_RESPONSE_seqno */
+ goto SvcRespFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcRespFail;
+ svcrespp->seqno = value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_SVC_RESPONSE_request */
+ goto SvcRespFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcRespFail;
+ if (readRequest(svcrespp->request) < 0)
+ goto SvcRespFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_SVC_RESPONSE_request */
+ goto SvcRespFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto SvcRespFail;
+
+ if (atp != MESSAGE_svc_response)
+ goto SvcRespFail;
+ return svcrespp;
+
+ SvcRespFail:
+ NI_DestroyMsgSvcresp(svcrespp);
+ return NULL;
+} /* readSVC_RESPONSE */
+
+
+static void
+writeSVC_RESPONSE(NISvcRespPtr svcrespp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_svc_response);
+ value.intvalue = (Int4) svcrespp->seqno;
+ AsnWrite(aip, MSG_SVC_RESPONSE_seqno, &value);
+ AsnStartStruct(aip, MSG_SVC_RESPONSE_request);
+ writeRequest(svcrespp->request);
+ AsnEndStruct(aip, MSG_SVC_RESPONSE_request);
+ AsnEndStruct(aip, MESSAGE_svc_response);
+} /* writeSVC_RESPONSE */
+
+
+/************************************ COMMAND *********************************/
+
+NLM_EXTERN NICmdPtr NI_MakeMsgCmd(void)
+{
+ NICmdPtr cp;
+
+ cp = (NICmdPtr) MemNew(sizeof(NICmd));
+ cp->seqno = 0;
+ return cp;
+} /* NI_MakeMsgCmd() */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgCmd(NICmdPtr cp)
+{
+ if (cp == NULL)
+ return 1;
+ MemFree(cp);
+ return 0;
+} /* NI_DestroyMsgCmd() */
+
+
+static NICmdPtr
+readCOMMAND(void)
+{
+ DataVal value;
+ NICmdPtr cmdp;
+
+ cmdp = NI_MakeMsgCmd();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* seqno */
+ goto CmdFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto CmdFail;
+ cmdp->seqno = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* command */
+ goto CmdFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto CmdFail;
+ cmdp->code = (MsgCommand) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) != MESSAGE_command)
+ goto CmdFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto CmdFail;
+ return cmdp;
+
+ CmdFail:
+ NI_DestroyMsgCmd(cmdp);
+ return NULL;
+} /* readCOMMAND */
+
+
+static void
+writeCOMMAND(NICmdPtr cmdp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_command);
+ value.intvalue = (Int4) cmdp->seqno;
+ AsnWrite(aip, MSG_CMD_seqno, &value);
+ value.intvalue = (Int4) cmdp->code;
+ AsnWrite(aip, MSG_CMD_command, &value);
+ AsnEndStruct(aip, MESSAGE_command);
+} /* writeCOMMAND */
+
+
+/************************************ PRE-RESPONSE *********************************/
+
+NLM_EXTERN NIPreRespPtr NI_MakeMsgPreResp(void)
+{
+ NIPreRespPtr cp;
+
+ cp = (NIPreRespPtr) MemNew(sizeof(NIPreResp));
+ cp->seqno = 0;
+ return cp;
+} /* NI_MakeMsgPreResp() */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgPreResp(NIPreRespPtr cp)
+{
+ if (cp == NULL)
+ return 1;
+ MemFree(cp);
+ return 0;
+} /* NI_DestroyMsgPreResp() */
+
+
+static NIPreRespPtr
+readPRE_RESPONSE(void)
+{
+ DataVal value;
+ NIPreRespPtr prp;
+
+ prp = NI_MakeMsgPreResp();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* seqno */
+ goto PrFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto PrFail;
+ prp->seqno = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* server IP */
+ goto PrFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto PrFail;
+ prp->server_ip = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) != MESSAGE_svc_pre_response)
+ goto PrFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto PrFail;
+ return prp;
+
+ PrFail:
+ NI_DestroyMsgPreResp(prp);
+ return NULL;
+} /* readPRE_RESPONSE */
+
+
+static void
+writePRE_RESPONSE(NIPreRespPtr prp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_svc_pre_response);
+ value.intvalue = (Int4) prp->seqno;
+ AsnWrite(aip, MSG_SVC_PRE_RESPONSE_seqno, &value);
+ value.intvalue = (Int4) prp->server_ip;
+ AsnWrite(aip, MSG_SVC_PRE_RESPONSE_server_ip, &value);
+ AsnEndStruct(aip, MESSAGE_svc_pre_response);
+} /* writePRE_RESPONSE */
+
+/************************************ ACCT ************************************/
+
+NLM_EXTERN NIAcctPtr NI_MakeMsgAcct(void)
+{
+ NIAcctPtr ap;
+
+ ap = (NIAcctPtr) MemNew(sizeof(NIAcct));
+ ap->seqno = 0;
+ ap->jobname = NULL;
+ return ap;
+} /* NI_MakeMsgAcct() */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgAcct(NIAcctPtr ap)
+{
+ if (ap == NULL)
+ return 1;
+ if (ap->jobname != NULL)
+ MemFree(ap->jobname);
+ MemFree(ap);
+ return 0;
+} /* NI_DestroyMsgAcct() */
+
+
+static NIAcctPtr
+readACCT(void)
+{
+ DataVal value;
+ NIAcctPtr accp;
+
+ accp = NI_MakeMsgAcct();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* seqno */
+ goto AcctFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AcctFail;
+ accp->seqno = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* conid */
+ goto AcctFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AcctFail;
+ accp->conid = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* jobname */
+ goto AcctFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AcctFail;
+ accp->jobname = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* usertime */
+ goto AcctFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AcctFail;
+ accp->usertime = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* systemtime */
+ goto AcctFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AcctFail;
+ accp->systemtime = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) != MESSAGE_acct)
+ goto AcctFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto AcctFail;
+ return accp;
+
+ AcctFail:
+ NI_DestroyMsgAcct(accp);
+ return NULL;
+} /* NIreadACCT */
+
+
+static void
+writeACCT(NIAcctPtr accp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_acct);
+ value.intvalue = (Int4) accp->seqno;
+ AsnWrite(aip, MSG_ACCT_seqno, &value);
+ value.intvalue = (Int4) accp->conid;
+ AsnWrite(aip, MSG_ACCT_conid, &value);
+ value.ptrvalue = (Pointer) accp->jobname;
+ AsnWrite(aip, MSG_ACCT_jobname, &value);
+ value.intvalue = (Int4) accp->usertime;
+ AsnWrite(aip, MSG_ACCT_usertime, &value);
+ value.intvalue = (Int4) accp->systemtime;
+ AsnWrite(aip, MSG_ACCT_systemtime, &value);
+ AsnEndStruct(aip, MESSAGE_acct);
+} /* NIwriteACCT */
+
+
+/************************************ CATALOG *********************************/
+
+NLM_EXTERN NICatalogPtr NI_MakeMsgCatalog(void)
+{
+ NICatalogPtr cp;
+
+ cp = (NICatalogPtr) MemNew(sizeof(NICatalog));
+ cp->motd = NULL;
+ cp->toolsetL = NULL;
+ return cp;
+} /* NI_MakeCatalog */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgCatalog(NICatalogPtr cp)
+{
+ NodePtr np;
+
+
+ if (cp == NULL)
+ return 1;
+ if (cp->motd != NULL)
+ MemFree(cp->motd);
+ if ((np = cp->toolsetL) != NULL) {
+ do {
+ NI_DestroyToolset((NIToolsetPtr) np->elem);
+ np = ListDelete(np);
+ } while (np != NULL);
+ }
+ MemFree(cp);
+ return 0;
+} /* NI_DestroyMsgCatalog */
+
+
+static NICatalogPtr
+readCATALOG(void)
+{
+ DataVal value;
+ NICatalogPtr catp;
+ NIToolsetPtr tsp;
+
+ catp = NI_MakeMsgCatalog();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_CATALOG_seqno */
+ goto CatalogFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto CatalogFail;
+ catp->seqno = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto CatalogFail;
+
+ if (atp == MSG_CATALOG_motd) { /* MSG_CATALOG_motd ? */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto CatalogFail;
+ catp->motd = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto CatalogFail;
+ }
+
+ if (atp == MSG_CATALOG_toollists) { /* MSG_CATALOG_toollists ? */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto CatalogFail;
+ while ((atp = AsnReadId(aip, amp, atp)) == MSG_CATALOG_toollists_E) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto CatalogFail;
+ tsp = NI_MakeToolset();
+ if (readToolset(tsp) < 0)
+ goto CatalogFail;
+ ListBreakRing(tsp->services);
+ ListBreakRing(tsp->resources);
+ catp->toolsetL = ListInsert((VoidPtr) tsp, catp->toolsetL); /* end of list */
+ }
+ if (atp == NULL)
+ goto CatalogFail;
+ catp->toolsetL = catp->toolsetL->next; /* point to first */
+ if (AsnReadVal(aip, atp, &value) < 0) /* MSG_CATALOG_toollists */
+ goto CatalogFail;
+ ListBreakRing(catp->toolsetL);
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto CatalogFail;
+ }
+
+ if (atp != MESSAGE_catalog)
+ goto CatalogFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto CatalogFail;
+ return catp;
+
+ CatalogFail:
+ NI_DestroyMsgCatalog(catp);
+ return NULL;
+} /* readCATALOG */
+
+
+static void
+writeCATALOG(NICatalogPtr catp)
+{
+ DataVal value;
+ NodePtr np, lastnode;
+
+ AsnStartStruct(aip, MESSAGE_catalog);
+ value.intvalue = (Int4) catp->seqno;
+ AsnWrite(aip, MSG_CATALOG_seqno, &value);
+ if (catp->motd != NULL) {
+ value.ptrvalue = (Pointer) catp->motd;
+ AsnWrite(aip, MSG_CATALOG_motd, &value);
+ }
+
+ np = catp->toolsetL;
+ if (np != NULL) {
+ AsnStartStruct(aip, MSG_CATALOG_toollists);
+ lastnode = np->last;
+ while (np != NULL) {
+ AsnStartStruct(aip, MSG_CATALOG_toollists_E);
+ writeToolset((NIToolsetPtr) np->elem);
+ AsnEndStruct(aip, MSG_CATALOG_toollists_E);
+ if (np == lastnode)
+ break;
+ np = np->next;
+ }
+ AsnEndStruct(aip, MSG_CATALOG_toollists);
+ }
+
+ AsnEndStruct(aip, MESSAGE_catalog);
+} /* writeCatalog */
+
+
+/************************************ LOAD STATUS *********************************/
+
+NLM_EXTERN NIStatusPtr NI_MakeMsgStatus(void)
+{
+ NIStatusPtr sp;
+
+ sp = (NIStatusPtr) MemNew(sizeof(NIStatus));
+ sp->load = 0.0;
+ sp->power = 0.0;
+ sp->lightThresh = 0.0;
+ sp->heavyThresh = 0.0;
+ sp->jobPenalty = 0.0;
+ return sp;
+} /* NI_MakeStatus */
+
+
+NLM_EXTERN Int2 NI_DestroyMsgStatus(NIStatusPtr sp)
+{
+ NodePtr np;
+
+
+ if (sp == NULL)
+ return 1;
+ MemFree(sp);
+ return 0;
+} /* NI_DestroyMsgStatus */
+
+static NIStatusPtr
+readSTATUS(void)
+{
+ DataVal value;
+ NIStatusPtr statusp;
+
+ statusp = NI_MakeMsgStatus();
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_LOAD_STATUS_load */
+ goto StatusFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto StatusFail;
+ statusp->load = value.realvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_LOAD_STATUS_power */
+ goto StatusFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto StatusFail;
+ statusp->power = value.realvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_LOAD_STATUS_light_thresh */
+ goto StatusFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto StatusFail;
+ statusp->lightThresh = value.realvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_LOAD_STATUS_heavy_thresh */
+ goto StatusFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto StatusFail;
+ statusp->heavyThresh = value.realvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* MSG_LOAD_STATUS_job_penalty */
+ goto StatusFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto StatusFail;
+ statusp->jobPenalty = value.realvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto StatusFail;
+
+ if (atp != MESSAGE_load_status)
+ goto StatusFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto StatusFail;
+ return statusp;
+
+ StatusFail:
+ NI_DestroyMsgStatus(statusp);
+ return NULL;
+} /* readSTATUS */
+
+
+static void
+writeSTATUS(NIStatusPtr statp)
+{
+ DataVal value;
+
+ AsnStartStruct(aip, MESSAGE_load_status);
+
+ value.realvalue = (FloatLo) statp->load;
+ AsnWrite(aip, MSG_LOAD_STATUS_load, &value);
+ value.realvalue = (FloatLo) statp->power;
+ AsnWrite(aip, MSG_LOAD_STATUS_power, &value);
+ value.realvalue = (FloatLo) statp->lightThresh;
+ AsnWrite(aip, MSG_LOAD_STATUS_light_thresh, &value);
+ value.realvalue = (FloatLo) statp->heavyThresh;
+ AsnWrite(aip, MSG_LOAD_STATUS_heavy_thresh, &value);
+ value.realvalue = (FloatLo) statp->jobPenalty;
+ AsnWrite(aip, MSG_LOAD_STATUS_job_penalty, &value);
+
+ AsnEndStruct(aip, MESSAGE_load_status);
+} /* writeStatus */
+
+
+/************************************ REQUEST *********************************/
+
+NLM_EXTERN ReqPtr NI_MakeRequest(void)
+{
+ ReqPtr rp;
+
+ rp = (ReqPtr) MemNew(sizeof(Request));
+ rp->clientAddr = NULL;
+ rp->clientPort = 0;
+ rp->service = NI_MakeService();
+ rp->resourceL = NULL;
+ return(rp);
+} /* NI_MakeRequest() */
+
+
+NLM_EXTERN Int2 NI_DestroyRequest(ReqPtr rp)
+{
+ if (rp == NULL)
+ return 1;
+ if (rp->clientAddr != NULL)
+ MemFree(rp->clientAddr);
+ if (rp->service != NULL)
+ NI_DestroyService(rp->service);
+ if (rp->resourceL != NULL) { /* destroy list of nodes and resources they point to */
+ while (rp->resourceL != NULL) {
+ NI_DestroyResource((NIResPtr)rp->resourceL->elem);
+ rp->resourceL = ListDelete(rp->resourceL);
+ }
+ }
+ MemFree(rp);
+ return 0;
+} /* NI_DestroyRequest() */
+
+
+static int
+readRequest(ReqPtr reqp)
+{
+ DataVal value;
+ NIResPtr resp;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto RequestFail;
+ if (atp == REQUEST_address) { /* REQUEST_address ? */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto RequestFail;
+ reqp->clientAddr = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto RequestFail;
+ }
+ if (atp == REQUEST_port) { /* REQUEST_port ? */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto RequestFail;
+ reqp->clientPort = (Uint2) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto RequestFail;
+ }
+ if (AsnReadVal(aip, atp, &value) < 0) /* REQUEST_svcentry */
+ goto RequestFail;
+ if (readService(reqp->service) < 0)
+ goto RequestFail;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == REQUEST_resentry) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto RequestFail;
+
+ while ((atp = AsnReadId(aip, amp, atp)) == REQUEST_resentry_E) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto RequestFail;
+ resp = NI_MakeResource();
+ if (readResource(resp) < 0) {
+ NI_DestroyResource(resp);
+ goto RequestFail;
+ }
+ reqp->resourceL = ListInsert((VoidPtr) resp, reqp->resourceL); /* end of list */
+ }
+ if (atp == NULL)
+ goto RequestFail;
+ reqp->resourceL = reqp->resourceL->next; /* point to first */
+ if (AsnReadVal(aip, atp, &value) < 0) /* REQUEST_resentry */
+ goto RequestFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto RequestFail;
+ }
+ if (atp == NULL)
+ goto RequestFail;
+
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto RequestFail;
+ return 0;
+
+ RequestFail:
+ if (reqp->resourceL != NULL) { /* destroy list of nodes and resources they point to */
+ while (reqp->resourceL != NULL) {
+ NI_DestroyResource((NIResPtr)reqp->resourceL->elem);
+ reqp->resourceL = ListDelete(reqp->resourceL);
+ }
+ }
+ return -1;
+} /* readrequest */
+
+
+static void
+writeRequest(ReqPtr reqp)
+{
+ DataVal value;
+ NodePtr np, lastnode;
+
+ if (reqp->clientAddr != NULL) {
+ value.ptrvalue = (Pointer) reqp->clientAddr;
+ AsnWrite(aip, REQUEST_address, &value);
+ }
+ if (reqp->clientPort != 0) {
+ value.intvalue = (Int4) reqp->clientPort;
+ AsnWrite(aip, REQUEST_port, &value);
+ }
+ AsnStartStruct(aip, REQUEST_svcentry);
+ writeService(reqp->service);
+ AsnEndStruct(aip, REQUEST_svcentry);
+
+ np = reqp->resourceL;
+ if (np != NULL) {
+ AsnStartStruct(aip, REQUEST_resentry);
+ lastnode = np->last;
+ while (np != NULL) {
+ AsnStartStruct(aip, REQUEST_resentry_E);
+ writeResource((NIResPtr) np->elem);
+ AsnEndStruct(aip, REQUEST_resentry_E);
+ if (np == lastnode)
+ break;
+ np = np->next;
+ }
+ AsnEndStruct(aip, REQUEST_resentry);
+ }
+} /* writeRequest */
+
+
+/************************************ UID *************************************/
+
+NLM_EXTERN NI_UidPtr NI_MakeUid(void)
+{
+ NI_UidPtr up;
+
+ up = (NI_UidPtr) MemNew(sizeof(NI_Uid));
+ up->username = NULL;
+ up->group = NULL;
+ up->domain = NULL;
+ return up;
+} /* NI_MakeUid */
+
+
+NLM_EXTERN Int2 NI_DestroyUid(NI_UidPtr up)
+{
+ if (up == NULL)
+ return 1;
+ if (up->username != NULL)
+ MemFree(up->username);
+ if (up->group != NULL)
+ MemFree(up->group);
+ if (up->domain != NULL)
+ MemFree(up->domain);
+ MemFree(up);
+ return 0;
+} /* NI_DestroyUid */
+
+
+static int
+readUid(NI_UidPtr uidptr)
+{
+ DataVal value;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL || atp != IDENTITY_username) /* username */
+ goto UidFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto UidFail;
+ uidptr->username = (CharPtr) value.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* group ? */
+ goto UidFail;
+ if (atp == IDENTITY_group) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto UidFail;
+ uidptr->group = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* domain ? */
+ goto UidFail;
+ }
+ if (atp == IDENTITY_domain) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto UidFail;
+ uidptr->domain = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto UidFail;
+ }
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto UidFail;
+ return 0;
+
+ UidFail:
+ return -1;
+} /* readUid */
+
+
+static void
+writeUid(NI_UidPtr uidptr)
+{
+ DataVal value;
+
+ value.ptrvalue = (Pointer) uidptr->username;
+ AsnWrite(aip, IDENTITY_username, &value);
+
+ if (uidptr->group != NULL) {
+ value.ptrvalue = (Pointer) uidptr->group;
+ AsnWrite(aip, IDENTITY_group, &value);
+ }
+ if (uidptr->domain != NULL) {
+ value.ptrvalue = (Pointer) uidptr->domain;
+ AsnWrite(aip, IDENTITY_domain, &value);
+ }
+} /* writeUid */
+
+
+/************************************ SERVICE *********************************/
+
+NLM_EXTERN NISvcPtr NI_MakeService(void)
+{
+ NISvcPtr sp;
+
+ sp = (NISvcPtr) MemNew(sizeof(NIService));
+ sp->name = NULL;
+ sp->minVersion = 0;
+ sp->maxVersion = 0;
+ sp->id = 0;
+ sp->priority = 0;
+ sp->priorityTimeout = 0;
+ sp->priorityPenalty = 0;
+ sp->group = NULL;
+ sp->descrip = NULL;
+ sp->typeL = NULL;
+ sp->encryptionSupported = FALSE;
+ sp->trackingPeriod = 0;
+ sp->trackingCount = 0;
+ return sp;
+} /* NI_MakeService() */
+
+
+NLM_EXTERN Int2 NI_DestroyService(NISvcPtr sp)
+{
+ if (sp == NULL)
+ return 1;
+ if (sp->name != NULL)
+ MemFree(sp->name);
+ if (sp->group != NULL)
+ MemFree(sp->group);
+ if (sp->descrip != NULL)
+ MemFree(sp->descrip);
+ if (sp->typeL != NULL) { /* destroy list of service types */
+ ListStrDel(sp->typeL);
+ }
+ if (sp->subSetList != NULL) {
+ ListStrDel(sp->subSetList);
+ }
+ if (sp->superSetList != NULL) {
+ ListStrDel(sp->superSetList);
+ }
+
+ MemFree(sp);
+ return 0;
+} /* NI_DestroyService() */
+
+
+static int
+readService(NISvcPtr svcptr)
+{
+ DataVal value;
+ CharPtr svctype;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* SVC_ENTRY_name */
+ goto ServiceFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->name = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* SVC_ENTRY_minvers */
+ goto ServiceFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->minVersion = (Uint2) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* SVC_ENTRY_maxvers */
+ goto ServiceFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->maxVersion = (Uint2) value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ if (atp == SVC_ENTRY_id) { /* SVC_ENTRY_id ? */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->id = (Uint2) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+ if (atp == SVC_ENTRY_priority) { /* SVC_ENTRY_priority ? */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->priority = (Uint2) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+ if (atp == SVC_ENTRY_group) { /* SVC_ENTRY_group ? */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->group = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+ if (atp == SVC_ENTRY_description) { /* SVC_ENTRY_description ? */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->descrip = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+ if (atp == SVC_ENTRY_types) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+
+ /* read the list of service types */
+ while ((atp = AsnReadId(aip, amp, atp)) == SVC_ENTRY_types_E)
+ {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svctype = value.ptrvalue;
+ svcptr->typeL = ListInsert((VoidPtr) svctype, svcptr->typeL);
+ }
+ if (atp == NULL)
+ goto ServiceFail;
+ svcptr->typeL = svcptr->typeL->next; /* point to first */
+ if (AsnReadVal(aip, atp, &value) < 0) /* SVC_ENTRY_types */
+ goto ServiceFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+
+ if (atp == SVC_ENTRY_priority_timeout) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->priorityTimeout = (Uint2) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+
+ if (atp == SVC_ENTRY_priority_penalty) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->priorityPenalty = (Uint2) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+
+ if (atp == SVC_ENTRY_encryption_supported) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->encryptionSupported = value.boolvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+
+ if (atp == SVC_ENTRY_tracking_period) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->trackingPeriod = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+
+ if (atp == SVC_ENTRY_tracking_count) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ svcptr->trackingCount = value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ServiceFail;
+ }
+
+ if (atp == NULL)
+ goto ServiceFail;
+
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ServiceFail;
+ return 0;
+
+ ServiceFail:
+ return -1;
+} /* readService */
+
+
+static void
+writeService(NISvcPtr svcptr)
+{
+ DataVal value;
+ NodePtr np;
+ NodePtr lastnode;
+
+ value.ptrvalue = (Pointer) svcptr->name;
+ AsnWrite(aip, SVC_ENTRY_name, &value);
+ value.intvalue = (Int4) svcptr->minVersion;
+ AsnWrite(aip, SVC_ENTRY_minvers, &value);
+ value.intvalue = (Int4) svcptr->maxVersion;
+ AsnWrite(aip, SVC_ENTRY_maxvers, &value);
+
+ if (svcptr->id != 0) {
+ value.intvalue = (Int4) svcptr->id;
+ AsnWrite(aip, SVC_ENTRY_id, &value);
+ }
+ if (svcptr->priority != 0) {
+ value.intvalue = (Int4) svcptr->priority;
+ AsnWrite(aip, SVC_ENTRY_priority, &value);
+ }
+ if (svcptr->group != NULL) {
+ value.ptrvalue = (Pointer) svcptr->group;
+ AsnWrite(aip, SVC_ENTRY_group, &value);
+ }
+ if (svcptr->descrip != NULL) {
+ value.ptrvalue = (Pointer) svcptr->descrip;
+ AsnWrite(aip, SVC_ENTRY_description, &value);
+ }
+
+ np = svcptr->typeL;
+ if (np != NULL) {
+ AsnStartStruct(aip, SVC_ENTRY_types);
+ lastnode = np->last;
+ while (np != NULL) {
+ value.ptrvalue = (Pointer) np->elem;
+ AsnWrite(aip, SVC_ENTRY_types_E, &value);
+ if (np == lastnode)
+ break;
+ np = np->next;
+ }
+ AsnEndStruct(aip, SVC_ENTRY_types);
+ }
+
+ if (svcptr->priorityTimeout != 0)
+ {
+ value.intvalue = svcptr->priorityTimeout;
+ AsnWrite(aip, SVC_ENTRY_priority_timeout, &value);
+ }
+
+ if (svcptr->priorityPenalty != 0)
+ {
+ value.intvalue = svcptr->priorityPenalty;
+ AsnWrite(aip, SVC_ENTRY_priority_penalty, &value);
+ }
+
+ if (svcptr->encryptionSupported)
+ {
+ value.boolvalue = svcptr->encryptionSupported;
+ AsnWrite(aip, SVC_ENTRY_encryption_supported, &value);
+ }
+
+ if (svcptr->trackingPeriod != 0)
+ {
+ value.intvalue = svcptr->trackingPeriod;
+ AsnWrite(aip, SVC_ENTRY_tracking_period, &value);
+ }
+
+ if (svcptr->trackingCount != 0)
+ {
+ value.intvalue = svcptr->trackingCount;
+ AsnWrite(aip, SVC_ENTRY_tracking_count, &value);
+ }
+} /* writeService */
+
+
+/************************************ RESOURCE ********************************/
+
+NLM_EXTERN NIResPtr NI_MakeResource(void)
+{
+ NIResPtr rp;
+
+ rp = (NIResPtr) MemNew(sizeof(NIResource));
+ rp->name = NULL;
+ rp->type = NULL;
+ rp->minVersion = 0;
+ rp->maxVersion = 0;
+ rp->id = 0;
+ rp->group = NULL;
+ rp->descrip = NULL;
+ return rp;
+} /* NI_MakeResource() */
+
+
+NLM_EXTERN Int2 NI_DestroyResource(NIResPtr rp)
+{
+ if (rp == NULL)
+ return 1;
+ if (rp->name != NULL)
+ MemFree(rp->name);
+ if (rp->type != NULL)
+ MemFree(rp->type);
+ if (rp->group != NULL)
+ MemFree(rp->group);
+ if (rp->descrip != NULL)
+ MemFree(rp->descrip);
+ MemFree(rp);
+ return 0;
+} /* NI_DestroyResource */
+
+
+static int
+readResource(NIResPtr resptr)
+{
+ DataVal value;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* RES_ENTRY_name */
+ goto ResourceFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ResourceFail;
+ resptr->name = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* RES_ENTRY_type */
+ goto ResourceFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ResourceFail;
+ resptr->type = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* RES_ENTRY_minvers */
+ goto ResourceFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ResourceFail;
+ resptr->minVersion = (Uint2) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* RES_ENTRY_maxvers */
+ goto ResourceFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ResourceFail;
+ resptr->maxVersion = (Uint2) value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ResourceFail;
+ if (atp == RES_ENTRY_id) { /* RES_ENTRY_id */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ResourceFail;
+ resptr->id = (Uint2) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ResourceFail;
+ }
+ if (atp == RES_ENTRY_group) { /* RES_ENTRY_group */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ResourceFail;
+ resptr->group = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ResourceFail;
+ }
+ if (atp == RES_ENTRY_description) { /* RES_ENTRY_description */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ResourceFail;
+ resptr->descrip = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ResourceFail;
+ }
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ResourceFail;
+ return 0;
+
+ ResourceFail:
+ return -1;
+} /* readResource */
+
+
+static void
+writeResource(NIResPtr resptr)
+{
+ DataVal value;
+
+ value.ptrvalue = (Pointer) resptr->name;
+ AsnWrite(aip, RES_ENTRY_name, &value);
+ value.ptrvalue = (Pointer) resptr->type;
+ AsnWrite(aip, RES_ENTRY_type, &value);
+ value.intvalue = (Int4) resptr->minVersion;
+ AsnWrite(aip, RES_ENTRY_minvers, &value);
+ value.intvalue = (Int4) resptr->maxVersion;
+ AsnWrite(aip, RES_ENTRY_maxvers, &value);
+
+ if (resptr->id != 0) {
+ value.intvalue = (Int4) resptr->id;
+ AsnWrite(aip, RES_ENTRY_id, &value);
+ }
+ if (resptr->group != NULL) {
+ value.ptrvalue = (Pointer) resptr->group;
+ AsnWrite(aip, RES_ENTRY_group, &value);
+ }
+ if (resptr->descrip != NULL) {
+ value.ptrvalue = (Pointer) resptr->descrip;
+ AsnWrite(aip, RES_ENTRY_description, &value);
+ }
+} /* writeResource */
+
+
+/************************************ REGION *********************************/
+
+NLM_EXTERN NIRegionPtr NI_MakeRegion(void)
+{
+ NIRegionPtr rp;
+
+ rp = (NIRegionPtr) MemNew(sizeof(NIRegion));
+ rp->regionName = NULL;
+ rp->priorityDelta = 0;
+ return rp;
+} /* NI_MakeRegion() */
+
+
+NLM_EXTERN Int2 NI_DestroyRegion(NIRegionPtr rp)
+{
+ if (rp == NULL)
+ return 1;
+ if (rp->regionName != NULL)
+ MemFree(rp->regionName);
+
+ MemFree(rp);
+ return 0;
+} /* NI_DestroyRegion() */
+
+
+static int
+readRegion(NIRegionPtr regptr)
+{
+ DataVal value;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* REGION_DESCR_region_name */
+ goto RegionFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto RegionFail;
+ regptr->regionName = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* REGION_DESCR_priority_delta */
+ goto RegionFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto RegionFail;
+ regptr->priorityDelta = (Uint2) value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto RegionFail;
+
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto RegionFail;
+ return 0;
+
+ RegionFail:
+ return -1;
+} /* readRegion */
+
+
+static void
+writeRegion(NIRegionPtr regptr)
+{
+ DataVal value;
+
+ value.ptrvalue = (Pointer) regptr->regionName;
+ AsnWrite(aip, REGION_DESCR_region_name, &value);
+ value.intvalue = (Int4) regptr->priorityDelta;
+ AsnWrite(aip, REGION_DESCR_priority_delta, &value);
+} /* writeRegion */
+
+
+
+/************************************ PubKey ********************************/
+
+NLM_EXTERN NIPubKeyPtr NI_MakePubKey(void)
+{
+ NIPubKeyPtr pubkey;
+
+ pubkey = (NIPubKeyPtr) MemNew(sizeof(NIPubKey));
+ pubkey->bits = 0;
+ pubkey->modulus = NULL;
+ pubkey->exponent = NULL;
+ return pubkey;
+} /* NI_MakePubKey */
+
+
+NLM_EXTERN Int2 NI_DestroyPubKey(NIPubKeyPtr pubkey)
+{
+ if (pubkey == NULL)
+ return 1;
+ if (pubkey->modulus != NULL)
+ BSFree (pubkey->modulus);
+ if (pubkey->exponent != NULL)
+ BSFree (pubkey->exponent);
+ MemFree(pubkey);
+ return 0;
+}
+
+
+static int
+readPubKey(NIPubKeyPtr pubkey)
+{
+ DataVal value;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL || atp != RSA_PUBKEY_bits)
+ goto PubKeyFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto PubKeyFail;
+ pubkey->bits = (Int2) value.intvalue;
+
+ /* modulus */
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto PubKeyFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto PubKeyFail;
+ pubkey->modulus = (ByteStorePtr) value.ptrvalue;
+
+ /* exponent */
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto PubKeyFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto PubKeyFail;
+ pubkey->exponent = (ByteStorePtr) value.ptrvalue;
+
+ /* end struct */
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto PubKeyFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto PubKeyFail;
+ return 0;
+
+ PubKeyFail:
+ return -1;
+}
+
+static void
+writePubKey(NIPubKeyPtr pubkey)
+{
+ DataVal value;
+
+ if (pubkey == NULL)
+ return;
+ value.intvalue = pubkey->bits;
+ AsnWrite(aip, RSA_PUBKEY_bits, &value);
+ value.ptrvalue = pubkey->modulus;
+ AsnWrite(aip, RSA_PUBKEY_modulus, &value);
+ value.ptrvalue = pubkey->exponent;
+ AsnWrite(aip, RSA_PUBKEY_exponent, &value);
+}
+
+NLM_EXTERN int NI_ReadPubKey(AsnIoPtr extaip, AsnTypePtr extatp, NIPubKeyPtr pubkey)
+{
+ AsnIoPtr savaip = aip;
+ AsnTypePtr savatp = atp;
+ DataVal value;
+ int retval = -1;
+
+ if (! InitMsg())
+ return 0;
+ aip = extaip;
+ atp = extatp;
+ if ((atp = AsnReadId(aip, amp, atp)) == RSA_PUBKEY)
+ {
+ if (AsnReadVal(aip, atp, &value) >= 0)
+ {
+ retval = readPubKey(pubkey);
+ }
+ }
+ aip = savaip;
+ atp = savatp;
+ return retval;
+}
+
+NLM_EXTERN void NI_WritePubKey(AsnIoPtr extaip, AsnTypePtr extatp, NIPubKeyPtr pubkey)
+{
+ AsnIoPtr savaip = aip;
+ AsnTypePtr savatp = atp;
+
+ if (! InitMsg())
+ return;
+ aip = extaip;
+ atp = extatp;
+ if (extatp != NULL)
+ AsnStartStruct(extaip, extatp);
+ writePubKey(pubkey);
+ if (extatp != NULL)
+ AsnEndStruct(extaip, extatp);
+ aip = savaip;
+ atp = savatp;
+}
+
+
+
+/************************************ DispInfo ********************************/
+
+NLM_EXTERN NIDispInfoPtr NI_MakeDispInfo(void)
+{
+ NIDispInfoPtr dip;
+
+ dip = (NIDispInfoPtr) MemNew(sizeof(NIDispInfo));
+ dip->serialno = -1;
+ dip->isalternatelist = FALSE;
+ dip->numdispatchers = 0;
+ dip->displist = NULL;
+ dip->pubKey = NULL;
+ return dip;
+} /* NI_MakeDispInfo */
+
+
+NLM_EXTERN Int2 NI_DestroyDispInfo(NIDispInfoPtr dip)
+{
+ Int2 num;
+
+ if (dip == NULL)
+ return 1;
+ if (dip->displist != NULL)
+ {
+ for (num = 0; num < dip->numdispatchers; num++)
+ {
+ dip->displist[num] = (CharPtr) MemFree(dip->displist[num]);
+ }
+ MemFree(dip->displist);
+ }
+ if (dip->pubKey != NULL)
+ {
+ NI_DestroyPubKey(dip->pubKey);
+ }
+ MemFree(dip);
+ return 0;
+} /* NI_DestroyDispInfo */
+
+
+static int
+readDispInfo(NIDispInfoPtr dip)
+{
+ DataVal value;
+ int num;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL || atp != DISPATCHER_INFO_serial_no)
+ goto DispInfoFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto DispInfoFail;
+ dip->serialno = value.intvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* is altlist?*/
+ goto DispInfoFail;
+ if (atp == INFO_is_alternate_list) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto DispInfoFail;
+ dip->isalternatelist = value.boolvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* num disps ?*/
+ goto DispInfoFail;
+ }
+
+ if (atp == DISPATCHER_INFO_num_dispatchers) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto DispInfoFail;
+ dip->numdispatchers = (int) value.intvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* disps ? */
+ goto DispInfoFail;
+ }
+ if (atp == DISPATCHER_INFO_disp_list) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto DispInfoFail;
+ dip->displist = (CharPtr PNTR) MemNew(sizeof(CharPtr) * dip->numdispatchers);
+ atp = AsnReadId(aip, amp, atp);
+ for (num = 0; num < dip->numdispatchers &&
+ atp == DISPATCHER_INFO_disp_list_E; num++)
+ {
+ if (AsnReadVal(aip, atp, &value) <= 0)
+ goto DispInfoFail;
+ dip->displist[num] = (CharPtr) value.ptrvalue;
+ atp = AsnReadId(aip, amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &value) <= 0)
+ goto DispInfoFail;
+ atp = AsnReadId(aip, amp, atp);
+ }
+ if (atp == DISPATCHER_INFO_pub_key) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto DispInfoFail;
+ dip->pubKey = NI_MakePubKey();
+ if (readPubKey(dip->pubKey) < 0)
+ goto DispInfoFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto DispInfoFail;
+ }
+
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto DispInfoFail;
+ return 0;
+
+ DispInfoFail:
+ return -1;
+} /* readDispInfo */
+
+
+static void
+writeDispInfo(NIDispInfoPtr dip)
+{
+ DataVal value;
+ int num;
+
+ if (dip == NULL)
+ return;
+ value.intvalue = dip->serialno;
+ AsnWrite(aip, DISPATCHER_INFO_serial_no, &value);
+ value.boolvalue = dip->isalternatelist;
+ AsnWrite(aip, INFO_is_alternate_list, &value);
+ value.intvalue = dip->numdispatchers;
+ AsnWrite(aip, DISPATCHER_INFO_num_dispatchers, &value);
+ if (dip->displist != NULL) {
+ AsnStartStruct (aip, DISPATCHER_INFO_disp_list);
+ for (num = 0; num < dip->numdispatchers; num++) {
+ value.ptrvalue = dip->displist[num];
+ AsnWrite (aip, DISPATCHER_INFO_disp_list_E, &value);
+ }
+ AsnEndStruct (aip, DISPATCHER_INFO_disp_list);
+ }
+ if (dip->pubKey != NULL) {
+ AsnStartStruct (aip, DISPATCHER_INFO_pub_key);
+ writePubKey (dip->pubKey);
+ AsnEndStruct (aip, DISPATCHER_INFO_pub_key);
+ }
+} /* writeDispInfo */
+
+NLM_EXTERN int NI_ReadDispInfo(AsnIoPtr extaip, AsnTypePtr extatp, NIDispInfoPtr dip)
+{
+ AsnIoPtr savaip = aip;
+ AsnTypePtr savatp = atp;
+ DataVal value;
+ int retval = -1;
+
+ if (! InitMsg())
+ return 0;
+ aip = extaip;
+ atp = extatp;
+ if ((atp = AsnReadId(aip, amp, atp)) == DISPATCHER_INFO)
+ {
+ if (AsnReadVal(aip, atp, &value) >= 0)
+ {
+ retval = readDispInfo(dip);
+ }
+ }
+ aip = savaip;
+ atp = savatp;
+ return retval;
+}
+
+NLM_EXTERN void NI_WriteDispInfo(AsnIoPtr extaip, AsnTypePtr extatp, NIDispInfoPtr dip)
+{
+ AsnIoPtr savaip = aip;
+ AsnTypePtr savatp = atp;
+
+ if (! InitMsg())
+ return;
+ aip = extaip;
+ atp = extatp;
+ if (extatp != NULL)
+ AsnStartStruct(extaip, extatp);
+ writeDispInfo(dip);
+ if (extatp != NULL)
+ AsnEndStruct(extaip, extatp);
+ aip = savaip;
+ atp = savatp;
+}
+
+
+/************************************ TOOLSET *********************************/
+
+NLM_EXTERN NIToolsetPtr NI_MakeToolset(void)
+{
+ NIToolsetPtr tsp;
+
+ tsp = (NIToolsetPtr) MemNew(sizeof(NIToolset));
+ tsp->host = NULL;
+ tsp->motd = NULL;
+ tsp->services = NULL;
+ tsp->resources = NULL;
+ tsp->regions = NULL;
+ return tsp;
+} /* NI_MakeToolset */
+
+
+NLM_EXTERN Int2 NI_DestroyToolset(NIToolsetPtr tsp)
+{
+ NodePtr np;
+
+ if (tsp == NULL)
+ return 1;
+ if (tsp->host != NULL)
+ MemFree(tsp->host);
+ if (tsp->motd != NULL)
+ MemFree(tsp->motd);
+
+ if ((np = tsp->services) != NULL) {
+ do {
+ NI_DestroyService((NISvcPtr)np->elem);
+ np = ListDelete(np);
+ } while (np != NULL);
+ }
+
+ if ((np = tsp->resources) != NULL) {
+ do {
+ NI_DestroyResource((NIResPtr)np->elem);
+ np = ListDelete(np);
+ } while (np != NULL);
+ }
+
+ if ((np = tsp->regions) != NULL) {
+ do {
+ NI_DestroyRegion((NIRegionPtr)np->elem);
+ np = ListDelete(np);
+ } while (np != NULL);
+ }
+
+ MemFree(tsp);
+ return 0;
+} /* NI_DestroyToolset */
+
+
+NLM_EXTERN NIToolsetPtr NI_GetCatToolset(NIToolsetPtr tsp)
+{
+ NIToolsetPtr dtsp;
+ NISvcPtr svcp, tsvcp;
+ NIResPtr resp, tresp;
+ NodePtr np;
+
+ dtsp = NI_MakeToolset();
+
+ if (tsp->host != NULL)
+ dtsp->host = StringSave(tsp->host);
+ if (tsp->motd != NULL)
+ dtsp->motd = StringSave(tsp->motd);
+
+ if (tsp->services != NULL) {
+ np = tsp->services->last;
+ do {
+ np = ListGetNext(np);
+ svcp = (NISvcPtr) np->elem;
+ /* note that services which are a "subset" of another listed */
+ /* service are filtered-out here */
+ if (svcp != NULL && svcp->subSetList == NULL) {
+ tsvcp = NI_MakeService();
+ if (svcp->name != NULL)
+ tsvcp->name = StringSave(svcp->name);
+
+ if (svcp->typeL != NULL)
+ { /* make a copy of the list */
+ tsvcp->typeL = ListStrCopy(svcp->typeL);
+ }
+
+ tsvcp->minVersion = svcp->minVersion;
+ tsvcp->maxVersion = svcp->maxVersion;
+ tsvcp->priority = svcp->priority;
+ tsvcp->id = 0; /* these two not sent in catalog */
+ tsvcp->group = NULL;
+ if (svcp->descrip != NULL)
+ tsvcp->descrip = StringSave(svcp->descrip);
+ dtsp->services = ListInsert((VoidPtr) tsvcp, dtsp->services);
+ }
+ } while (np != tsp->services->last);
+ if (dtsp->services != NULL)
+ {
+ dtsp->services = dtsp->services->next; /* point to first */
+ }
+ }
+
+ if (tsp->resources != NULL) {
+ np = tsp->resources->last;
+ do {
+ np = ListGetNext(np);
+ resp = (NIResPtr) np->elem;
+ if (resp != NULL) {
+ tresp = NI_MakeResource();
+ if (resp->name != NULL)
+ tresp->name = StringSave(resp->name);
+ if (resp->type != NULL)
+ tresp->type = StringSave(resp->type);
+ tresp->minVersion = resp->minVersion;
+ tresp->maxVersion = resp->maxVersion;
+ tresp->id = 0; /* these two not sent in catalog */
+ tresp->group = NULL;
+ if (resp->descrip != NULL)
+ tresp->descrip = StringSave(resp->descrip);
+ dtsp->resources = ListInsert((VoidPtr) tresp, dtsp->resources);
+ }
+ } while (np != tsp->resources->last);
+ if (dtsp->resources != NULL)
+ {
+ dtsp->resources = dtsp->resources->next; /* point to first */
+ }
+ }
+
+ return dtsp;
+} /* NI_GetCatToolset */
+
+
+static int
+readToolset(NIToolsetPtr tsp)
+{
+ DataVal value;
+ NISvcPtr svcp;
+ NIResPtr resp;
+ NIRegionPtr reg;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* TOOLSET_host */
+ goto ToolsetFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ tsp->host = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ToolsetFail;
+
+ if (atp == TOOLSET_motd) { /* TOOLSET_motd ? */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ tsp->motd = (CharPtr) value.ptrvalue;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ToolsetFail;
+ }
+ if (atp == TOOLSET_services) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ while ((atp = AsnReadId(aip, amp, atp)) == TOOLSET_services_E) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ svcp = NI_MakeService();
+ readService(svcp);
+ tsp->services = ListInsert((VoidPtr) svcp, tsp->services);
+ }
+ if (atp == NULL)
+ goto ToolsetFail;
+ tsp->services = tsp->services->next; /* point to first */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ToolsetFail;
+ }
+ if (atp == TOOLSET_resources) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ while ((atp = AsnReadId(aip, amp, atp)) == TOOLSET_resources_E) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ resp = NI_MakeResource();
+ readResource(resp);
+ tsp->resources = ListInsert((VoidPtr) resp, tsp->resources);
+ }
+ if (atp == NULL)
+ goto ToolsetFail;
+ tsp->resources = tsp->resources->next; /* point to first */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ToolsetFail;
+ }
+ if (atp == TOOLSET_regions) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ while ((atp = AsnReadId(aip, amp, atp)) == TOOLSET_regions_E) {
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ reg = NI_MakeRegion();
+ readRegion(reg);
+ tsp->regions = ListInsert((VoidPtr) reg, tsp->regions);
+ }
+ if (atp == NULL)
+ goto ToolsetFail;
+ tsp->regions = tsp->regions->next; /* point to first */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL)
+ goto ToolsetFail;
+ }
+
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto ToolsetFail;
+ return 0;
+
+ ToolsetFail:
+ return -1;
+} /* readToolset */
+
+static void
+writeToolset(NIToolsetPtr tsp)
+{
+ DataVal value;
+ NodePtr np, lastnode;
+
+ if (tsp->host != NULL)
+ value.ptrvalue = (Pointer) tsp->host;
+ else
+ value.ptrvalue = (Pointer) StringSave("N/A");
+ AsnWrite(aip, TOOLSET_host, &value);
+
+ if (tsp->motd != NULL) {
+ value.ptrvalue = (Pointer) tsp->motd;
+ AsnWrite(aip, TOOLSET_motd, &value);
+ }
+ np = tsp->services;
+ if (np != NULL) {
+ AsnStartStruct(aip, TOOLSET_services);
+ lastnode = np->last;
+ while (np != NULL) {
+ AsnStartStruct(aip, TOOLSET_services_E);
+ writeService((NISvcPtr) np->elem);
+ AsnEndStruct(aip, TOOLSET_services_E);
+ if (np == lastnode)
+ break;
+ np = np->next;
+ }
+ AsnEndStruct(aip, TOOLSET_services);
+ }
+ np = tsp->resources;
+ if (np != NULL) {
+ AsnStartStruct(aip, TOOLSET_resources);
+ lastnode = np->last;
+ while (np != NULL) {
+ AsnStartStruct(aip, TOOLSET_resources_E);
+ writeResource((NIResPtr) np->elem);
+ AsnEndStruct(aip, TOOLSET_resources_E);
+ if (np == lastnode)
+ break;
+ np = np->next;
+ }
+ AsnEndStruct(aip, TOOLSET_resources);
+ }
+ np = tsp->regions;
+ if (np != NULL) {
+ AsnStartStruct(aip, TOOLSET_regions);
+ lastnode = np->last;
+ while (np != NULL) {
+ AsnStartStruct(aip, TOOLSET_regions_E);
+ writeRegion((NIRegionPtr) np->elem);
+ AsnEndStruct(aip, TOOLSET_regions_E);
+ if (np == lastnode)
+ break;
+ np = np->next;
+ }
+ AsnEndStruct(aip, TOOLSET_regions);
+ }
+} /* writeToolset */
+
+
+/******************************************************************************/
+/* */
+/* Message and Handle Functions */
+/* */
+/******************************************************************************/
+
+/*
+ * Purpose: "High level" message read for ASN.1 messages
+ *
+ * Parameters:
+ * hp "Message handle", describing parameters of input environment
+ * unblocked Flag indicating whether input should "block" if unable
+ * to read a complete message
+ *
+ * Returns:
+ * NULL, if unable to read a message ... if hp->have_blocked is
+ * set, then this reflects an inability to read a complete
+ * message at this time
+ * a pointer to the message which was just read, otherwise
+ *
+ *
+ * Description:
+ * Try to read a message from the socket specified by the hp
+ * data structure. A message must begin with the "MESSAGE"
+ * identifier, followed by the type of the message. Once the
+ * type of the message has been determined, the remainder of
+ * the message is read using the corresponding readXXX()
+ * function.
+ *
+ * Matters are more complex when the "unblocked" parameter
+ * is TRUE. In this case, if a failure occurs on a message read,
+ * an attempt is made to see whether any bytes of data were
+ * read from the socket upon this invocation. If so, the
+ * have_blocked flag is set for the caller, and AsnIoReset() is
+ * called to deal with a future attempt to read from this socket
+ * when more data becomes available.
+ *
+ * Note:
+ * This is the highest level read function which should be
+ * called by an application program. All the other "static"
+ * functions called here should not be called directly by an
+ * application program.
+ *
+ * The ASN.1 error handling is performing using the setjmp()/
+ * longjmp() paradigm, where a function can return to an earlier
+ * context if an error occurs.
+ *
+ * Currently, it is not possible to distinguish
+ * between an ASN.1 format error, and an ASN failure due to
+ * inability to read the requested quantity of data. For this
+ * reason, if the "unblocked" option is selected, it will take
+ * hp->r_timeout seconds to detect either of these
+ * conditions. In the best of all possible worlds, it would
+ * be possible to distinguish between "data not YET available"
+ * and "invalid data" conditions.
+ */
+
+NLM_EXTERN NIMsgPtr MsgRead(MHandPtr hp, Boolean unblocked)
+{
+ DataVal value;
+ NIMsgPtr mp = NULL;
+ int start_byte_count = hp->num_queued_bytes;
+ NodePtr timer = NULL;
+ NodePtr localTimer = NULL;
+
+ ni_errno = NIE_MSGREAD;
+
+ hp->unblocked_mode = unblocked;
+ hp->have_blocked = FALSE;
+
+ /* for unblocked I/O, set a "hangup" timeout which can be detected at */
+ /* at later time, if we are unable to read a complete or valid message */
+ if (unblocked && hp->readTimeoutHook != NULL)
+ timer = NI_SetTimer(time(NULL) + hp->r_timeout, hp->readTimeoutHook,
+ (VoidPtr) hp);
+ hp->readTimer = timer;
+
+ if (hp->longjump == TRUE) {
+ if (SetJump(ni_env)) {
+ /* return from LongJump (error handler) */
+ goto MsgReadFail;
+ }
+ }
+
+ StringCpy(ni_errtext, "AsnReadId or AsnReadVal returned bad value");
+ aip = hp->raip;
+ atp = MESSAGE;
+ if ((atp = AsnReadId(aip, amp, atp)) != MESSAGE) /* Must read a MESSAGE */
+ goto MsgReadFail; /* don't have to read val as Null return is always fatal to channel */
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto MsgReadFail;
+
+ if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* type of message */
+ goto MsgReadFail;
+ if (AsnReadVal(aip, atp, &value) < 0)
+ goto MsgReadFail;
+
+ mp = (NIMsgPtr) MemNew(sizeof(NIMessage));
+ mp->conid = hp->conid;
+ mp->type = NI_UNKNOWN;
+
+ if (atp == MESSAGE_ack) {
+ if ((mp->msun.ack = readACK()) != NULL)
+ mp->type = NI_ACK;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_nack) {
+ if ((mp->msun.nack = readNACK()) != NULL)
+ mp->type = NI_NACK;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_login) {
+ if ((mp->msun.login = readLOGIN()) != NULL)
+ mp->type = NI_LOGIN;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_svc_list) {
+ if ((mp->msun.svclist = readSVC_LIST()) != NULL)
+ mp->type = NI_SVC_LIST;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_svc_request) {
+ if ((mp->msun.svcreq = readSVC_REQUEST()) != NULL)
+ mp->type = NI_SVC_REQUEST;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_svc_response) {
+ if ((mp->msun.svcresp = readSVC_RESPONSE()) != NULL)
+ mp->type = NI_SVC_RESPONSE;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_command) {
+ if ((mp->msun.command = readCOMMAND()) != NULL)
+ mp->type = NI_COMMAND;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_svc_pre_response) {
+ if ((mp->msun.preresp = readPRE_RESPONSE()) != NULL)
+ mp->type = NI_SVC_PRE_RESPONSE;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_acct) {
+ if ((mp->msun.acct = readACCT()) != NULL)
+ mp->type = NI_ACCT;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_catalog) {
+ if ((mp->msun.catalog = readCATALOG()) != NULL)
+ mp->type = NI_CATALOG;
+ goto gotmessage;
+ }
+
+ if (atp == MESSAGE_load_status) {
+ if ((mp->msun.status = readSTATUS()) != NULL)
+ mp->type = NI_STATUS;
+ goto gotmessage;
+ }
+
+ gotmessage:
+ if (mp->type == NI_UNKNOWN) {
+ StringCpy(ni_errtext, "unknown msg type");
+ goto MsgReadFail;
+ }
+ else { /* got good stuff */
+ MsgFreeSavedData(hp); /* free associated data */
+ hp->unblocked_mode = FALSE;
+ hp->have_blocked = FALSE;
+ localTimer = hp->readTimer;
+ hp->readTimer = NULL;
+ NI_CancelTimer(localTimer);
+ return mp;
+ }
+
+ MsgReadFail:
+ if (mp != NULL)
+ MsgDestroy(mp);
+
+ /* if ( things didn't go well, but there was more data read from the */
+ /* socket ) then */
+ if (start_byte_count < hp->num_queued_bytes)
+ hp->have_blocked = TRUE; /* set things up to try again */
+
+ if (hp->have_blocked)
+ { /* failed due to data unavailability */
+ hp->cur_index = 0; /* reset queued read pointer */
+ AsnIoReset (aip); /* reset ASN input stream */
+ /* caller should try again later, based upon detecting hp->have_blocked */
+ }
+ hp->unblocked_mode = FALSE;
+ return NULL;
+} /* MsgRead */
+
+
+
+/*
+ * Purpose: "High level" message write for ASN.1 messages
+ *
+ * Parameters:
+ * hp "Message handle", describing parameters of I/O environment
+ * mp Message to be written
+ * noDestroy If set, refrain from destroying the message
+ *
+ * Returns:
+ * -1, if unable to write the message
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Try to write a message from the socket specified by the hp
+ * data structure. The writing of the message is performed
+ * using the writeXXX() function which corresponds to the type
+ * of the message to be written.
+ */
+
+NLM_EXTERN Int2 MsgWrite(MHandPtr hp, NIMsgPtr mp, Boolean noDestroy)
+{
+ DataVal value;
+
+ ni_errno = NIE_MSGWRITE;
+
+ if (hp->longjump == TRUE) {
+ if (SetJump(ni_env)) {
+ /* return from LongJump (error handler) */
+ if (! noDestroy)
+ MsgDestroy(mp); /* failing, so destroy it */
+ return -1;
+ }
+ }
+
+ aip = hp->waip;
+ AsnWrite(aip, MESSAGE, &value);
+
+ switch (mp->type) {
+ case NI_ACK:
+ writeACK(mp->msun.ack);
+ break;
+
+ case NI_NACK:
+ writeNACK(mp->msun.nack);
+ break;
+
+ case NI_LOGIN:
+ writeLOGIN(mp->msun.login);
+ break;
+
+ case NI_SVC_LIST:
+ writeSVC_LIST(mp->msun.svclist);
+ break;
+
+ case NI_SVC_REQUEST:
+ writeSVC_REQUEST(mp->msun.svcreq);
+ break;
+
+ case NI_SVC_RESPONSE:
+ writeSVC_RESPONSE(mp->msun.svcresp);
+ break;
+
+ case NI_COMMAND:
+ writeCOMMAND(mp->msun.command);
+ break;
+
+ case NI_SVC_PRE_RESPONSE:
+ writePRE_RESPONSE(mp->msun.preresp);
+ break;
+
+ case NI_ACCT:
+ writeACCT(mp->msun.acct);
+ break;
+
+ case NI_CATALOG:
+ writeCATALOG(mp->msun.catalog);
+ break;
+
+ case NI_STATUS:
+ writeSTATUS(mp->msun.status);
+ break;
+
+ default:
+ ni_errno = NIE_MSGUNK;
+ StringCpy(ni_errtext, "unable to write msg");
+ if (! noDestroy)
+ MsgDestroy(mp);
+ return -1;
+ }
+
+ AsnIoFlush(aip);
+ if (! noDestroy)
+ MsgDestroy(mp);
+ return 0;
+} /* MsgWrite */
+
+
+
+/*
+ * Purpose: Build a message of the specified type, populating it with
+ * a pointer to the actual message data, and the connection ID.
+ *
+ * Parameters:
+ * type The type of message to be built
+ * conn Connection ID associated with this session
+ * stp Pointer to the actual message data
+ *
+ * Returns:
+ * NULL, if unable to allocate memory for the message, or if
+ * the specified message type is invalid
+ * a pointer to the newly-build message, otherwise
+ *
+ *
+ * Description:
+ * Create a message data structure, and populate it as indicated.
+ */
+
+NLM_EXTERN NIMsgPtr MsgBuild(MsgType type, Uint4 conn, VoidPtr stp)
+{
+ NIMsgPtr mp;
+
+ if (! InitMsg())
+ return NULL;
+ mp = (NIMsgPtr) MemNew(sizeof(NIMessage));
+ if (mp == NULL)
+ return NULL;
+ mp->type = type;
+ mp->conid = conn;
+
+ switch (mp->type) {
+ case NI_ACK:
+ mp->msun.ack = (NIAckPtr) stp;
+ break;
+
+ case NI_NACK:
+ mp->msun.nack = (NINackPtr) stp;
+ break;
+
+ case NI_LOGIN:
+ mp->msun.login = (NILoginPtr) stp;
+ break;
+
+ case NI_SVC_LIST:
+ mp->msun.svclist = (NISvcListPtr) stp;
+ break;
+
+ case NI_SVC_REQUEST:
+ mp->msun.svcreq = (NISvcReqPtr) stp;
+ break;
+
+ case NI_SVC_RESPONSE:
+ mp->msun.svcresp = (NISvcRespPtr) stp;
+ break;
+
+ case NI_COMMAND:
+ mp->msun.command = (NICmdPtr) stp;
+ break;
+
+ case NI_SVC_PRE_RESPONSE:
+ mp->msun.preresp = (NIPreRespPtr) stp;
+ break;
+
+ case NI_ACCT:
+ mp->msun.acct = (NIAcctPtr) stp;
+ break;
+
+ case NI_CATALOG:
+ mp->msun.catalog = (NICatalogPtr) stp;
+ break;
+
+ case NI_STATUS:
+ mp->msun.status = (NIStatusPtr) stp;
+ break;
+
+ default:
+ ni_errno = NIE_MSGUNK;
+ StringCpy(ni_errtext, "unable to build");
+ MemFree (mp);
+ return NULL;
+ }
+ return mp;
+} /* MsgBuild */
+
+
+
+/*
+ * Purpose: Destroy the specified message
+ *
+ * Parameters:
+ * mp A pointer to the message structure to be destroyed
+ *
+ * Returns:
+ * -1, if the specified pointer is NULL, or if the message
+ * is of an unknown type
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Destroy the specified message, using the appropriate message
+ * destructor function.
+ */
+
+NLM_EXTERN Int2 MsgDestroy(NIMsgPtr mp)
+{
+ if (mp == NULL)
+ return -1;
+
+ switch (mp->type) {
+ case NI_ACK:
+ NI_DestroyMsgAck(mp->msun.ack);
+ break;
+
+ case NI_NACK:
+ NI_DestroyMsgNack(mp->msun.nack);
+ break;
+
+ case NI_LOGIN:
+ NI_DestroyMsgLogin(mp->msun.login);
+ break;
+
+ case NI_SVC_LIST:
+ NI_DestroyMsgSvclist(mp->msun.svclist);
+ break;
+
+ case NI_SVC_REQUEST:
+ NI_DestroyMsgSvcreq(mp->msun.svcreq);
+ break;
+
+ case NI_SVC_RESPONSE:
+ NI_DestroyMsgSvcresp(mp->msun.svcresp);
+ break;
+
+ case NI_COMMAND:
+ NI_DestroyMsgCmd(mp->msun.command);
+ break;
+
+ case NI_SVC_PRE_RESPONSE:
+ NI_DestroyMsgPreResp(mp->msun.preresp);
+ break;
+
+ case NI_ACCT:
+ NI_DestroyMsgAcct(mp->msun.acct);
+ break;
+
+ case NI_CATALOG:
+ NI_DestroyMsgCatalog(mp->msun.catalog);
+ break;
+
+ case NI_STATUS:
+ NI_DestroyMsgStatus(mp->msun.status);
+ break;
+
+ default:
+ ni_errno = NIE_MSGUNK;
+ StringCpy(ni_errtext, "unable to destroy msg");
+ MemFree(mp);
+ return -1;
+ }
+
+ MemFree(mp);
+ return 0;
+} /* MsgDestroy */
+
+
+
+/*
+ * Purpose: Create a message handle
+ *
+ * Returns:
+ * NULL, if unable to allocate the required memory, open
+ * a socket, set the socket to non-blocking mode, or
+ * initialize the ASN.1 I/O streams successfully
+ * a pointer to the new message handle, otherwise
+ *
+ *
+ * Description:
+ * Create a "message" handle, which is the basic unit of message
+ * I/O. A message handle includes, among other things, a logical
+ * connection ID, a socket used for both input and output, ASN.1
+ * I/O stream pointers, and a queue of input data which has
+ * already been read from the socket, but has not yet been
+ * processed successfully using ASN.1.
+ *
+ * Note:
+ * This is currently the only place where conid is incremented,
+ * and therefore, the only place where conid is written to the
+ * Conid file.
+ */
+
+#ifdef OS_MAC
+ /* workaround for weaknesses of Mac OpenTransport */
+ Boolean UsingOpenTransport(void);
+#endif
+
+NLM_EXTERN MHandPtr MsgMakeHandle(Boolean createSocket)
+{
+ MHandPtr mh;
+ Boolean dontset = FALSE;
+
+ if (! InitMsg()) {
+ StringCpy(ni_errtext, "Network services ASN.1 initialization failed");
+ ni_errno = NIE_ASN1SPECFAIL;
+ return NULL;
+ }
+ if ((mh = (MHandPtr) MemNew(sizeof(MHandle))) == NULL) {
+ StringCpy(ni_errtext, "unable to allocate new memory");
+ return NULL;
+ }
+ mh->hostname = NULL;
+ mh->conid = conid++;
+ WriteConFile(conid);
+ mh->seqno = 1;
+ mh->sok = -1;
+
+ if (createSocket) {
+ if ((mh->sok = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) ==
+ INVALID_SOCKET) {
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(mh->sok);
+#endif
+ StringCpy(ni_errtext, sys_errlist[SOCK_INDEX_ERRNO]);
+ MemFree(mh);
+ return NULL;
+ }
+ LOG_SOCKET(mh->sok, TRUE);
+ if (NI_SETNONBLOCKING(mh->sok) == -1) {
+ StringCpy(ni_errtext, sys_errlist[SOCK_INDEX_ERRNO]);
+ MemFree(mh);
+ return NULL;
+ }
+ }
+ mh->r_timeout = NI_READ_TIMEOUT;
+ mh->w_timeout = NI_WRITE_TIMEOUT;
+ mh->state = NI_CREATED;
+ mh->extra_proc_info = NULL;
+ mh->read_filter = NULL;
+ mh->write_filter = NULL;
+ mh->write_filt_pass_thru = TRUE;
+ mh->read_filt_pass_thru = TRUE;
+ mh->readTimeoutHook = NULL;
+ mh->writeTimeoutHook = NULL;
+ mh->readTimer = NULL;
+ mh->writeTimer = NULL;
+ mh->encryption = NULL;
+ mh->isBrokered = FALSE;
+ mh->brokeredPort = 0;
+ mh->peer = 0;
+ if ((mh->raip = AsnIoNew((ASNIO_BIN | ASNIO_IN), (FILE *) NULL, (Pointer) mh, NI_AsnRead, NI_AsnWrite)) == NULL) {
+ LOG_SOCKET(mh->sok, FALSE);
+ NI_CLOSESOCKET(mh->sok);
+ StringCpy(ni_errtext, "unable to allocate new AsnIoPtr (raip)");
+ MemFree(mh);
+ return NULL;
+ }
+ if ((mh->waip = AsnIoNew((ASNIO_BIN | ASNIO_OUT), (FILE *) NULL, (Pointer) mh, NI_AsnRead, NI_AsnWrite)) == NULL) {
+ AsnIoClose(mh->raip);
+ LOG_SOCKET(mh->sok, FALSE);
+ NI_CLOSESOCKET(mh->sok);
+ StringCpy(ni_errtext, "unable to allocate new AsnIoPtr (waip)");
+ MemFree(mh);
+ return NULL;
+ }
+#ifdef OS_MAC
+ /* workaround for weaknesses of Mac OpenTransport */
+ if (UsingOpenTransport())
+ {
+ AsnIoSetBufsize(mh->waip, NI_BLOCKSIZE / 2);
+ dontset = TRUE;
+ }
+#endif
+ if (! dontset)
+ {
+ AsnIoSetBufsize(mh->waip, NI_BLOCKSIZE);
+ }
+ mh->longjump = FALSE;
+ mh->access_time = time(NULL);
+ mh->have_blocked = FALSE;
+ mh->num_queued_bytes = 0;
+ mh->cur_index = 0;
+ mh->queued_data_list = NULL;
+ mh->unblocked_mode = FALSE;
+ return mh;
+} /* MsgMakeHandle */
+
+
+
+/*
+ * Purpose: Destroy the specified message handle
+ *
+ * Parameters:
+ * hp A pointer to the message handle to be destroyed
+ *
+ * Returns:
+ * -1, if the specified pointer is NULL
+ * 0, otherwise
+ *
+ *
+ * Description:
+ * Destroy the specified message handle, close its socket,
+ * close the ASN streams, and free any associated queued data.
+ */
+
+NLM_EXTERN Int2 MsgDestroyHandle(MHandPtr hp)
+{
+ if (hp == NULL)
+ return -1;
+ if (hp->sok != INVALID_SOCKET)
+ {
+ LOG_SOCKET(hp->sok, FALSE);
+ NI_CLOSESOCKET(hp->sok);
+ }
+ if (hp->hostname != NULL)
+ MemFree(hp->hostname);
+ NI_CancelTimer(hp->readTimer);
+ NI_CancelTimer(hp->writeTimer);
+ /* avoid a rare, unexplained condition by zapping the file descriptor */
+ if (hp->raip != NULL && hp->raip->fp == (FILE *) -1)
+ hp->raip->fp = NULL;
+ if (hp->waip != NULL && hp->waip->fp == (FILE *) -1)
+ hp->waip->fp = NULL;
+ AsnIoClose(hp->raip);
+ AsnIoClose(hp->waip);
+ if (hp->encryption != NULL)
+ {
+ NI_DestroyEncrStruct(hp->encryption);
+ }
+ MsgFreeSavedData(hp);
+ MemFree(hp);
+ return 0;
+} /* MsgDestroyHandle */
+
+
+
+/*
+ * Purpose: Set "longjump" error mechanism
+ *
+ * Parameters:
+ * mh A pointer to the message handle for which the "longjump"
+ * error is to be set.
+ *
+ *
+ * Description:
+ * Set the ASN I/O error handler to be a function which will
+ * simply "longjump", and hence return control to the place at
+ * which setjmp() was last called. The "longjump" flag should
+ * be check by a setjmp() caller, prior to calling setjmp(), to
+ * assure that the error handling mechanism is in place.
+ */
+
+NLM_EXTERN void MsgSetLJError(MHandPtr mh)
+{
+ AsnIoSetErrorMsg(mh->raip, NI_ASNIOError);
+ AsnIoSetErrorMsg(mh->waip, NI_ASNIOError);
+ mh->longjump = TRUE;
+} /* MsgSetLJError */
+
+
+
+/*
+ * Purpose: Set the "read" timeout for this message handle
+ *
+ * Parameters:
+ * mh A pointer to the message handle for which the read timeout
+ * is to be set.
+ *
+ *
+ * Description:
+ * Set the "read" timeout for this message handle. A default
+ * value is set-up at the time when the message handle is created.
+ *
+ * Note:
+ * This timeout is also used for the "hung" timeout.
+ */
+
+NLM_EXTERN void MsgSetReadTimeout(MHandPtr mh, int t)
+{
+ mh->r_timeout = t;
+} /* MsgSetReadTimeout */
+
+
+/*
+ * Purpose: Set the "write" timeout for this message handle
+ *
+ * Parameters:
+ * mh A pointer to the message handle for which the write timeout
+ * is to be set.
+ *
+ *
+ * Description:
+ * Set the "write" timeout for this message handle. A default
+ * value is set-up at the time when the message handle is created.
+ */
+
+NLM_EXTERN void MsgSetWriteTimeout(MHandPtr mh, int t)
+{
+ mh->w_timeout = t;
+} /* MsgSetWriteTimeout */
+
+
+/*
+ * Purpose: Set the filter parameters for this message handle
+ *
+ * Parameters:
+ * mh A pointer to the message handle for which the parameters
+ * are to be set.
+ *
+ * ex_proc A pointer to an optional user-defined data structure to be
+ * used by the read and write filters.
+ *
+ * wfilt A write filter function, which may be used, e.g., to collect
+ * statistics, or to compress the data to be written.
+ *
+ * rfilt A read filter function, which may be used, e.g., to collect
+ * statistics, or to decompress the data which was read.
+ *
+ * wfilt_pass Indicates whether wfilt needs to modify the data buffer (e.g.,
+ * this will be FALSE if doing statistics only, but TRUE if
+ * doing data compression).
+ *
+ * rfilt_pass Indicates whether rfilt needs to return a modified data
+ * buffer (e.g., this will be FALSE if doing statistics only,
+ * but TRUE if doing data decompression).
+ *
+ *
+ * Description:
+ * Set the I/O filters for this message handle. A default
+ * value (no filter) is set up at the time when the message
+ * handle is created.
+ *
+ * Note:
+ * It is the responsibility of the higher-level software (i.e.,
+ * not this module) to free any data associated with ex_proc.
+ */
+
+NLM_EXTERN void MsgSetFilters(MHandPtr mh, VoidPtr ex_proc, NI_WriteFilt wfilt,
+ NI_ReadFilt rfilt, Boolean wfilt_pass, Boolean rfilt_pass)
+{
+ if (mh == NULL)
+ return;
+
+ mh->extra_proc_info = ex_proc;
+ mh->write_filter = wfilt;
+ mh->read_filter = rfilt;
+ mh->write_filt_pass_thru = wfilt_pass;
+ mh->read_filt_pass_thru = rfilt_pass;
+}
+
+
+/*
+ * Purpose: Set the timeout hooks for this message handle
+ *
+ * Parameters:
+ * mh A pointer to the message handle for which the parameters
+ * are to be set.
+ *
+ * rhook A hook to be called when the read timeout expires
+ *
+ * whook A hook to be called when the write timeout expires
+ *
+ *
+ * Description:
+ * Set the read and write timeout hooks for this message handle.
+ * A default value (no hook) is set up at the time when the
+ * message handle is created.
+ *
+ * Note:
+ * The write hook is currently usused (6/2/93).
+ */
+
+NLM_EXTERN void MsgSetTimeoutHooks(MHandPtr mh, NI_TimeoutHook rhook, NI_TimeoutHook whook)
+{
+ if (mh == NULL)
+ return;
+
+ mh->readTimeoutHook = rhook;
+ mh->writeTimeoutHook = whook;
+}
+
+/*
+ * Purpose: Initialize the ASN.1 object loader for this module
+ *
+ * Parameters:
+ * none
+ *
+ *
+ * Description:
+ * Dynamically load the ASN.1 static header, if necessary.
+ */
+
+static Boolean
+InitMsg (void)
+{
+ static Boolean loaded = FALSE;
+
+ if (loaded)
+ return TRUE;
+ if (! AsnLoad())
+ return FALSE;
+ loaded = TRUE;
+ return TRUE;
+}
+
+
+/******************************************************************************/
+/* */
+/* Functions used by AsnTool for socket IO (readfunc and writefunc) */
+/* */
+/******************************************************************************/
+
+/*
+ * Purpose: Read some data on behalf of the ASN.1 library
+ *
+ * Parameters:
+ * p A pointer to the message handle structure
+ * buf The buffer into which the data should be read
+ * len Maximum number of bytes to be read
+ *
+ * Returns:
+ * 0, if operating in "unblocked mode", and are unable to
+ * read the requested amount of data
+ * -ETIMEOUT, if blocked, waiting for data to be available, but
+ * none arrived before the read timeout expired
+ * -errno [ system error number ], for other errors
+ * the number of bytes read, otherwise
+ *
+ *
+ * Description:
+ * This is the 'readfunc' function used by ASN.1 to read some
+ * data from the specified ASN.1 I/O stream.
+ *
+ * First, try to read some data from the "queued data", i.e.,
+ * data which was read from the socket on a previous iteration,
+ * but ASN.1 processing failed because there was insufficient
+ * data.
+ *
+ * Subsequently, try to read from the socket. If the data is
+ * unavailable, and running in "blocked" mode, wait for either
+ * the data to appear or for the read timeout to expire.
+ *
+ * In the case where data is read successfully, store it in
+ * the "queued data" area.
+ *
+ * Once data has been read successfully, optionally post-process
+ * it through a filter routine. This routine may, e.g., collect
+ * statistics or provide a de-compression mechanism. If it is
+ * a de-compression mechanism, any data which would not fit in
+ * the original buffer is stored in the "queued data" area, to
+ * be re-read by the next call to this function.
+ */
+
+NLM_EXTERN Int2 LIBCALLBACK NI_AsnRead(Pointer p, CharPtr buf, Uint2 len)
+{
+ MHandPtr mh;
+ int bytesread;
+ int ready;
+ time_t secs0, secs1;
+ fd_set rfds;
+ struct timeval timeout;
+ CharPtr extra_buf;
+ Int4 extra_buf_len;
+ CharPtr extra_encr_buf;
+ Int4 extra_encr_buf_len;
+ NI_NetServHook activityHook;
+
+ mh = (MHandPtr) p;
+
+ /* always provide caller with queued data, if available */
+ if (MsgHaveSavedData(mh))
+ {
+ return MsgReadSavedData(mh, buf, len);
+ }
+
+ mh->access_time = time(NULL);
+
+ DisabVibrant();
+
+ while ((bytesread = NI_READSOCKET(mh->sok, buf, len)) <= 0) {
+#ifndef NETP_INET_PCNFS
+ if (bytesread == 0) {
+ break;
+ }
+#else
+ SOCK_ERRNO = tk_geterrno (mh->sok);
+#endif
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(bytesread);
+#endif
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ continue;
+
+ case EAGAIN:
+#if EAGAIN != EWOULDBLOCK
+ case EWOULDBLOCK:
+#endif /* EAGAIN != EWOULDBLOCK */
+ if (mh->unblocked_mode)
+ {
+ mh->have_blocked = TRUE;
+ EnabVibrant();
+ return 0;
+ }
+ FD_ZERO(&rfds);
+ FD_SET(mh->sok, &rfds);
+ secs0 = secs1 = time(NULL);
+
+ RepeatSelect:
+ /* a simple poll is effected when timeout.tv_sec == 0 */
+ timeout.tv_sec = mh->r_timeout - (secs1 - secs0);
+ timeout.tv_usec = 0;
+ ready = NI_select(mh->sok + 1, &rfds, NULL, NULL, &timeout);
+ if (ready > 0)
+ continue;
+ if (ready == 0)
+ {
+ EnabVibrant();
+ return (-ABS(ETIMEDOUT));
+ }
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ /* update the timeout because select() does not */
+ secs1 = time(NULL);
+ if (secs1 - secs0 > (time_t) mh->r_timeout)
+ secs1 = secs0 + mh->r_timeout;
+ goto RepeatSelect;
+
+ default:
+ break;
+ }
+ EnabVibrant();
+ return (-ABS(SOCK_ERRNO));
+
+ default:
+ EnabVibrant();
+ return (-ABS(SOCK_ERRNO));
+ }
+#ifdef WIN16
+#ifdef NETP_INET_WSOCK
+ {
+ MSG msg;
+
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+#else
+ Yield();
+#endif
+#endif
+ }
+
+ EnabVibrant();
+
+ extra_buf = NULL;
+ extra_encr_buf = NULL;
+ if (mh->read_filter != NULL)
+ {
+ if (mh->read_filt_pass_thru)
+ {
+ mh->read_filter (mh, buf, bytesread, len, NULL, NULL);
+ }
+ else {
+ bytesread = (int) mh->read_filter (mh, buf, bytesread, len,
+ &extra_buf, &extra_buf_len);
+ }
+ }
+
+ if (mh->encryption != NULL && mh->encryption->read_filter != NULL)
+ {
+ bytesread = (int) mh->encryption->read_filter (mh, buf, bytesread,
+ len, &extra_encr_buf,
+ &extra_encr_buf_len);
+ }
+
+ if ((activityHook = NI_ActivityHook()) != NULL)
+ {
+ activityHook (mh, NetServHook_read, bytesread);
+ }
+
+ /* save what we just read */
+ MsgSaveData (mh, buf, bytesread);
+
+ if (extra_buf != NULL)
+ { /* there was some extra data which we didn't get to read */
+ MsgSaveData (mh, extra_buf, (Uint2) extra_buf_len);
+ mh->cur_index -= extra_buf_len; /* enqueue data for next read */
+ MemFree (extra_buf);
+ extra_buf = NULL;
+ }
+
+ if (extra_encr_buf != NULL)
+ { /* there was some extra encrypted data which we didn't get to read */
+ MsgSaveData (mh, extra_encr_buf, (Uint2) extra_encr_buf_len);
+ mh->cur_index -= extra_encr_buf_len; /* enqueue data for next read */
+ MemFree (extra_encr_buf);
+ extra_encr_buf = NULL;
+ }
+
+ return bytesread;
+} /* NI_AsnRead */
+
+
+
+/*
+ * Purpose: Write some data on behalf of the ASN.1 library
+ *
+ * Parameters:
+ * p A pointer to the message handle structure
+ * buf The buffer into which the data should be written
+ * len Number of bytes to be written
+ *
+ * Returns:
+ * -ETIMEOUT, if unable to write the data before the write
+ * timeout expired
+ * -errno [ system error number ], for other errors
+ * the number of bytes written, otherwise
+ *
+ *
+ * Description:
+ * This is the 'writefunc' function used by ASN.1 to write some
+ * data to the specified ASN.1 I/O stream.
+ *
+ * If unable to write the data immediately, block until it is
+ * possible to write the data, or until the write timeout expires.
+ *
+ * The data to be output is optionally passed through a filter
+ * routine. This routine may, for example, collect statistics
+ * or compress the data to be written.
+ *
+ * Note:
+ * It is relatively unlikely that "writing" will block, thus
+ * causing the calling application to block. For "writing" to
+ * block, there would need to be flow control imposed in the
+ * TCP/IP protocol suite, which is an unlikely occurance when
+ * passing small quantities of data.
+ */
+
+NLM_EXTERN Int2 LIBCALLBACK NI_AsnWrite(Pointer p, CharPtr buf, Uint2 len)
+{
+ MHandPtr mh;
+ Int2 byteswrit, bytesleft;
+ int ready;
+ fd_set wfds;
+ time_t secs0, secs1 = 0;
+ struct timeval timeout;
+ CharPtr newbuf;
+ Uint2 newlen;
+ CharPtr tmpbuf = NULL;
+ NI_NetServHook activityHook;
+
+ mh = (MHandPtr) p;
+ mh->access_time = time(NULL);
+
+ newbuf = buf;
+ newlen = len;
+ if (mh->write_filter != NULL)
+ {
+ if (mh->write_filt_pass_thru)
+ { /* write filter is "pass-through only" */
+ mh->write_filter (mh, buf, len, NULL);
+ }
+ else { /* write filter modifies buffer to be written */
+ tmpbuf = (CharPtr) MemNew(len + 5);
+ newlen = (Uint2) mh->write_filter(mh, buf, len, tmpbuf);
+ newbuf = tmpbuf;
+ }
+ }
+ if (mh->encryption != NULL && mh->encryption->write_filter != NULL)
+ {
+ tmpbuf = (CharPtr) MemNew(len + 9);
+ newlen = (Uint2) mh->encryption->write_filter(mh, newbuf, newlen, tmpbuf);
+ newbuf = tmpbuf;
+ }
+
+ if ((activityHook = NI_ActivityHook()) != NULL)
+ {
+ activityHook (mh, NetServHook_write, newlen);
+ }
+
+ DisabVibrant();
+
+ for (bytesleft = newlen; bytesleft > 0; bytesleft -= byteswrit,
+ newbuf += byteswrit) {
+ while ((byteswrit = NI_WRITESOCKET(mh->sok, newbuf, bytesleft)) <= 0) {
+ if (byteswrit == 0)
+ {
+#ifdef NETP_INET_NEWT
+ /* this is a real kludge to deal with the fact that NEWT */
+ /* sometimes returns 0 on a send() for no good reason; we simulate*/
+ /* that we were told that the send() would block */
+ byteswrit = -EWOULDBLOCK;
+#else
+ WriteCleanup(tmpbuf);
+ return 0;
+#endif /* NETP_INET_NEWT */
+ }
+
+#ifdef NETP_INET_NEWT
+ SOCK_ERRNO = ABS(byteswrit);
+#endif
+#ifdef NETP_INET_PCNFS
+ SOCK_ERRNO = tk_geterrno (mh->sok);
+#endif
+
+ byteswrit = 0; /* don't allow byte count to become messed up */
+
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ continue;
+
+ case EAGAIN:
+#if EAGAIN != EWOULDBLOCK
+
+ case EWOULDBLOCK:
+#endif
+#ifdef NETP_INET_NEWT
+ /* work-around for bug in version 2.00 of NEWT; a select()*/
+ /* will never recognize when it's O.K. to write to a */
+ /* socket */
+ if (secs1 == 0)
+ {
+ secs1 = secs0 = time(NULL);
+ }
+ else {
+ secs1 = time(NULL);
+ if (secs1 - secs0 > (time_t) mh->w_timeout)
+ {
+ WriteCleanup(tmpbuf);
+ return (-ABS(ETIMEDOUT));
+ }
+ }
+ break;
+#endif
+ FD_ZERO(&wfds);
+ FD_SET(mh->sok, &wfds);
+ secs0 = secs1 = time(NULL);
+
+ RepeatSelect:
+ /* a simple poll is effected when timeout.tv_sec == 0 */
+ timeout.tv_sec = mh->w_timeout - (secs1 - secs0);
+ timeout.tv_usec = 0;
+ ready = NI_select(mh->sok + 1, NULL, &wfds, NULL, &timeout);
+ if (ready > 0)
+ continue;
+ if (ready == 0)
+ {
+ WriteCleanup(tmpbuf);
+ return (-ABS(ETIMEDOUT));
+ }
+ switch (SOCK_ERRNO) {
+ case EINTR:
+ /* update the timeout because select() does not */
+ secs1 = time(NULL);
+ if (secs1 - secs0 > (time_t) mh->w_timeout)
+ secs1 = secs0 + mh->w_timeout;
+ goto RepeatSelect;
+ default:
+ break;
+ }
+ WriteCleanup(tmpbuf);
+ return (-ABS(SOCK_ERRNO));
+
+ default:
+ WriteCleanup(tmpbuf);
+ return (-ABS(SOCK_ERRNO));
+ }
+#ifdef WIN16
+#ifdef NETP_INET_WSOCK
+ {
+ MSG msg;
+
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+#else
+ Yield();
+#endif
+#endif
+ }
+ }
+
+ WriteCleanup(tmpbuf);
+ return (Int2)len;
+} /* NI_AsnWrite */
+
+
+/*
+ * Purpose: Clean-up for NI_AsnWrite
+ *
+ * Parameters:
+ * tmpbuf Temporary buffer to be freed, if non-NULL
+ *
+ *
+ * Description:
+ * Frees temporary buffer, and re-enables Vibrant for user
+ * input. Used because there are so many return paths from
+ * NI_AsnWrite.
+ *
+ */
+
+static void
+WriteCleanup (CharPtr tmpbuf)
+{
+ if (tmpbuf != NULL)
+ {
+ MemFree (tmpbuf);
+ }
+ EnabVibrant();
+}
+
+
+/*
+ * Purpose: ASN.1 Error handling
+ *
+ * Parameters:
+ * level Error code to be returned
+ * str Error text generated by ASN.1
+ *
+ *
+ * Description:
+ * This is the error handling function used by ASN.1; it is called
+ * when any ASN.1 I/O error occurs.
+ *
+ * When an ASN.1 I/O error occurs, this function stores the
+ * error text in a safe place, and "longjumps", returning
+ * control to a point where setjmp() was last called. This point
+ * should occur in a relatively high-level function (above the
+ * ASN.1 library).
+ *
+ * Note:
+ * Due to the implementation of setjmp()/longjmp(), if level is
+ * 0, then the setjmp() caller will see the value 1; this
+ * mechanism is used to allow a setjmp() caller to distinguish
+ * between the case when they have just "set" the jump environment
+ * (return value == 0), and all other cases.
+ */
+
+NLM_EXTERN void LIBCALLBACK NI_ASNIOError(Int2 level, CharPtr str)
+{
+ StringCpy(ni_errtext, str);
+ LongJump(ni_env, level);
+} /* NI_ASNIOError */
+
+
+
+#if defined(NETP_INET_NEWT) || defined(NETP_INET_WSOCK)
+
+/*
+ * Purpose: Implementation of blocked select() for use with NEWT and WSOCK
+ *
+ * Parameters:
+ * width "width" of file descriptor bits maps
+ * rfds Read file descriptor bit maps
+ * wfds Write file descriptor bit maps
+ * xfds Exception file descriptor bit maps
+ *
+ * Returns:
+ * 0, if the timeout period elapses
+ * -1, if an error occurred
+ * the number of available file descriptors (selected file
+ * descriptors which are available for processing), otherwise
+ *
+ *
+ * Description:
+ * Provide a "blocked" select() mechanism, because NEWT does
+ * not provide one.
+ *
+ * Note:
+ * When calling select(), the width of the file descriptor
+ * maps is increased by one, to handle an off-by-one error
+ * associated with the NEWT library.
+ *
+ * This function is used in WinSock (rather than WinSock's
+ * select function) to ensure that message removal/dispatching
+ * is done in a manner which does not interfere with scrollbar
+ * management.
+ */
+
+NLM_EXTERN int NI_poll_select(int width, fd_set PNTR rfds, fd_set PNTR wfds, fd_set PNTR xfds, struct timeval PNTR timeout)
+{
+ fd_set trfds, twfds, txfds;
+ int rdy;
+ time_t t_end;
+ struct timeval tmout;
+
+ if (rfds != NULL)
+ Nlm_MemCopy(&trfds, rfds, sizeof(trfds));
+ if (wfds != NULL)
+ Nlm_MemCopy(&twfds, wfds, sizeof(twfds));
+ if (xfds != NULL)
+ Nlm_MemCopy(&txfds, xfds, sizeof(txfds));
+
+ t_end = timeout->tv_sec + Nlm_GetSecs();
+ tmout.tv_sec = 0;
+ tmout.tv_usec = 0;
+#ifdef NETP_INET_WSOCK
+ width--;
+#endif
+ while (Nlm_GetSecs() < t_end) {
+ if (rfds != NULL)
+ Nlm_MemCopy(rfds, &trfds, sizeof(trfds));
+ if (wfds != NULL)
+ Nlm_MemCopy(wfds, &twfds, sizeof(twfds));
+ if (xfds != NULL)
+ Nlm_MemCopy(xfds, &txfds, sizeof(txfds));
+
+#ifdef NETP_INET_WSOCK
+ {
+ MSG msg;
+ Boolean done = FALSE;
+
+ /* get all the available messages, avoiding WM_LBUTTONUP since */
+ /* this will cause scroll bars to hang, for some unknown reason */
+ while (! done)
+ {
+ done = TRUE;
+ if (PeekMessage(&msg, NULL, 0, WM_LBUTTONUP-1, PM_REMOVE))
+ {
+ done = FALSE;
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ if (PeekMessage(&msg, NULL, WM_LBUTTONUP+1, 0xffff, PM_REMOVE))
+ {
+ done = FALSE;
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ }
+#else
+#ifdef WIN16
+ Yield();
+#endif
+#endif
+ /* select with (width + 1) because NetManage boundary condition error */
+
+ if ((rdy = select((width + 1), rfds, wfds, xfds, &tmout)) != 0) {
+ if (rdy < 0) { /* error */
+#ifdef NETP_INET_NEWT
+ errno = ABS(rdy);
+#endif
+ rdy = -1;
+ }
+ return rdy;
+ }
+
+ }
+ return 0; /* timed out */
+} /* NI_poll_select */
+
+#endif
+
+
+#ifdef NI_BLOCK_WITH_FUNCTION
+
+
+/*
+ * Purpose: Implementation of setting non-blocked-socket mode for platforms
+ * for which it is difficult to perform this functionality within
+ * a macro.
+ *
+ * Parameters:
+ * fd Socket file descriptor
+ *
+ */
+
+NLM_EXTERN int NI_SetNonBlocking (int fd)
+{
+ int mode = 1;
+
+#ifdef NETP_INET_WSOCK
+ u_long lmode = 1;
+ return ioctlsocket (fd, FIONBIO, &lmode);
+#endif
+
+#ifdef NETP_INET_PCNFS
+ return tk_ioctl (fd, FIONBIO, &mode);
+#endif
+#ifdef NETP_INET_TGV
+ return socket_ioctl (fd, FIONBIO, &mode);
+#endif
+#ifdef NETP_INET_WPW
+ long lmode = 0;
+ return ioctl (fd, FIONBIO, &mode);
+#endif
+#ifdef NETP_INET_TWG
+ /**************************************************************************/
+ /* WARNING: THIS IS CURRENTLY NOT IMPLEMENTED PROPERLY BECAUSE WE (W. */
+ /* GILBERT/J. EPSTEIN) ARE NOT ABLE TO MAKE NETWORK SERVICES */
+ /* OPERATE PROPERLY IN NON-BLOCKING MODE. AT SOME FUTURE DATE, */
+ /* THE REMAINDER OF NETWORK SERVICES SHOULD BE DEBUGGED AND THE */
+ /* FOLLOWING LINE SHOULD READ: lmode = 1 */
+ /* 17 June 1993 */
+ /**************************************************************************/
+ /*
+ long lmode = 0;
+ return ioctl (fd, FIONBIO, &lmode);
+ */
+ return 0;
+#endif
+#ifdef NETP_INET_UCX
+ /**************************************************************************/
+ /* WARNING: THIS IS CURRENTLY UNIMPLEMENTED BECAUSE IT IS NOT CLEAR THAT */
+ /* IT IS POSSIBLE TO SPECIFY BLOCKING/NONBLOCKING MODE FOR UCX */
+ /* 22 June 1993 */
+ /**************************************************************************/
+ return 0;
+#endif
+}
+
+/*
+ * Purpose: Implementation of setting blocked-socket mode for platforms
+ * for which it is difficult to perform this functionality within
+ * a macro.
+ *
+ * Parameters:
+ * fd Socket file descriptor
+ *
+ */
+
+NLM_EXTERN int NI_SetBlocking (int fd)
+{
+ int mode = 0;
+
+#ifdef NETP_INET_WSOCK
+ u_long lmode = 0;
+ return ioctlsocket (fd, FIONBIO, &lmode);
+#endif
+
+#ifdef NETP_INET_PCNFS
+ return tk_ioctl (fd, FIONBIO, &mode);
+#endif
+#ifdef NETP_INET_TGV
+ return socket_ioctl (fd, FIONBIO, &mode);
+#endif
+#ifdef NETP_INET_WPW
+ long lmode = 0;
+ return ioctl (fd, FIONBIO, &lmode);
+#endif
+#ifdef NETP_INET_TWG
+ /*
+ long lmode = 0;
+ return ioctl (fd, FIONBIO, &lmode);
+*/
+ return 0;
+#endif
+#ifdef NETP_INET_UCX
+ /**************************************************************************/
+ /* WARNING: THIS IS CURRENTLY UNIMPLEMENTED BECAUSE IT IS NOT CLEAR THAT */
+ /* IT IS POSSIBLE TO SPECIFY BLOCKING/NONBLOCKING MODE FOR UCX */
+ /* 22 June 1993 */
+ /**************************************************************************/
+ return 0;
+#endif
+}
+
+#endif /* BLOCK_WITH_FUNCTION */
+
+
+/*
+ * Purpose: Test as to whether there's available data already enqueued
+ *
+ * Parameters:
+ * mh Pointer to "message handle" data structure
+ *
+ * Returns:
+ * FALSE, if there is no data already enqueued
+ * TRUE, otherwise
+ *
+ *
+ * Description:
+ * Determine whether there is currently enqueued data on a
+ * "message handle" data structure.
+ */
+
+static Boolean
+MsgHaveSavedData(MHandPtr mh)
+{
+ if (!mh->unblocked_mode)
+ return FALSE;
+ if (mh->queued_data_list == NULL)
+ return FALSE;
+ if (mh->num_queued_bytes <= 0)
+ return FALSE;
+ return (mh->cur_index < mh->num_queued_bytes);
+}
+
+
+/*
+ * Purpose: Read data which was previously stored in this "message handle"
+ *
+ * Parameters:
+ * mh Pointer to "message handle" data structure
+ * buf Buffer where data should be stored
+ * len Maximum number of bytes to read out
+ *
+ * Returns:
+ * the number of bytes read from the enqueued data list
+ *
+ *
+ * Description:
+ * Return up to len bytes of enqueued data, by traversing
+ * the enqueued data structure, beginning with the location
+ * where the "current byte" pointer is currently pointing.
+ *
+ * Note:
+ * The enqueued data is stored in a list of chained blocks, where
+ * at all times, all the blocks are full, except (possibly) the
+ * last block.
+ */
+
+#define MSG_READ_BLOCK_SIZE 1024
+
+static int
+MsgReadSavedData(MHandPtr mh, CharPtr buf, Uint2 len)
+{
+ NodePtr startpt;
+ NodePtr blk;
+ int addl_queue_data;
+ int local_index;
+ int bytes_copied;
+ int data_in_this_block;
+ int bytes_to_copy;
+
+ if (mh->queued_data_list == NULL || len <= 0 || mh->num_queued_bytes == 0)
+ return 0;
+ blk = startpt = mh->queued_data_list;
+ addl_queue_data = mh->num_queued_bytes - mh->cur_index;
+ local_index = 0;
+ bytes_copied = 0;
+
+ /* traverse the portion of the list which is necessary to get past */
+ /* the current "file" pointer, and then copy up to len bytes of */
+ /* data from the remaining blocks */
+ do {
+ /* if ( this is the last block ) then */
+ if (mh->num_queued_bytes - local_index < MSG_READ_BLOCK_SIZE)
+ data_in_this_block = mh->num_queued_bytes % MSG_READ_BLOCK_SIZE;
+ else
+ data_in_this_block = MSG_READ_BLOCK_SIZE;
+
+ /* if ( there is more data to be skipped over ) then */
+ if (local_index < mh->cur_index)
+ { /* there is more data to be skipped over */
+ if (local_index + data_in_this_block <= mh->cur_index)
+ { /* skip this block */
+ local_index += data_in_this_block;
+ continue;
+ }
+ else { /* skip a portion of this block, and copy the remainder */
+ data_in_this_block -= (mh->cur_index - local_index);
+ local_index = mh->cur_index;
+ }
+ }
+
+ bytes_to_copy = MIN((int) len, data_in_this_block);
+ MemCopy(buf, blk->elem, bytes_to_copy);
+ buf += bytes_to_copy;
+ len -= bytes_to_copy;
+ bytes_copied += bytes_to_copy;
+ mh->cur_index += bytes_to_copy;
+ local_index += bytes_to_copy;
+ } while ( (blk = ListGetNext(blk)) != startpt && len > 0);
+
+ return bytes_copied;
+}
+
+
+
+/*
+ * Purpose: Store len bytes of data from a buffer, for future use
+ *
+ * Parameters:
+ * mh Pointer to "message handle" data structure
+ * buf Buffer of data to be copied
+ * len Number of bytes to save
+ *
+ *
+ * Description:
+ * Store len bytes of data at the end of a list of "enqueued data."
+ * After finding the current end of the queue, data is added
+ * to the final block (up to its capacity), and then, if needed,
+ * additional blocks are allocated to store the remaining data.
+ */
+
+static void
+MsgSaveData(MHandPtr mh, CharPtr buf, Uint2 len)
+{
+ NodePtr tail;
+ int bytes_to_copy;
+ int starting_byte;
+ CharPtr newdata;
+
+ if (len == 0 || !mh->unblocked_mode)
+ return;
+
+ /* get to the correct place in the list, and then start storing */
+
+ tail = mh->queued_data_list;
+
+ /* point to tail of list; in a ring, the element before the head is the */
+ /* tail */
+ if (tail != NULL)
+ tail = tail->last;
+
+ /* if ( more room in the current element ) then */
+ if ((starting_byte = mh->num_queued_bytes % MSG_READ_BLOCK_SIZE) != 0)
+ {
+ bytes_to_copy = MIN(MSG_READ_BLOCK_SIZE - starting_byte, (int) len);
+ newdata = (CharPtr) tail->elem;
+ MemCopy (&newdata[starting_byte], buf, bytes_to_copy);
+ len -= bytes_to_copy;
+ buf += len;
+ mh->num_queued_bytes += bytes_to_copy;
+ }
+
+ /* while ( there is more data to be copied ) */
+ while (len > 0)
+ { /* create a new element, and copy data into that element */
+
+ newdata = MemNew(MSG_READ_BLOCK_SIZE);
+ bytes_to_copy = MIN(MSG_READ_BLOCK_SIZE, len);
+ MemCopy (newdata, buf, bytes_to_copy);
+ buf += bytes_to_copy;
+ len -= bytes_to_copy;
+ mh->num_queued_bytes += bytes_to_copy;
+ tail = ListInsert(newdata, tail);
+ }
+
+ mh->cur_index = mh->num_queued_bytes;
+
+ if (tail == NULL)
+ mh->queued_data_list = NULL;
+ else
+ mh->queued_data_list = tail->next;
+}
+
+
+
+/*
+ * Purpose: Free data associated with an "enqueued data list"
+ *
+ * Parameters:
+ * mh Pointer to "message handle" data structure
+ *
+ *
+ * Description:
+ * Free all the message elements associated with a list of
+ * enqueued data, and set other message handle elements to
+ * appropriate values such that software accessing those structures
+ * will not, erroneously, think that there is valid enqueued data
+ * in the structure.
+ */
+
+static void
+MsgFreeSavedData (MHandPtr mh)
+{
+ NodePtr np;
+ CharPtr elem;
+
+ mh->unblocked_mode = FALSE;
+ mh->have_blocked = FALSE;
+ mh->num_queued_bytes = 0;
+ mh->cur_index = 0;
+
+ np = mh->queued_data_list;
+
+ mh->queued_data_list = NULL;
+
+ while (np != NULL)
+ {
+ elem = (CharPtr) np->elem;
+ if (elem != NULL)
+ MemFree (elem);
+ np = ListDelete(np);
+ }
+}
+
+
+/*
+ * Purpose: Set and pop the hour-glass cursor
+ *
+ * Parameters:
+ * none
+ *
+ * Description:
+ * According to the NEWT/NetManage documentation, it is
+ * beneficial to make the cursor into an hourglass to block-out
+ * unwanted events during some socket calls.
+ */
+
+#if defined(NETP_INET_NEWT) || defined(NETP_INET_WSOCK)
+static HCURSOR saveCursor = NULL;
+
+static void SetHourGlass(void)
+{
+#ifdef NETP_INET_NEWT
+ static HCURSOR hourCursor;
+
+ hourCursor = LoadCursor(NULL, IDC_WAIT);
+ saveCursor = SetCursor(hourCursor);
+#endif
+}
+
+static void PopHourGlass(void)
+{
+#ifdef NETP_INET_NEWT
+ if (saveCursor != NULL)
+ SetCursor(saveCursor);
+#endif
+}
+#endif /* NETP_INET_NEWT */
+
diff --git a/network/nsclilib/ni_msg.h b/network/nsclilib/ni_msg.h
new file mode 100644
index 00000000..9d409473
--- /dev/null
+++ b/network/nsclilib/ni_msg.h
@@ -0,0 +1,399 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_msg.h
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 5/12/92 Epstein Converted tabs to spaces
+*
+* 04-21-93 Schuler Changed declaration of NI_AsnNew(), NI_AsnWrite(),
+* and NI_ASNIOError() to use LIBCALLBACK calling convention.
+*
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_msg.h,v $
+* Revision 6.0 1997/08/25 18:39:06 madden
+* Revision changed to 6.0
+*
+* Revision 5.4 1997/07/01 19:13:00 vakatov
+* [WIN32] DLL'd "netcli.lib"
+*
+* Revision 5.3 1997/01/28 21:24:50 epstein
+* eliminate reference to ni_list.h
+*
+ * Revision 5.2 1996/06/27 18:15:06 kans
+ * extra comma removed
+ *
+ * Revision 5.1 1996/06/27 17:18:02 epstein
+ * add load-balancing
+ *
+ * Revision 5.0 1996/05/28 14:11:55 ostell
+ * Set to revision 5.0
+ *
+ * Revision 4.1 1995/11/27 20:59:29 epstein
+ * add client support for direct-connection services
+ *
+ * Revision 4.0 95/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.17 1995/05/24 12:08:49 epstein
+ * add support for tracking of how many times a client IP has used a service within a time interval
+ *
+ * Revision 1.16 95/05/17 17:52:44 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NI_MSG_
+#define _NI_MSG_
+
+#include <setjmp.h>
+
+#include "ncbinet.h"
+#include "ni_net.h"
+
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef WIN16
+#define Jumpbuf CATCHBUF
+#define SetJump Catch
+#define LongJump Throw
+#else
+#define Jumpbuf jmp_buf
+#define SetJump setjmp
+#define LongJump longjmp
+#endif
+
+#define NI_BLOCK_TIMEOUT 60
+#define NI_BLOCKSIZE 4096 /* matches TCP_MAXSEG in many systems */
+
+/* VARS */
+
+extern Uint4 conid; /* globally unique connection ID counter */
+
+
+/* TYPES */
+
+#define MsgType enum msgtype
+MsgType {
+ NI_UNKNOWN = 0,
+ NI_ACK,
+ NI_NACK,
+ NI_LOGIN,
+ NI_SVC_LIST,
+ NI_SVC_REQUEST,
+ NI_SVC_RESPONSE,
+ NI_COMMAND,
+ NI_ACCT,
+ NI_CATALOG,
+ NI_SVC_PRE_RESPONSE,
+ NI_STATUS
+};
+
+#define MsgCommand enum msgcommand
+MsgCommand {
+ NI_SEND_SVCLIST = 1, /* send me a list of your services */
+ NI_SEND_CATALOG, /* send me the catalog (dispatcher) */
+ NI_KILL, /* kill yourself */
+ NI_POLL /* health check poll */
+};
+
+typedef struct NIPubKey { /* internal format for public key */
+ Int2 bits; /* bits used in modulus */
+ ByteStorePtr modulus;
+ ByteStorePtr exponent;
+} NIPubKey, PNTR NIPubKeyPtr;
+
+typedef struct NIDispInfo {
+ Int4 serialno; /* unique dispatcher serial # */
+ Boolean isalternatelist;/* is this an alternate disp-list ? */
+ int numdispatchers; /* number of dispatchers in disp-list */
+ CharPtr PNTR displist; /* list of dispatchers */
+ NIPubKeyPtr pubKey; /* public RSA key */
+} NIDispInfo, PNTR NIDispInfoPtr;
+
+typedef struct NIAck {
+ Uint4 seqno;
+ NIDispInfoPtr dispinfo;
+ CharPtr adminInfo; /* info. regarding guest's admin */
+ CharPtr motd; /* message of the day */
+} NIAck, PNTR NIAckPtr;
+
+typedef struct NINack {
+ Uint4 seqno;
+ NI_Error code;
+ CharPtr reason;
+ NIDispInfoPtr dispinfo;
+} NINack, PNTR NINackPtr;
+
+typedef struct NILogin {
+ Uint4 seqno;
+ NI_UidPtr uid; /* ID structure */
+ CharPtr password; /* must be encrypted */
+ Int4 dispserialno; /* unique dispatcher serial # */
+ Boolean encryptionDesired; /* encryption desired by client */
+ NIPubKeyPtr pubKey; /* public RSA key */
+ ByteStorePtr desKey; /* DES key for ncbid<->dispd comm */
+ Int2 connectDelay; /* connection delay (seconds) */
+ Uint2 server_port; /* port on server mashine */
+} NILogin, PNTR NILoginPtr;
+
+typedef struct NISvcList {
+ Uint4 seqno;
+ NIToolsetPtr toolset;
+ Boolean knowsTracking; /* does this ncbid know about tracking? */
+} NISvcList, PNTR NISvcListPtr;
+
+typedef struct NITicket {
+ Uint4 seqno; /* ticket sequence number */
+ ByteStorePtr confounding_rand_num;
+ ByteStorePtr client_ip_1; /* ticket is valid from either of */
+ ByteStorePtr client_ip_2; /* these 2 addresses */
+ ByteStorePtr server_ip; /* this ticket is only valid at this server IP */
+ ByteStorePtr client_des_key; /* encription key */
+ ByteStorePtr ticket_expiration; /* expiration time */
+ ByteStorePtr checksum; /* checksum of the ticket */
+} NITicket, PNTR NITicketPtr;
+
+typedef struct NISvcReq {
+ Uint4 seqno;
+ Uint4 conid; /* for client accounting */
+ NI_UidPtr uid;
+ ReqPtr request;
+ Uint4 platform; /* client's platform */
+ CharPtr applId; /* application identifier */
+ ByteStorePtr desKey;
+ Boolean wantPreResponse; /* client wants to know server's IP */
+ Uint4 server_ip;
+ Uint2 server_port; /* port on server machine */
+ Boolean want_ticket; /* request of direct connection */
+ NITicketPtr ticket; /* ticket for direct connection */
+} NISvcReq, PNTR NISvcReqPtr;
+
+typedef struct NISvcResp {
+ Uint4 seqno;
+ ReqPtr request;
+} NISvcResp, PNTR NISvcRespPtr;
+
+typedef struct NICmd {
+ Uint4 seqno;
+ MsgCommand code;
+} NICmd, PNTR NICmdPtr;
+
+typedef struct NIPreResp {
+ Uint4 seqno;
+ Uint4 server_ip;
+} NIPreResp, PNTR NIPreRespPtr;
+
+typedef struct NIAcct {
+ Uint4 seqno;
+ Uint4 conid;
+ CharPtr jobname;
+ Uint4 usertime;
+ Uint4 systemtime;
+} NIAcct, PNTR NIAcctPtr;
+
+typedef union NIMSun {
+ NIAckPtr ack;
+ NINackPtr nack;
+ NILoginPtr login;
+ NISvcListPtr svclist;
+ NISvcReqPtr svcreq;
+ NISvcRespPtr svcresp;
+ NICmdPtr command;
+ NIAcctPtr acct;
+ NICatalogPtr catalog;
+ NIStatusPtr status;
+ NIPreRespPtr preresp;
+} NIMSun, PNTR NIMSunPtr;
+
+typedef struct NIMessage {
+ MsgType type;
+ Uint4 conid; /* for ACKing */
+ NIMSun msun; /* message structure union */
+} NIMessage, PNTR NIMsgPtr;
+
+
+/* FUNCTION PROTOTYPES */
+
+NLM_EXTERN NIMsgPtr MsgRead PROTO((MHandPtr handle, Boolean unblocked));
+
+NLM_EXTERN Int2 MsgWrite PROTO((MHandPtr handle, NIMsgPtr mp, Boolean noDestroy));
+
+NLM_EXTERN NIMsgPtr MsgBuild PROTO((MsgType type, Uint4 conn, VoidPtr stp));
+
+NLM_EXTERN Int2 MsgDestroy PROTO((NIMsgPtr mp));
+
+NLM_EXTERN MHandPtr MsgMakeHandle PROTO((Boolean createSocket));
+
+NLM_EXTERN Int2 MsgDestroyHandle PROTO((MHandPtr hp));
+
+NLM_EXTERN void MsgSetLJError PROTO((MHandPtr mh));
+
+NLM_EXTERN void MsgSetReadTimeout PROTO((MHandPtr mh, int t));
+
+NLM_EXTERN void MsgSetWriteTimeout PROTO((MHandPtr mh, int t));
+
+NLM_EXTERN void MsgSetFilters PROTO((MHandPtr mh, VoidPtr ex_proc, NI_WriteFilt wfilt, NI_ReadFilt rfilt, Boolean wfilt_pass, Boolean rfilt_pass));
+
+NLM_EXTERN void MsgSetTimeoutHooks PROTO((MHandPtr mh, NI_TimeoutHook rhook, NI_TimeoutHook whook));
+
+NLM_EXTERN Int2 LIBCALLBACK NI_AsnRead PROTO((Pointer p, CharPtr buf, Uint2 len));
+
+NLM_EXTERN Int2 LIBCALLBACK NI_AsnWrite PROTO((Pointer p, CharPtr buf, Uint2 len));
+
+NLM_EXTERN void LIBCALLBACK NI_ASNIOError PROTO((Int2 level, CharPtr str));
+
+NLM_EXTERN int NI_poll_select PROTO((int width, fd_set PNTR rfds, fd_set PNTR wfds, fd_set PNTR xfds, struct timeval PNTR timeout));
+NLM_EXTERN int NI_SetBlocking PROTO((int sock));
+NLM_EXTERN int NI_SetNonBlocking PROTO((int sock));
+
+
+/* Message Type Functions */
+
+NLM_EXTERN NIAckPtr NI_MakeMsgAck PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgAck PROTO((NIAckPtr));
+
+NLM_EXTERN NINackPtr NI_MakeMsgNack PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgNack PROTO((NINackPtr));
+
+NLM_EXTERN NILoginPtr NI_MakeMsgLogin PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgLogin PROTO((NILoginPtr));
+
+NLM_EXTERN NISvcListPtr NI_MakeMsgSvclist PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgSvclist PROTO((NISvcListPtr));
+
+NLM_EXTERN NISvcReqPtr NI_MakeMsgSvcreq PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgSvcreq PROTO((NISvcReqPtr));
+
+NLM_EXTERN NISvcRespPtr NI_MakeMsgSvcresp PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgSvcresp PROTO((NISvcRespPtr));
+
+NLM_EXTERN NICmdPtr NI_MakeMsgCmd PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgCmd PROTO((NICmdPtr));
+
+NLM_EXTERN NIPreRespPtr NI_MakeMsgPreResp PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgPreResp PROTO((NIPreRespPtr));
+
+NLM_EXTERN NIAcctPtr NI_MakeMsgAcct PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgAcct PROTO((NIAcctPtr));
+
+NLM_EXTERN NISvcPtr NI_MakeService PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyService PROTO((NISvcPtr));
+
+NLM_EXTERN NIResPtr NI_MakeResource PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyResource PROTO((NIResPtr));
+
+NLM_EXTERN NIRegionPtr NI_MakeRegion PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyRegion PROTO((NIRegionPtr));
+
+NLM_EXTERN ReqPtr NI_MakeRequest PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyRequest PROTO((ReqPtr));
+
+NLM_EXTERN NITicketPtr NI_MakeTicket PROTO((void));
+
+NLM_EXTERN NICatalogPtr NI_MakeMsgCatalog PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgCatalog PROTO((NICatalogPtr));
+
+NLM_EXTERN NIStatusPtr NI_MakeMsgStatus PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyMsgStatus PROTO((NIStatusPtr));
+
+NLM_EXTERN NI_UidPtr NI_MakeUid PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyUid PROTO((NI_UidPtr));
+
+NLM_EXTERN NIPubKeyPtr NI_MakePubKey PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyPubKey PROTO((NIPubKeyPtr));
+
+NLM_EXTERN int NI_ReadPubKey PROTO((AsnIoPtr extaip, AsnTypePtr extatp, NIPubKeyPtr dip));
+NLM_EXTERN void NI_WritePubKey PROTO((AsnIoPtr extaip, AsnTypePtr extatp, NIPubKeyPtr dip));
+
+NLM_EXTERN NIDispInfoPtr NI_MakeDispInfo PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyDispInfo PROTO((NIDispInfoPtr));
+
+NLM_EXTERN int NI_ReadDispInfo PROTO((AsnIoPtr extaip, AsnTypePtr extatp, NIDispInfoPtr dip));
+NLM_EXTERN void NI_WriteDispInfo PROTO((AsnIoPtr extaip, AsnTypePtr extatp, NIDispInfoPtr dip));
+
+NLM_EXTERN NIToolsetPtr NI_MakeToolset PROTO((void));
+
+NLM_EXTERN Int2 NI_DestroyToolset PROTO((NIToolsetPtr tsp));
+
+NLM_EXTERN NIToolsetPtr NI_GetCatToolset PROTO((NIToolsetPtr tsp));
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif
diff --git a/network/nsclilib/ni_net.h b/network/nsclilib/ni_net.h
new file mode 100644
index 00000000..704fd50e
--- /dev/null
+++ b/network/nsclilib/ni_net.h
@@ -0,0 +1,214 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_net.h
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+* 05-12-92 Epstein Converted tabs to spaces
+* 01-21-94 Schuler Added NETP_INET_MACTCP symbol
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: ni_net.h,v $
+* Revision 6.0 1997/08/25 18:39:09 madden
+* Revision changed to 6.0
+*
+* Revision 5.0 1996/05/28 14:11:55 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:56:32 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.18 1995/07/05 14:23:58 kans
+ * move #include <sys/select.h> to ncbilcl.r6k
+ *
+ * Revision 1.17 1995/05/17 17:52:48 epstein
+ * add RCS log revision history
+ *
+*/
+
+#ifndef _NI_NET_
+
+#if !defined(COMP_MPW) && !defined(OS_VMS) && !defined(COMP_METRO)
+#include <fcntl.h>
+#endif /* skip for COMP_MPW or OS_VMS or COMP_METRO */
+
+#if defined(OS_MAC) && !defined(NETP_defined)
+#define NETP_INET_MACTCP
+#endif
+
+#ifdef NETP_INET_MACTCP
+#include <netdb.h>
+#include <s_types.h>
+#include <s_socket.h>
+#include <s_ioctl.h>
+#include <neti_in.h>
+#include <a_inet.h>
+#include <s_time.h>
+#define _NI_NET_
+#endif /* NETP_INET_MACTCP */
+
+#ifdef NETP_INET_WSOCK
+#undef NEAR
+#undef FAR
+#undef Beep
+#undef PASCAL
+#undef CDECL
+#undef TRUE
+#undef FALSE
+#define STRICT
+#include <windows.h>
+#include <winsock.h>
+#define _NI_NET_
+#endif /* NETP_INET_WSOCK */
+
+#ifdef NETP_INET_NEWT
+#undef TRUE
+#undef FALSE
+#undef NULL
+#include <nmpcip.h>
+#define _NI_NET_
+#endif /* NETP_INET_NEWT */
+
+#ifdef NETP_INET_PCNFS
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <windows.h>
+#include <in_addr.h>
+#include <sys/nfs_time.h>
+#include <tk_errno.h>
+#define _NI_NET_
+#endif /* NETP_INET_PCNFS */
+
+/* TGV, Inc. Multinet TCP/IP suite */
+#ifdef NETP_INET_TGV
+#include "Multinet_root:[multinet.include]netdb.h"
+#include "Multinet_root:[multinet.include.sys]types.h"
+#include "Multinet_root:[multinet.include.sys]socket.h"
+#include "Multinet_root:[multinet.include.sys]ioctl.h"
+#include "Multinet_root:[multinet.include.netinet]in.h"
+#include "Multinet_root:[multinet.include.arpa]inet.h"
+/*#include "Multinet_root:[multinet.include.sys]time.h"*/
+#include "Multinet_root:[multinet.include]errno.h"
+#define _NI_NET_
+#endif /* NETP_INET_TGV */
+
+/* The Wollongong Group, Inc. TCP/IP suite */
+#ifdef NETP_INET_TWG
+#include <netdb.h>
+#include <types.h>
+#include <socket.h>
+/*#include <ioctl.h>*/
+#include <in.h>
+#include <inet.h>
+#include <time.h>
+#include <errno.h>
+#define _NI_NET_
+#endif /* NETP_INET_TWG */
+
+/* The Wollongong PathWay API 1.0 suite for OpenVMS */
+#ifdef NETP_INET_WPW
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <errno.h>
+#define _NI_NET_
+#endif /* NETP_INET_TWG */
+
+/* DEC TCP/IP for OpenVMS */
+#ifdef NETP_INET_UCX
+#include <netdb.h>
+#include <types.h>
+#include <socket.h>
+#include <in.h>
+#include <inet.h>
+#include <time.h>
+#include <ucx$inetdef.h>
+#include <iodef.h>
+#define _NI_NET_
+#endif /* NETP_INET_UCX */
+
+
+/* default */
+#ifndef _NI_NET_
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#define _NI_NET_
+#endif /* _NI_NET_ */
+
+ /*** included from ni_lib.c *****/
+
+#ifdef OS_UNIX
+#include <signal.h>
+#endif /* OS_UNIX */
+#ifdef NETP_INET_MACTCP
+#include <neterrno.h> /* include missing error numbers */
+#endif /* NETP_INET_MACTCP */
+#ifdef OS_VMS
+#include <perror.h>
+#endif /* OS_VMS */
+
+#ifdef NETP_SOCKS
+#include <socks.h>
+#endif
+
+ /*** included from ni_msg.c *****/
+
+#ifdef NETP_INET_MACTCP
+#include <s_fcntl.h>
+#include <neterrno.h> /* missing error numbers on Mac */
+#endif /* NETP_INET_MACTCP */
+#ifdef OS_VMS
+#include <perror.h>
+#endif /* OS_VMS */
+
+#endif
+
diff --git a/network/nsclilib/ni_types.h b/network/nsclilib/ni_types.h
new file mode 100644
index 00000000..6e900bce
--- /dev/null
+++ b/network/nsclilib/ni_types.h
@@ -0,0 +1,287 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: ni_types.h
+*
+* Author: Beatty, Gish
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.3 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* $Log: ni_types.h,v $
+* Revision 6.3 1998/09/08 17:59:07 vakatov
+* Added WWW/Firewall network interface
+*
+* Revision 6.2 1998/05/05 22:45:39 vakatov
+* Added "eNII_Debug" network interface
+*
+* Revision 6.1 1998/03/30 17:56:06 vakatov
+* Added ENIInterface enumerator definition and added "interface" field
+* to the NI_Dispatcher struct
+*
+* Revision 5.3 1997/01/28 21:24:33 epstein
+* move NodePtr definition to ncbimisc.h
+*
+* Revision 5.2 1996/06/28 17:14:39 epstein
+* add job-penalty
+*
+* Revision 5.1 1996/06/27 17:18:17 epstein
+* add load-balancing
+*
+* Revision 4.2 1996/04/29 15:29:10 epstein
+* add disp to NI_HandPtr so that service-handle can encapsulate greater context
+*
+* Revision 4.1 1995/11/27 20:59:31 epstein
+* add client support for direct-connection services
+*
+* Revision 1.19 1995/05/24 12:09:04 epstein
+* add support for tracking of how many times a client IP has used a service within a time interval
+*/
+
+#ifndef _NI_TYPES_
+#define _NI_TYPES_
+
+#include <ncbi.h>
+#include <asn.h>
+
+#define NI_Handle MHandle /* for API use */
+#define NI_HandPtr MHandPtr /* for API use */
+#define NI_Request Request /* for API use */
+#define NI_ReqPtr ReqPtr /* for API use */
+
+#define INETADDR_SIZ 16 /* of the form 255.255.255.255 */
+
+#define NI_ConnState enum NIConState
+NI_ConnState {
+ NI_ERROR_COND = 0,
+ NI_CREATED,
+ NI_BOUND,
+ NI_CONNECTED,
+ NI_DISCARD, /* disconnect pending (requested) */
+ NI_DISCONNECTED
+};
+
+typedef Int4 (LIBCALLBACK *NI_ReadFilt) PROTO((VoidPtr mh, CharPtr buf, int bytesread, int len, CharPtr PNTR extra_buf, Int4Ptr extra_buf_len));
+typedef Int4 (LIBCALLBACK *NI_WriteFilt) PROTO((VoidPtr mh, CharPtr buf, int len, CharPtr tmpbuf));
+typedef void (LIBCALLBACK *NI_TimeoutHook) PROTO((Pointer p));
+
+typedef struct encr {
+ VoidPtr desWriteContext; /* really a DES_CBC_CTX structure */
+ VoidPtr desReadContext; /* really a DES_CBC_CTX structure */
+ Uint1 encrType;
+ Int1 state;
+ Int2 numDeferredBytes;
+ Int2 realDataLeft;
+ Int2 bytesToRead;
+ Uchar deferredData[15];
+ NI_WriteFilt write_filter; /* output filter routine */
+ NI_ReadFilt read_filter; /* input filter routine */
+} NI_EncrData, PNTR NI_EncrDataPtr;
+
+
+typedef struct MHandle {
+ CharPtr hostname; /* name of peer machine */
+ Uint4 conid; /* unique connection id number */
+ Uint4 seqno; /* unique message number */
+ NI_ConnState state; /* of connection - bound, connected, etc. */
+ int sok; /* the socket or file descriptor */
+ int r_timeout; /* read timeout value in seconds */
+ int w_timeout; /* write timeout value in seconds */
+ Uint4 peer; /* Internet address of peer */
+ AsnIoPtr raip; /* ASNtool IO read pointer */
+ AsnIoPtr waip; /* ASNtool IO write pointer */
+ Boolean longjump; /* TRUE if OK to use longjump (servers) */
+ time_t access_time; /* time stamp of last access */
+ Boolean unblocked_mode; /* is this interface "unblocked" ? */
+ Boolean have_blocked; /* have we blocked reading this msg? */
+ int num_queued_bytes; /* amt of queued data for this msg */
+ int cur_index; /* current index for reading queue */
+ NodePtr queued_data_list; /* queued data for this msg */
+ VoidPtr extra_proc_info; /* extra processing info, used externally */
+ NI_WriteFilt write_filter; /* output filter routine */
+ NI_ReadFilt read_filter; /* input filter routine */
+ Boolean write_filt_pass_thru; /* write filter is pass-thru */
+ Boolean read_filt_pass_thru; /* read filter is pass-thru */
+ NI_TimeoutHook readTimeoutHook; /* hook for read timeout expiration */
+ NI_TimeoutHook writeTimeoutHook; /* hook for write tmout expiration */
+ NodePtr readTimer;
+ NodePtr writeTimer;
+ Boolean isBrokered;
+ Uint2 brokeredPort;
+ NI_EncrDataPtr encryption;
+ Uint2 connectDelay;
+ struct NI_Dispatcher PNTR disp;
+} MHandle, PNTR MHandPtr;
+
+typedef enum _NetServHookCode_ {
+ NetServHook_dispconn = 1,
+ NetServHook_svcreq,
+ NetServHook_svcdisconn,
+ NetServHook_dispdisconn,
+ NetServHook_read,
+ NetServHook_write
+} NI_NetServHookCode;
+
+typedef void (LIBCALLBACK *NI_NetServHook) PROTO((NI_HandPtr, NI_NetServHookCode, int));
+
+
+typedef struct NICatalog {
+ Uint4 seqno;
+ CharPtr motd;
+ NodePtr toolsetL;
+} NICatalog, PNTR NICatalogPtr;
+
+typedef struct NIStatus {
+ FloatHi load;
+ FloatHi power;
+ FloatHi lightThresh;
+ FloatHi heavyThresh;
+ FloatHi jobPenalty;
+} NIStatus, PNTR NIStatusPtr;
+
+typedef struct NIRegion {
+ CharPtr regionName;
+ Uint2 priorityDelta; /* incentive to clients in that region */
+} NIRegion, PNTR NIRegionPtr;
+
+typedef struct NIToolset {
+ CharPtr host;
+ CharPtr motd;
+ NodePtr services;
+ NodePtr resources;
+ NodePtr regions;
+} NIToolset, PNTR NIToolsetPtr;
+
+typedef struct NIService {
+ CharPtr name; /* name of service */
+ Uint2 minVersion;
+ Uint2 maxVersion; /* NULL if infinite */
+ Uint2 id; /* ID that is unique on host */
+ Uint2 priority; /* priority of service */
+ CharPtr group; /* group with access to resource */
+ CharPtr descrip; /* description of service */
+ NodePtr typeL; /* list of res types supported by svc */
+ NodePtr subSetList; /* svcs of which this supports a subset */
+ NodePtr superSetList; /* svcs of which this supports a superset */
+ Uint2 priorityTimeout; /* timeout by which dispd must hear */
+ Uint2 priorityPenalty; /* resp from ncbid or impose penalty */
+ Boolean encryptionSupported; /* does this service support encryption? */
+ Uint2 trackingPeriod; /* time over which Dispatcher track(s/ed) this service */
+ Uint4 trackingCount; /* # service requests for this service&IP during tracking-period */
+} NIService, PNTR NISvcPtr;
+
+typedef struct NIResource {
+ CharPtr name;
+ CharPtr type; /* same as a service name ? */
+ Uint2 minVersion;
+ Uint2 maxVersion;
+ Uint2 id; /* ID that is unique on host */
+ CharPtr group; /* group with access to resource */
+ CharPtr descrip; /* description of resource */
+} NIResource, PNTR NIResPtr;
+
+typedef struct NI_Uid {
+ CharPtr username; /* kerberos principle */
+ CharPtr group; /* kerberos instance */
+ CharPtr domain; /* kerberos realm */
+} NI_Uid, PNTR NI_UidPtr;
+
+
+/* The available connection interfaces
+ */
+typedef enum {
+ /* Refer to "s_NII" in "ni_lib_.c" when changing the enumerator ordering
+ * or adding new interfaces */
+ eNII_Dispatcher = 0, /* old-fashioned NCBI dispatched-based connection */
+ eNII_WWW, /* WWW-based connection */
+ eNII_WWWFirewall, /* eNII_WWW + pass through the NCBI firewall daemon */
+ eNII_WWWDirect, /* WWW-based stateless connection */
+ eNII_Debug, /* direct client-server connection */
+
+ /* FEATURE: add new interfaces *above* this point(i.e. above eNII_Default),
+ * so that eNII_Default be equal to the number of avail. interfaces */
+ eNII_Default /* let program try environment and config files */
+
+/* NII_DEFAULT will be used if user did not explicitely specify the interface
+ * and if application failed to find it in environment and config files */
+#define NII_DEFAULT eNII_WWW
+} ENIInterface;
+
+
+typedef struct NI_Dispatcher {
+ ENIInterface interface;
+ struct Request PNTR reqResponse; /* ptr to request struct with actual services/resources used */
+ CharPtr dispHostName;
+ CharPtr dispServiceName;
+ Int4 dispSerialNo;
+ Char localHostAddr[INETADDR_SIZ]; /* Internet address of client */
+ NI_HandPtr dispHP; /* handle for dispatcher */
+ NI_HandPtr svcsHP; /* handle for incoming services */
+ Uint2 clientPort;
+ NI_UidPtr identity; /* client identity struct */
+ int dispTimeout; /* timeout when communicating w/dispatcher */
+ Int2 loport; /* range of client ports to bind */
+ Int2 hiport; /* range of client ports to bind */
+ Int2 referenceCount; /* # of services connected via this dispatcher */
+ Boolean someBrokered; /* some services are brokered */
+ Boolean brokeredDummy; /* indicates that this is a dummy */
+ ValNodePtr encryptInfo; /* encryption information, or NULL */
+ Boolean useSocks; /* client should use SOCKS */
+ CharPtr adminInfo; /* info. regarding administrator */
+ CharPtr motd; /* message of the day for user */
+ Boolean useOutServ; /* indicates that client will use direct connection */
+} NI_Dispatcher, PNTR NI_DispatcherPtr;
+
+typedef struct Request {
+ CharPtr clientAddr;
+ Uint2 clientPort;
+ NISvcPtr service; /* ptr to a service (NOT a node) */
+ NodePtr resourceL; /* ptr to list of resources */
+ NI_DispatcherPtr dispatcher; /* dispatcher on which req is made */
+} Request, PNTR ReqPtr;
+
+typedef struct NI_PubKey {
+ Int2 bits; /* bits used in modulus */
+ ByteStorePtr modulus;
+ ByteStorePtr exponent;
+} NI_PubKey, PNTR NI_PubKeyPtr;
+
+
+typedef struct NI_DispInfo {
+ Int4 serialno; /* unique dispatcher serial # */
+ Boolean isalternatelist;/* is this an alternate disp-list ? */
+ int numdispatchers; /* number of dispachers in disp-list */
+ CharPtr PNTR displist; /* list of dispatchers */
+ NI_PubKeyPtr pubKey;
+} NI_DispInfo, PNTR NI_DispInfoPtr;
+
+
+#endif
diff --git a/network/nsclilib/ni_www.c b/network/nsclilib/ni_www.c
new file mode 100644
index 00000000..ef01b3c0
--- /dev/null
+++ b/network/nsclilib/ni_www.c
@@ -0,0 +1,526 @@
+/* $RCSfile: ni_www.c,v $ $Revision: 4.18 $ $Date: 1998/12/15 17:28:52 $
+* ==========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ==========================================================================
+*
+* Authors: Denis Vakatov, Sergei Shavirin, Eugene Yaschenko
+*
+* File Description:
+* Basic client code for the new(HTTPD-based) NCBI dispatchers
+* (regular and connectionless protocols)
+*
+* --------------------------------------------------------------------------
+* $Log: ni_www.c,v $
+* Revision 4.18 1998/12/15 17:28:52 vakatov
+* Added config parameter "SRV_PROXY_TRANSPARENT" -- to indicate the use
+* of transparent/non-transparent CERN-like proxy
+*
+* Revision 4.17 1998/12/08 17:03:58 vakatov
+* Look for SRV_*** connection parameters in #SRV_SECTION(="NET_SERV")
+* rather than in "configSection"(service-specific)
+*
+* Revision 4.16 1998/09/08 17:59:08 vakatov
+* Added WWW/Firewall network interface
+*
+* Revision 4.15 1998/08/05 20:19:37 vakatov
+* s_AsnRead(): Always make sure that the network conection is
+* established by the moment of data read;
+* + minor logic fix due to the fix in "ncbicli.c" R5.0
+*
+* Revision 4.14 1998/05/20 20:22:05 vakatov
+* Added two new config. options SRV_PROXY_HOST and SRV_PROXY_PORT in order
+* to allow one to connect via a proxy HTTP server
+*
+* Revision 4.13 1998/05/08 15:26:59 vakatov
+* [LB_DIRECT] now can skip IP addresses(for the dispatcher hosts) which
+* were already offered by the load-balancing daemon but failed by some reason
+*
+* Revision 4.12 1998/05/01 19:16:56 vakatov
+* Connection establishing defaults: 2 attempts with 30 sec timeout(was 3 & 20)
+*
+* Revision 4.11 1998/04/30 23:02:25 vakatov
+* s_ServiceDisconnect(): check "sinfo->nic" for NULL
+*
+* Revision 4.10 1998/04/09 15:36:36 vakatov
+* [LB_DIRECT] Introduced SRV_NO_LB_DIRECT env/conf variable to let one
+* disable the use of local "nsdaemon" load-balance info
+*
+* Revision 4.9 1998/04/08 23:04:21 vakatov
+* Count references to the Dispatcher struct to avoid its premature freeing
+*
+* Revision 4.8 1998/04/03 22:46:43 vakatov
+* [#LB_DIRECT] Allowed shortcut around micasa/sucasa(for the hosts
+* running "lbdaemon")
+*
+* Revision 4.7 1998/04/02 20:21:10 vakatov
+* Added possibility to printout service reply headers
+*
+* Revision 4.6 1998/03/30 17:50:20 vakatov
+* Ingrafted to the main NCBI CVS tree
+*
+* ==========================================================================
+*/
+
+#include <ncbi.h>
+#include <ncbinet.h>
+#include <ncbicli.h>
+#include <lbapi.h>
+
+
+/*********************************
+ * INTERNALS
+ */
+
+/* Hard-coded constants, environment parameter names & defaults
+ */
+
+#define SRV_SECTION "NET_SERV"
+
+#define ENV_PROXY_HOST "SRV_PROXY_HOST"
+#define DEF_PROXY_HOST ""
+
+#define ENV_PROXY_PORT "SRV_PROXY_PORT"
+#define DEF_PROXY_PORT 80
+
+#define ENV_PROXY_TRANSPARENT "SRV_PROXY_TRANSPARENT"
+#define DEF_PROXY_TRANSPARENT ""
+
+#define ENV_ENGINE_HOST "SRV_ENGINE_HOST"
+#define DEF_ENGINE_HOST "www.ncbi.nlm.nih.gov"
+
+#define ENV_ENGINE_PORT "SRV_ENGINE_PORT"
+#define DEF_ENGINE_PORT 80
+
+#define ENV_ENGINE_URL "SRV_ENGINE_URL"
+#define DEF_ENGINE_URL "/Service/nph-dispd.cgi"
+
+#define ENV_CONN_TIMEOUT "SRV_CONN_TIMEOUT"
+#define DEF_CONN_TIMEOUT 30
+
+#define ENV_CONN_TRY "SRV_CONN_TRY"
+#define DEF_CONN_TRY 3
+
+#define ENV_DEBUG_PRINTOUT "SRV_DEBUG_PRINTOUT"
+#define DEF_DEBUG_PRINTOUT ""
+
+#ifdef LB_DIRECT
+#define DEF_ENGINE_LB_URL "/Service/nph-ncbid.cgi"
+#define ENV_NO_LB_DIRECT "SRV_NO_LB_DIRECT"
+#endif /* LB_DIRECT */
+
+
+/* Local typedefs
+ */
+
+typedef struct {
+ Char client_host[64]; /* effective client hostname */
+ Char service[256]; /* requested service */
+ Char disp_host[64]; /* dispatcher: host */
+ Char disp_path[256]; /* dispatcher: path(to CGI script) */
+ Uint2 disp_port; /* dispatcher: service port */
+ NIC nic; /* handle to the connection */
+ STimeout timeout; /* i/o(connection and read/write) timeout */
+ Uint4 conn_try; /* max. number of attempts to establish conn. */
+ ENIC_Agent agent;
+ Uint4 flags; /* to be passed to NIC_GetService() */
+ Boolean no_lb_direct; /* prohibit the use of local "nsdaemon" */
+ AsnIoBSPtr aibsp;
+} ServiceInfo;
+
+
+/* Static functions
+ */
+
+#ifdef LB_DIRECT
+static unsigned s_AlternateDispatcher(ServiceInfo *sinfo,
+ unsigned *skip_ip, size_t n_skip)
+{
+ Uint4 ip_addr;
+ Char str_addr[16];
+
+ if ( sinfo->no_lb_direct )
+ return 0;
+
+ ip_addr = (Uint4)LBGetIPAddress(sinfo->service, 0, skip_ip, n_skip);
+ if (!ip_addr || !Uint4toInaddr(ip_addr, str_addr, sizeof(str_addr)))
+ return 0;
+
+ StringNCpy_0(sinfo->disp_host, str_addr, sizeof(sinfo->disp_host));
+ sinfo->disp_port = DEF_ENGINE_PORT;
+ StringNCpy_0(sinfo->disp_path, DEF_ENGINE_LB_URL, sizeof(DEF_ENGINE_LB_URL));
+ return ip_addr;
+}
+#endif
+
+static Boolean s_Connect(ServiceInfo *sinfo)
+{
+ Uint4 conn_try;
+#ifdef LB_DIRECT
+ unsigned skip_ip[MAX_NUM_HOSTS];
+ MemSet(skip_ip, '\0', sizeof(skip_ip));
+#endif
+
+ ASSERT( !sinfo->nic );
+ for (conn_try = 0; !sinfo->nic && conn_try < sinfo->conn_try;
+ conn_try++) {
+#ifdef LB_DIRECT
+ skip_ip[conn_try] = s_AlternateDispatcher(sinfo, skip_ip,
+ conn_try%MAX_NUM_HOSTS);
+#endif
+ sinfo->nic = NIC_GetService
+ (sinfo->service,
+ sinfo->disp_host, sinfo->disp_port, sinfo->disp_path,
+ &sinfo->timeout, sinfo->agent, sinfo->client_host,
+ sinfo->aibsp->bsp, sinfo->flags);
+ }
+
+ return (Boolean)(sinfo->nic != 0);
+}
+
+
+static Int2 LIBCALLBACK s_AsnRead(Pointer p, CharPtr buff, Uint2 len)
+{
+ ServiceInfo *sinfo = (ServiceInfo *)p;
+
+ if (BSLen(sinfo->aibsp->bsp) > 0) {
+ /* connect, if needed; flush the content of output BSP, if any */
+ if ( sinfo->nic ) {
+ if (sinfo->agent == eNIC_WWWDirect) {
+ NIC_CloseService(sinfo->nic);
+ sinfo->nic = 0;
+ if ( !s_Connect(sinfo) ) /* it also flushes the content of out. BSP */
+ return 0;
+ } else { /* flush the content of output BSP */
+ Nlm_BSUnitPtr bsup;
+ SOCK sock = NIC_GetSOCK(sinfo->nic);
+ ASSERT(sinfo->agent == eNIC_WWWClient);
+ for (bsup = sinfo->aibsp->bsp->chain; bsup && bsup->len;
+ bsup = bsup->next) {
+ const void *ptr = Nlm_HandLock(bsup->str);
+ ESOCK_ErrCode err_code = SOCK_Write(sock, ptr, (Uint4)bsup->len, 0);
+ Nlm_HandUnlock(bsup->str);
+ if (err_code != eSOCK_ESuccess)
+ return 0;
+ }
+ }
+ } else {
+ if ( !s_Connect(sinfo) ) /* it also flushes the content of output BSP */
+ return 0;
+ }
+
+ /* cleanup the output BSP content */
+ BSSeek(sinfo->aibsp->bsp, 0, SEEK_SET);
+ BSDelete(sinfo->aibsp->bsp, BSLen(sinfo->aibsp->bsp));
+ }
+ else { /* no data to (pre-)write; just connect if necessary */
+ if (!sinfo->nic && !s_Connect(sinfo))
+ return 0;
+ }
+
+
+ {{ /* read */
+ Uint4 n_read;
+ SOCK_Read(NIC_GetSOCK(sinfo->nic), buff, (Uint4)len, &n_read);
+ return (Int2)n_read;
+ }}
+}
+
+
+static void LIBCALLBACK s_AsnErrorFunc(Int2 type, CharPtr message)
+{
+ ErrPostEx(SEV_ERROR, 77, type, message);
+}
+
+
+/* The interface implementaion functions
+ */
+
+static NI_DispatcherPtr s_GenericInit
+(ENIInterface interface,
+ CharPtr configFile, CharPtr configSection, Boolean showMonitor,
+ CharPtr lastDispatcher, Int2 lastDispLen)
+{
+ NI_DispatcherPtr disp = (NI_DispatcherPtr)MemNew(sizeof(NI_Dispatcher));
+ disp->interface = interface;
+
+ if ( lastDispatcher )
+ StringNCpy_0(lastDispatcher, "WWW Based Dispatcher", lastDispLen);
+
+ disp->motd = StringSave("This system uses HTTPD servers on NCBI to "
+ "initialize network connection");
+ disp->adminInfo = StringSave("");
+ disp->referenceCount = 1;
+ return disp;
+}
+
+
+static NI_DispatcherPtr s_GenericInitWWW
+(CharPtr configFile, CharPtr configSection, Boolean showMonitor,
+ CharPtr lastDispatcher, Int2 lastDispLen)
+{
+ return s_GenericInit(eNII_WWW, configFile, configSection, showMonitor,
+ lastDispatcher, lastDispLen);
+}
+
+
+static NI_DispatcherPtr s_GenericInitWWWFirewall
+(CharPtr configFile, CharPtr configSection, Boolean showMonitor,
+ CharPtr lastDispatcher, Int2 lastDispLen)
+{
+ return s_GenericInit(eNII_WWWFirewall, configFile, configSection,
+ showMonitor, lastDispatcher, lastDispLen);
+}
+
+
+static NI_DispatcherPtr s_GenericInitWWWDirect
+(CharPtr configFile, CharPtr configSection, Boolean showMonitor,
+ CharPtr lastDispatcher, Int2 lastDispLen)
+{
+ return s_GenericInit(eNII_WWWDirect, configFile, configSection, showMonitor,
+ lastDispatcher, lastDispLen);
+}
+
+
+static NI_DispatcherPtr s_SetDispatcherWWW
+(NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
+ Int4 dispserialnum, ValNodePtr encryption, Boolean useOutServ)
+{
+ return s_GenericInitWWW(0, 0, 0, 0, 0);
+}
+
+static NI_DispatcherPtr s_SetDispatcherWWWFirewall
+(NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
+ Int4 dispserialnum, ValNodePtr encryption, Boolean useOutServ)
+{
+ return s_GenericInitWWWFirewall(0, 0, 0, 0, 0);
+}
+
+static NI_DispatcherPtr s_SetDispatcherWWWDirect
+(NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
+ Int4 dispserialnum, ValNodePtr encryption, Boolean useOutServ)
+{
+ return s_GenericInitWWWDirect(0, 0, 0, 0, 0);
+}
+
+
+static NI_HandPtr s_GenericGetService
+(NI_DispatcherPtr disp, CharPtr configFile, CharPtr configSection,
+ CharPtr defService, Boolean hasResource)
+{
+ NI_HandPtr result = (NI_HandPtr)MemNew(sizeof(NI_Handle));
+ ServiceInfo *sinfo = (ServiceInfo *)MemNew(sizeof(ServiceInfo));
+
+ {{ /* alternate service name */
+ static const Char ENV_PREFIX[] = "NI_SERVICE_NAME_";
+ CharPtr envName = (CharPtr)MemNew(sizeof(ENV_PREFIX) +
+ StringLen(configSection));
+ StringCpy(envName, ENV_PREFIX);
+ StringCat(envName, configSection);
+ NI_GetEnvParamEx(configFile, configSection, envName, "SERVICE_NAME",
+ sinfo->service, sizeof(sinfo->service), defService);
+ MemFree(envName);
+ }}
+
+ /* alternate the dispatcher's host name */
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_ENGINE_HOST,
+ sinfo->disp_host, sizeof(sinfo->disp_host), DEF_ENGINE_HOST);
+
+ {{ /* alternate the dispatcher's port */
+ Char str[32];
+ int val;
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_ENGINE_PORT,
+ str, sizeof(str), "");
+ val = atoi(str);
+ sinfo->disp_port = (Uint2)(val > 0 ? val : DEF_ENGINE_PORT);
+ }}
+
+ /* alternate the dispatcher's CGI path */
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_ENGINE_URL,
+ sinfo->disp_path, sizeof(sinfo->disp_path), DEF_ENGINE_URL);
+
+ {{ /* CERN-like firewall proxy server? */
+ Char proxy_host[sizeof(sinfo->disp_host)];
+ /* get the PROXY server name, if specified */
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_PROXY_HOST,
+ proxy_host, sizeof(proxy_host), DEF_PROXY_HOST);
+
+ if ( *proxy_host ) { /* use PROXY server */
+ Char str[32 + sizeof(sinfo->disp_host) + sizeof(sinfo->disp_path)];
+ int val;
+ Uint2 proxy_port;
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_PROXY_PORT,
+ str, sizeof(str), "");
+ val = atoi(str);
+ proxy_port = (Uint2)(val > 0 ? val : DEF_PROXY_PORT);
+ sprintf(str, "http://%s:%u%s",
+ sinfo->disp_host, (unsigned)sinfo->disp_port, sinfo->disp_path);
+ StringNCpy_0(sinfo->disp_host, proxy_host, sizeof(sinfo->disp_host));
+ sinfo->disp_port = proxy_port;
+ StringNCpy_0(sinfo->disp_path, str, sizeof(sinfo->disp_path));
+
+ /* non-transparent proxy? */
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_PROXY_TRANSPARENT,
+ str, sizeof(str), DEF_PROXY_TRANSPARENT);
+ if (!*str || (StringICmp(str, "1" ) &&
+ StringICmp(str, "true") &&
+ StringICmp(str, "yes" )))
+ sinfo->flags |= NIC_CERN_PROXY;
+
+ /* auto-set to FIREWALL mode */
+ sinfo->flags |= NIC_FIREWALL;
+ }
+ }}
+
+ {{ /* alternate the connection timeout */
+ Char str[32];
+ double val;
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_CONN_TIMEOUT,
+ str, sizeof(str), "");
+ val = atof(str);
+ if (val <= 0)
+ val = DEF_CONN_TIMEOUT;
+ sinfo->timeout.sec = (Uint4)val;
+ sinfo->timeout.usec = (Uint4)((val - sinfo->timeout.sec) * 1000000);
+ }}
+
+ {{ /* alternate the max. number of attemts to establish a connection */
+ Char str[32];
+ int val;
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_CONN_TRY,
+ str, sizeof(str), "");
+ val = atoi(str);
+ sinfo->conn_try = (Uint4)((val > 0) ? val : DEF_CONN_TRY);
+ }}
+
+ {{ /* alternate the connection flags */
+ Char str[32];
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_DEBUG_PRINTOUT,
+ str, sizeof(str), DEF_DEBUG_PRINTOUT);
+ if (*str && (!StringICmp(str, "1" ) ||
+ !StringICmp(str, "true") ||
+ !StringICmp(str, "yes" )))
+ sinfo->flags |= NIC_DEBUG_PRINTOUT;
+ }}
+
+#ifdef LB_DIRECT
+ {{ /* if to prohibit the use of local "nsdaemon" info */
+ Char str[32];
+ NI_GetEnvParam(configFile, SRV_SECTION, ENV_NO_LB_DIRECT,
+ str, sizeof(str), "");
+ sinfo->no_lb_direct = (Boolean)
+ (*str && StringICmp(str, "0") &&
+ StringICmp(str, "false") && StringICmp(str, "no"));
+ }}
+#endif
+
+ /* open ASN i/o, etc. */
+ result->extra_proc_info = sinfo;
+ sinfo->aibsp = AsnIoBSOpen("wb", BSNew(1024));
+ result->waip = sinfo->aibsp->aip;
+ result->raip = AsnIoNew((ASNIO_BIN | ASNIO_IN), (FILE *)0,
+ (void *)sinfo, s_AsnRead, (IoFuncType)0);
+
+ AsnIoSetErrorMsg(result->raip, s_AsnErrorFunc);
+ AsnIoSetErrorMsg(result->waip, s_AsnErrorFunc);
+ switch ( disp->interface ) {
+ case eNII_WWWFirewall:
+ sinfo->flags |= NIC_FIREWALL;
+ case eNII_WWW:
+ sinfo->agent = eNIC_WWWClient;
+ break;
+ case eNII_WWWDirect:
+ sinfo->agent = eNIC_WWWDirect;
+ break;
+ default:
+ ASSERT ( 0 );
+ return 0;
+ }
+ result->hostname = StringSave("");
+ result->disp = disp;
+ disp->referenceCount++;
+
+ return result;
+}
+
+
+static Int2 s_EndServices(NI_DispatcherPtr disp)
+{
+ ASSERT ( disp->referenceCount > 0 );
+ if (--disp->referenceCount == 0) {
+ MemFree(disp->adminInfo);
+ MemFree(disp->motd);
+ MemFree(disp);
+ }
+ return 0;
+}
+
+
+static Int2 s_ServiceDisconnect(NI_HandPtr mhp)
+{
+ ServiceInfo *sinfo = (ServiceInfo *)mhp->extra_proc_info;
+ ByteStorePtr bsp = sinfo->aibsp->bsp;
+
+ s_EndServices(mhp->disp);
+ if ( sinfo->nic )
+ NIC_CloseService(sinfo->nic);
+ AsnIoBSClose(sinfo->aibsp);
+ BSFree(bsp);
+ MemFree(sinfo);
+ AsnIoClose(mhp->raip);
+ MemFree(mhp->hostname);
+ MemFree(mhp);
+ return 0;
+}
+
+
+/* Exported table of interface functions
+ */
+static const NIInterface s_NII_WWW = {
+ s_GenericInitWWW,
+ s_SetDispatcherWWW,
+ s_GenericGetService,
+ s_ServiceDisconnect,
+ s_EndServices
+};
+const NIInterface *g_NII_WWW = &s_NII_WWW;
+
+static const NIInterface s_NII_WWWFirewall = {
+ s_GenericInitWWWFirewall,
+ s_SetDispatcherWWWFirewall,
+ s_GenericGetService,
+ s_ServiceDisconnect,
+ s_EndServices
+};
+const NIInterface *g_NII_WWWFirewall = &s_NII_WWWFirewall;
+
+static const NIInterface s_NII_WWWDirect = {
+ s_GenericInitWWWDirect,
+ s_SetDispatcherWWWDirect,
+ s_GenericGetService,
+ s_ServiceDisconnect,
+ s_EndServices
+};
+const NIInterface *g_NII_WWWDirect = &s_NII_WWWDirect;
+
+
+/* EOF */
diff --git a/network/nsclilib/readme b/network/nsclilib/readme
new file mode 100644
index 00000000..567417f3
--- /dev/null
+++ b/network/nsclilib/readme
@@ -0,0 +1,142 @@
+ Summary on the new configuration resources for NCBI network clients
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ By Denis V. Vakatov NCBI/NLM/NIH (vakatov@ncbi.nlm.nih.gov)
+
+
+Due to the recent works on the old NCBI dispatcher replacement
+I introduced some new resources which affect the new NCBI network
+client functionality.
+
+Supported network interfaces
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SRV_CONN_MODE -- to specify which one of the now available network
+ interfaces should be used.
+Value:
+ DISPATCHER -- old NCBI dispatcher
+ WWW -- Web-based dispatcher in the stateful connection mode [default]
+ FIREWALL -- just like "WWW" but the data connection goes through the NCBI
+ firewall daemon that listens at one of well-known hosts/ports
+ STATELESS -- Web-based dispatcher in the stateless connection mode
+ DEBUG -- direct client-to-server connection(bypass dispatchers)
+
+
+Resources for WWW, FIREWALL and STATELESS interfaces
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SRV_ENGINE_****: to compose URL of the NCBI HTTP-based dispatcher
+[default = http://www.ncbi.nlm.nih.gov:80/Service/nph-dispd.cgi]
+
+SRV_ENGINE_HOST: [default = www.ncbi.nlm.nih.gov]
+SRV_ENGINE_PORT: [default = 80]
+SRV_ENGINE_URL: [default = /Service/nph-dispd.cgi]
+
+
+SRV_PROXY_****: to connect via a CERN-like proxy server
+[default = n/a]
+
+SRV_PROXY_HOST: [default = n/a]
+SRV_PROXY_PORT: [default = 80]
+
+SRV_PROXY_TRANSPARENT: [default = "no"]
+Value:
+ "1", "yes", "true" (case-insensitive) -- transparent CERN-like proxy
+ otherwise -- non-transparent [default]
+
+Notes:
+ 1) SRV_PROXY_PORT has no sense if SRV_PROXY_HOST is not specified
+ 2) If SRV_PROXY_HOST is set in WWW mode then auto-switch to FIREWALL mode
+
+
+SRV_DEBUG_PRINTOUT: to printout messages sent by dispatcher when
+ establishing client-server connection
+Value:
+ "1", "yes", "true" (case-insensitive) -- do printout
+ otherwise -- do not printout [default]
+
+
+SRV_NO_LB_DIRECT: to prohibit the use of local load-balancing daemon
+Value:
+ "0", "false", "no" (case-insensitive) -- do not use local load-balancing
+ otherwise -- try to use local load-balancing [default]
+
+
+SRV_CONN_TIMEOUT: to set timeout for the connection establishment
+Value:
+ a positive integer or floating-point value(in sec.) [default = 30]
+
+
+SRV_CONN_TRY: maximum number of attempts to establish the connection
+Value:
+ a positive integer [default = 3]
+
+
+Resources for DEBUG interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+NI_DEBUG_HOST: the server host to connect to
+Value(mandatory):
+ smth. like "123.45.67.89" or "mysrvhost" or "xxx@yyy.zzz.gov"
+
+NI_DEBUG_PORT: the server port to connect to
+Value(mandatory):
+ a positive integer
+
+NI_DEBUG_TRY: maximum number of attempts to establish the connection
+Value:
+ a positive integer [default = 2]
+
+
+How to set the resource values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The above resource values can be set either by using the NCBI resource
+(configuration) file or (on UNIX, MS Windows and VMS) by setting relevant
+environment variable. The environment variable overrides the value
+set in the NCBI resource file.
+
+[NET_SERV]
+SRV_CONN_MODE
+SRV_DEBUG_PRINTOUT
+SRV_NO_LB_DIRECT
+SRV_CONN_TIMEOUT
+SRV_CONN_TRY
+
+[ENTREZ_NET]
+NI_DEBUG_HOST
+NI_DEBUG_PORT
+NI_DEBUG_TRY
+
+
+For example, in order to set the connection establishment timeout to
+12.345 sec. you should set environment variable:
+
+UNIX csh:
+ setenv SRV_CONN_TIMEOUT 12.345
+UNIX sh, bash:
+ SRV_CONN_TIMEOUT=12.345
+ export SRV_CONN_TIMEOUT
+DOS prompt:
+ set SRV_CONN_TIMEOUT=12.345
+
+or, in the NCBI configuration file:
+
+ [NET_SERV]
+ SRV_CONN_TIMEOUT=12.345
+
+
+NOTES
+~~~~~
+
+1. STATELESS connection mode is usually not available for the distributed
+applications. It is hardcoded to be unavailable unless "ni_lib_.c"
+module is compiled with the "-DALLOW_STATELESS" flag.
+
+2. The local LOAD-BALANCING is *never* available for the distributed
+applications. It is hardcoded to be unavailable unless "ni_lib_.c"
+and "lbapi.c" modules are compiled with the "-DLB_DIRECT" flags, on
+Solaris or IRIX. Then, the client must run on the host that:
+a) belongs to one of NCBI subnets and
+b) has "lbdaemon"(load-balance daemon) application running on it.
+
+$Date: 1998/12/15 17:40:51 $
diff --git a/network/nsdemocl/Makefile b/network/nsdemocl/Makefile
new file mode 100644
index 00000000..468f7ed1
--- /dev/null
+++ b/network/nsdemocl/Makefile
@@ -0,0 +1,23 @@
+#
+#$Id: Makefile,v 6.1 1998/09/14 19:58:14 shavirin Exp $
+#
+
+include $(NCBI)/ncbi.mk
+
+CC=cc
+
+EQUERY_LIBS = -lnetcli -lncbiobj -lncbi -lm -lsocket -lnsl -lresolv
+OBJ_FILES = catalogc.o
+
+CFLAGS= -g
+
+.c.o:
+ $(CC) -c -g -I. -I$(NCBI_INCDIR) $(CFLAGS) $<
+
+all: catalogc
+
+catalogc.purify: $(OBJ_FILES) Makefile
+ purify $(CC) $(OBJ_FILES) -L$(NCBI_ALTLIB) $(EQUERY_LIBS) -o ./catalogc
+
+catalogc: $(OBJ_FILES) Makefile
+ $(CC) $(OBJ_FILES) -L$(NCBI_ALTLIB) $(EQUERY_LIBS) -o ./catalogc
diff --git a/network/nsdemocl/catalogc.c b/network/nsdemocl/catalogc.c
new file mode 100644
index 00000000..1a04dbfc
--- /dev/null
+++ b/network/nsdemocl/catalogc.c
@@ -0,0 +1,464 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: catalogc.c
+*
+* Author: Epstein, Shavirin
+*
+* Version Creation Date: 1/1/92
+*
+* $Revision: 6.1 $
+*
+* File Description: Client to request services catalog from the dispatcher
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: catalogc.c,v $
+* Revision 6.1 1998/09/14 19:57:52 shavirin
+* Initial revision with this filename.
+*
+* Revision 6.0 1997/08/25 18:40:05 madden
+* Revision changed to 6.0
+*
+* Revision 5.0 1996/05/28 14:13:55 ostell
+* Set to revision 5.0
+*
+ * Revision 4.1 1995/11/27 21:01:47 epstein
+ * add new parameter in NI_SetDispatcher()
+ *
+ * Revision 4.0 1995/07/26 13:57:04 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.8 1995/05/17 17:52:55 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include "ncbinet.h"
+#include "ni_net.h"
+
+#include "echo_asn.h"
+
+
+#define IOBUFSIZ 1024
+#define SMBUFSIZ 256
+
+static Int2 getUserInput PROTO((CharPtr bp, CharPtr prompt));
+static Int2 getService PROTO((CharPtr bp, NI_DispatcherPtr disp));
+static Int2 getResource PROTO((CharPtr bp));
+static Int2 getVersions PROTO((Uint2 *min, Uint2 *max));
+static Boolean getYN PROTO((CharPtr s));
+static void printCatalog PROTO((NICatalogPtr catp));
+static void printCatalogWithBars PROTO((NICatalogPtr catp));
+static CharPtr readServer PROTO((NI_HandPtr hp));
+static Int2 writeServer PROTO((NI_HandPtr hp, CharPtr buf));
+
+#ifdef COMP_THINKC
+#include <console.h>
+#define OS_UNIX 1 /* lie */
+#endif /* COMP_THINKC */
+
+
+main(int argc, CharPtr argv[])
+{
+#ifdef OS_UNIX
+ extern CharPtr optarg;
+ Int2 errflg = 0, c;
+#endif
+ Int2 status;
+ CharPtr dispatcher = NULL, service = NULL, username = NULL;
+ NI_HandPtr svc_handle;
+ Char svcname[SMBUFSIZ], iobuf[IOBUFSIZ];
+ Char cuser[SMBUFSIZ], resname[SMBUFSIZ];
+ Uint2 min, max, rmin, rmax;
+ CharPtr intext;
+ NI_ReqPtr reqp; /* for user constructed request */
+ CharPtr module;
+ NI_DispatcherPtr disp;
+
+#ifdef COMP_THINKC
+ argc = ccommand(&argv);
+#endif /* COMP_THINKC */
+ module = argv[0];
+
+#ifdef OS_UNIX
+ while ((c = getopt(argc, argv, "d:s:u:")) != -1)
+ switch (c) {
+ case 'd':
+ dispatcher = optarg;
+ break;
+ case 's':
+ service = optarg;
+ break;
+ case 'u':
+ username = optarg;
+ break;
+ case '?':
+ default:
+ ++errflg;
+
+ }
+ if (errflg > 0) {
+ fprintf(stderr, "\nUsage: %s [-d dispatcher host] [-s service] [-u username]\n", module);
+ exit(1);
+ }
+#else
+ switch (argc) {
+ case 4:
+ username = argv[3];
+ case 3:
+ service = argv[2];
+ case 2:
+ dispatcher = argv[1];
+ break;
+ case 1:
+ break;
+ default:
+ printf("\n Error: too many parameters\n");
+ exit(1);
+ }
+#endif
+
+ RECONNECT:
+
+ disp = NI_SetDispatcher(NULL, dispatcher, service, 0, 0, NULL, FALSE); /* NULL vals = defaults */
+
+ if (username == NULL) {
+ if (getUserInput(cuser, "\nEnter user name: ") == -1) {
+ printf("\nDone\n");
+ exit(0);
+ }
+ }
+ else
+ StringNCpy(cuser, username, SMBUFSIZ);
+
+
+ if (NI_InitServices(disp, cuser, NULL, NULL, NULL) < 0) {
+ printf("\nUnable to initiate services - %s\n", ni_errlist[ni_errno]);
+ exit(1);
+ }
+ printf("\n=== Connected to NCBI Dispatcher ===\n");
+ printf("\nEnter \"cat\" to get a catalog or \"catbars\" to get a machine-parsable catalog\n");
+
+ while (getService(svcname, disp) == 0) {
+ if (getVersions(&min, &max) != 0)
+ break;
+ reqp = NI_SVCRequestBuild(disp);
+ NI_RequestSetService(reqp, svcname, min, max);
+
+ while ((status = getResource(resname)) == 0) {
+ if (getVersions(&rmin, &rmax) != 0)
+ break;
+ NI_RequestAddResource(reqp, resname, "TEST", rmin, rmax);
+ }
+ if (status == -1)
+ break;
+ if ((svc_handle = NI_ServiceRequest(reqp)) == NULL) {
+ printf("\nUnable to get service - %s: %s\n", ni_errlist[ni_errno], ni_errtext);
+ continue;
+ }
+ else {
+ printf("\nRequest OK: %s %d - %d\n", disp->reqResponse->service->name, disp->reqResponse->service->minVersion, disp->reqResponse->service->maxVersion);
+ }
+
+ while (getUserInput(iobuf, "\nEnter message for Application: ") == 0) {
+ if (writeServer(svc_handle, iobuf) == 0) {
+ if ((intext = readServer(svc_handle)) != NULL) {
+ printf("\nService echoed:\n%s\n", intext);
+ MemFree(intext);
+ }
+ else {
+ printf("\nService disconnected\n");
+ break;
+ }
+ }
+ else {
+ printf("\nServer disconnected (write)\n");
+ break;
+ }
+ }
+ NI_ServiceDisconnect(svc_handle);
+ }
+ NI_EndServices(disp);
+ printf("\nDisconnected from dispatcher\n");
+ if (getYN("Do you want to re-connect? (y/n): "))
+ goto RECONNECT;
+ exit(0);
+} /* main */
+
+
+static Int2 getService(CharPtr bp, NI_DispatcherPtr disp)
+{
+ NICatalogPtr catalog;
+
+ RESET:
+ printf("\nEnter service: ");
+ gets(bp);
+ if (strcasecmp(bp, "stop") == 0)
+ return -1;
+
+ if (strcasecmp(bp, "cat") == 0 || strcasecmp(bp, "catbars") == 0) {
+ if ((catalog = NI_GetCatalog(disp)) != NULL) {
+ if (strcasecmp(bp, "cat") == 0)
+ printCatalog(catalog);
+ else
+ printCatalogWithBars(catalog);
+ NI_DestroyMsgCatalog(catalog);
+ } else
+ printf("Error getting catalog - %s\n", ni_errlist[ni_errno]);
+ goto RESET;
+ }
+ return 0;
+} /* getService */
+
+
+static Int2 getResource(CharPtr bp)
+{
+ printf("Enter resource: ");
+ gets(bp);
+ if (StringLen(bp) == 0)
+ return 1;
+ if (strcasecmp(bp, "stop") == 0)
+ return -1;
+ return 0;
+} /* getResource */
+
+
+static Int2 getVersions(Uint2 *min, Uint2 *max)
+{
+ unsigned tmin, tmax;
+
+ printf("Enter minimum version: ");
+ scanf("%u", &tmin);
+ printf("Enter maximum version: ");
+ scanf("%u", &tmax);
+ getchar();
+ *min = (Uint2) tmin;
+ *max = (Uint2) tmax;
+ return 0;
+} /* getVersions */
+
+
+static Int2 getUserInput(CharPtr bp, CharPtr prompt)
+{
+ printf(prompt);
+ gets(bp);
+ if (strcasecmp(bp, "stop") == 0)
+ return -1;
+ return 0;
+} /* getUserInput */
+
+
+static Boolean getYN(CharPtr s)
+{
+ Char ans[20];
+
+ printf("%s", s);
+ gets(ans);
+ if (ans[0] == 'y' || ans[0] == 'Y')
+ return TRUE;
+ else
+ return FALSE;
+} /* getYN */
+
+
+static Boolean
+ResourceCompatWService(NIResPtr resp, NISvcPtr service)
+{
+ NodePtr np = service->typeL;
+
+ if (np == NULL)
+ return FALSE;
+
+ do {
+ np = np->next;
+ if (strcasecmp(np->elem, MATCHES_ANY_TYPE) == 0 ||
+ strcasecmp(np->elem, resp->type) == 0)
+ return TRUE;
+ } while (np != NULL && np != service->typeL);
+
+ return FALSE;
+}
+
+
+static void printCatalogWithBars(NICatalogPtr cat)
+{
+ NIToolsetPtr tsp;
+ NISvcPtr svcp;
+ NIResPtr resp;
+ NodePtr tsnp, np, np2;
+
+ printf("\n==============================================================================\n");
+ printf("== %-72.72s ==\n", cat->motd);
+ printf("==============================================================================\n");
+ printf ("SERVER|SVC NAME|SVC DESCR|SVC MIN|SVC MAX|SVC PRIORITY|RES NAME|RES DESCR|RES MIN|RES MIN|RES TYPE\n");
+
+ tsnp = cat->toolsetL;
+ for (tsnp = cat->toolsetL; tsnp != NULL; tsnp = tsnp->next)
+ { /* for each server */
+ tsp = (NIToolsetPtr) tsnp->elem;
+ for (np = tsp->services; np != NULL; np = np->next)
+ { /* for each service */
+ svcp = (NISvcPtr) np->elem;
+ for (np2 = tsp->resources; np2 != NULL; np2 = np2->next)
+ { /* for each resource */
+ resp = (NIResPtr) np2->elem;
+ if (ResourceCompatWService(resp,svcp))
+ {
+ printf ("%s|%s|%s|%d|%d|%d|%s|%s|%d|%d|%s\n",
+ tsp->host, svcp->name, svcp->descrip,
+ svcp->minVersion, svcp->maxVersion, svcp->priority,
+ resp->name, resp->descrip, resp->minVersion,
+ resp->maxVersion, resp->type);
+ }
+ }
+ }
+ }
+}
+
+static void printCatalog(NICatalogPtr cat)
+{
+ NIToolsetPtr tsp;
+ NISvcPtr svcp;
+ NIResPtr resp;
+ NodePtr tsnp, np;
+
+ printf("\n==============================================================================\n");
+ printf("== %-72.72s ==\n", cat->motd);
+ printf("==============================================================================\n");
+
+ tsnp = cat->toolsetL;
+ while (tsnp != NULL) {
+ tsp = (NIToolsetPtr) tsnp->elem;
+ printf("SERVER: %s [%s]\n", tsp->host, tsp->motd);
+ if ((np = tsp->services) != NULL) {
+ Boolean highest;
+ NIToolsetPtr tsp2;
+ NodePtr tsnp2, np2;
+ NISvcPtr svcp2;
+
+ printf("SERVICES:\n");
+ while (np != NULL) {
+ svcp = (NISvcPtr) np->elem;
+ highest = TRUE;
+ for (tsnp2 = cat->toolsetL; tsnp2 != NULL && highest; tsnp2 = tsnp2->next)
+ {
+ tsp2 = (NIToolsetPtr) tsnp2->elem;
+ for (np2 = tsp2->services; np2 != NULL && highest; np2 = np2->next)
+ {
+ svcp2 = (NISvcPtr) np2->elem;
+ if (StrCmp(svcp->name, svcp2->name) == 0)
+ highest = svcp->priority >= svcp2->priority;
+ }
+ }
+ printf("%c %-15.15s Vers. %2d-%2d Pr.%3d %-39.39s\n", highest ? '*' : ' ', svcp->name, svcp->minVersion, svcp->maxVersion, svcp->priority, svcp->descrip);
+ np = np->next;
+ }
+ }
+ if ((np = tsp->resources) != NULL) {
+ printf("RESOURCES:\n");
+ while (np != NULL) {
+ resp = (NIResPtr) np->elem;
+ printf(" %-15.15s Vers. %2d-%2d %-45.45s\n", resp->name, resp->minVersion, resp->maxVersion, resp->descrip);
+ np = np->next;
+ }
+ }
+ printf("------------------------------------------------------------------------------\n");
+ tsnp = tsnp->next;
+ }
+} /* printCatalog */
+
+
+static CharPtr readServer(NI_HandPtr hp)
+{
+ AsnTypePtr atp;
+ AsnIoPtr aip;
+ DataVal value;
+ CharPtr process, sp;
+ Char buf[IOBUFSIZ];
+
+ aip = hp->READ_AIP;
+ atp = ECHO_STRING;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ECHO_STRING) {
+ if (atp != NULL)
+ AsnReadVal(aip, atp, &value);
+ return NULL;
+ }
+ AsnReadVal(aip, atp, &value);
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ECHO_STRING_process) {
+ AsnReadVal(aip, atp, &value);
+ return NULL;
+ }
+ AsnReadVal(aip, atp, &value);
+ process = value.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ECHO_STRING_text) {
+ AsnReadVal(aip, atp, &value);
+ return NULL;
+ }
+ AsnReadVal(aip, atp, &value);
+
+ sprintf(buf, "\tProcess: %s\n\tValue: %s", process, value.ptrvalue);
+ MemFree(process);
+ MemFree(value.ptrvalue);
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ECHO_STRING) {
+ AsnReadVal(aip, atp, &value);
+ return NULL;
+ }
+ AsnReadVal(aip, atp, &value);
+
+ sp = MemNew(StringLen(buf)+1);
+ StringCpy(sp, buf);
+ return sp;
+} /* readServer*/
+
+
+static Int2 writeServer(NI_HandPtr hp, CharPtr buf)
+{
+ AsnIoPtr aip;
+ DataVal value;
+
+ aip = hp->WRITE_AIP;
+ AsnStartStruct(aip, ECHO_STRING);
+ value.ptrvalue = "client";
+ AsnWrite(aip, ECHO_STRING_process, &value);
+ value.ptrvalue = buf;
+ AsnWrite(aip, ECHO_STRING_text, &value);
+ AsnEndStruct(aip, ECHO_STRING);
+ AsnIoFlush(aip);
+ return 0;
+} /* writeServer*/
diff --git a/network/nsdemocl/echo.asn b/network/nsdemocl/echo.asn
new file mode 100644
index 00000000..4b02a5c8
--- /dev/null
+++ b/network/nsdemocl/echo.asn
@@ -0,0 +1,53 @@
+--$Revision: 6.0 $
+-- ===========================================================================
+--
+-- PUBLIC DOMAIN NOTICE
+-- National Center for Biotechnology Information
+--
+-- This software/database is a "United States Government Work" under the
+-- terms of the United States Copyright Act. It was written as part of
+-- the author's official duties as a United States Government employee and
+-- thus cannot be copyrighted. This software/database is freely available
+-- to the public for use. The National Library of Medicine and the U.S.
+-- Government have not placed any restriction on its use or reproduction.
+--
+-- Although all reasonable efforts have been taken to ensure the accuracy
+-- and reliability of the software and data, the NLM and the U.S.
+-- Government do not and cannot warrant the performance or results that
+-- may be obtained by using this software or data. The NLM and the U.S.
+-- Government disclaim all warranties, express or implied, including
+-- warranties of performance, merchantability or fitness for any particular
+-- purpose.
+--
+-- Please cite the author in any work or product based on this material.
+--
+-- ===========================================================================
+--
+-- File Name: echo.asn
+--
+-- Author: Beatty, Gish
+--
+-- Version Creation Date: 1/1/92
+--
+-- $Revision: 6.0 $
+--
+-- File Description:
+-- ASN.1 message header
+--
+-- ==========================================================================
+
+
+TEST-ECHO DEFINITIONS ::=
+BEGIN
+
+EXPORTS ECHO-String;
+
+ECHO-String ::= SEQUENCE {
+ process VisibleString, -- name of process
+ text VisibleString -- text echoed
+}
+
+END
+
+
+
diff --git a/network/nsdemocl/encrutil.c b/network/nsdemocl/encrutil.c
new file mode 100644
index 00000000..9db63c00
--- /dev/null
+++ b/network/nsdemocl/encrutil.c
@@ -0,0 +1,277 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: encrutil.c
+*
+* Author: Epstein
+*
+* Version Creation Date: 2/14/94
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Encryption utility standalone program, to perform many simple encryption
+* tasks and validate encryption operation on a given machine.
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+*
+* RCS Modification History:
+* $Log: encrutil.c,v $
+* Revision 6.0 1997/08/25 18:40:10 madden
+* Revision changed to 6.0
+*
+* Revision 5.0 1996/05/28 14:13:55 ostell
+* Set to revision 5.0
+*
+ * Revision 4.0 1995/07/26 13:57:04 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.5 1995/05/17 17:52:58 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <ncbi.h>
+#include <asn.h>
+#include <ncbinet.h>
+
+#define RSA_ENCR_TEXT "The quick"
+#define DES_ENCR_TEXT "The quick brown fox jumped over the lazy dog"
+
+#define NEEDED_CONFOUND 500
+
+Args myargs[] = {
+ {"Bits in public key modulus", "508","508", "1024", TRUE,'b',ARG_INT,0.0,0,NULL},
+ {"pUblic key file", "pubkey.enc", NULL, NULL, TRUE, 'u', ARG_STRING,0.0,0,NULL},
+ {"pRivate key file", "dispd.privkey", NULL, NULL, TRUE, 'r', ARG_STRING,0.0,0,NULL},
+ {"password for des Encryption of private key", NULL, NULL, NULL, TRUE, 'e', ARG_STRING,0.0,0,NULL},
+ {"perform Validation", "F", NULL, NULL, TRUE, 'v', ARG_BOOLEAN, 0.0,0,NULL},
+ {"Arbitrary file used to confound key cracking", NULL, NULL, NULL, TRUE, 'a', ARG_STRING, 0.0,0,NULL},
+ {"additional Help", "F", NULL, NULL, TRUE, 'h', ARG_BOOLEAN, 0.0,0,NULL}};
+
+static void
+PrintHelp(void)
+{
+ printf ("\nThis program generates public-encryption keys for use in the NCBI network\n");
+ printf ("services paradigm. It can also be used to validate the operation of DES\n");
+ printf ("and public-key encryption on the computer where this program is run.\n\n");
+ printf ("If the '-v' option (validation) is specified, the program randomly generates a\n");
+ printf ("DES key and a public-private RSA pair, and tests encryption and decryption under\n");
+ printf ("both DES and RSA. The normal output of keys is not performed in this case.\n\n");
+ printf ("If the '-e' (password for DES Encryption of private key) option is used, the\n");
+ printf ("specified password is encoded (but not encrypted!) and displayed upon the\n");
+ printf ("standard output, while the private RSA key is encrypted using that encoded DES\n");
+ printf ("key and written to the private key output file. This option provides a way to\n");
+ printf ("store a private key in a file without fear that compromise of that file\n");
+ printf ("will immediately result in compromise of the private key.\n\n");
+}
+
+static void
+EncodePassword(CharPtr encoding, CharPtr desPassword)
+{
+ Uchar input[12];
+ UcharPtr inp = input;
+ UcharPtr out = (UcharPtr) encoding;
+ Int2 i;
+ Int2 j;
+ Uint4 temp;
+ Uchar ch;
+
+ StrNCpy((CharPtr) input, desPassword, sizeof(input));
+ for (j = 0; j < 3; j++)
+ {
+ temp = 0;
+
+ for (i = 0; i < 4; i++)
+ {
+ ch = *inp++;
+ if (ch >= 128)
+ ch -= 128;
+ if (ch >= 32)
+ ch -= 32;
+ if (ch >= 64)
+ ch -= 32;
+ /* ch is now normalized between 0 and 63 */
+ temp = temp * 64 + ch;
+ }
+ *out++ = temp / 65536;
+ temp /= 256;
+ *out++ = temp / 256;
+ *out++ = temp & 255;
+ }
+}
+
+
+Int2
+Main()
+{
+ int Numarg = sizeof(myargs)/sizeof(Args);
+ AsnIoPtr pubAip;
+ NI_PubKeyPtr pub1;
+ VoidPtr privKey;
+ FILE *fp;
+ UcharPtr text;
+ UcharPtr cipherText = NULL;
+ UcharPtr plainText = NULL;
+ Int2 cLen, newlen;
+ CharPtr privFileName;
+ CharPtr pubFileName;
+ CharPtr desPassword = NULL;
+ int bits;
+ Char c;
+ Int2 numConfoundChars;
+ Int2 numConfoundLongWords;
+ Char databuf[9];
+ Char strbuf[20];
+ Uint4 longWord;
+
+ if (! NI_EncrAvailable())
+ {
+ printf ("The NCBI toolkit does not support encryption in the manner in which this\n");
+ printf ("executable was prepared. To support encryption, be sure that ni_encr.c appears\n");
+ printf ("in the link, rather than ni_encrs.c\n");
+ return -1;
+ }
+
+ if ( ! GetArgs("Encryption utilities $Revision: 6.0 $", Numarg, myargs))
+ return 1;
+
+ if (myargs[6].intvalue)
+ {
+ PrintHelp();
+ return 0;
+ }
+
+ bits = myargs[0].intvalue;
+ pubFileName = myargs[1].strvalue;
+ privFileName = myargs[2].strvalue;
+ if (myargs[3].strvalue != NULL && myargs[3].strvalue[0] != '\0')
+ { /* encode an existing private key using the specified password */
+ Int2 privkeylen;
+ Char encoding[9];
+ Int4 newLen;
+ NI_HandPtr encrHP;
+ NI_EncrDataPtr encr;
+ CharPtr encryptedPrivKey;
+ Int2 i;
+
+ desPassword = myargs[3].strvalue;
+ EncodePassword(encoding, desPassword);
+ fp = FileOpen(privFileName, "r");
+ privKey = NI_LoadPrivKey(fp, &privkeylen);
+ encrHP = MsgMakeHandle(FALSE);
+ NI_SetupDESEncryption(encrHP, encoding);
+ encr = encrHP->encryption;
+ encryptedPrivKey = (CharPtr) MemNew(privkeylen + 100);
+ newLen = encr->write_filter(encrHP, privKey, privkeylen, encryptedPrivKey);
+ MsgDestroyHandle(encrHP);
+ FileClose(fp);
+ fp = FileOpen(privFileName, "w");
+ FileWrite(encryptedPrivKey, newLen, 1, fp);
+ MemFree (encryptedPrivKey);
+ FileClose(fp);
+
+ /* print out the environment variable which must be used for decryption */
+ printf ("NI_DES_FOR_PRIVKEY=");
+ for (i = 0; i < 8; i++)
+ printf ("%02X", encoding[i] & 255);
+ printf ("\n");
+ return 0;
+ }
+
+
+#ifdef NOT_REALPROG
+ pubAip = AsnIoOpen("dispd.pubkeytest", "r");
+ pub1 = (NI_PubKeyPtr) NI_MakePubKey();
+ NI_ReadPubKey(pubAip, NULL, pub1);
+ AsnIoClose(pubAip);
+ if ((cLen = NI_PubKeyEncrypt(pub1, text, StrLen(text) + 1, &cipherText)) < 0)
+ {
+ fprintf (stderr, "Encryption failed (%d)\n", cLen);
+ exit (1);
+ }
+ fp = FileOpen("dispd.privkeytest", "r");
+ privKey = NI_LoadPrivKey(fp, NULL);
+ FileClose(fp);
+ if ((newlen = NI_PubKeyDecrypt(privKey, &plainText, cipherText, cLen)) < 0)
+ {
+ fprintf (stderr, "Decryption failed (%d)\n", newlen);
+ exit (1);
+ }
+ MemFree(privKey);
+ fprintf (stderr, "Decrypted text is %s, length is %d\n", plainText, newlen);
+ MemFree (plainText);
+ MemFree (cipherText);
+ NI_DestroyPubKey (pub1);
+
+#else
+ if (myargs[5].strvalue != NULL && myargs[5].strvalue[0] != '\0')
+ {
+ if ((fp = FileOpen(myargs[5].strvalue, "r")) == NULL)
+ {
+ fprintf (stderr, "Unable to open `confounder' file %s for reading\n",
+ myargs[5].strvalue);
+ exit (1);
+ }
+ numConfoundChars = 0;
+ numConfoundLongWords = 0;
+ longWord = 0;
+ while ((c = getc(fp)) != EOF && numConfoundLongWords < NEEDED_CONFOUND)
+ {
+ if (c != NULLB)
+ {
+ longWord = longWord * 256 + c;
+ numConfoundChars++;
+ if (numConfoundChars == 4)
+ {
+ numConfoundChars = 0;
+ sprintf (strbuf, "CONFOUND_%d", numConfoundLongWords++);
+ sprintf (databuf, "%ld", longWord);
+ TransientSetAppParam ("NCBI", "NET_SERV", strbuf, databuf);
+ }
+ }
+ }
+ FileClose(fp);
+ if (numConfoundLongWords < NEEDED_CONFOUND)
+ {
+ fprintf (stderr, "Confounder file %s contains too few non-zero data bytes\n",
+ myargs[5].strvalue);
+ exit (1);
+ }
+ }
+
+ pubAip = AsnIoOpen(pubFileName, "w");
+ fp = FileOpen(privFileName, "w");
+ NI_GenAndWritePEMKeys(bits, pubAip, fp);
+ AsnIoClose(pubAip);
+ FileClose(fp);
+ return 0;
+#endif
+}
diff --git a/network/nsdemocl/vclient.c b/network/nsdemocl/vclient.c
new file mode 100644
index 00000000..be4ed05c
--- /dev/null
+++ b/network/nsdemocl/vclient.c
@@ -0,0 +1,696 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: vclient.c
+*
+* Author: Beatty
+*
+* Version Creation Date: 4/9/92
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Simple Vibrant-based NCBI network services client
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: vclient.c,v $
+* Revision 6.0 1997/08/25 18:40:12 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1997/07/18 15:50:08 epstein
+* add declaration for catalog deletion function
+*
+* Revision 5.0 1996/05/28 14:13:55 ostell
+* Set to revision 5.0
+*
+ * Revision 4.1 1995/11/27 21:01:41 epstein
+ * add new parameter in NI_SetDispatcher()
+ *
+ * Revision 4.0 1995/07/26 13:57:04 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.10 1995/05/17 17:53:03 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <vibrant.h>
+#include <panels.h>
+#include "ncbinet.h"
+#include "echo_asn.h"
+
+#define DISPATCHER "dispatch1.nlm.nih.gov"
+#define USER "anonymous"
+#define TEXT_SIZE 20
+#define IOSTR_SIZE 255
+
+static Nlm_TexT WidDialogText PROTO((Nlm_GrouP, Nlm_CharPtr, Nlm_CharPtr, Nlm_Int2, Nlm_TxtActnProc, Nlm_Int2));
+static void ReadProc PROTO((TexT));
+static void WriteProc PROTO((TexT));
+static void SvcReadProc PROTO((TexT));
+static void ShowCatalog PROTO((NICatalogPtr));
+static void catalogAction PROTO((TablE, Int2, Int2));
+static void DismissCatalogProc PROTO((ButtoN));
+static void MakeCatWindow PROTO((void));
+static void SvcCatalogProc PROTO((ButtoN));
+static void DispReadProc PROTO((TexT));
+static void DispAcceptProc PROTO((ButtoN));
+static void DispCancelProc PROTO((ButtoN));
+static void SvcAcceptProc PROTO((ButtoN));
+static void SvcCancelProc PROTO((ButtoN));
+static void SvcSelectProc PROTO((ButtoN));
+static void SendProc PROTO((ButtoN));
+static void SvcConnectProc PROTO((ButtoN));
+static void SvcDisconnectProc PROTO((ButtoN));
+static void DispSelectProc PROTO((ButtoN));
+static void DispConnectProc PROTO((ButtoN));
+static void DispDisconnectProc PROTO((ButtoN));
+static void QuitProc PROTO((IteM));
+static Boolean ReadServer PROTO((NI_HandPtr));
+static Int2 WriteServer PROTO((NI_HandPtr, CharPtr));
+extern Int2 NI_DestroyMsgCatalog(NICatalogPtr cp);
+
+
+static WindoW ioWindow;
+static GrouP ioGroup;
+static GrouP dispGroup;
+static GrouP svcGroup;
+
+static ButtoN serviceButton;
+static ButtoN sendButton;
+static ButtoN svcConnButton;
+static ButtoN svcDisconnButton;
+static ButtoN dispatchButton;
+static ButtoN dispConnButton;
+static ButtoN dispDisconnButton;
+static TexT readText;
+static TexT processText;
+static TexT echoText;
+static CharPtr procTextP;
+static CharPtr echoTextP;
+
+static WindoW catalogWindow;
+static SlatE catSlate;
+static TablE catTable;
+static ButtoN dismissButton;
+static Int2 currentCatRow;
+
+static WindoW dispWindow;
+static ButtoN dispAcceptButton;
+static ButtoN dispCancelButton;
+static TexT dispName;
+static TexT userName;
+static TexT groupName;
+static TexT passWord;
+
+static WindoW svcWindow;
+static GrouP svcSvcGroup;
+static GrouP svcResGroup;
+static ButtoN catalogButton;
+static ButtoN acceptButton;
+static ButtoN cancelButton;
+static TexT service;
+static TexT resource;
+static TexT smin, smax, rmin, rmax;
+static Char svc [64], res [64], svctype[64], tsvmin [8], tsvmax [8], trsmin [8], trsmax [8];
+static Char dispatcher_name [64];
+static Char user_name [64];
+static Char group_name [64];
+static Char pass_word [64];
+static Char dname [64], uname [64], pword[64], gname[64];
+static Int2 svmin, svmax, rsmin, rsmax;
+static NICatalogPtr catalog;
+static NI_DispatcherPtr dispatcher = NULL;
+
+
+Boolean dispConnected = FALSE;
+Boolean svcConnected = FALSE;
+Boolean svcSpecified = FALSE;
+
+NI_HandPtr shSvc;
+
+
+static Nlm_TexT
+WidDialogText(Nlm_GrouP prnt, Nlm_CharPtr prompt, Nlm_CharPtr dfault, Nlm_Int2 charWidth, Nlm_TxtActnProc actn, Nlm_Int2 promptwid)
+{
+ GrouP g;
+
+ g = HiddenGroup (prnt, 2, 0, NULL);
+ (void) StaticPrompt (g, prompt, stdCharWidth * promptwid,
+ stdLineHeight, systemFont, 'l');
+ return DialogText (g, dfault, charWidth, actn);
+}
+
+static void
+ReadProc (TexT readText)
+{
+ Char str [IOSTR_SIZE];
+
+ GetTitle (readText, str, sizeof (str));
+ if (StrngEql (str, "", FALSE)) {
+ Disable (sendButton);
+ }
+ else {
+ if (svcConnected)
+ Enable (sendButton);
+ }
+} /* ReadProc */
+
+static void
+WriteProc (TexT readText)
+{
+ Disable (sendButton);
+} /* ReadProc */
+
+static void
+SvcReadProc (TexT t)
+{
+ GetTitle (service, svc, sizeof (svc));
+ GetTitle (smin, tsvmin, sizeof (tsvmin));
+ GetTitle (smax, tsvmax, sizeof (tsvmax));
+ GetTitle (resource, res, sizeof (res));
+ GetTitle (rmin, trsmin, sizeof (trsmin));
+ GetTitle (rmax, trsmax, sizeof (trsmax));
+
+ if (StringLen (svc) > 0 && StringLen (tsvmin) > 0 && StringLen (tsvmax) > 0
+ && StringLen (res) > 0 && StringLen (trsmin) > 0 && StringLen (trsmax) > 0) {
+ Enable (acceptButton);
+ }
+ else {
+ Disable (acceptButton);
+ }
+} /* SvcReadProc */
+
+static void
+ShowCatalog (NICatalogPtr cat)
+{
+ Char buf [512];
+ NIToolsetPtr tsp;
+ NISvcPtr svcp;
+ NIResPtr resp;
+ NodePtr tsnp, np;
+
+ Char nm[64], desc[255], type[64];
+
+ SetTitle (catalogWindow, cat->motd);
+
+ tsnp = cat->toolsetL;
+ while (tsnp != NULL) {
+ if ((tsp = (NIToolsetPtr) tsnp->elem) != NULL) {
+ if ((np = tsp->services) != NULL) {
+ while (np != NULL) {
+ svcp = (NISvcPtr) np->elem;
+ StringCpy(nm, svcp->name);
+ StringCpy(desc, svcp->descrip);
+ if (svcp->typeL == NULL)
+ StringCpy(type, "NO TYPE");
+ else
+ StringCpy(type, svcp->typeL->elem);
+ sprintf(buf, "%s\t%s\t%d\t%d\t%s\n", type, nm, svcp->minVersion, svcp->maxVersion, desc);
+ AppendTableText (catTable, buf);
+ np = np->next;
+ }
+ }
+ }
+ tsnp = tsnp->next;
+ }
+ Show (catalogWindow);
+ Select (catalogWindow);
+} /* ShowCatalog */
+
+static void
+catalogAction (TablE t, Int2 row, Int2 col)
+{
+
+ if (row != currentCatRow) {
+ if (currentCatRow != 0) {
+ SetTableBlockHilight (catTable, currentCatRow, currentCatRow, 1, 7, FALSE);
+ }
+ currentCatRow = row;
+ SetTableBlockHilight (catTable, currentCatRow, currentCatRow, 1, 7, TRUE);
+ }
+ if (dblClick) {
+ GetTableText (catTable, row, 1, svctype, sizeof(svctype));
+ GetTableText (catTable, row, 2, svc, sizeof(svc));
+ GetTableText (catTable, row, 3, tsvmin, sizeof(tsvmin));
+ GetTableText (catTable, row, 4, tsvmax, sizeof(tsvmax));
+ SetTitle (service, svc);
+ SetTitle (smin, tsvmin);
+ SetTitle (smax, tsvmax);
+ GetTitle (resource, res, sizeof (res));
+ GetTitle (rmin, trsmin, sizeof (trsmin));
+ GetTitle (rmax, trsmax, sizeof (trsmax));
+ Enable (acceptButton);
+/* Remove (catalogWindow); */
+ Hide (catalogWindow);
+ NI_DestroyMsgCatalog(catalog);
+ catalog = NULL;
+ }
+} /* catalogAction */
+
+static void
+DismissCatalogProc (ButtoN dcButton)
+{
+ Hide (catalogWindow);
+/* Remove (catalogWindow); */
+ NI_DestroyMsgCatalog(catalog);
+ catalog = NULL;
+} /* DismissCatalogProc */
+
+static void
+MakeCatWindow (void)
+{
+ GrouP pg;
+ PrompT p;
+ RecT r;
+ WindoW tPort;
+
+ catalogWindow = FixedWindow (-50, -33, -10, -10, "Catalog", NULL);
+
+ pg = HiddenGroup (catalogWindow, 10, 0, NULL);
+ SetGroupMargins (pg, 1, 1);
+ SetGroupSpacing (pg, 1, 1);
+ p = StaticPrompt (pg, "Type", stdCharWidth * 6, stdLineHeight, systemFont, 'l');
+ p = StaticPrompt (pg, "Name", stdCharWidth * 10, stdLineHeight, systemFont, 'l');
+ p = StaticPrompt (pg, "Min", stdCharWidth * 3, stdLineHeight, systemFont, 'l');
+ p = StaticPrompt (pg, "Max", stdCharWidth * 3, stdLineHeight, systemFont, 'l');
+ p = StaticPrompt (pg, "Description", stdCharWidth * 21, stdLineHeight, systemFont, 'l');
+
+ catSlate = ScrollSlate (catalogWindow, 43, 6);
+ catTable = TablePanel (catSlate, 0, systemFont, catalogAction);
+ RecordColumn (catTable, 6, 'l', FALSE, FALSE, NULL);
+ RecordColumn (catTable, 10, 'l', FALSE, TRUE, NULL);
+ RecordColumn (catTable, 3, 'r', FALSE, TRUE, NULL);
+ RecordColumn (catTable, 3, 'r', FALSE, TRUE, NULL);
+ RecordColumn (catTable, 21, 'l', FALSE, TRUE, NULL);
+ currentCatRow = 0;
+ ObjectRect (catSlate, &r);
+ InsetRect (&r, 4, 4);
+ RegisterRect ((PaneL) catTable, &r);
+ if (Visible (catTable) && AllParentsVisible (catTable)) {
+ tPort = SavePort (catTable);
+ Select (catTable);
+ InvalRect (&r);
+ RestorePort (tPort);
+ }
+ dismissButton = DefaultButton (catalogWindow, "Dismiss", DismissCatalogProc);
+
+} /* MakeCatWindow */
+
+static void
+SvcCatalogProc (ButtoN scButton)
+{
+ if ((catalog = NI_GetCatalog (dispatcher)) != NULL) {
+ MakeCatWindow ();
+ ShowCatalog (catalog);
+ } else
+ Message (MSG_OK, "Unable to get catalog");
+} /* SvcCatalogProc */
+
+static void
+DispReadProc (TexT t)
+{
+
+ GetTitle (dispName, dname, sizeof(dname));
+ GetTitle (userName, uname, sizeof(uname));
+ GetTitle (groupName, gname, sizeof(gname));
+ GetTitle (passWord, pword, sizeof(pword));
+
+ if (StringLen(dname) > 0 && StringLen(uname) > 0) { /* password may not be needed */
+ Enable (dispAcceptButton);
+ }
+ else {
+ Disable (dispAcceptButton);
+ }
+}
+
+static void
+DispAcceptProc (ButtoN scButton)
+{
+
+ StringCpy (dispatcher_name, dname);
+ StringCpy (user_name, uname);
+ StringCpy (group_name, gname);
+ StringCpy (pass_word, pword);
+ Hide (dispWindow);
+}
+
+static void
+DispCancelProc (ButtoN scButton)
+{
+ Hide (dispWindow);
+ SetTitle (dispName, dispatcher_name);
+ SetTitle (userName, user_name);
+ SetTitle (groupName, group_name);
+ SetTitle (passWord, pass_word);
+ /* Enable (dispAcceptButton); */
+}
+
+static void
+SvcAcceptProc (ButtoN scButton)
+{
+ svmin = atoi (tsvmin);
+ svmax = atoi (tsvmax);
+ rsmin = atoi (trsmin);
+ rsmax = atoi (trsmax);
+ Hide (svcWindow);
+ Enable (serviceButton);
+ svcSpecified = TRUE;
+} /* SvcAcceptProc */
+
+static void
+SvcCancelProc (ButtoN scButton)
+{
+ Hide (svcWindow);
+ Enable (serviceButton);
+} /* SvcCancelProc */
+
+static void
+SvcSelectProc (ButtoN scButton)
+{
+ Disable (serviceButton);
+ Disable (acceptButton);
+ if (dispConnected)
+ Enable (catalogButton);
+ else
+ Disable (catalogButton);
+ Show (svcWindow);
+ Select (service);
+ Select (svcWindow);
+} /* SvcSelectProc */
+
+static void
+SendProc (ButtoN sendButton)
+{
+ Char str [IOSTR_SIZE];
+
+ Disable (sendButton);
+ GetTitle (readText, str, sizeof (str));
+ SetTitle (readText, "");
+
+ if (WriteServer (shSvc, str) == 0) {
+ if (ReadServer (shSvc)) {
+ SetTitle (processText, procTextP);
+ MemFree (procTextP);
+ SetTitle (echoText, echoTextP);
+ MemFree (echoTextP);
+ }
+ }
+ Select (readText);
+} /* SendProc */
+
+static void
+SvcConnectProc (ButtoN cButton)
+{
+ if (! svcSpecified) {
+ Message (MSG_OK, "No service has been specified");
+ return;
+ }
+ if ((shSvc = NI_ServiceGet (dispatcher, svc, svmin, svmax, res, svctype, rsmin, rsmax)) == NULL) {
+ Message (MSG_OK, "Unable to get service [%s]: %s", svc, ni_errlist[ni_errno]);
+ return;
+ }
+ svcConnected = TRUE;
+ Enable (svcDisconnButton);
+ Disable (svcConnButton);
+ SetTitle (echoText, "");
+ SetTitle (processText, "");
+ Select (readText); /* put the insertion point in the read text box */
+} /* SvcConnectProc */
+
+static void
+SvcDisconnectProc (ButtoN dButton)
+{
+ if (svcConnected) {
+ NI_ServiceDisconnect (shSvc);
+ svcConnected = FALSE;
+ }
+ Enable (svcConnButton);
+ Disable (svcDisconnButton);
+} /* SvcDisconnectProc */
+
+static void
+DispSelectProc (ButtoN dButton)
+{
+ Disable (dispAcceptButton);
+ Show (dispWindow);
+ Select (dispName);
+ Select (dispWindow);
+} /* DispSelectProc */
+
+static void
+DispConnectProc (ButtoN cButton)
+{
+ dispatcher = NI_SetDispatcher (NULL, dispatcher_name, NULL, 0, 0, NULL, FALSE);
+ if (NI_InitServices (dispatcher, user_name, group_name[0] == '\0' ? NULL : group_name, pass_word, NULL) < 0) {
+ Message (MSG_OK, "Unable to connect to dispatcher");
+ return;
+ }
+ else
+ dispConnected = TRUE;
+
+ Disable (dispConnButton);
+ Enable (dispDisconnButton);
+ Enable (svcConnButton);
+} /* DispConnectProc */
+
+static void
+DispDisconnectProc (ButtoN dButton)
+{
+ if (svcConnected) {
+ NI_ServiceDisconnect (shSvc);
+ svcConnected = FALSE;
+ }
+ if (dispConnected) {
+ NI_EndServices (dispatcher);
+ dispatcher = NULL;
+ dispConnected = FALSE;
+ }
+ Disable (dispDisconnButton);
+ Disable (svcConnButton);
+ Disable (svcDisconnButton);
+ Enable (dispConnButton);
+} /* DispDisconnectProc */
+
+static void
+QuitProc (IteM i)
+{
+ if (svcConnected)
+ NI_ServiceDisconnect (shSvc);
+ if (dispConnected) {
+ NI_EndServices (dispatcher);
+ dispatcher = NULL;
+ }
+ QuitProgram ();
+} /* QuitProc */
+
+extern Int2
+Main ()
+{
+ GrouP g, gs;
+ MenU m;
+ IteM i;
+
+ /* service window */
+
+ svcWindow = FixedWindow (-60, -40, -10, -10, "Service Selection", NULL);
+
+ gs = HiddenGroup (svcWindow, 0, 3, NULL);
+ SetGroupMargins (gs, 10, 10);
+ SetGroupSpacing (gs, 10, 10);
+
+ svcSvcGroup = NormalGroup (gs, 0, 10, "Service", NULL, NULL);
+ SetGroupMargins (svcSvcGroup, 10, 10);
+ SetGroupSpacing (svcSvcGroup, 10, 10);
+
+ svcSvcGroup = NormalGroup (gs, 0, 10, "Service", NULL, NULL);
+ SetGroupMargins (svcSvcGroup, 10, 10);
+ SetGroupSpacing (svcSvcGroup, 10, 10);
+ service = WidDialogText (svcSvcGroup, "Name", "", 8, SvcReadProc, 3);
+ Break (svcSvcGroup);
+ smin = WidDialogText (svcSvcGroup, "Min", "1", 5, SvcReadProc, 3);
+ Advance (svcSvcGroup);
+ smax = WidDialogText (svcSvcGroup, "Max", "0", 5, SvcReadProc, 3);
+
+ svcResGroup = NormalGroup (gs, 0, 10, "Resource", NULL, NULL);
+ SetGroupMargins (svcResGroup, 10, 10);
+ SetGroupSpacing (svcResGroup, 10, 10);
+ resource = WidDialogText (svcResGroup, "Name", "echo", 8, SvcReadProc, 3);
+
+ Break (svcWindow);
+ catalogButton = PushButton (svcWindow, "Catalog", SvcCatalogProc);
+ Advance (svcWindow);
+ acceptButton = PushButton (svcWindow, "Accept", SvcAcceptProc);
+ Advance (svcWindow);
+ cancelButton = PushButton (svcWindow, "Cancel", SvcCancelProc);
+
+ /* dispatcher window */
+
+ dispWindow = FixedWindow (-30, -20, -10, -10, "Dispatcher Selection", NULL);
+
+ g = HiddenGroup (dispWindow, 0, 4, NULL);
+ SetGroupMargins (g, 10, 10);
+ SetGroupSpacing (g, 10, 10);
+
+ StringCpy (dispatcher_name, DISPATCHER);
+ StringCpy (user_name, USER);
+ StringCpy (group_name, "");
+ StringCpy (pass_word, "");
+
+ gs = HiddenGroup (g, 2, 0, NULL);
+ StaticPrompt (gs, "Dispatcher Name", 0, 0, systemFont, 'l');
+ dispName = DialogText (gs, dispatcher_name, TEXT_SIZE, DispReadProc);
+ StaticPrompt (gs, "User Name", 0, 0, systemFont, 'l');
+ userName = DialogText (gs, user_name, TEXT_SIZE, DispReadProc);
+ StaticPrompt (gs, "Group Name", 0, 0, systemFont, 'l');
+ groupName = DialogText (gs, group_name, TEXT_SIZE, DispReadProc);
+ StaticPrompt (gs, "Password", 0, 0, systemFont, 'l');
+ passWord = PasswordText (gs, pass_word, TEXT_SIZE, DispReadProc);
+
+ Break (dispWindow);
+ dispAcceptButton = PushButton (dispWindow, "Accept", DispAcceptProc);
+ Advance (dispWindow);
+ dispCancelButton = PushButton (dispWindow, "Cancel", DispCancelProc);
+
+ /* main window */
+
+ ioWindow = FixedWindow (-50, -33, -10, -10, "Network Services Test Client", NULL);
+ m = PulldownMenu (ioWindow, "File");
+ i = CommandItem (m, "Quit", QuitProc);
+
+ g = HiddenGroup (ioWindow, 0, 3, NULL);
+ SetGroupMargins (g, 10, 10);
+ SetGroupSpacing (g, 10, 10);
+
+ ioGroup = NormalGroup (g, 0, 10, "Echo", NULL, NULL);
+ SetGroupMargins (ioGroup, 10, 10);
+ SetGroupSpacing (ioGroup, 10, 10);
+
+ gs = HiddenGroup (ioGroup, 2, 0, NULL);
+ StaticPrompt (gs, "Enter Text", 0, 0, systemFont, 'l');
+ readText = DialogText (gs, "", TEXT_SIZE, WriteProc);
+ StaticPrompt (gs, "Process", 0, 0, systemFont, 'l');
+ processText = DialogText (gs, "", TEXT_SIZE, WriteProc);
+ StaticPrompt (gs, "Echo Text", 0, 0, systemFont, 'l');
+ echoText = DialogText (gs, "", TEXT_SIZE, WriteProc);
+
+ sendButton = PushButton (ioGroup, "Send", SendProc);
+ Disable (sendButton);
+ Select (readText);
+
+ svcGroup = NormalGroup (g, 0, 10, "Service", NULL, NULL);
+ SetGroupMargins (svcGroup, 10, 10);
+ SetGroupSpacing (svcGroup, 30, 10);
+ serviceButton = PushButton (svcGroup, "Specify", SvcSelectProc);
+ Advance (svcGroup);
+ svcConnButton = PushButton (svcGroup, "Connect", SvcConnectProc);
+ Advance (svcGroup);
+ svcDisconnButton = PushButton (svcGroup, "Disconnect", SvcDisconnectProc);
+ Disable (svcConnButton);
+ Disable (svcDisconnButton);
+
+ dispGroup = NormalGroup (g, 0, 10, "Dispatcher", NULL, NULL);
+ SetGroupMargins (dispGroup, 10, 10);
+ SetGroupSpacing (dispGroup, 30, 10);
+ dispatchButton = PushButton (dispGroup, "Specify", DispSelectProc);
+ Advance (dispGroup);
+ dispConnButton = PushButton (dispGroup, "Connect", DispConnectProc);
+ Advance (dispGroup);
+ dispDisconnButton = PushButton (dispGroup, "Disconnect", DispDisconnectProc);
+ Disable (dispDisconnButton);
+
+ Show (ioWindow);
+ ProcessEvents ();
+ return 0;
+} /* Main */
+
+static Boolean
+ReadServer (NI_HandPtr hp)
+{
+ AsnTypePtr atp;
+ AsnIoPtr aip;
+ DataVal value;
+
+ aip = hp->READ_AIP;
+ atp = ECHO_STRING;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ECHO_STRING) {
+ if (atp != NULL)
+ AsnReadVal(aip, atp, &value);
+ return FALSE;
+ }
+ AsnReadVal(aip, atp, &value);
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ECHO_STRING_process) {
+ AsnReadVal(aip, atp, &value);
+ return FALSE;
+ }
+ AsnReadVal(aip, atp, &value);
+ procTextP = value.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ECHO_STRING_text) {
+ AsnReadVal(aip, atp, &value);
+ return FALSE;
+ }
+ AsnReadVal(aip, atp, &value);
+ echoTextP = value.ptrvalue;
+
+ if ((atp = AsnReadId(aip, amp, atp)) != ECHO_STRING) {
+ AsnReadVal(aip, atp, &value);
+ return FALSE;
+ }
+ AsnReadVal(aip, atp, &value);
+
+ return TRUE;
+} /* readServer*/
+
+static Int2
+WriteServer (NI_HandPtr hp, CharPtr buf)
+{
+ AsnIoPtr aip;
+ DataVal value;
+
+ aip = hp->WRITE_AIP;
+ AsnStartStruct(aip, ECHO_STRING);
+ value.ptrvalue = StringSave("WinClient");
+ AsnWrite(aip, ECHO_STRING_process, &value);
+ value.ptrvalue = StringSave(buf);
+ AsnWrite(aip, ECHO_STRING_text, &value);
+ AsnEndStruct(aip, ECHO_STRING);
+ AsnIoFlush(aip);
+ return 0;
+} /* writeServer */
+
+
diff --git a/network/pcnfs/README b/network/pcnfs/README
new file mode 100644
index 00000000..74ae243a
--- /dev/null
+++ b/network/pcnfs/README
@@ -0,0 +1,21 @@
+In order to use the NCBI network services in conjunction with the PC-NFS 4.0
+development tools, it is necessary to copy and create the following directories
+into this directory after you have installed PC-NFS development software
+version 4.0a:
+
+include (including all its associated subdirectories)
+borlib
+msclib
+
+These files are copyrighted by Sun Microsystems, so it is not possible for
+NCBI to distribute them in its software tree.
+
+Note that you may, e.g., refrain from copying the msclib directory if
+you are only using the Borland compiler, and conversely.
+
+Note that applications developed in this environment must (according to
+the PC-NFS documentation) only be run with PC-NFS version 4.0 or 4.0a.
+
+Note that for PC-NFS version 5.0 and up, you should ignore this
+directory and instead use the instructions which appear in the winsock
+directory of this source tree, since PC-NFS 5.0 is WinSock-compliant.
diff --git a/network/socks/socks.cstc.4.2.pre1.tar.Z b/network/socks/socks.cstc.4.2.pre1.tar.Z
new file mode 100644
index 00000000..cc4c38c7
--- /dev/null
+++ b/network/socks/socks.cstc.4.2.pre1.tar.Z
Binary files differ
diff --git a/network/socks/socks.cstc.4.2/CHANGES b/network/socks/socks.cstc.4.2/CHANGES
new file mode 100644
index 00000000..79c534d3
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/CHANGES
@@ -0,0 +1,118 @@
+Pre-release 1 of version 4.2 of SOCKS.CSTC, dated June 30, 1994
+
+-Made consistent use of u_int32 for alpha port. (David Mischel)
+
+-Included partial port (server and library) for NextStep 3.2. (William Lewis)
+
+-Made clients behave like non-SOCKSified programs if /etc/socks.conf
+ is absent.
+
+-Made the printing of client banner controllable using environment
+ variable SOCKS_BANNER. (Bryan Curnutt)
+
+-Added compile-time option to disable syslog from clients. (Jason Baietto)
+
+-Added DNS_THROUGH_NIS in Makefile to accomodate sites which resolve
+ DNS through their NIS server and have no local /etc/resolv.conf.
+
+-Include bsdinstall, a shell script written by Phil Hochstetler,
+ phil@sequent.com, which simulate BSD's install for SYSV systems.
+
+=======================================
+Beta release of version 4.2 of SOCKS.CSTC, dated March 21, 1994
+
+-Added code to allow use of filenames in the *=userlist field.
+ The filenames must be a complete path (starting with /). Userids
+ and comments can be used in such files. Updated the man pages
+ sockd.conf.5 and soccks.conf.5 to document the new feature.
+
+-Merged in code to show sockd's usage details in the output of
+ ps commamd. Only work with non-SYSV hosts. (Matt Cohen)
+
+========================================
+Beta release of version 4.2 of SOCKS.CSTC, dated February 22, 1994
+
+-Corrected mistakes in determining privileged/non-privileged port.
+
+-Dereferenced addr in saddrtoname.c. (Anthony Starks)
+
+-Added code to zero out all sockaddr_in structures before using them.
+ (Carlos Mora)
+
+-Added code to treat IP address 0.0.0.0 as localhost. (Anthony Shipman)
+
+-Added code to save host and port after a successful direct connect.
+ (Ian Dunkin)
+
+-Made the facility and the log levels for syslog configurable in
+ socks.h. (Jon Luini)
+
+-Made the optimization flag for cc configurable in Makefile. (Craig Metz)
+
+-Made SendDst() and GetDst() quit when write() or read() returns 0.
+ (David Nochlin)
+
+-Added code to use iotcl(...,FIOSSAIOOWN...) in place of
+ fcntl(...F_SETOWN...) for hpux. (John Brezak)
+
+=======================================
+Beta release of version 4.2 of SOCKS.CSTC, dated February 9, 1994.
+
+Changes since release 4.1
+
+1) Merged in SCO/ODT 2.x and BSDi v1.0 ports by Chris Riney.
+
+2) Merged in PS/2 AIX 1.2.1 port by Craig Metz.
+
+3) Merged in DEC OSF 1.3 port by Alain Mellan.
+
+4) Merged in the code to prevent premature closing of a TCP session
+ on the SOCKS server when the server is much faster than the
+ client host. Contributed by Andy McFadden.
+
+5) Merged in the code for using environment variable SOCKS_DNAME
+ to override the setting of SOCKS_DEFAULT_DNAME. Contributed by
+ Jon Luini.
+
+6) It handles non-blocking connect() call correctly, at least for
+ the way non-blocking connect()'s are done in Mosaic 2.1. This
+ necessitates the addition of Rselect() to the library.
+
+7) You can build libsocks.a with Rbind() which accepts the same
+ calling sequence as regular bind(), i.e., without the extra
+ last argument.
+
+8) Call to SOCKSinit() is made optional.
+
+9) Rrcmd() is optionally added to the library.
+
+The combined effect of 6) through 9) is that, for most applications,
+you can do the SOOCKSification without doing anything to the code
+at all. Just add
+
+-Dconnect=Rconnect -Dbind=Rbind -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dselect=Rselect
+
+to cc and make sure the appropraite SOCKS library is used in linking.
+I hope this will encourage developers to produce SOCKSified version
+of their applications. (By the way, if you really want that, you should
+certainly make the effort of letting your friendly software vendors
+or developers know about it. Customers's demands count a great deal
+in the software market.)
+
+10) In anticipation of client hosts that can't run identd, a new
+ filed '?=n' is added to the control line for sockd.conf. This
+ enables the use of invoking sockd with -I option to use identd
+ in general but have it turned off for some specific client hosts.
+ (You can also use '?=I' or '?=i' to turn identd on for a line, I
+ just see the use of '?=n' as more likely.)
+
+11) Deliver out-of-band data end to end.
+
+12) Connection to 127.0.0.1 (localhost) is always direct. No more
+ need to specify that in /etc/socks.conf.
+
+ Ying-Da Lee (214)518-3490 (214)518-3552 (FAX)
+ Principal Member, Technical Staff
+ NEC Systems Laboratory, C&C Software Technology Center /
+ ylee@syl.dl.nec.com
+
diff --git a/network/socks/socks.cstc.4.2/COPYRIGHTS b/network/socks/socks.cstc.4.2/COPYRIGHTS
new file mode 100644
index 00000000..7d64e6bf
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/COPYRIGHTS
@@ -0,0 +1,50 @@
+-----------------------------------------------------------------
+Copyright (c) 1989 Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-----------------------------------------------------------------
+Portions Copyright (c) 1993, 1994 by NEC Systems Laboratory.
+
+Permission to use, copy, modify, and distribute this software for
+any purpose with or without fee is hereby granted, provided that
+the above copyright notice and this permission notice appear in all
+copies, and that the name of NEC Systems Laboratory not be used in
+advertising or publicity pertaining to distribution of the document
+or software without specific, written prior permission.
+
+THE SOFTWARE IS PROVIDED ``AS IS'' AND NEC SYSTEMS LABORATORY DISCLAIMS
+ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NEC
+SYSTEMS LABORATORY BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/network/socks/socks.cstc.4.2/How_to_SOCKSify b/network/socks/socks.cstc.4.2/How_to_SOCKSify
new file mode 100644
index 00000000..3c59428f
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/How_to_SOCKSify
@@ -0,0 +1,35 @@
+Four Easy Steps to SOCKSify (Most of) Your Favorite Network Programs
+ For use with SOCKS.CSTC version 4.2
+ (Ying-Da Lee, ylee@syl.dl.nec.com>)
+===================================================================
+
+1) Find out if UDP is used in the program by doing "grep SOCK_DGRAM" on
+ all the source files. If any such lines are found (and are not comments),
+ you can't make it work with SOCKS. There is, however, a UDP relayer
+ which is to UDP what SOCKS is to TCP, and you may want to look into
+ it. It is written by Tom Fitzgerald <fitz@wang.com> and is available
+ from host ftp.wang.com, file /pub/fitz/udprelay-0.2.tar.Z.
+
+2) At or near the beginning of the main procedure, add this line:
+
+ SOCKSinit(argv[0]);
+
+ This step can be omitted. The only consequence is that the generic
+ 'SOCKSclient' rather than the actual client program name will be
+ used in the syslog lines on the client host.
+
+3) Add
+
+ -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dbind=Rbind -Daccept=Raccept -Dlisten=Rlisten -Dselect=Rselect
+
+ to all cc lines. If Makefile is used, this is simply done by adding
+ the above to the definition of macro CFLAGS.
+
+4) Make sure that the appropriate SOCKS library (version 4.2, built with
+ -DSHORTENED_RBIND) is linked in in the ld or the last cc command to
+ produce the executable.
+
+That's it for most programs. Build the program and try it, chances
+are it would work. If it doesn't and you still like to have a SOCKSified
+version, please read the file What_SOCKS_expects.
+
diff --git a/network/socks/socks.cstc.4.2/Makefile b/network/socks/socks.cstc.4.2/Makefile
new file mode 100644
index 00000000..f243dc90
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/Makefile
@@ -0,0 +1,311 @@
+#DEBUG=-DDEBUG
+
+SHELL=/bin/sh
+
+#SOCKS=-DSOCKS
+# or
+SOCKS=-Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect
+# If the second definition of SOCKS is used, you MUST also
+# define SHORTENED_RBIND
+
+# If your system doesn't have PWD defined, define it here:
+#PWD=/projects/insg/socks.cstc.4.2beta
+# It should be this current directory.
+
+# If your system has getcwd() but no getwd(), uncomment the next line:
+#GETCWD=-DGETCWD
+
+# Define FASCIST if you want ftp (rftp) to log names of all files transferred
+#FASCIST=-DFASCIST
+
+# Define RCMD and SUPPORT_RCMD if you want to support Rrcmd, which is required
+# for SOCKSified rlogin, rsh, and rcp.
+#RCMD=Rrcmd.o
+#SUPPORT_RCMD=-DSUPPORT_RCMD
+
+# Define FOR_PS if your system is not SYSV and you want to have the
+# command 'ps' show some details of sockd's activity.
+#FOR_PS=-DFOR_PS
+
+# Define SHORTENED_RBIND to make Rbind() take exactly the same
+# argument list as the regular bind(), i.e., without the additional
+# 'remhost' argument.
+SHORTENED_RBIND=-DSHORTENED_RBIND
+
+# optimization flag for cc
+OPTIMIZE=-g
+#OPTIMIZE=-O
+# Be careful with the OPTIMIZE flag. SunPro's SC2.0.1, for example, is
+# knwon to produce incorrect code when -O is used.
+
+# Define NO_CLIENT_LOG if you don't want SOCKS clients to produce
+# log entries of its activities.
+#NO_CLIENT_LOG= -Dopenlog= -Dsyslog=
+
+# Define DNS_THROUGH_NIS if your SOCKS client hosts let their NIS
+# servers do the DNS loopkup for them. You are in this category if
+# your client hosts has no /etc/resolv.conf but can resolve all
+# internal and external names.
+#DNS_THROUGH_NIS=-DDNS_THROUGH_NIS
+
+# Directory into which to install the man pages
+MAN_DEST_DIR = /usr/local/man
+
+# Directory into which the SOCKS server should be installed
+SERVER_BIN_DIR = /usr/etc
+
+# Directory into the client programs should be installed
+CLIENTS_BIN_DIR = /usr/local/bin
+
+# SunOS 4.1.x should use
+CC=cc
+#CC=gcc
+OTHER_CFLAGS= $(GETCWD) $(FASCIST) $(SHORTENED_RBIND) -DCOMPAT $(MONITOR) $(DEBUG)
+RANLIB=ranlib
+OS=sun4.1
+INSTALL=install
+GETPASS=getpass.o
+RESOLV_LIB=-lresolv
+# ... or
+#RESOLV_LIB=
+
+# IRIX should use
+#CC=cc
+#RESOLV_LIB=-lsun
+#OTHER_CFLAGS=-cckr $(GETCWD) $(FASCIST) $(SHORTENED_RBIND) -DCOMPAT
+#RANLIB=/bin/true
+#OS=irix4
+#INSTALL=bsdinstall
+#GETPASS=getpass.o
+
+# Ultrix 4.0 should use
+#CC=cc
+#OTHER_CFLAGS= $(GETCWD) $(SHORTENED_RBIND) $(FASCIST)
+#RANLIB=ranlib
+#OS=ultrix4.0
+#INSTALL=install
+#GETPASS=getpass.o
+#RESOLV_LIB=-lresolv
+
+# HP-UX should use
+#CC=cc
+#OTHER_CFLAGS= $(GETCWD) $(FASCIST) $(SHORTENED_RBIND) -DCOMPAT
+#RANLIB=/bin/true
+#OS=hpux9
+#INSTALL=install
+#GETPASS=
+#RESOLV_LIB=
+
+# RS/6000 AIX 3.2 should use
+#CC=cc
+#RESOLV_LIB=-lbsd
+#OTHER_CFLAGS=-D_BSD -D_NONSTD_TYPES -D_NO_PROTO -DAIX $(GETCWD) $(FASCIST) $(SHORTENED_RBIND) -DCOMPAT
+#RANLIB=ranlib
+#OS=aix3.2
+#INSTALL=install
+#GETPASS=
+
+# PS/2 AIX 1.2 should use
+#CC=cc
+#RESOLV_LIB=-lbsd
+#OTHER_CFLAGS=-D_BSD -D_NONSTD_TYPES -D_NO_PROTO -DAIX $(GETCWD) $(FASCIST) -DCOMPAT -I/usr/local/include -DAIX_PS2
+#RANLIB=ranlib
+#OS=aix_ps2
+#INSTALL=install
+#GETPASS=
+
+# SOLARIS should use
+#CC=cc
+#RESOLV_LIB=-lresolv -lnsl -lsocket
+#OTHER_CFLAGS=-DSOLARIS -Dindex=strchr -Drindex=strrchr $(SHORTENED_RBIND) -DUSE_DIRENT $(GETCWD) $(FASCIST) -DCOMPAT
+#RANLIB=/bin/true
+#OS=solaris2.2
+#INSTALL=install
+#GETPASS=getpass.o
+
+# Interactive Systems Unix should use
+#OTHER_CFLAGS = -DISC $(GETCWD) $(FASCIST) $(SHORTENED_RBIND) -DCOMPAT
+#CC=cc
+#RANLIB=ranlib
+#OS=sun4.1
+#INSTALL=install
+#GETPASS=
+#RESOLV_LIB=-lresolv
+
+# netBSD should use
+#OTHER_CFLAGS = $(GETCWD) $(SHORTENED_RBIND) $(FASCIST)
+#CC=cc
+#RANLIB=ranlib
+#OS=netbsd0.9
+#INSTALL=install
+#GETPASS=
+#RESOLV_LIB=
+
+# LINUX should use
+#CC=gcc
+#RESOLV_LIB=
+#OTHER_CFLAGS=-traditional -DLINUX $(GETCWD) $(FASCIST) $(SHORTENED_RBIND) -DCOMPAT
+#OS=linux
+#INSTALL=install
+#GETPASS=getpass.o
+
+# UnixWare should use
+#CC=cc
+#RESOLV_LIB=-lresolv -lnsl -lsocket
+#OTHER_CFLAGS= -DSOLARIS -Dindex=strchr -Drindex=strrchr -DUSE_DIRENT $(SHORTENED_RBIND) $(GETCWD) $(FASCIST) -DCOMPAT
+#RANLIB=/bin/true
+#INSTALL=/usr/ucb/install
+#OS=UnixWare
+#GETPASS=getpass.o
+
+# Alpha OSF should use:
+#CC=cc
+#RESOLV_LIB=-lresolv
+#OS=alphaOSF
+#OTHER_CFLAGS= $(GETCWD) $(FASCIST) $(SHORTENED_RBIND) -DCOMPAT
+#RANLIB=ranlib
+#INSTALL=install
+#GETPASS=
+
+# SCO UNIX/ODT should use:
+#CC=cc
+#OS=sco
+#RESOLV_LIB=-lsocket
+#OTHER_CFLAGS= $(GETCWD) $(FASCIST) -DSCO -DSVR3 -Dindex=strchr -Drindex=strrc $(SHORTENED_RBIND) -DUSE_DIRENT
+#RANLIB=/bin/true
+#GETPASS=
+#PWD=/test/chris/socks.cstc.4.1
+
+# BSD/386 should use:
+#CC=cc
+#OS=bsdi
+#RESOLV_LIB=
+#OTHER_CFLAGS= $(GETCWD) $(SHORTENED_RBIND) $(FASCIST)
+#RANLIB=ranlib
+#GETPASS=
+
+# NextStep 3.2, SOCKS server and library only
+# (William Lewis, wiml@omnigroup.com)
+#CC=cc
+#OTHER_CFLAGS= $(GETCWD) $(FASCIST) $(SHORTENED_RBIND) -DCOMPAT $(MONITOR) $(DEBUG) -Dstrdup=NXCopyStringBuffer
+#RANLIB=ranlib
+#GETPASS=getpass.o
+#RESOLV_LIB=-lresolv
+# ... or
+#RESOLV_LIB=
+
+# >>>---------------- Others:
+
+# Define RESOLV_LIB if your system doesn't search resolver
+# library automatically.
+# Leave it undefined otherwise.
+#RESOLV_LIB=-lresolv
+# If your compiler or loader complains about _res_init being
+# an undefined symbol, then you must define RESOLV_LIB.
+
+#RANLIB=ranlib
+# Systems (e.g., IRIX) that do not need (and thus don't have) ranlib should use
+#RANLIB=/bin/true
+
+# Comment out defintion of GETPASS if your system has problems
+# compiling it, the version built into your system will then be used.
+# The getpass() function in most Unix systems truncates passwords
+# after 8 characters; the version provided here does not.
+# This only affects ftp with non-anonymous login, and telnet.
+# Ftp with anonymous login allows long passwords regardless
+# of whether GETPASS is defined or not.
+#GETPASS=getpass.o
+
+# The 'install' command is assumed to be the BSD variety (using -m to
+# set the file mode). If the default 'install' on your system doesn't
+# do that, you have to either specify an alternative one in the line below
+# (e.g., /usr/ucb/install) or modify the other Makefile.
+#INSTALL= install
+
+# Macro OS is used in making rtelnet. See the list near top of
+# rtelnet/telnet/Makefile for available choices.
+
+# Remember to include -Dindex=strchr -Drindex=strrchr in OTHER_CFLAGS if
+# you don't have index() and rindex() (Sys-V camp)
+
+# <<<----------------
+
+# The Internet Whois server; used to be nic.ddn.mil.
+WHOIS_SERVER= WHOIS_SERVER=-DWHOIS_SERVER\'=\"rs.internic.net\"\'
+
+SOCKS_LIB=$(PWD)/lib/libsocks.a
+IDENT_LIB=$(PWD)/libident/libident.a
+
+#==============================================================================
+
+all: LIB LIBIDENT server clients
+
+server: LIB LIBIDENT
+ (cd sockd; $(MAKE) CC="$(CC)" RESOLV_LIB="$(RESOLV_LIB)" \
+ OPTIMIZE="$(OPTIMIZE)" \
+ SOCKS_LIB="$(SOCKS_LIB)" SUPPORT_RCMD="$(SUPPORT_RCMD)" \
+ IDENT_LIB="$(IDENT_LIB)" \
+ OTHER_CFLAGS="$(OTHER_CFLAGS) $(FOR_PS)")
+
+clients: RFINGER RFTP RTELNET
+
+LIB:
+ (cd lib; $(MAKE) CC="$(CC)" GETPASS="$(GETPASS)" \
+ OPTIMIZE="$(OPTIMIZE)" \
+ RCMD="$(RCMD)" SUPPORT_RCMD="$(SUPPORT_RCMD)" \
+ DNS_THROUGH_NIS="$(DNS_THROUGH_NIS)" \
+ OTHER_CFLAGS="$(OTHER_CFLAGS) $(NO_CLIENT_LOG)" \
+ RANLIB="$(RANLIB)")
+
+LIBIDENT:
+ (cd libident; $(MAKE) CC="$(CC)" OTHER_CFLAGS="$(OTHER_CFLAGS)" \
+ OPTIMIZE="$(OPTIMIZE)" RANLIB="$(RANLIB)")
+
+# This also build rwhois
+RFINGER: LIB
+ (cd rfinger; $(MAKE) CC="$(CC)" $(WHOIS_SERVER) \
+ OPTIMIZE="$(OPTIMIZE)" SOCKS="$(SOCKS)" \
+ RESOLV_LIB="$(RESOLV_LIB)" SOCKS_LIB="$(SOCKS_LIB)" \
+ OTHER_CFLAGS="$(OTHER_CFLAGS) $(NO_CLIENT_LOG)")
+
+RTELNET: LIB
+ (cd rtelnet; $(MAKE) CC="$(CC)" OS="$(OS)" SOCKS_LIB="$(SOCKS_LIB)" \
+ OPTIMIZE="$(OPTIMIZE)" SOCKS="$(SOCKS)" \
+ RESOLV_LIB="$(RESOLV_LIB)" \
+ OTHER_CFLAGS="$(OTHER_CFLAGS) $(NO_CLIENT_LOG)")
+
+RFTP: LIB
+ (cd rftp; $(MAKE) CC="$(CC)" SOCKS_LIB="$(SOCKS_LIB)" \
+ OPTIMIZE="$(OPTIMIZE)" SOCKS="$(SOCKS)" \
+ RESOLV_LIB="$(RESOLV_LIB)" \
+ OTHER_CFLAGS="$(OTHER_CFLAGS) $(NO_CLIENT_LOG)")
+
+install.server:
+ (cd sockd; $(MAKE) INSTALL="$(INSTALL)" MAN_DEST_DIR="$(MAN_DEST_DIR)" \
+ CC="$(CC)" RESOLV_LIB="$(RESOLV_LIB)" \
+ OPTIMIZE="$(OPTIMIZE)" \
+ SOCKS_LIB="$(SOCKS_LIB)" SUPPORT_RCMD="$(SUPPORT_RCMD)" \
+ IDENT_LIB="$(IDENT_LIB)" \
+ OTHER_CFLAGS="$(OTHER_CFLAGS) $(FOR_PS)" \
+ SERVER_BIN_DIR="$(SERVER_BIN_DIR)" install install.man)
+
+install.clients: install.man
+ for i in rfinger rftp rtelnet; do \
+ (cd $$i ; $(MAKE) INSTALL="$(INSTALL)" \
+ CC="$(CC)" OS="$(OS)" SOCKS_LIB="$(SOCKS_LIB)" \
+ OPTIMIZE="$(OPTIMIZE)" SOCKS="$(SOCKS)" \
+ RCMD="$(RCMD)" SUPPORT_RCMD="$(SUPPORT_RCMD)" \
+ DNS_THROUGH_NIS="$(DNS_THROUGH_NIS)" \
+ RESOLV_LIB="$(RESOLV_LIB)" \
+ OTHER_CFLAGS="$(OTHER_CFLAGS) $(NO_CLIENT_LOG)" \
+ CLIENTS_BIN_DIR="$(CLIENTS_BIN_DIR)" \
+ install) done
+install.man:
+ (cd doc; $(MAKE) INSTALL="$(INSTALL)" MAN_DEST_DIR="$(MAN_DEST_DIR)" \
+ install)
+
+clean:
+ for i in lib libident sockd rfinger rftp rtelnet ; do \
+ ( cd $$i ; $(MAKE) clean) done
+
+
diff --git a/network/socks/socks.cstc.4.2/README.1st b/network/socks/socks.cstc.4.2/README.1st
new file mode 100644
index 00000000..a03de48c
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/README.1st
@@ -0,0 +1,249 @@
+This is CSTC 4.2 release of SOCKS, a package that allows Unix hosts
+behind a firewall to gain full access to the internet without requiring
+direct IP reachability. It does require a SOCKS server program being
+run on a hosts that can communicate directly to hosts behind the firewall
+as well as hosts on the Internet at large. It is based on the original
+SOCKS written by David Koblas <koblas@netcom.com>.
+
+The package includes full source for the SOCKS server and SOCKSified
+client programs of finger, ftp, telnet, and whois. A few other SOCKSified
+clients may be found on ftp.nec.com, in directory /pub/security/socks.cstc.
+Increasingly, software developers are beginning to include SOCKS support
+directly into their products, for example, Mosaic, Lynx, and a version
+of Trumpet Winsock.
+
+This release is known to run on the following Unix platforms:
+
+SunOS 4.1.x (ylee@syl.dl.nec.com)
+Irix 4.0.x (imd1707@ggr.co.uk)
+Ultrix 4.3 (als@cpsg.com.au, imd1707@ggr.co.uk)
+HP-UX 9.0x (als@cpsg.com.au, ken.shackelford@sdrc.com, bryan@Stoner.COM)
+AIX 3.2.x (ken.shackelford@sdrc.com, bryan@Stoner.COM)
+Interactive Systems Unix (ken.shackelford@sdrc.com)
+Alpha OSF 1.3 (ken.shackelford@sdrc.com, amellan@acri.fr, treese@crl.dec.com)
+Solaris 2.2 (ylee@syl.dl.nec.com)
+NetBSD 0.9 (bryan@Stoner.COM)
+UnixWare (pax@ankh.metrolink.com)
+Linux 0.99pl13 (cornell@syl.dl.nec.com, cmetz@thor.tjhsst.edu)
+SCO/ODT 2.x (Chris Riney)
+BSDi 1.0 (Chris Riney)
+PS/2 AIX 1.2.1 (cmetz@thor.tjhsst.edu)
+NextStep 3.2 (server and library only, William Lewis)
+
+-------------------
+All 4.2 clients work with all 4.x servers. 4.0 clients work
+with single-homed 4.2 servers but NOT with 4.2 multi-homed servers.
+4.1 clients work with 4.2 servers, both single- and multi-homed.
+'sockd -ver' tells you not only the version number but also whether
+it is single- or multi-homed.
+
+Please see below for the procedure for building and testing.
+Remember that the names of the control files are all configurable
+in include/socks.h. It will probably greatly reduce your frustration
+while you are flipping between the old and the new versions if you
+uses different file names for the new version.
+
+There is now a mailing list devoted to issues related
+to SOCKS. To join the list, please send an email subscription request
+to majordomo-request@syl.dl.nec.com with
+
+ subscribe socks your@email.address
+
+in the body of the message.
+
+Finally, I want to thanks all the people who have helped in making
+and shaping this release. Many of them are listed in the CHANGES
+file, but undoubted many more are left out due to my poor memory --
+to those, my apologies.
+
+ Ying-Da Lee (214)518-3490 (214)518-3552 (FAX)
+ Principal Member, Technical Staff
+ NEC Systems Laboratory, C&C Software Technology Center /
+ NEC USA, Corporate Network Administration Division
+ ylee@syl.dl.nec.com
+====================================================================
+
+Please read the file 'COPYRIGHTS' before you proceed further.
+
+In the following section, by 'top directory' we mean the top
+directory of the SOCKS package, i.e., the directory you are
+in right now.
+
+-------------------------------------------------------------
+
+HOW TO BUILD THE PROGRAMS
+
+1. Check and modify the following files to suit your systems:
+
+ Makefile
+ include/socks.h
+
+ Be sure that the macro 'SOCKS_DEFAULT_SERVER' in include/sosks.h
+ is set correctly to the host that will be running the proxy server
+ for your site. Although this can be overridden at run time with
+ environment variable SOCKS_SERVER, it is a lot simpler if you put
+ in the right name at compile time. Also be sure to uncomment and set
+ the macro 'SOCKS_DEFAULT_NS' in the same file if yor client machines
+ normally cann't do DNS resolution for outside hosts.
+
+ Be sure that the macros 'ORIG_FINGER' and 'MULTIHOMED_SERVER' in
+ include/socks.h are set correctly.
+
+ In most cases, you should have no needs to modify the Makefiles
+ in the subdirectories. But if you run into problems, you may
+ have to look into modifying
+
+ sockd/Makefile
+ libident/Makefile
+ lib/Makefile
+ rfinger/Makefile
+ rftp/Makefile
+ rtelnet/Makefile
+
+ If your system is not among those included in the top Makefile,
+ then you may also have to construct an entry for your system
+ in the file rtelnet/Config.local.
+
+2. cd to the top directory and issue 'make' command. It's a good
+ idea to direct stdout and stderr to a file so that you can
+ see what's being done afterwards. There will be a few warning
+ messages which you can ignore. This builds the server as well
+ as all the clients.
+
+ If you only want to build the server (and the program for testing
+ your sever configuration file, and the program for converting the
+ file from the old format), use comannd 'make server' instead.
+ Use command 'make clients' to build only the client programs. You
+ can also build the individual clients using 'make RFINGER',
+ 'make RFTP', and 'make RTELNET', all from the top directory.
+
+3. All the man pages (except for libident) are in directory doc.
+ You are encouraged to print them out and read them before proceeding
+ to the next part.
+
+-------------------------------------------------------------
+
+HOW TO INSTALL THE SERVER
+
+1. Become superuser on the proxy server host for your site.
+
+2. cd to the top directory and issue 'make install.server'.
+ This installs programs sockd and test_sockd_conf as well
+ as the man pages for them.
+
+3. Add the line
+socks 1080/tcp
+ to file /etc/services. It would be nice also to include
+gopher 70/tcp
+WWW 80/tcp
+ in the file if you don't already have them.
+
+4. Add the line
+socks stream tcp nowait nobody /usr/etc/sockd sockd
+ to file /etc/inetd.conf. Use the actual path where sockd
+ is installed if not in /usr/etc. If you want to make use of
+ identd on your client machines when it is available, use
+socks stream tcp nowait nobody /usr/etc/sockd sockd -i
+ If you want to REQUIRE identd be run on your client machines,
+ use
+socks stream tcp nowait nobody /usr/etc/sockd sockd -I
+ Running sockd with -I will reject all requests from hosts that
+ do not run identd.
+
+5. Set up access control with file /etc/sockd.conf. You have to
+ read the man pages for sockd, sockd.conf, and test_sockd_conf
+ for the details.
+ For a quick test, you can use these four lines in the file: (Replace
+ 'client_IP' with the IP address of the host on which you will be
+ testing the client programs.)
+permit client_IP 255.255.255.255
+# One LONG line follows:
+deny 0.0.0.0 0.0.0.0 : /usr/ucb/finger @%A | /usr/ucb/mail -s 'SOCKD: rejected -- from %u@%A to host %Z (service %S)' root
+# Another LONG line:
+#BAD_ID: /usr/ucb/finger @%A | /usr/ucb/mail -s '%U pretends to be %u on host %A' root@%A root
+# Last line:
+#NO_IDENTD: /usr/ucb/mail -s 'Please run identd on %A' %u@%A root@%A
+ This is essentially the contents of file sockd/sockd.conf.sample.
+ *** NOTE *** The meanings of 1's and 0's in address masks are
+ reversed from 4.0 and earlier versions. If you already have a working
+ /etc/sockd.conf with an earlier version, use the program
+ sockd/flip_cfmasks to produce one for the new version.
+
+6. If the server host is multi-homed and you built sockd with the
+ macro MULTIHOMED_SERVER in include/socks.h defined, you must
+ also supply the file /etc/sockd.route. For a typical dual-homed
+ server, this can simply be a one-liner:
+out_interface 0.0.0.0 0.0.0.0
+ where out_interface is the IP address of the server's network
+ interface leading to the outside world. The format for lines
+ in this file should be
+# comments
+Interface_addr dst_addr dst_mask
+
+ Read the man page on sockd.route !!!
+
+7. Run a few tests using program test_sockd_conf to make sure you
+ have the configuration file set up correctly. On a multi-homed
+ server, the program also tests /etc/sockd.route and shows which
+ interface is to be used.
+
+8. Send a SIGHUP signal to the running inetd process so that it will
+ use the new configuration. You may also have to do other things to
+ accommodate syslog facility. Read the man pages.
+
+-------------------------------------------------------------
+
+HOW TO TEST THE CLIENT PROGRAMS
+
+ NOTE: Build and install identd on your client hosts first. This is
+ required if you run sockd with -I option. It is a good idea anyway.
+
+ Set up the file /etc/socks.conf on the client host. Lines in this
+ file should be of the form
+# comments
+deny [*=userlist] dst_addr dst_mask [op port]
+direct [*=userlist] dst_addr dst_mask [op port]
+sockd [@=serverlist] [*=userlist] dst_addr dst_mask [op port]
+ Fields in square brackets are optional. The optional @=serverlist
+ field with a 'sockd' line specifies the list of SOCKS servers
+ the client should try (in the given order) instead of the default
+ SOCKS server. If the @=serverlist part is omitted, then the default
+ SOCKS server is used. Commas are used in the userlist and serverlist
+ as separators, no white spaces are allowed.
+
+ Read the man page on socks.conf !!!
+
+ On a client host (for testing purpose, this can be the same as
+ the proxy server), the clients rfinger, rwhois, rftp, and rtelnet,
+ can be tried out without any additional setup on the
+ client host once the server is running. They should behave like
+ finger, whois, ftp, and telnet, respectively. rftp DOES
+ echo your password IF you are using 'anonymous' as the log-in name.
+
+ Quite a lot of details of operations of both the clients and the
+ server are logged. Checking the contents of the log files may be
+ helpful when you run into problems. You should try using these
+ clients to connect to both inside and outside hosts and check the
+ log messages to see whether the correct ways are used.
+
+-------------------------------------------------------------
+
+HOW TO INSTALL CLIENT PROGRAMS
+
+1. Become superuser on the client host.
+
+2. cd to the top directory, then issue the command 'make install.clients'.
+ This installs rfinger, rwhois, rftp, rtelnet, and
+ their man pages.
+
+3. Rename your regular 'finger', 'whois', 'ftp', and 'telnet'
+ to something else. The new name for the 'finger' program
+ must be EXACTLY what you used for defining the macro ORIG_FINGER in
+ include/socks.h. Then either rename the SOCKS clients or use symbolic
+ links for them. For example, if you have installed the clients in
+ directory /usr/local/bin and your regular 'finger', 'whois', 'ftp',
+ and 'telnet' were in /usr/ucb, then you should do
+ln -s /usr/local/bin/rfinger /usr/ucb/finger
+ln -s /usr/local/bin/rftp /usr/ucb/ftp
+ln -s /usr/local/bin/rhwois /usr/ucb/whois
+ln -s /usr/local/bin/rtelnet /usr/ucb/telnet
diff --git a/network/socks/socks.cstc.4.2/README.4.0 b/network/socks/socks.cstc.4.2/README.4.0
new file mode 100644
index 00000000..a1e9f992
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/README.4.0
@@ -0,0 +1,292 @@
+This is SOCKS, a package consisting of a proxy server (sockd)
+and client programs corresponding to finger, whois, ftp, telnet,
+xgopher, and xmosaic, as well as a library module (libsocks.a)
+for adapting other applications into new client programs.
+
+The original SOCKS was written by David Koblas <koblas@netcom.com>,
+which included the library module and finger, whois, and ftp clients.
+
+Clients programs added since the original are:
+
+-telnet: adapted from telnet.91.03.25 by David Borman <dab@cray.com>.
+ This version is supposed to be much easier than the previous one
+ to port to many different systems.
+-xgopher: adapted from xgopher ver. 1.2 by Allan Tuchman <a-tuchman@uiuc.edu>.
+-xmosaic: adapted from xmosaic ver. 1.2 by NCSA staff (contact
+ Marc Andreesen, <marca@ncsa.uiuc.edu>).
+
+The SOCKS protocol has changed with this version. Since the server and
+the clients must use the same SOCKS protocol, this server does not work
+with clients of previous releases, and these clients do not work with
+servers of previous releases.
+
+The access control mechanism has been expanded:
+
+-A list of users can be included along with other fields (source address,
+ destination address, service/port) for permission/denial of access.
+-Identd is used (controlled by option -i and -I) in SOCKS server to try
+ to verify the actual user-ids. The code uses the library written by
+ Peter Eriksson <pen@lysator.liu.se> and /Pär Emanuelsson <pell@lysator.liu.se>.
+-A shell command can optionally be specified with each line. The command
+ is executed if the conditions of that line are satisfied. This is adapted
+ from the same feature and code used in the log_tcp package by Wietse
+ Venema <wietse@wzv.win.tue.nl>.
+-Special entries (#NO_IDENTD: and #BAD_ID:) can be included to specify
+ shell commands to be executed when the client host doesn't run identd
+ and when identd's report doesn't agree with what the client prgram says.
+
+The following can be a reasonable sockd.conf using the new features:
+
+# Permit root on 129.101.64.3 all services
+permit *=root 129.101.64.3 0.0.0.0
+#
+# Permit root and usersa on 129.101.112.10 telnet access to network 222.22.22
+permit *=usera,root 129.101.112.10 0.0.0.0 222.22.22.0 0.0.0.255 eq telnet
+#
+# Permit all users on network 129.101 access to ftp
+permit 129.101.0.0 0.0.255.255 eq ftp
+#
+# Deny everything else. Upon an attempt, finger the client host and pipe
+# the result into an email to root with appropriate Subject line.
+deny 0.0.0.0 255.255.255.255 : finger @%A | /usr/ucb/mail -s 'SOCKD: rejected -- from %u@%A to host %Z (service %S)' root
+#
+# If the client doesn't run identd, tell the user and root there to run it.
+#NO_IDENTD: /usr/ucb/mail -s 'Please run identd on %A' %u@%A root@%A
+#
+# Someone is masquerading as someone else. Finger the client host
+# and pipe the result into an email message for local root and root on
+# the client host with appropriate Subject line.
+#BAD_ID: finger @%A | /usr/ucb/mail -s '%U pretends to be %u on host %A' root@%A root
+
+The test_sockd_conf program can be used to test the access control file,
+including the special entries and the execution of shell commands.
+
+The Identd server is available through anonymous ftp from many places.
+Consult archie. Or you can pick it up from ftp.inoc.dl.nec.com, the
+file is pub/security/pidentd-2.1.2.tar.gz. This copy corrected a mistake
+in the INSTALL file: In step 10, second paragraph, the line
+ TELNET session and enter "4711 , 113", where you replace 4711 with the
+should read
+ TELNET session and enter "113 , 4711", where you replace 4711 with the
+The author of pidentd is Peter Eriksson (pen@lysator.liu.se).
+
+Finally, the network/host byte order confusion has been cleaned up. That
+should make porting to other systems a lot easier. Only machines for which
+the assumptions that short=int=16 bits and long=32 bits do not hold
+are still likely to have serious problems.
+
+The package has been ported for ULTRIX 4.3 by Ian Dunkin <imd1707@ggr.co.uk>
+and Anthony Shipman <als@cpsg.com.au>, for IRIX 4.0.1 by Ian Dunkin (again),
+and partially for HPUX by Anthony Shipman (again!). (We are a small bunch
+of busy bees.) I also include patches by Craig Metz <cmetz@thor.tjhsst.edu>
+to SOCKSize xarchie and ncftp. I have not try these patches out
+myself though.
+
+I want to thank all the people I have mentioned so far, as well as the
+following, who has helped with their bug reports, comments, and suggestions:
+
+Alain Mellan <amellan@acri.fr>, Heinz Naef <whna@nexos.com>, Rejane Forre
+<for@pttnms.ewi.ch>, Michael Lachowski <mlachow@maverick1.erenj.com>,
+Nancy Ball <nancy_ball@sematech.org>, David Vincenzetti <vince@dsi.unimi.it>,
+LaMont Jones <lamont@sp1.cup.hp.com>, Brandon Butterworth
+<brandon@dd.eng.bbc.co.uk>, Richard Schultz <rich@ccrwest.org>.
+
+Please read the file 'COPYRIGHTS' before you proceed further.
+
+In the following section, by 'top directory' we mean the top
+directory of the SOCKS package, i.e., the directory you are
+in right now.
+
+-------------------------------------------------------------
+
+HOW TO BUILD THE PROGRAMS
+
+1. Check and modify the following files to suit your systems:
+
+ Makefile
+ include/socks.h
+ sockd/Makefile
+ libident/Makefile
+ lib/Makefile
+ rfinger/Makefile
+ rftp/Makefile
+ rtelnet/Makefile
+ rxgopher/Makefile
+ rxmosaic/Makefile
+ rxmosaic/libwww/Makefile
+ rxmosaic/libhtmlw/Makefile
+ rxmosaic/src/Makefile
+
+ Be very careful with the Makefiles of rxgopher and rxmosaic.
+ For rxgopher, the Makefile is an exact copy of Makefile.YDL in the same
+ directory. If you have 'xmkmf' on your system, you may want
+ to use that to generate the Makefile itself. See the comment
+ under the section RXGOPHER in the Makefile in the top directory.
+
+ The other Makefiles should not require much tweaking. Generally speaking,
+ macros RESOLV_LIB, SOCKS_LIB, IDENT_LIB, CCKR, RANLIB, and INSTALL are
+ defined in the top level Makfile and then passed down to lower level during
+ the make, overriding the settings in the lower-level Makfiles, so
+ you should define them in the top level Makfile and ignore them in
+ other Makefiles. (The redundancy is provided so that you can do
+ a make in the subdirectories. That is not recommended, however.)
+
+ Be sure that the macro 'SOCKS_DEFAULT_SERVER' in include/sosks.h
+ is set correctly to the host that will be running the proxy server
+ for your site. Although this can be overridden at run time with
+ environment variable SOCKS_SERVER, it is a lot simpler if you put
+ in the right name at compile time. Also be sure to uncomment and set
+ the macro 'SOCKS_DEFAULT_NS' in the same file if yor client machines
+ normally cann't do DNS resolution for outside hosts.
+
+2. cd to the top directory and issue 'make' command. It's a good
+ idea to direct stdout and stderr to a file so that you can
+ see what's being done afterwards. There will be a few warning
+ messages which you can ignore. This builds the server as well
+ as all the clients.
+
+ If you only want to build the server (and the program for testing
+ your sever configuration file), use comannd 'make server' instead.
+ Use command 'make clients' to build only the client programs. You
+ can also build the individual clients using 'make RFINGER',
+ 'make RFTP', 'make RTELNET', 'make RXGOPHER', and 'make RXMOSAIC',
+ all from the top directory.
+
+
+-------------------------------------------------------------
+
+HOW TO INSTALL THE SERVER
+
+1. Become superuser on the proxy server host for your site.
+
+2. cd to the top directory and issue 'make install.server'.
+ This installs programs sockd and test_sockd_conf as well
+ as the man pages for them. Print the man pages and read them.
+
+3. Add the line
+socks 1080/tcp
+ to file /etc/services. It would be nice also to include
+gopher 70/tcp
+WWW 80/tcp
+ in the file if you don't already have them.
+
+4. Add the line
+socks stream tcp nowait nobody /usr/etc/sockd sockd
+ to file /etc/inetd.conf. Use the actual path where sockd
+ is installed if not in /usr/etc. If you want to make use of
+ identd on your client machines when it is available, use
+socks stream tcp nowait nobody /usr/etc/sockd sockd -i
+ If you want to REQUIRE identd be run on your client machines,
+ use
+socks stream tcp nowait nobody /usr/etc/sockd sockd -I
+ Running sockd with -I will reject all requests from hosts that
+ do not run identd.
+
+5. Set up access control with file /etc/sockd.conf. You have to
+ read the man pages for sockd and test_sockd_conf for the details.
+ For a quick test, you can use these four lines in the file: (Replace
+ 'client_IP' with the IP address of the host on which you will be
+ testing the client programs.)
+permit client_IP 0.0.0.0
+deny 0.0.0.0 255.255.255.255 : /usr/ucb/finger @%A | /usr/ucb/mail -s 'SOCKD: rejected -- from %u@%A to host %Z (service %S)' root
+#BAD_ID: /usr/ucb/finger @%A | /usr/ucb/mail -s '%U pretends to be %u on host %A' root@%A root
+#NO_IDENTD: /usr/ucb/mail -s 'Please run identd on %A' %u@%A root@%A
+ This is essentially the contents of file sockd/sockd.conf.sample.
+
+6. Run a few tests using program test_sockd_conf to make sure your
+ have the configuration file set up correctly.
+
+7. Send a SIGHUP signal to the running inetd process so that it will
+ use the new configuration. You may also have to do other things to
+ accommodate syslog facility. Read the man pages.
+
+-------------------------------------------------------------
+
+HOW TO TEST THE CLIENT PROGRAMS -- EXCEPT rxgopher
+
+ NOTE: Build and install identd on your client hosts first. This is
+ required if you run sockd with -I option. It is a good idea anyway.
+
+ On a client host (for testing purpose, this can be the same
+ as the proxy server), the clients rfinger, rwhois, rftp, rtelnet,
+ and rxmosaic can be tried out without any special setup on the
+ client host once the server is running. They shoudl behave like
+ finger, whois, ftp, telnet, and xmosaic, respectively. rftp DOES
+ echo your password IF you are using 'anonymous' as the log-in name.
+
+-------------------------------------------------------------
+
+HOW TO TEST rxgopher
+[Lifted from README file of xgopher package.]
+
+1. cd to rxgopher directory.
+
+2. Modify the application defaults file (RXgopher.ad).
+ Little change may be necessary. However, entries in this
+ file for host name, port number, help file name, etc.,
+ override those defaults compiled into rxgopher through
+ the configuration file.
+
+3. Make the application defaults file (RXgopher.ad) known to X.
+ There are several ways to do this for testing without installing
+ the file in a system directory. Choose one of the following -
+ whichever is most comfortable for you.
+
+
+ IMPORTANT! Remove all of the application defaults from previous
+ versions of rxgopher before you attempt to run rxgopher 1.2.
+
+
+ a. xrdb -merge RXgopher.ad
+
+ b. setenv XENVIRONMENT `pwd`/RXgopher.ad
+ (`pwd` will return the current directory, which should be the
+ rxgopher source directory.)
+
+ c. if you have your own app-defaults directory, say ~/app-defaults:
+ setenv XAPPLRESDIR ~/app-defaults/
+ cp RXgopher.ad ~/app-defaults/RXgopher
+ Note the name change.
+
+ COLOR OPTION: If you are using a color display, it is strongly
+ recommended that you also include the rxgopher
+ color resources. if you used method (a) above, then
+ also use:
+ xrdb -merge RXgopher-color.ad -nocpp
+
+ Otherwise, consider using the file RXgopher-complete.ad
+ instead of RXgopher.ad. The former file has all of the
+ color resources included in it.
+
+ This is sufficient for now, and to let you test. For
+ permanent installation, see the later section of this
+ document which discusses color resources.
+
+4. To test, issue the command 'rxgopher' (without the quotes).
+
+
+-------------------------------------------------------------
+
+HOW TO INSTALL CLIENT PROGRAMS
+
+1. Become superuser on the client host.
+
+2. cd to the top directory, then issue the command 'make install.clients'.
+ This installs rfinger, rwhois, rftp, rtelnet, rxgopher, rxmosaic, and
+ their man pages. It also installs the help file and the application
+ defaults file for rxgopher.
+
+3. For color setting and other details regarding rxgopher, please read
+ the README file in rxgopher directory.
+
+
+-------------------------------------------------------------
+
+Good luck and enjoy it.
+
+ Ying-Da Lee (214)518-3490 (214)518-3552 (FAX)
+ Principal Member Technical Staff
+ NEC Systems Laboratory, C&C Software Technology Center /
+ NEC USA, Corporate Network Administration Division
+ ylee@syl.dl.nec.com
+
diff --git a/network/socks/socks.cstc.4.2/README.4.1 b/network/socks/socks.cstc.4.2/README.4.1
new file mode 100644
index 00000000..a7d3674f
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/README.4.1
@@ -0,0 +1,332 @@
+This is CSTC 4.1 release of SOCKS, a package that allows Unix hosts
+behind a firewall to gain full access to the internet without requiring
+direct IP reachability. It does require a SOCKS server program being
+run on a hosts that can communicate directly to hosts behind the firewall
+as well as hosts on the Internet at large. It is based on the original
+SOCKS written by David Koblas <koblas@netcom.com>.
+
+The package includes full source for the SOCKS server and SOCKSified
+client programs of finger, ftp, telnet, and whois. Other SOCKSified
+clients such as xgopher (ver. 1.3.1) and Mosaic (ver. 2.0) can be
+found on ftp.nec.com, in directory /pub/security/socks.cstc. (On
+WWW, the URL is file://ftp.nec.com/pub/security/socks.cstc ) Mosaic 2.1
+as distributed by NCSA already contains the SOCKSification patch in its
+source, which is available from ftp.ncsa.uiuc.edu, in /Mosaic/Mosaic-source.
+
+This release is known to run on the following Unix platforms:
+
+SunOS 4.1.x (ylee@syl.dl.nec.com)
+Irix 4.0.x (imd1707@ggr.co.uk)
+Ultrix 4.3 (als@cpsg.com.au, imd1707@ggr.co.uk)
+HP-UX 9.0x (als@cpsg.com.au, ken.shackelford@sdrc.com, bryan@Stoner.COM)
+AIX 3.2.x (ken.shackelford@sdrc.com, bryan@Stoner.COM)
+Interactive Systems Unix (ken.shackelford@sdrc.com)
+Alpha OSF 1.3 (ken.shackelford@sdrc.com, amellan@acri.fr, treese@crl.dec.com)
+Solaris 2.2 (ylee@syl.dl.nec.com)
+NetBSD 0.9 (bryan@Stoner.COM)
+UnixWare (pax@ankh.metrolink.com)
+Linux 0.99pl13 (cornell@syl.dl.nec.com, cmetz@thor.tjhsst.edu)
+
+-------------------- MAJOR CHANGES SINCE 4.0
+
+1)You now have the option to build 'sockd' to run on a multi-homed
+ host by defining the symbol 'MULTIHOMED_SERVER' in include/socks.h.
+ A multi-homed server requires another control file /etc/sockd.route
+ to tell it which of its network interfaces it should use for communicating
+ with which networks or hosts. For example:
+
+# Use interface 120.10.1.5 for host 100.1.2.3
+120.10.1.5 100.1.2.3 255.255.255.255
+# Use interface 120.10.2.10 for hosts in network 193.10.2
+120.10.2.10 193.10.2.0 255.255.255.0
+# Use interface 198.1.1.1 for all other connections
+198.1.1.1 0.0.0.0 0.0.0.0
+
+ For a typical dual-homed server, all you need is a single line:
+
+outside_interface 0.0.0.0 0.0.0.0
+
+ where 'outside_interface' should be the IP address of the network
+ interface going outside of your firewall.
+
+ test_sockd_conf has been updated so that it also checks the new control
+ file and tells you which interface will be used.
+
+2)You can now build 'versatile' clients, which uses SOCKS server(s)
+ to reach outside of your firewall but connects directly to hosts
+ within the firewall. So, for example, you can save away your regular
+ ftp program and replace it with the versatile SOCKS ftp client (rftp).
+ You have to be careful with 'finger' though and make sure that the
+ macro 'ORIG_FINGER' is properly defined in include/socks.h.
+
+ All versatile clients use the file /etc/socks.conf to decide whether
+ a connection should be denied, done directly, or done indirectly through
+ SOCKS server at one or more hosts. For example:
+
+# Deny ftp and telnet access by baduser
+deny *=baduser 0.0.0.0 0.0.0.0 eq ftp: mail -s 'ftp by baduser' root
+deny *=baduser 0.0.0.0 0.0.0.0 eq telnet: mail -s 'telnet by baduser' root
+# Be sure to include the next line for localhost!
+direct 127.0.0.1 255.255.255.255
+# Use direct connection to all hosts in network 120.10
+direct 120.10.0.0 255.255.0.0
+# Use the defaiult SOCKS server to connect to host 13.13.13.13
+sockd 13.13.13.13 255.255.255.255
+# For other connections, try SOCKS servers at 120.10.2.3, 120.10.50.1,
+# in that order
+sockd @=120.10.2.3,120.10.50.1 0.0.0.0 0.0.0.0
+
+3)As you may have already noticed, the interpretation of address masks
+ are changed. 1's in a mask now denote the bit positions that matter
+ while 0's denote the don't-care bit positions. In other words, they
+ are now interpreted the same way as IP netmasks. This holds true not
+ only for the two new control files mentioned above, but also for
+ /etc/sockd.conf. A new program 'flip_cfmasks' is provided in the sockd
+ subdirectory to convert the old format to the new one. Just do
+
+flip_cfmasks /etc/sockd.conf sockd.conf.flip
+
+ check the output file sockd.conf.flip to see if all is well (with any
+ luck it should be) and then use that with the new server.
+
+4)An optional getpass() is provided to communicate with systems that
+ may require longer password (> 8 characters). This is for regular
+ passwords. As in 4.0, "passwords" for anonymous ftp can be longer than
+ 8 characters even without using the optional getpass().
+
+5)Termination of a TCP session is now also logged on the SOCKS server,
+ including the number of bytes transported in either direction.
+
+6)An compile time option is provided to make ftp (rftp) log the name
+ of every file transferred.
+
+7)The man pages are substantially revamped.
+
+All 4.1 clients work with all 4.0 and 4.1 servers. 4.0 clients work
+with single-homed 4.1 servers but NOT with 4.1 multi-homed servers.
+'sockd -ver' tells you not only the version number but also whether
+it is single- or multi-homed.
+
+Please see below for the procedure for building and testing.
+Remember that the names of the control files are all configurable
+in include/socks.h. It will probably greatly reduce your frustration
+while you are flipping between the old and the new versions if you
+uses different file names for the new version.
+
+
+There is now a mailing list devoted to issues related
+to SOCKS. To join the list, please send an email subscription request
+with your email address to socks-request@inoc.dl.nec.com.
+
+Finally, I want to thanks all the people who have helped in making
+and shaping this release. I certainly remember discussions and
+contributions from the following, please forgive me (and remind me)
+if I inadvertently leave your name off the list.
+
+ brandon@dd.eng.bbc.co.uk (Brandon.Butterworth), bryan@Stoner.COM
+ (A. Bryan Curnutt), Ian Dunkin <imd1707@ggr.co.uk>,
+ Ingo_Dean@Warren.MentorG.com, Cornell Kinderknecht
+ <cornell@syl.dl.nec.com>, kupec@agouron.com (John W. Kupec),
+ jonl@hal.com (jon r. luini), amellan@acri.fr (Alain Mellan),
+ Craig Metz <cmetz@thor.tjhsst.edu>, montnaro@ausable.crd.ge.com
+ (Skip Montanaro), whna@nexos.com (Heinz Naef), nagler@olsen.ch
+ (Rob Nagler), "Jason Ornstein" <ornstein@xor.com>, pax@ankh.metrolink.com
+ (Garry M. Paxinos), mikey@netcom.com (Michael Pechner), royle@knmi.nl
+ (Keenan Royle), ken.shackelford@sdrc.com (Ken Shackelford), Anthony
+ Shipman <als@cpsg.com.au>, Rich Schultz <rich@ccrwest.org>,
+ treese@crl.dec.com (Win Treese), Paul.Vickers@barclays.co.uk (Paul Vickers),
+ vince@dsi.unimi.it (David Vincenzetti), posc!waddell@uunet.uu.net
+ (David Waddell)
+
+ Ying-Da Lee (214)518-3490 (214)518-3552 (FAX)
+ Principal Member, Technical Staff
+ NEC Systems Laboratory, C&C Software Technology Center /
+ NEC USA, Corporate Network Administration Division
+ ylee@syl.dl.nec.com
+====================================================================
+
+Please read the file 'COPYRIGHTS' before you proceed further.
+
+In the following section, by 'top directory' we mean the top
+directory of the SOCKS package, i.e., the directory you are
+in right now. Ignore statements about rtelnet, rxgopher, and
+rxmosaic if you are not building them.
+
+-------------------------------------------------------------
+
+HOW TO BUILD THE PROGRAMS
+
+1. Check and modify the following files to suit your systems:
+
+ Makefile
+ include/socks.h
+
+ Be sure that the macro 'SOCKS_DEFAULT_SERVER' in include/sosks.h
+ is set correctly to the host that will be running the proxy server
+ for your site. Although this can be overridden at run time with
+ environment variable SOCKS_SERVER, it is a lot simpler if you put
+ in the right name at compile time. Also be sure to uncomment and set
+ the macro 'SOCKS_DEFAULT_NS' in the same file if yor client machines
+ normally cann't do DNS resolution for outside hosts.
+
+ Be sure that the macros 'ORIG_FINGER' and 'MULTIHOMED_SERVER' in
+ include/socks.h are set correctly.
+
+ In most cases, you should have no needs to modify the Makefiles
+ in the subdirectories. But if you run into problems, you may
+ have to look into modifying
+
+ sockd/Makefile
+ libident/Makefile
+ lib/Makefile
+ rfinger/Makefile
+ rftp/Makefile
+ rtelnet/Makefile
+
+ If your system is not among those included in the top Makefile,
+ then you may also have to construct an entry for your system
+ in the file rtelnet/Config.local.
+
+2. cd to the top directory and issue 'make' command. It's a good
+ idea to direct stdout and stderr to a file so that you can
+ see what's being done afterwards. There will be a few warning
+ messages which you can ignore. This builds the server as well
+ as all the clients.
+
+ If you only want to build the server (and the program for testing
+ your sever configuration file, AND THE PROGRAM FOR CONVERTING THE
+ FILE TO THE NEW FORMAT), use comannd 'make server' instead.
+ Use command 'make clients' to build only the client programs. You
+ can also build the individual clients using 'make RFINGER',
+ 'make RFTP', and 'make RTELNET', all from the top directory.
+
+3. All the man pages (except for libident) are in directory doc.
+ You are encouraged to print them out and read them before proceeding
+ to the next part.
+
+-------------------------------------------------------------
+
+HOW TO INSTALL THE SERVER
+
+1. Become superuser on the proxy server host for your site.
+
+2. cd to the top directory and issue 'make install.server'.
+ This installs programs sockd and test_sockd_conf as well
+ as the man pages for them.
+
+3. Add the line
+socks 1080/tcp
+ to file /etc/services. It would be nice also to include
+gopher 70/tcp
+WWW 80/tcp
+ in the file if you don't already have them.
+
+4. Add the line
+socks stream tcp nowait nobody /usr/etc/sockd sockd
+ to file /etc/inetd.conf. Use the actual path where sockd
+ is installed if not in /usr/etc. If you want to make use of
+ identd on your client machines when it is available, use
+socks stream tcp nowait nobody /usr/etc/sockd sockd -i
+ If you want to REQUIRE identd be run on your client machines,
+ use
+socks stream tcp nowait nobody /usr/etc/sockd sockd -I
+ Running sockd with -I will reject all requests from hosts that
+ do not run identd.
+
+5. Set up access control with file /etc/sockd.conf. You have to
+ read the man pages for sockd, sockd.conf, and test_sockd_conf
+ for the details.
+ For a quick test, you can use these four lines in the file: (Replace
+ 'client_IP' with the IP address of the host on which you will be
+ testing the client programs.)
+permit client_IP 255.255.255.255
+# One LONG line follows:
+deny 0.0.0.0 0.0.0.0 : /usr/ucb/finger @%A | /usr/ucb/mail -s 'SOCKD: rejected -- from %u@%A to host %Z (service %S)' root
+# Another LONG line:
+#BAD_ID: /usr/ucb/finger @%A | /usr/ucb/mail -s '%U pretends to be %u on host %A' root@%A root
+# Last line:
+#NO_IDENTD: /usr/ucb/mail -s 'Please run identd on %A' %u@%A root@%A
+ This is essentially the contents of file sockd/sockd.conf.sample.
+ *** NOTE *** The meanings of 1's and 0's in address masks are
+ reversed from previous versions. If you already have a working
+ /etc/sockd.conf with an earlier version, use the program
+ sockd/flip_cfmasks to produce one for the new version.
+
+6. If the server host is multi-homed and you built sockd with the
+ macro MULTIHOMED_SERVER in include/socks.h defined, you must
+ also supply the file /etc/sockd.route. For a typical dual-homed
+ server, this can simply be a one-liner:
+out_interface 0.0.0.0 0.0.0.0
+ where out_interface is the IP address of the server's network
+ interface leading to the outside world. The format for lines
+ in this file should be
+# comments
+Interface_addr dst_addr dst_mask
+
+ Read the man page on sockd.route !!!
+
+7. Run a few tests using program test_sockd_conf to make sure you
+ have the configuration file set up correctly. On a multi-homed
+ server, the program also tests /etc/sockd.route and shows which
+ interface is to be used.
+
+8. Send a SIGHUP signal to the running inetd process so that it will
+ use the new configuration. You may also have to do other things to
+ accommodate syslog facility. Read the man pages.
+
+-------------------------------------------------------------
+
+HOW TO TEST THE CLIENT PROGRAMS
+
+ NOTE: Build and install identd on your client hosts first. This is
+ required if you run sockd with -I option. It is a good idea anyway.
+
+ Set up the file /etc/socks.conf on the client host. Lines in this
+ file should be of the form
+# comments
+deny [*=userlist] dst_addr dst_mask [op port]
+direct [*=userlist] dst_addr dst_mask [op port]
+sockd [@=serverlist] [*=userlist] dst_addr dst_mask [op port]
+ Fields in square brackets are optional. The optional @=serverlist
+ field with a 'sockd' line specifies the list of SOCKS servers
+ the client should try (in the given order) instead of the default
+ SOCKS server. If the @=serverlist part is omitted, then the default
+ SOCKS server is used. Commas are used in the userlist and serverlist
+ as separators, no white spaces are allowed.
+
+ Read the man page on socks.conf !!!
+
+ On a client host (for testing purpose, this can be the same as
+ the proxy server), the clients rfinger, rwhois, rftp, and rtelnet,
+ can be tried out without any additional setup on the
+ client host once the server is running. They should behave like
+ finger, whois, ftp, and telnet, respectively. rftp DOES
+ echo your password IF you are using 'anonymous' as the log-in name.
+
+ Quite a lot of details of operations of both the clients and the
+ server are logged. Checking the contents of the log files may be
+ helpful when you run into problems. You should try using these
+ clients to connect to both inside and outside hosts and check the
+ log messages to see whether the correct ways are used.
+
+-------------------------------------------------------------
+
+HOW TO INSTALL CLIENT PROGRAMS
+
+1. Become superuser on the client host.
+
+2. cd to the top directory, then issue the command 'make install.clients'.
+ This installs rfinger, rwhois, rftp, rtelnet, and
+ their man pages.
+
+3. Rename your regular 'finger', 'whois', 'ftp', and 'telnet'
+ to something else. The new name for the 'finger' program
+ must be EXACTLY what you used for defining the macro ORIG_FINGER in
+ include/socks.h. Then either rename the SOCKS clients or use symbolic
+ links for them. For example, if you have installed the clients in
+ directory /usr/local/bin and your regular 'finger', 'whois', 'ftp',
+ and 'telnet' were in /usr/ucb, then you should do
+ln -s /usr/local/bin/rfinger /usr/ucb/finger
+ln -s /usr/local/bin/rftp /usr/ucb/ftp
+ln -s /usr/local/bin/rhwois /usr/ucb/whois
+ln -s /usr/local/bin/rtelnet /usr/ucb/telnet
diff --git a/network/socks/socks.cstc.4.2/README.4.2 b/network/socks/socks.cstc.4.2/README.4.2
new file mode 100644
index 00000000..a03de48c
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/README.4.2
@@ -0,0 +1,249 @@
+This is CSTC 4.2 release of SOCKS, a package that allows Unix hosts
+behind a firewall to gain full access to the internet without requiring
+direct IP reachability. It does require a SOCKS server program being
+run on a hosts that can communicate directly to hosts behind the firewall
+as well as hosts on the Internet at large. It is based on the original
+SOCKS written by David Koblas <koblas@netcom.com>.
+
+The package includes full source for the SOCKS server and SOCKSified
+client programs of finger, ftp, telnet, and whois. A few other SOCKSified
+clients may be found on ftp.nec.com, in directory /pub/security/socks.cstc.
+Increasingly, software developers are beginning to include SOCKS support
+directly into their products, for example, Mosaic, Lynx, and a version
+of Trumpet Winsock.
+
+This release is known to run on the following Unix platforms:
+
+SunOS 4.1.x (ylee@syl.dl.nec.com)
+Irix 4.0.x (imd1707@ggr.co.uk)
+Ultrix 4.3 (als@cpsg.com.au, imd1707@ggr.co.uk)
+HP-UX 9.0x (als@cpsg.com.au, ken.shackelford@sdrc.com, bryan@Stoner.COM)
+AIX 3.2.x (ken.shackelford@sdrc.com, bryan@Stoner.COM)
+Interactive Systems Unix (ken.shackelford@sdrc.com)
+Alpha OSF 1.3 (ken.shackelford@sdrc.com, amellan@acri.fr, treese@crl.dec.com)
+Solaris 2.2 (ylee@syl.dl.nec.com)
+NetBSD 0.9 (bryan@Stoner.COM)
+UnixWare (pax@ankh.metrolink.com)
+Linux 0.99pl13 (cornell@syl.dl.nec.com, cmetz@thor.tjhsst.edu)
+SCO/ODT 2.x (Chris Riney)
+BSDi 1.0 (Chris Riney)
+PS/2 AIX 1.2.1 (cmetz@thor.tjhsst.edu)
+NextStep 3.2 (server and library only, William Lewis)
+
+-------------------
+All 4.2 clients work with all 4.x servers. 4.0 clients work
+with single-homed 4.2 servers but NOT with 4.2 multi-homed servers.
+4.1 clients work with 4.2 servers, both single- and multi-homed.
+'sockd -ver' tells you not only the version number but also whether
+it is single- or multi-homed.
+
+Please see below for the procedure for building and testing.
+Remember that the names of the control files are all configurable
+in include/socks.h. It will probably greatly reduce your frustration
+while you are flipping between the old and the new versions if you
+uses different file names for the new version.
+
+There is now a mailing list devoted to issues related
+to SOCKS. To join the list, please send an email subscription request
+to majordomo-request@syl.dl.nec.com with
+
+ subscribe socks your@email.address
+
+in the body of the message.
+
+Finally, I want to thanks all the people who have helped in making
+and shaping this release. Many of them are listed in the CHANGES
+file, but undoubted many more are left out due to my poor memory --
+to those, my apologies.
+
+ Ying-Da Lee (214)518-3490 (214)518-3552 (FAX)
+ Principal Member, Technical Staff
+ NEC Systems Laboratory, C&C Software Technology Center /
+ NEC USA, Corporate Network Administration Division
+ ylee@syl.dl.nec.com
+====================================================================
+
+Please read the file 'COPYRIGHTS' before you proceed further.
+
+In the following section, by 'top directory' we mean the top
+directory of the SOCKS package, i.e., the directory you are
+in right now.
+
+-------------------------------------------------------------
+
+HOW TO BUILD THE PROGRAMS
+
+1. Check and modify the following files to suit your systems:
+
+ Makefile
+ include/socks.h
+
+ Be sure that the macro 'SOCKS_DEFAULT_SERVER' in include/sosks.h
+ is set correctly to the host that will be running the proxy server
+ for your site. Although this can be overridden at run time with
+ environment variable SOCKS_SERVER, it is a lot simpler if you put
+ in the right name at compile time. Also be sure to uncomment and set
+ the macro 'SOCKS_DEFAULT_NS' in the same file if yor client machines
+ normally cann't do DNS resolution for outside hosts.
+
+ Be sure that the macros 'ORIG_FINGER' and 'MULTIHOMED_SERVER' in
+ include/socks.h are set correctly.
+
+ In most cases, you should have no needs to modify the Makefiles
+ in the subdirectories. But if you run into problems, you may
+ have to look into modifying
+
+ sockd/Makefile
+ libident/Makefile
+ lib/Makefile
+ rfinger/Makefile
+ rftp/Makefile
+ rtelnet/Makefile
+
+ If your system is not among those included in the top Makefile,
+ then you may also have to construct an entry for your system
+ in the file rtelnet/Config.local.
+
+2. cd to the top directory and issue 'make' command. It's a good
+ idea to direct stdout and stderr to a file so that you can
+ see what's being done afterwards. There will be a few warning
+ messages which you can ignore. This builds the server as well
+ as all the clients.
+
+ If you only want to build the server (and the program for testing
+ your sever configuration file, and the program for converting the
+ file from the old format), use comannd 'make server' instead.
+ Use command 'make clients' to build only the client programs. You
+ can also build the individual clients using 'make RFINGER',
+ 'make RFTP', and 'make RTELNET', all from the top directory.
+
+3. All the man pages (except for libident) are in directory doc.
+ You are encouraged to print them out and read them before proceeding
+ to the next part.
+
+-------------------------------------------------------------
+
+HOW TO INSTALL THE SERVER
+
+1. Become superuser on the proxy server host for your site.
+
+2. cd to the top directory and issue 'make install.server'.
+ This installs programs sockd and test_sockd_conf as well
+ as the man pages for them.
+
+3. Add the line
+socks 1080/tcp
+ to file /etc/services. It would be nice also to include
+gopher 70/tcp
+WWW 80/tcp
+ in the file if you don't already have them.
+
+4. Add the line
+socks stream tcp nowait nobody /usr/etc/sockd sockd
+ to file /etc/inetd.conf. Use the actual path where sockd
+ is installed if not in /usr/etc. If you want to make use of
+ identd on your client machines when it is available, use
+socks stream tcp nowait nobody /usr/etc/sockd sockd -i
+ If you want to REQUIRE identd be run on your client machines,
+ use
+socks stream tcp nowait nobody /usr/etc/sockd sockd -I
+ Running sockd with -I will reject all requests from hosts that
+ do not run identd.
+
+5. Set up access control with file /etc/sockd.conf. You have to
+ read the man pages for sockd, sockd.conf, and test_sockd_conf
+ for the details.
+ For a quick test, you can use these four lines in the file: (Replace
+ 'client_IP' with the IP address of the host on which you will be
+ testing the client programs.)
+permit client_IP 255.255.255.255
+# One LONG line follows:
+deny 0.0.0.0 0.0.0.0 : /usr/ucb/finger @%A | /usr/ucb/mail -s 'SOCKD: rejected -- from %u@%A to host %Z (service %S)' root
+# Another LONG line:
+#BAD_ID: /usr/ucb/finger @%A | /usr/ucb/mail -s '%U pretends to be %u on host %A' root@%A root
+# Last line:
+#NO_IDENTD: /usr/ucb/mail -s 'Please run identd on %A' %u@%A root@%A
+ This is essentially the contents of file sockd/sockd.conf.sample.
+ *** NOTE *** The meanings of 1's and 0's in address masks are
+ reversed from 4.0 and earlier versions. If you already have a working
+ /etc/sockd.conf with an earlier version, use the program
+ sockd/flip_cfmasks to produce one for the new version.
+
+6. If the server host is multi-homed and you built sockd with the
+ macro MULTIHOMED_SERVER in include/socks.h defined, you must
+ also supply the file /etc/sockd.route. For a typical dual-homed
+ server, this can simply be a one-liner:
+out_interface 0.0.0.0 0.0.0.0
+ where out_interface is the IP address of the server's network
+ interface leading to the outside world. The format for lines
+ in this file should be
+# comments
+Interface_addr dst_addr dst_mask
+
+ Read the man page on sockd.route !!!
+
+7. Run a few tests using program test_sockd_conf to make sure you
+ have the configuration file set up correctly. On a multi-homed
+ server, the program also tests /etc/sockd.route and shows which
+ interface is to be used.
+
+8. Send a SIGHUP signal to the running inetd process so that it will
+ use the new configuration. You may also have to do other things to
+ accommodate syslog facility. Read the man pages.
+
+-------------------------------------------------------------
+
+HOW TO TEST THE CLIENT PROGRAMS
+
+ NOTE: Build and install identd on your client hosts first. This is
+ required if you run sockd with -I option. It is a good idea anyway.
+
+ Set up the file /etc/socks.conf on the client host. Lines in this
+ file should be of the form
+# comments
+deny [*=userlist] dst_addr dst_mask [op port]
+direct [*=userlist] dst_addr dst_mask [op port]
+sockd [@=serverlist] [*=userlist] dst_addr dst_mask [op port]
+ Fields in square brackets are optional. The optional @=serverlist
+ field with a 'sockd' line specifies the list of SOCKS servers
+ the client should try (in the given order) instead of the default
+ SOCKS server. If the @=serverlist part is omitted, then the default
+ SOCKS server is used. Commas are used in the userlist and serverlist
+ as separators, no white spaces are allowed.
+
+ Read the man page on socks.conf !!!
+
+ On a client host (for testing purpose, this can be the same as
+ the proxy server), the clients rfinger, rwhois, rftp, and rtelnet,
+ can be tried out without any additional setup on the
+ client host once the server is running. They should behave like
+ finger, whois, ftp, and telnet, respectively. rftp DOES
+ echo your password IF you are using 'anonymous' as the log-in name.
+
+ Quite a lot of details of operations of both the clients and the
+ server are logged. Checking the contents of the log files may be
+ helpful when you run into problems. You should try using these
+ clients to connect to both inside and outside hosts and check the
+ log messages to see whether the correct ways are used.
+
+-------------------------------------------------------------
+
+HOW TO INSTALL CLIENT PROGRAMS
+
+1. Become superuser on the client host.
+
+2. cd to the top directory, then issue the command 'make install.clients'.
+ This installs rfinger, rwhois, rftp, rtelnet, and
+ their man pages.
+
+3. Rename your regular 'finger', 'whois', 'ftp', and 'telnet'
+ to something else. The new name for the 'finger' program
+ must be EXACTLY what you used for defining the macro ORIG_FINGER in
+ include/socks.h. Then either rename the SOCKS clients or use symbolic
+ links for them. For example, if you have installed the clients in
+ directory /usr/local/bin and your regular 'finger', 'whois', 'ftp',
+ and 'telnet' were in /usr/ucb, then you should do
+ln -s /usr/local/bin/rfinger /usr/ucb/finger
+ln -s /usr/local/bin/rftp /usr/ucb/ftp
+ln -s /usr/local/bin/rhwois /usr/ucb/whois
+ln -s /usr/local/bin/rtelnet /usr/ucb/telnet
diff --git a/network/socks/socks.cstc.4.2/README.DK b/network/socks/socks.cstc.4.2/README.DK
new file mode 100644
index 00000000..e09e62f2
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/README.DK
@@ -0,0 +1,49 @@
+
+ #####
+ # # #### #### # # ####
+ # # # # # # # #
+ ##### # # # #### ####
+ # # # # # # #
+ # # # # # # # # # #
+ ##### #### #### # # ####
+
+
+This system was described in a paper appearing the the 1992 USENIX
+Security Simposium. This code has been in use at a variety of sites
+for many years, and is now available for general consumption.
+
+One quick disclaimer, which is that documentation isn't up to snuff,
+the best best thing available is the USENIX procedings. If you
+notice something in particular lacking please let me know.
+
+I can reached at, for any questions comments or other sudgestions:
+ koblas@netcom.com
+
+What the directories contain:
+
+ include -- Common include file for both the daemon and library
+ lib -- Standard library containting replacement calls
+ rfinger -- Example Rconnect() program, contains both finger & whois
+ rftp -- The standard BSD Networking release finger, copied
+ from ftp.uu.net, and modified to work with Socks
+ sockd -- The daemon that runs on the gateway host.
+ doc -- Some unfinished documentation
+
+*** The short and simple installation instructions:
+
+1) Look at the socks.h in the include directory, cusomize it for your site.
+
+2) Put the following line in your /etc/services file
+ socks 1080/tcp # Socks gateway service
+
+3) Cusomize sockd/sockd.conf to your sites needs
+
+4) Copy sockd/sockd and sockd/sockd.conf to your gateway host
+
+5) Add the following line to your /etc/inetd.conf file on the gateway
+ socks stream tcp nowait nobody /etc/sockd sockd
+
+6) Reload your inetd on the gateway host (kill -HUP <pid of inetd>)
+
+7) Test out rwhois or rfinger in the rfinger directory to see if
+ things are working.
diff --git a/network/socks/socks.cstc.4.2/What_SOCKS_expects b/network/socks/socks.cstc.4.2/What_SOCKS_expects
new file mode 100644
index 00000000..daf974d0
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/What_SOCKS_expects
@@ -0,0 +1,48 @@
+ What SOCKS Expects In the Client Programs
+
+ Ying-Da Lee
+ <ylee@syl.dl.nec.com>
+
+SOCKS is intended for easy conversion of existing network TCP client
+programs. Towards that end, it expects that the programs are written
+in a certain way.
+
+SOCKS only pays attention to six socket functions: connect(), bind(),
+getsockname(), listen(), accept(), select(), and rcmd(). (select and
+rcmd() do not apply to versions prior to version 4.2 of SOCKS.CSTC.)
+SOCKS makes the following assumptions.
+
+1) Everything is done in TCP.
+
+2) The very first function invoked must be connect(), or rcmd().
+
+3) If connect() is used on a non-blocking socket, no I/O should occur
+ on that socket until after another connect() with the same arguments
+ returns with -1 and errno indicating EISCONN. This is required even
+ if select() on write is used to check the readiness of that socket.
+ Also, while a connection is still pending, no attempts may
+ be made to start another connection via connect() or the bind()--
+ getsockname()--listen()--accept() sequence.
+
+4) bind() is used after a successful connect() call to a host for a
+ specific service. It is used to establish an auxiliary TCP
+ session with the same host in the previous connect() call and for
+ the same service.
+
+5) bind() is followed by
+
+ getsockname()
+ listen()
+ accept()
+
+ in the order given above.
+
+Most client programs fit these assumptions very well; such programs
+can be SOCKSified without changing the code at all using the steps
+described in the file How_to_SOCKSified.
+
+Some client programs use a bind() before each connect(). If the bind()
+is used to claim a specific port or a specific network interface, the
+current SOCKS is not able to accommodate such use. Very often though,
+such a bind() call is there for no reason at all, and should simply
+be deleted.
diff --git a/network/socks/socks.cstc.4.2/What_are_the_risks b/network/socks/socks.cstc.4.2/What_are_the_risks
new file mode 100644
index 00000000..e8bd387d
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/What_are_the_risks
@@ -0,0 +1,70 @@
+>From daemon@inoc.dl.nec.com Wed Dec 1 17:44:07 1993
+Date: Wed, 1 Dec 93 17:42:55 CST
+From: ylee@syl.dl.nec.com (Ying-Da Lee)
+Message-Id: <9312012342.AA26065@florida.syl.dl.nec.com>
+To: socks@inoc.dl.nec.com, zz5@dswpa.dsdoe.ornl.gov
+Subject: Re: Comparing firewall packages...
+Cc: ylee@syl.dl.nec.com
+X-Mailing-List: socks@syl.dl.nec.com (SOCKS discussion list)
+Status: RO
+
+>I will be working with SOCKS now. Any information would be
+>appreciated. I just want to know how secure SOCKS is, and what
+>guarantees can be made about it... Thanks.
+
+I don't know about guarantees. Should we start with 'as far as I
+know, there is no way...' and see where it ends?
+
+As far as I know, there is no way to initiate an attack into your
+firewalled internal network through SOCKS if your SOCKS server is
+properly configured. For example, if your internal network is
+200.100.50 and you put the line
+
+deny 0.0.0.0 0.0.0.0 200.100.50.0 255.255.255.0
+
+at the top of your sockd.conf, the SOCKS server will fend off
+all attempts to go through it to reach your inside hosts. No
+routing tricks or IP address spoofing will make any difference.
+
+This is not to say that you are not incurring some risks by
+running SOCKS. You are, but these are the risks/vulnerabilities
+accompanying the applications you allow to run on top of SOCKS,
+not with SOCKS itself. For example, doing any network communication
+without encryption runs the risk of having your password or other
+confidential information stolen, whether you use SOCKS or not.
+Blindly "displaying" a postscript file can end in a disaster
+regardless of whether you retrieved the file through SOCKS or
+not. SOCKS doesn't add more on top of these risks, but it doesn't
+help you deal with them either.
+
+Should it?
+
+It really can't if SOCKS is to remain a general purpose TCP relayer
+without delving into the specific application protocols. This accounts
+for the server's high effficiency. This independence of the application
+protocol also makes it easy to convert an application program into a
+SOCKS client. In addition, SOCKS probably will have a fairly easy time
+accommodating security devices in the application protocols if and when
+they are used.
+
+So, if on balance you find the security risks of existing telnet, ftp,
+Mosaic, etc. outweigh their usefulness to you and you are unable or
+unwilling to develop a more secure version, then SOCKS is not for you.
+If the balance tilts the other way, welcome to SOCKS.
+
+I hope that's enough for a start.
+
+ Ying-Da Lee (214)518-3490 (214)518-3552 (FAX)
+ Principal Member, Technical Staff
+ NEC Systems Laboratory, C&C Software Technology Center /
+ NEC USA, Corporate Network Administration Division
+ ylee@syl.dl.nec.com
+
+**************
+The rest of this message was automatically appended by the socks list
+mail munger. To send a message to the entire list, address it to:
+socks@inoc.dl.nec.com. However, if you want to get off the list or
+change your address, please send a message to socks-request@inoc.dl.nec.com,
+and NOT the entire list. Thank you.
+**************
+
diff --git a/network/socks/socks.cstc.4.2/bsdinstall b/network/socks/socks.cstc.4.2/bsdinstall
new file mode 100644
index 00000000..a24c87ad
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/bsdinstall
@@ -0,0 +1,27 @@
+#!/bin/sh
+# A BSD-like install script for SYSV systems.
+# Written by Phil Hochstetler, phil@sequent.com
+if [ $# -lt 2 ]; then
+ echo "Usage: install [-m ddd] srcfile dstdir" 1>&2
+ exit 1
+fi
+if [ X"$1" = X"-m" ]; then
+ CMD="chmod $2 $3"
+ shift
+ shift
+else
+ CMD=
+fi
+
+if [ X"$1" = X -o X"$2" = X -o X"$3" != X ]; then
+ echo "Usage: install [-m XXX] srcfile dstdir" 1>&2
+ exit 1
+fi
+
+FILE="$1"
+DIR="$2"
+if [ ! -d "$DIR" ]; then
+ mkdir $DIR
+fi
+
+cp $FILE $DIR && $CMD
diff --git a/network/socks/socks.cstc.4.2/doc/Makefile b/network/socks/socks.cstc.4.2/doc/Makefile
new file mode 100644
index 00000000..30135b5c
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/Makefile
@@ -0,0 +1,25 @@
+# Directory into which the man pages are to be installed.
+MAN_DEST_DIR = /usr/local/man
+
+# The 'install' command is assumed to be the BSD variety (using -m to
+# set the file mode). If the default 'install' on your system doesn't
+# do that, you have to either specify an alternative one in the line below
+# (e.g., /usr/ucb/install) or modify the other Makefile.
+INSTALL= install
+# UnixWare should use:
+#INSTALL=/usr/ucb/install
+# IRIX should use:
+#INSTALL=bsdinstall
+#========================================================
+
+install:
+ for i in *.1; do \
+ $(INSTALL) -m 444 $$i $(MAN_DEST_DIR)/man1 ;\
+ done
+ for i in *.5; do \
+ $(INSTALL) -m 444 $$i $(MAN_DEST_DIR)/man5 ;\
+ done
+ for i in *.8; do \
+ $(INSTALL) -m 444 $$i $(MAN_DEST_DIR)/man8 ;\
+ done
+
diff --git a/network/socks/socks.cstc.4.2/doc/rfinger.1 b/network/socks/socks.cstc.4.2/doc/rfinger.1
new file mode 100644
index 00000000..15f6c1ee
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/rfinger.1
@@ -0,0 +1 @@
+.so man1/socks_clients.1
diff --git a/network/socks/socks.cstc.4.2/doc/rftp.1 b/network/socks/socks.cstc.4.2/doc/rftp.1
new file mode 100644
index 00000000..15f6c1ee
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/rftp.1
@@ -0,0 +1 @@
+.so man1/socks_clients.1
diff --git a/network/socks/socks.cstc.4.2/doc/rtelnet.1 b/network/socks/socks.cstc.4.2/doc/rtelnet.1
new file mode 100644
index 00000000..15f6c1ee
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/rtelnet.1
@@ -0,0 +1 @@
+.so man1/socks_clients.1
diff --git a/network/socks/socks.cstc.4.2/doc/rwhois.1 b/network/socks/socks.cstc.4.2/doc/rwhois.1
new file mode 100644
index 00000000..15f6c1ee
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/rwhois.1
@@ -0,0 +1 @@
+.so man1/socks_clients.1
diff --git a/network/socks/socks.cstc.4.2/doc/sockd.8 b/network/socks/socks.cstc.4.2/doc/sockd.8
new file mode 100644
index 00000000..cb30c537
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/sockd.8
@@ -0,0 +1,136 @@
+.TH SOCKD 8 "February 9, 1994"
+.SH NAME
+sockd \- Internet firewall secure socket server (proxy server)
+.SH SYNOPSIS
+\fBsockd [ \-ver | \-i | \-I ]\fP
+.SH DESCRIPTION
+\fIsockd \fR is an internet secure socket server, often referred to
+as a proxy server. It was designed
+primarily to provide hosts within a firewall access to resources
+outside of the firewall.
+
+Normally, hosts inside a firewall has no IP-accessibility to the network
+outside of the firewall. This reduces the risk of being intruded
+by unauthorized people from the Internet. Unfortunately, without
+IP-accessibility users on the inside hosts can no longer use many
+of the important tools such as telnet, ftp, xgopher, Mosaic, etc. to
+access the tremendous resources available in the Internet.
+
+With \fIsockd\fR installed on a server host, users on the other
+inside hosts can gain back the lost functionalities by using
+clients programs designed to work with \fIsockd\fR proxy server,
+e.g, \fIrtelnet\fR in place of \fItelnet\fR, \fIrftp\fR in place
+of \fIftp\fR, \fIrfinger\fR in place of \fIfinger\fR,
+etc. Since these client programs work
+like their normal counterparts without requiring direct IP-accessibility
+to the Internet, convenience to the uesrs is accomplished without
+breaching the security. The server host that runs \fIsockd\fR does
+have to be open to the Internet, and it therefore requires special
+attention to make sure that it is secure.
+
+\fIsockd\fR is usually installed in directory /usr/etc and should
+be run under the control of \fIinetd\fR. To do so,
+add the line
+
+.nf
+.in +1
+socks 1080/tcp
+
+.fi
+.in -1
+to file \fB/etc/services\fP, and the line
+
+.nf
+.in +1
+socks stream tcp nowait nobody /usr/etc/sockd sockd
+
+.fi
+.in -1
+to file \fB/etc/inetd.conf\fP. Then send a SIGHUP signal to the
+running \fIinetd\fR process to make it read and use the new contents
+of the files. You may also choose to use \fIidentd\fR (RFC 1413) to verify
+the user's identity by appending option \fB\-i\fP or \fB\-I\fP to
+the line in \fB/etc/inetd.conf\fP.
+
+A configuration file \fB/etc/sockd.conf\fP is used to control access
+to \fIsockd\fR and its services. Permission and denial of a service
+request can be decided based on various combinations of the requesting
+host, the destination host, the type of service (destination port number),
+as well as the requesting user. (See \fIsockd.conf\fP(5).)
+
+If the server host is multi-homed, i.e., having more than one network
+interface and with its IP_FORWARDING turtned off, it must run a multi-homed
+version of \fIsockd\fP, which requires another control file
+\fB/etc/sockd.route\fP to decide which interface to use for connection
+to any given destination host. See \fIsockd.route\fP(5).
+
+A program called \fItest_sockd_conf\fP is provided for you to check
+your \fIsockd\fR configuration file(s). Be sure to use it everytime after
+you modify the configuration file(s).
+
+\fIsockd\fR uses \fIsyslog\fR with facility \fBdaemon\fP and level
+\fBnotice\fP to log its activities and errors. Typical lines look
+like
+
+.nf
+.in +1
+Apr 11 08:51:29 eon sockd[636]: connected -- Connect from don(don)@abc.edu to wxy.com (telnet)
+Apr 11 09:24:59 eon sockd[636]: terminated -- Connect from don(don)@abc.edu to wxy.com (telnet)
+Apr 11 09:24:59 eon sockd[636]: 1048 bytes from abc.edu, 285143 bytes from wxy.com
+Jun 22 18:24:54 eon sockd[884]: refused -- Connect from sam(unknown)@big.com to small.com (ftp)
+.in -1
+.fi
+
+In these lines, the first user-id is the one reported by the client program,
+the second one (within the parentheses) is what is reported by \fIidentd\fP
+on the client host.
+These log lines usually appear in file \fB/var/adm/messages\fP though that
+can be changed by modifying \fB/etc/syslog.conf\fP. (See \fIsyslogd\fR(8)
+and \fIsyslog.conf\fR(5).)
+
+If you allow access to infosystems such as Gopher or WWW,
+you should be aware that they by nature would tend to get connections
+to hosts all over the world and would use not only Gopher and WWW ports
+but possibly also ports for finger, telnet, ftp, nntp, etc. as well as
+non-priveleged ports ( > 1023).
+.SH OPTIONS
+The options are mutually exclusive and thus may only be used one at a time.
+.TP
+.B\-ver
+With this option, \fIsockd\fR prints its own version number,
+whether it is a single-homed or multi-homed version, and whether
+it supports clients that use Rrcmd(), and then quits.
+.TP
+.B\-I
+Use \fIidentd\fR (RFC 1413) to verify the requester's user-id. Deny access if
+connection to client's \fIidentd\fR fails or if the result does not match
+the user-id reported by the client program. Client hosts without a properly
+installed \fIidentd\fR daemon will not be served. User verification is
+done before and in addition to the normal access control.
+.TP
+.B\-i
+Similar to \fB-I\fP but more lenient. Access is denied only if client's
+\fIidentd\fR reports a user-id that's different from what the client
+program claims.
+.PP
+Log entries similar to the following are produced upon failure of
+user-id verification:
+
+.nf
+.in +1
+Apr 15 14:42:51 eon sockd[729]: cannot connect to identd on big.edu
+Apr 15 14:42:51 eon sockd[729]: refused -- Connect from bob(unknown)@big.edu to xyz.com (ftp)
+Jul 15 12:23:06 eon sockd[832]: *Alert*: real user is sam, not jim
+Jul 15 12:23:06 eon sockd[832]: refused -- Connect from jim(sam)@abc.org to bad.place.com (WWW)
+.in -1
+.fi
+.SH FILES
+\fB/etc/sockd.conf\fP, \fB/etc/inetd.conf\fP, \fB/etc/services\fP,
+\fB/var/adm/messages\fP, \fB/etc/syslog.conf\fP
+.SH SEE ALSO
+\fIsocks_clients\fP(1), \fItest_sockd_conf\fP(8), \fIsockd.conf\fp(5),
+\fIsockd.route\fP(5), \fIsocks.conf\fP(5)
+.SH AUTHOR
+.nf
+David Koblas, koblas@sgi.com
+Ying-Da Lee, ylee@syl.dl.nec.com
diff --git a/network/socks/socks.cstc.4.2/doc/sockd.conf.5 b/network/socks/socks.cstc.4.2/doc/sockd.conf.5
new file mode 100644
index 00000000..19d1c2d0
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/sockd.conf.5
@@ -0,0 +1,195 @@
+.TH SOCKD.CONF 5 "February 9, 1994"
+.SH NAME
+sockd.conf \- SOCKS server configuration file
+.SH SYNOPSIS
+\fB/etc/sockd.conf\fP
+.SH DESCRIPTION
+The file \fB/etc/sockd.conf\fP is used to control access
+to SOCKS proxy server \fIsockd\fR and its services. (See \fIsockd\fP(8).)
+Permission and denial of a service
+request can be decided based on various combinations of the requesting
+host, the destination host, the type of service (destination port number),
+as well as the requesting user. A line in \fB/etc/sockd.conf\fP can be
+up to 1023 characters long. Each line may contain the following fields
+in the indicated order:
+
+.in +1
+\fIaction [\fB?=\fIuse_idend] [\fB*=\fIuserlist] src_addr src_mask [dst_addr dst_mask] [op dst_port] [ : shell_cmd ]\fR
+
+.in -1
+Spaces and tabs separate the fields. Fields enclosed in square brackets
+are optional. Blank
+lines are allowed. Except for lines that start with \fB#NO_IDENTD:\fP or
+\fB#BAD_ID:\fP, everything from the first appearance of \fB#\fP to
+the end of the line is considered comment and thus ignored by \fIsockd\fP
+during normal validation.
+
+The \fIaction\fR field
+must be either \fBpermit\fP or \fBdeny\fP
+and indicates the action to be taken if a request matches the conditions
+specified in that line.
+
+The \fIuse_identd\fR field, when present, must be \fBI\fP, \fBi\fP, or
+\fBn\fP, and is used to specify whether \fIidentd\fR verification should be
+employed for the current line. \fB?=I\fP demands the use of
+\fIidentd\fR for verifying the user's identity, denying access if connection
+to client's \fIidentd\fR fails or if the result does not match the user-id
+reported by the client program. \fB?=i\fP also specifies the use of
+\fIidentd\fR, but denies access only if client's \fIidentd\fR reports a user-id
+different from what the client program claims. \fB?=n\fP turns off the
+use of \fIidentd\fP. For the line in which these fields are used, they
+override the global \fIidentd\fR setting, which is determined by options
+\fB-I\fP and \fB-i\fP on the \fIsockd\fR command line.
+
+The \fIuserlist\fR field, when present, consists of
+one or more user-ids or filenames, with comma as separator. No spaces
+or tabs are allowed in the list. The user-ids should be ids of users on the
+requesting host, not those on the destination host or the SOCKS server host.
+The filenames must be full pathnames with the leading \fB/\fP. Inside
+the specified files, user-ids may be listed one or several per line,
+with any combination of blanks, tabs, and commas as separators. The
+appearance of \fB#\fP marks the remainder of the line as comment. Each
+line in the files may be up to 1023 characters long.
+If the \fB*=\fIuserlist\fR field is omitted, the line applies to all user-ids.
+
+The \fIsrc_addr\fR and \fIdst_addr\fR fields specify IP addresses
+of hosts, networks, or subnets in the usual dotted form, e.g.,
+\fB129.201.4.0\fP. The \fIsrc_mask\fR and \fIdst_mask\fR fields
+are masks for the corresponding IP addresses.
+Bits in these masks that are set to 0 indicate the bit positions
+to be ignored during comparisons of IP addresses.
+So, specifying 255.255.255.255 in the mask demands an exact match with the
+specified IP address field, whereas 0.0.0.0 in the mask
+causes a match no matter what IP address is specified. (NOTE: This is the
+same way netmaks are usually interpreted, and is the opposite of the
+interpretation in previous versions of \fIsockd\fP.) If the
+\fIdst_addr dst_mask\fP pair is omitted, the line applies to all
+destination hosts.
+
+The \fIop\fR field must be
+\fBeq\fP, \fBneq\fP, \fBlt\fP, \fBgt\fP, \fBle\fP, or \fBge\fP,
+for the condition of equal, not equal, less than, greater than,
+less than or equal, and greater than or equal, respectively.
+The \fIdst_port\fR field can be either a port number, e.g., 23,
+or the equivalent service name as specified in the file /etc/services,
+e.g., \fBtelnet\fP for port number 23. If this pair is omitted, the
+line applies to all services, i.e., all destination port numbers.
+
+For example, consider the line
+
+.in +1
+permit *=root,clivep 128.103.4.10 255.255.255.255 179.200.20.0 255.255.255.0 le 1023
+
+.in -1
+To match the conditions indicated in this line, a request must come
+from a user named 'root' or 'clivep' on the host whose IP address is
+128.103.4.10 exactly, the destination host must have 179.200.20 in the
+first three bytes of its IP address (the last byte
+doesn't matter), and the service must use a port number
+less than or equal to 1023 on the destination host. Since the \fIaction\fR
+field is \fBpermit\fP, such requests will be granted.
+
+When a request is received by \fIsockd\fR, it checks against the lines
+in file \fB/etc/sockd.conf\fP, one line at a time. Once it finds a line
+with conditions that are matched by the request, the request is either
+granted or denied based on the \fIaction\fR field of that line. The
+remaining lines of file \fB/etc/sockd.conf\fP are skipped. If no matching
+line is found in the entire file, the request is denied.
+
+Be very careful how you order the lines in file \fB/etc/sockd.conf\fP.
+The following two lines in the indicated order
+
+.nf
+.in +1
+deny *=abxyz 128.140.13.24 0.0.0.0
+permit 128.140.13.24 0.0.0.0
+
+.fi
+.in -1
+disallow all requests by user 'abxyz' from host 128.140.13.24, but
+allow all requests by other users from the same host. Switch the order
+of the two lines and even requests by user 'abxyz' are granted.
+
+The \fIshell_cmd\fR field specifies a command string that is executed
+when the conditions on that line are satisfied. The following substitutions
+occur before the string is presented to the Borne shell for execution:
+.nf
+.in +1
+
+%A -- replaced by the client host's domainname if known, by its IP address otherwise
+%a -- replaced by the client host's IP address
+%c -- replaced by "connect" or "bind", the command \fIsockd\fP is asked to execute
+%p -- replaced by the process id of \fIsockd\fP
+%S -- replaced by the service name (e.g., ftp) if known, by the destination port number otherwise
+%s -- replaced by the destination port number
+%U -- replaced by the user-id reported by \fIidentd\fP
+%u -- replaced by the user-id reported by the client program
+%Z -- replaced by the destination host's domainname if known, by its IP address otherwise
+%z -- replaced by the destination host's IP address
+%% -- replaced by a single %
+
+.fi
+.in -1
+Several shell commands can be strung together in the usual way. For example,
+.nf
+
+.in +1
+/usr/ucb/finger @%A | /usr/ucb/mail -s 'SOCKS: rejected %u@%A to %Z (%S)' root root@%A
+
+.in -1
+.fi
+will \fIfinger\fP the client host and pipe the result into an email message
+for superusers at the server host and the client host with an appropriate
+Subject line. Most often this feature is used with a \fBdeny\fP line, but
+it can be used with \fBpermit\fP also.
+
+Although there is an implied 'deny all' at the end of the configuration file,
+you may supply one explicitly so as to take some specific action when requests
+are so rejected, e.g., (in one continuous line),
+.nf
+.in +1
+
+deny 0.0.0.0 0.0.0.0 : /usr/ucb/finger @%A |
+ /usr/ucb/mail -s 'SOCKS: rejected %u@%A to %Z (%S)' root root@%A
+
+.fi
+.in -1
+You may also specify in \fB/etc/sockd.conf\fP commands to be executed when
+\fIsockd\fP cannot connect to client's \fIidentd\fP or when the user-ids
+reported by the client programs and the client's \fIidentd\fP do not match.
+These special entries must have \fB#NO_IDENTD:\fP and \fB#BAD_ID:\fP at the very
+beginning of the line, followed by the shell commands to be excuted. For
+example:
+.nf
+.in +1
+
+#NO_IDENTD: /usr/ucb/mail -s 'Please run identd on host %A' root@%A
+#BAD_ID: finger @%A | /usr/ucb/mail -s '%U pretends to be %u on %A' root root@%A
+
+.fi
+.in -1
+A program called \fItest_sockd_conf\fP is provided for you to check
+your \fIsockd\fR configuration file. Be sure to use it everytime after
+you modify the configuration file. See \fItest_sockd_conf\fP(8).
+
+Strictly speaking, \fIsockd\fP has no concept of inside/outside, it
+does know which is the requesting host and which the destination
+and that is the basis of its access control. Therefore it can be used
+to facilitate
+access from outside world into your internal networks as well. Needless to
+say, you have to take extreme caution if you choose to do so. If you
+don't need that kind of access, it is recommended that you specifically
+deny such connections in \fBsokcd.conf\fR. For example, if the Class B
+network 129.1 is your internal network, use
+
+.nf
+.in +1
+deny 0.0.0.0 0.0.0.0 129.1.0.0 255.255.0.0
+.fi
+.in -1
+
+as the first line of your \fBsockd.conf\fP to protect your inside hosts
+from all attempts of access from the outside world through SOCKS.
+.SH SEE ALSO
+\fIsockd\fP(8), \fIsockd.route\fP(5), \fItest_sockd_conf\fP(8),
+\fIsocks.conf\fP(5), \fIsocks_clients\fP(1)
diff --git a/network/socks/socks.cstc.4.2/doc/sockd.route.5 b/network/socks/socks.cstc.4.2/doc/sockd.route.5
new file mode 100644
index 00000000..f09957b1
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/sockd.route.5
@@ -0,0 +1,79 @@
+.TH SOCKD.ROUTE 5 "November 17, 1993"
+.SH NAME
+sockd.route \- Routing file for multi-homed SOCKS proxy server
+.SH SYNOPSIS
+\fB/etc/sockd.route\fP
+.SH DESCRIPTION
+The file \fB/etc/sockd.route\fP is used by a multi-homed SOCKS server
+\fIsockd\fP to determine which of its network interfaces it should
+use to reach a given destination host.
+
+A multi-homed host is a host with more than one network interfaces
+and with its IP_FORWARDING turned off. Only the multi-homed version of
+\fIsockd\fP can be run on such hosts. Hosts which have a single
+network interface or that have enabled IP_FORWARDING -- even
+with multiple network interfaces -- can run the single-homed version
+of \fIsockd\fP, which requires no use of \fB/etc/sockd.route\fP.
+
+A line in the file can be up to 1024 characters long. Lines starting
+with a `#' are comments. Non-comment lines must be of the form
+
+\fIif_addr dst_addr dst_mask\fR
+
+All three fields are required and are separated by spaces or tabs.
+Each filed is specified in the usual dotted form of IP addresses,
+e.g., 128.23.16.2.
+\fIif_addr\fR must be the IP address of one of the network interfaces
+on the SOCKS server host. The \fIdst_addr dst_mask\fR pair together
+specify the destination IP address or a range of destination IP
+addresses. Bits in \fIdst_mask\fP that are set to 0 indicate the
+bit positions to be ignored during comparison of IP addresses. So,
+specifying 255.255.255.255 in \fIdst_mask\fP demands an exact match
+with \fIdst_addr\fP, whereas 0.0.0.0 in \fIdst_mask\fP causes a
+matching with any given destination address regardless of what is
+specified for \fIdst_addr\fP.
+
+When a multi-homed \fIsockd\fP receives a network request, it first
+checks with \fB/etc/sockd.conf\fP to decide whether the request
+should be allowed or denied. For an allowable request, \fIsockd\fP
+then checks the given destination IP address against the \fIdst_addr
+dst_mask\fP pair in \fB/etc/sockd.route\fP, one line at a line. Once
+a match is found, the network interface of the corresponding
+\fIif_addr\fR field is used for connection to the destination host.
+Remaining lines in the file are skipped. Therefore the order of the
+lines in the file is of extreme importance. If no match is found
+throughout the file, a line indicating the error is produced using
+\fIsyslog\fP with facility \fBdaemon\fP and level \fIerr\fP and
+\fIsockd\fP then terminates.
+
+The program \fItest_sockd_conf\fP checks \fB/etc/sockd.conf\fR as well
+as the regular configuration file \fB/etc/sockd.conf\fP.
+See \fItest_sockd_conf\fP(8).
+
+.SH EXAMPLES
+Suppose you have a dual-homed host with interface 129.1.2.3 connecting
+to your internal Class B network 129.1, and interface 129.1.254.1
+connecting to the outside world. If you only use the SOCKS server
+to provide connections to outside hosts, then the file \fB/etc/sockd.route\fP
+only needs one line:
+
+.nf
+.+1
+129.1.254.1 0.0.0.0 0.0.0.0
+.fi
+.-1
+
+If you also use the SOCKS server to provide connection to internal
+hosts as well, then two lines would suffice:
+
+.nf
+.+1
+129.1.2.3 129.1.0.0 255.255.0.0
+129.1.254.1 0.0.0.0 0.0.0.0
+.fi
+.-1
+
+Note that these two lines must be in the order given above.
+.SH SEE ALSO
+\fIsockd\fP(8), \fIsockd.route\fP(5), \fItest_sockd_conf\fP(8),
+\fIsocks.conf\fP(5), \fIsocks_clients\fP(1)
diff --git a/network/socks/socks.cstc.4.2/doc/socks.conf.5 b/network/socks/socks.cstc.4.2/doc/socks.conf.5
new file mode 100644
index 00000000..b2241a84
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/socks.conf.5
@@ -0,0 +1,142 @@
+.TH SOCKS.CONF 5 "February 9, 1994"
+.SH NAME
+.nf
+socks.conf \- SOCKS clients configuration file
+.fi
+.SH SYNOPSIS
+/etc/socks.conf
+.SH DESCRIPTION
+All SOCKS client programs use this file to determine whether to
+use direct or proxy connection to a given destination host, and
+to exert access control based on the destination host, the requested
+service (port number on the destination host), and the effective user-id
+of the requesting local user. If this file is absent, SOCKS clients will
+only try direct connections, making them behave like their regular couterparts.
+
+Each line in the file may be up to 1024 characters long.
+Lines starting with a \fB#\fP are comments. Non-comment lines must be
+of one of the three forms:
+
+.nf
+.+1
+\fBdeny \fI[\fB*=\fIuserlist] dst_addr dst_mask [op dst_port] [: shell_cmd]\fP
+\fBdirect \fI[\fB*=\fIuserlist] dst_addr dst_mask [op dst_port] [: shell_cmd]\fP
+\fBsockd \fI[\fB@=\fIserverlist] [\fB*=\fIuserlist] dst_addr dst_mask [op dst_port] [: shell_md]\fR
+.-1
+.fi
+
+A \fBdeny\fP line tells the SOCKS clients when to reject a request.
+A \fBdirect\fR lines tells when to use a direct connection. A \fBsockd\fR
+line indicates when to use a proxy connection and, optionally, which
+SOCKS proxy server or servers it should try.
+
+Spaces and tabs separate the fields. Fields enclosed in sqaure brackets
+are optional.
+
+The \fIuserlist\fR field, when present, consists of
+one or more user-ids or filenames, with comma as separator. No spaces
+or tabs are allowed in the list. The user-ids should be ids of users on the
+local host, not those on the destination host or the SOCKS server host.
+The filenames must be full pathnames with the leading \fB/\fP. Inside
+the specified files, user-ids may be listed one or several per line,
+with any combination of blanks, tabs, and commas as separators. The
+appearance of \fB#\fP marks the remainder of the line as comment. Each
+line in the files may be up to 1023 characters long.
+If the \fB*=\fIuserlist\fR field is omitted, the line applies to all user-ids.
+
+The \fIdst_addr dst_mask\fP pair together specify the destination IP address
+or the range of destination IP addresses. They are both given in the
+usual dotted form, e.g., 129.1.2.3. Bits in \fIdst_mask\fP that are set
+to 0 indicate the bit positions which should be masked off (i.e., ignored)
+during comparison of \fIdst_addr\fP and the actual destination IP address.
+So specifying 255.255.255.255 in \fIdst_mask\fP demands an exact match
+with \fIdst_addr\fP, whereas 0.0.0.0 in \fIdst_mask\fP causes an address
+match no matter what is specified for \fIdst_addr\fP. (NOTE: This is the
+same way netmasks are interpreted, but is the direct opposite of how the
+address masks are used in cisco router's access-lists.)
+
+The \fIop\fP field must be \fBeq\fR, \fBneq\fR, \fBlt\fR, \fBgt\fR,
+\fBle\fR, or \fBge\fR, for the condition of equal, not equal, less than,
+greater than, less than or equal, and greater than or equal, respectively.
+The \fIdst_port\fP field can be either a port number, e.g., 23, or the
+equivalent service name as specified in file /etc/services, e.g., \fBtelnet\fR
+for port number 23. If this pair is omitted, the line applies to all
+services.
+
+The \fIserverlist\fP, which may only be used in a \fBsockd\fR line,
+consists of one or more SOCKS proxy servers, which the client program should
+try to use (in the indicated order) for establishing a proxy connection.
+Only commas can be used as separator, no spaces
+or tabs are allowed in the list. Domain names of the servers may be used
+in the list, though it is probably more prudent to specify IP addresses.
+If this field is omitted, the client program will use the
+default SOCKS proxy server, which is determined by the environment variable
+\fBSOCKS_SERVER\fR if it exists, or the name compiled into the SOCKS client
+program otherwise.
+
+Consider
+
+.nf
+.+1
+sockd @=1.2.3.4 *=boss,root 11.12.13.14 255.255.255.255 eq telnet
+.-1
+.fi
+
+To match the condition indicated in this line, a request must come from
+a local user whose effective id is either boss or root, the detination
+IP address must be 11.12.13.14 exactly, and the service requested must
+be telnet. In that case, connection to host 11.12.13.14 should be done
+via a SOCKS proxy server on host 1.2.3.4.
+
+Every time a SOCKS client has to make a network connection, it checks
+the pending request against the file \fB/etc/socks.conf\fR, one line at
+a time. Once it finds a line with conditions that are matched by the
+request, the action specified on that line is taken. The remaining
+lines of file \fB/etc/socks.conf\fR are skipped. So the order of the
+lines in the file is extremely important; switch two lines and you may
+have entirely different results. If no matching line
+is found throughout the file, the request is denied.
+
+The \fIshell_cmd\fR field specifies a command string that is executed
+when the conditions on that line are satisfied. The following substitutions
+occur before the string is presented to the Borne shell for execution:
+.nf
+.in +1
+
+%A -- replaced by the client host's domainname if known, by its IP address otherwise
+%a -- replaced by the client host's IP address
+%c -- replaced by "connect" or "bind"
+%p -- replaced by the process id of the client program
+%S -- replaced by the service name (e.g., ftp) if known, by the destination port number otherwise
+%s -- replaced by the destination port number
+%U -- replaced by the user-id at login
+%u -- replaced by the effective user-id
+%Z -- replaced by the destination host's domainname if known, by its IP address otherwise
+%z -- replaced by the destination host's IP address
+%% -- replaced by a single %
+
+.fi
+.in -1
+Several shell commands can be strung together in the usual way with `|',
+`;', etc.
+
+Although there is an implied 'deny all' at the end of the control file,
+you may supply one explicitly so as to take some specific action when requests
+are so rejected, e.g.,
+.nf
+.in +1
+
+deny 0.0.0.0 0.0.0.0 : /usr/ucb/mail -s 'SOCKS: rejected %S from %u to %Z' root
+
+.fi
+.in -1
+Unlike the previous version, connection to address 127.0.0.1 or 0.0.0.0
+is always done directly to localhost, so there is no need to specify
+either of them in
+\fB/etc/socks.conf\fP.
+.SH ENVIRONMENT
+\fBSOCKS_SERVER\fR, if defined, specifies the name or IP address of the
+SOCKS proxy server host to use, overriding the default server
+compiled into the programs.
+.SH SEE ALSO
+\fIsockd\fP(8), \fIsocks_clients\fP(1), \fIsockd.conf\fP(5)
diff --git a/network/socks/socks.cstc.4.2/doc/socks_clients.1 b/network/socks/socks.cstc.4.2/doc/socks_clients.1
new file mode 100644
index 00000000..341b0902
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/socks_clients.1
@@ -0,0 +1,97 @@
+.TH SOCKS_CLIENTS 1 "November 16, 1993"
+.SH NAME
+.nf
+rfinger \- SOCKS client version of finger
+rftp \- SOCKS client version of ftp
+rtelnet \- SOCKS client version of telnet
+rwhois \- SOCKS client version of whois
+.fi
+.SH SYNOPSIS
+See the man pages on \fIfinger\fP(1), \fIftp\fP(1), \fItelnet\fP(1),
+\fIwhois\fP(1).
+.SH DESCRIPTION
+These programs provide the well-known functionalities to hosts within
+a firewall. Normally, when a firewall is constructed, IP-accessibility
+across the firewall is cut off to reduce security risk to hosts within
+the firewall. As a result, inside hosts can no longer use many of the
+well-known tools directly to access the resources outside the firewall.
+
+These programs restore the convenience of the well-known tools while
+maintaining the security requirement. Though the programs differ very
+much from their counterparts in the use of the communication scheme,
+they should behave almost indistinguishably to the users. Note though
+that rftp does echo the password as you type it in if you are using
+\fIanonymous\fP as log-in name. Unlike those of the previous versions,
+these are "versatile" clinets, meaning that they can be used for
+connections to inside hosts directly and to outside hosts via SOCKS
+proxy servers. So they can be used as replacements of their traditional
+counterparts.
+
+When any of these programs starts, if the environment variable
+\fBSOCKS_BANNER\fR is defined, the program prints to \fBstderr\fP
+its version number and
+the name or IP address of its default SOCKS proxy server.
+It then consults the configuration file \fB/etc/socks.conf\fP to
+determine whether a request should be allowed or denied based on the
+requesting user, the destination host, and the requested service. For
+allowable requests, the configuration file also dictates whether
+direct or proxy connection should be used to the given destination,
+and optionally the actual SOCKS servers to use for the proxy connection.
+See \fIsocks.conf\fP(5). If the file is absent, these programs will
+only try direct connections to the destination hosts, making them
+behaving like their regular counterparts.
+
+You can use environment variable \fBSOCKS_NS\fR to set the nameserver for
+domainname resolutions. Be sure you use the IP address of the
+nameserver you want to use, not its domainname. If \fBSOCKS_NS\fR doesn't
+exist, the IP address defined by the symbol \fBSOCKS_DEFAULT_NS\fR
+at compile time is used if the programs were compiled with that symbol
+defined. Otherwise the nameservers specified in \fB/etc/resolv.conf\fR
+are used.
+
+All the client programs uses \fIsyslog\fP with facility \fBdaemon\fR
+and level \fBnotice\fR to log their activities.
+These log lines usually appear in file \fB/var/adm/messages\fP though
+that can be changed by modifying \fB/etc/syslog.conf\fR. (See
+\fIsyslogd\fP(8) and \fIsyslog.conf\fP(5).)
+Typical lines look like
+
+.nf
+.in +1
+Apr 11 10:02:23 eon rfinger[631]: connect() from don(don) to abc.com (finger) using sockd at socksserv
+May 10 08:39:07 eon rftp[603]: connect() directly from blue(blue) to xyz.edu (ftp)
+May 10 08:39:09 eon rftp[603]: bind() directly from blue(blue) for xyz.edu (ftp)
+May 18 13:31:19 eon rtelnet[830]: connect() from root(jon) to xyz.edu (telnet) using sockd at sockd2
+May 18 14:51:19 eon rtelnet[921]: refused -- connect() from jon(jon) to xyz.edu (telnet)
+.in -1
+.fi
+
+Of the two user-ids appearing in each log line, the first is the
+effective user-id when the program is invoked, the second (that
+within the parentheses) is the one used at login. Access
+control applies to the effective user-ids.
+.SH SEE ALSO
+\fIsockd\fP(8), \fIfinger\fP(1), \fIftp\fP(1), \fItelnet\fP(1),
+\fIwhois\fP(1)
+.SH ENVIRONMENT
+\fBSOCKS_SERVER\fR, if defined, specifies the name or IP address of the
+SOCKS proxy server host to use, overriding the default server
+compiled into the programs.
+
+\fBSOCKS_NS\fR, if defined, specify the IP address of the domain nameserver
+that should be used for name resolution, overriding both the definition
+of symbol \fBSOCKS_DEFAULT_NS\fR and the file \fB/etc/resolv.conf\fR.
+
+\fBORIG_FINGER\fR, if defined, specified the (altered) full pathname of
+the original
+finger program, which should have been renamed before installing the
+rfinger as the regular finger. The \fIrfinger\fP program invokes
+the original \fIfinger\fP program to lookup information on local users.
+Normally this name should be compiled directly into \fIrfinger\fP, avoiding
+the need for this environment variable. Use \fBORIG_FINGER\FR only if
+you want to override what is compiled into \fIrfinger\fP.
+
+.SH AUTHOR
+David Koblas, koblas@netcom.com
+.PP
+Ying-Da Lee, ylee@syl.dl.nec.com
diff --git a/network/socks/socks.cstc.4.2/doc/test_sockd_conf.8 b/network/socks/socks.cstc.4.2/doc/test_sockd_conf.8
new file mode 100644
index 00000000..9fccc295
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/doc/test_sockd_conf.8
@@ -0,0 +1,200 @@
+.TH TEST_SOCKD_CONF 8 "August 6, 1993"
+.SH NAME
+test_sockd_conf \- Test the configuration file of \fIsockd\fR proxy server
+.SH SYNOPSIS
+\fBtest_sockd_conf [ \-I | \-i | \-B ] [ \-R \fIroute_file\fB] [ \-C \fIsockd_conf\fB ] \fIuser src_addr dst_addr dst_port\fR
+.SH DESCRIPTION
+\fItest_sockd_conf\fR is used for testing whether your configuration file
+for the \fIsockd\fR proxy server is set up correctly. See \fIsockd\fR(8)
+and \fIsockd.conf\fP(5) for details on the proxy server and the format
+of the configuration file.
+
+\fIsockd\fR uses the configuration file to determine whether a request
+for its service should be granted or denied, based on who the requesting
+user is, from which host the request originates, which host the
+request is trying to reach, and to which port number the request
+is trying to connect. It is not always obvious by looking at the
+configuration file whether it indeed grants all legitimate service requests
+and blocks all undesirable ones. You can use \fItest_sockd_conf\fR to
+make sure that the configuration does what you want it to do.
+
+For the multi-homed version of \fIsockd\fP, this program also checks
+the routing file \fI/etc/sockd.route\fP to indicated which interface
+on the server host will be used to reach the destination host. See
+\fIsockd.route\fP(5).
+
+\fIuser\fR is the id of an user on the request host. \fIsrc_addr\fR is
+the IP address of the request host. \fIdst_addr\fR is the IP address of
+the destination host. You may use domain names in place of the IP addresses
+if your system can resolve the names properly. \fIdst_port\fR is the
+port number on the destination host that the request wants to connect to.
+It can be replaced by the equivalent services name as specified in
+file \fB/etc/services\fP, e.g., \fBtelnet\fP and 23 are equivalent
+in this field.
+
+These parameters together forms a hypothetical service request which
+\fItest_sockd_conf\fR feeds to the access control mechanism of \fIsockd\fR.
+\fItest_sockd_conf\fR echoes the aguments, then prints either the line in the
+configuration file which matches the request if one is found or
+an indication that access is denied if no match if found in the entire file.
+If the matching line contains the optional shell command field, the command(s)
+will be executed. The program also produces log entries similar to what
+\fIsockd\fR does, which usually appear in file \fB/var/adm/messages\fP.
+You can also test the special entries #NO_IDENTD: and #BAD_ID: by specifying
+option \fB\-I\fP, \fB\-i\fP, or \fB\-B\fP. For multi-homed version, it also
+search the routing file to decide which network interface should be used
+for connection to the destination host.
+
+The program exits with code 1 if the request is permitted, 0 if denied.
+If errors in the arguments are found, it exits with code -1.
+.SH OPTION
+.TP
+\fB\-C\fI sockd_conf\fR
+Use \fIsockd_conf\fR as the configuration file to be tested. File
+\fB/etc/sockd.conf\fR is used by default.
+.TP
+.B\-I
+Simulate the situation when \fIsockd\fR is run with option \fB\-I\fP and
+the client host does not run \fIidentd\fP.
+.TP
+.B\-i
+Simulate the situation when \fIsockd\fR is run with option \fB\-i\fP and
+the client host does not run \fIidentd\fP.
+.TP
+.B\-B
+Simulate the situation when \fIsockd\fR is run with either \fB\-I\fP or
+\fB\-i\fP and the \fIidentd\fR on the client host reports a user-id
+different from what the client program claims.
+.TP
+.B\-R\fI route_file\fR
+Use \fIroute_file\fR as the routing file to be tested. File
+\fB/etc/sockd.route\fR is used by default. This option is allowed only
+with multi-homed version of SOCKS server.
+.SH EXAMPLES
+Assume that file \fB/etc/sockd.conf\fR consists of these lines:
+
+.nf
+.in +1
+deny *=clyde 128.12.6.0 255.255.255.0 : /usr/ucb/mail -s 'Rejected SOCKS access by %u' root
+permit *=root 128.12.6.4 255.255.255.255 137.12.0.0 255.255.0.0
+deny 128.12.0.0 255.255.0.0 eq telnet
+permit 128.12.0.0 255.255.0.0
+#NO_IDENTD: /usr/ucb/mail -s 'please run identd on %A' root@%A
+#BAD_ID: /usr/ucb/mail -s '%U pretends to be %u on %A' root
+
+
+Also assume that the file \fB/etc/sockd.route\fR consists of these line:
+129.10.1.2 10.0.0.0.0 255.0.0.0
+129.10.7.10 137.12.0.0 255.255.0.0
+129.10.254.1 0.0.0.0 0.0.0.0
+.in -1
+
+Following are the results of a few tests.
+
+.nf
+.in +1
+\fBtest_sockd_conf clyde 128.12.6.34 112.3.24.1 ftp\fR
+USER:clyde, SRC:128.12.6.34, DST:112.3.24.1, PORT:21
+Line 1: deny *=clyde 128.12.6.0 255.255.255.0 : /usr/ucb/mail -s 'Rejected SOCKS access by %u' root
+.in -1
+.fi
+A mail message is sent to root with the subject line 'Rejected SOCKS
+access by clyde'.
+.in +1
+.nf
+
+\fBtest_sockd_conf root 128.12.6.4 137.12.4.15 telnet\fR
+USER:root, SRC:128.12.6.4, DST:137.12.4.15, PORT:23
+Line 2: permit *=root 128.12.6.4 255.255.255.255 137.12.0.0 255.255.0.0
+==== Checking routing file (sockd.route)...
+Line 2: 129.10.7.10 137.12.0.0 255.255.0.0
+
+\fBtest_sockd_conf jane 128.12.2.13 137.12.4.15 telnet\fR
+USER:jane, SRC:128.12.2.13, DST:137.12.4.15, PORT:23
+Line 3: deny 128.12.0.0 255.255.0.0 eq telnet
+
+\fBtest_sockd_conf jim 128.12.6.4 126.87.13.2 telnet\fR
+USER:jim, SRC:128.12.6.4, DST:126.87.13.2, PORT:23
+Line 3: deny 128.12.0.0 255.255.0.0 eq telnet
+
+\fBtest_sockd_conf root 128.12.6.4 126.87.13.2 ftp\fR
+USER:root, SRC:128.12.6.4, DST:126.87.13.2, PORT:21
+Line 4: permit 128.12.0.0 255.255.0.0
+==== Checking routing file (sockd.route)...
+Line 3: 129.10.254.1 0.0.0.0 0.0.0.0
+
+\fBtest_sockd_conf sam 128.12.36.7 10.53.23.1 70\fR
+USER:sam, SRC:128.12.36.7, DST:10.53.23.1, PORT:70
+Line 4: permit 128.12.0.0 255.255.0.0
+==== Checking routing file (sockd.route)...
+Line 1: 129.10.1.2 10.0.0.0 255.0.0.0
+
+\fBtest_sockd_conf don 23.2.6.127 10.53.23.1 70\fR
+USER:don, SRC:23.2.6.127, DST:10.53.23.1, PORT:70
+ *** No match with any line. Access denied.
+
+\fBtest_sockd_conf clyde 128.12.1.62 112.3.24.1 ftp\fR
+USER:clyde, SRC:128.12.1.62, DST:112.3.24.1, PORT:21
+Line 4: permit 128.12.0.0 255.255.0.0
+==== Checking routing file (sockd.route)...
+Line 3: 129.10.254.1 0.0.0.0 0.0.0.0
+
+\fBtest_sockd_conf -I joe 128.12.6.4 126.87.13.2 ftp\fR
+USER:joe, SRC:128.12.6.4, DST:126.87.13.2, PORT:21
+Line 5: #NO_IDENTD: /usr/ucb/mail -s 'please run identd on %a' root@%A
+Access denied: cannot verify user-id.
+.in -1
+.fi
+A mail message is sent to root of the host 128.12.6.4 with the
+subject line 'please run identd on 128.12.6.4'.
+.nf
+.in +1
+
+\fBtest_sockd_conf -i joe 128.12.6.4 126.87.13.2 ftp\fR
+USER:joe, SRC:128.12.6.4, DST:126.87.13.2, PORT:21
+Line 5: #NO_IDENTD: /usr/ucb/mail -s 'please run identd on %a' root@%A
+Line 4: permit 128.12.0.0 0.0.255.255
+==== Checking routing file (sockd.route)...
+Line 3: 129.10.254.1 0.0.0.0 0.0.0.0
+.in -1
+.fi
+A mail message is sent to root of the host 128.12.6.4 with the
+subject line 'please run identd on 128.12.6.4'.
+.nf
+.in +1
+
+\fBtest_sockd_conf -i jim 128.12.6.4 126.87.13.2 telnet\fR
+USER:jim, SRC:128.12.6.4, DST:126.87.13.2, PORT:23
+Line 5: #NO_IDENTD: /usr/ucb/mail -s 'please run identd on %a' root@%A
+Line 3: deny 128.12.0.0 0.0.255.255 eq telnet
+.in -1
+.fi
+A mail message is sent to root of the host 128.12.6.4 with the
+subject line 'please run identd on 128.12.6.4'.
+.nf
+.in +1
+
+\fBtest_sockd_conf -B joe 128.12.6.4 126.87.13.2 ftp\fR
+USER:joe, SRC:128.12.6.4, DST:126.87.13.2, PORT:21
+Line 6: #BAD_ID: /usr/ucb/mail -s '%U pretends to be %u on %A' root
+Access denied: bad user-id.
+.in -1
+.fi
+A mail message is sent to root with the
+subject line 'unknown pretends to be joe on 128.12.6.4'.
+
+Note that lines in a configuration file may combine to act in a way
+that could surprise you. Be sure you run through a thorough sequence
+of tests after every modification. You may be caught
+surprise if you only run tests on the types of
+requests that you believe you are trying to affect.
+
+.SH FILES
+\fB/etc/sockd.conf\fR, \fB/var/adm/messages\fP
+
+.SH SEE ALSO
+\fIsockd\fR(8), \fIsockd.conf\fR(5), \fIsockd.route\fR(5), \fIsocks.conf\fR(5),
+\fIsocks_clients\fR(1)
+
+.SH AUTHOR
+Ying-Da Lee, ylee@syl.dl.nec.com
diff --git a/network/socks/socks.cstc.4.2/include/bstring.h b/network/socks/socks.cstc.4.2/include/bstring.h
new file mode 100644
index 00000000..9e36fa0c
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/include/bstring.h
@@ -0,0 +1,5 @@
+/* for systems without bcopy(), bzero() and bcmp() */
+#include <string.h>
+#define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len))
+#define bzero(b,len) memset(b, 0, (size_t)(len))
+#define bcmp(b1,b2,len) memcmp(b1, b2, (size_t)(len))
diff --git a/network/socks/socks.cstc.4.2/include/ptx-2.1.h b/network/socks/socks.cstc.4.2/include/ptx-2.1.h
new file mode 100644
index 00000000..f6ec5050
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/include/ptx-2.1.h
@@ -0,0 +1,32 @@
+/*
+ * Argument type passed to the wait() call. If you don't know what it is, then
+ * leave it blank. The macro will place a pointer to the type for a cast...
+ * This will either be "union wait" or "int".
+ */
+
+#define WAIT_ARG_TYPE int
+
+/*
+ * Argument type passed to the signal() call (second parameter). If you don't
+ * know what it is then don't define it.... this is placed in as a cast as-is.
+ */
+
+#define SIGNAL_ARG_TYPE void(*)(int)
+
+
+/* any additional missing headers */
+
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <dirent.h>
+#include <stdlib.h>
+
+/* any extra externs */
+
+extern int h_errno;
+
+/* fix for missing gettimeofday() call */
+
+#include <sys/procstats.h>
+#define gettimeofday(t, tz) get_process_stats((t), PS_SELF, NULL, NULL)
diff --git a/network/socks/socks.cstc.4.2/include/socks.h b/network/socks/socks.cstc.4.2/include/socks.h
new file mode 100644
index 00000000..eda1cf63
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/include/socks.h
@@ -0,0 +1,162 @@
+/*
+ * Default SOCKS server host; you MUST set this for your site.
+ * This is overridden at run time by the contents of environment
+ * variable SOCKS_SERVER if it exists.
+ */
+#define SOCKS_DEFAULT_SERVER "SOCKS.server.for.your.site"
+
+/*
+ * Default Domain Nameserver for the SOCKS clients.
+ * Leave it undefined if all your client mechines can do general
+ * DNS lookup for all Internet hosts correctly with the DNS servers
+ * specified in /etc/resolv.conf.
+ * Otherwise, define it using the IP ADDRESS (NOT NAME!) of a DNS
+ * server which can resolve all Internet hosts and which is IP-reachable
+ * from your client machines.
+ * This is overriden at run time by the contents of environment
+ * variable SOCKS_NS if it exists.
+ */
+/* #define SOCKS_DEFAULT_NS "1.2.3.4" */
+
+/* >>> jon r. luini <jonl@hal.com> */
+/*
+ * Default domain name to use for the resolver to use.
+ * Leave it undefined unless you run in an environment where
+ * you have a number of clients which will be running the socks
+ * utilities without the correct domain name specified in /etc/resolv.conf
+ * (or determined automatically by the system). If you try to run
+ * socks and it complains that it cannot lookup the local hostname,
+ * that is a good indication you need to define this appropriately.
+ * This is overriden at run time by the contents of environment
+ * variable SOCKS_DNAME if it exists.
+ */
+/* #define SOCKS_DEFAULT_DNAME "hal.COM" */
+/* <<< jon r. luini <jonl@hal.com> */
+
+/*
+ * Make clients that connect through SOCKS server to destinations
+ * outside the firewall, but connect directly to destinations inside
+ * the firewall. You can then, for example, rename the regular 'telnet'
+ * to 'telnet.orig' and make a symbolic link for 'telnet' to point
+ * to 'rtelnet' and from then on use the command 'telnet' no matter
+ * whether the hosts you try to connect is inside or outside the
+ * firewall.
+ */
+#define VERSATILE_CLIENTS
+
+/*
+ * Full pathname of the regular 'finger' program.
+ * If you are making versatile clients, you will have to rename your
+ * regular 'finger' program to something else, e.g., from /usr/ucb/finger
+ * to /usr/ucb/finger.orig and the pathname you should use here is the
+ * new (altered) pathname, i.e., /usr/ucb/finger.orig.
+ */
+#define ORIG_FINGER "/usr/ucb/finger.orig"
+/* Overridden at runtime by environment variable ORIG_FINGER if it exists. */
+
+/* Control file for versatile clients */
+#define SOCKS_CONF "/etc/socks.conf"
+
+/*
+ * Default port number for SOCKS services.
+ * On the SOCKS server host, if the server is under inetd control,
+ * then the port must be specified in socks/tcp entry in /etc/services.
+ * For servers not under inetd control and for all clients,
+ * the port number is obtained from socks/tcp entry in /etc/services if
+ * it exists, otherwise the number defined by SOCKS_DEF_PORT will be used.
+ */
+#define SOCKS_DEF_PORT 1080
+
+/*
+** How long (in seconds) to keep a connection around while it is idle
+*/
+#define SOCKS_TIMEOUT 2*60*60 /* 2hr in seconds */
+
+/* How long before connection attempts timed out */
+#define CLIENT_CONN_TIMEOUT 60*2 /* 2 minutes */
+#define SOCKD_CONN_TIMEOUT 60*3 /* 3 minutes */
+/* You may have to adjust these to fit your network situation */
+
+/*
+ * Where the config file lives on the SOCKS server host.
+ * This is the file that controls access to the SOCKS server
+ * and its services.
+ */
+#define SOCKD_CONF "/etc/sockd.conf"
+
+/*
+ * Define this if your SOCKS server is multi-homed (i.e.,
+ * having two or more network interfaces) and is not behaving
+ * as a router (i.e., has its IP forwarding turned off).
+ * Leave it undefined otherwise.
+ */
+/* #define MULTIHOMED_SERVER */
+
+/*
+ * For multi-homed servers, you must supply the file /etc/sockd.route
+ * to tell the program which interface to use for communicating with
+ * which destination networks/hosts. See sockd man pages for details.
+ * This has no effects if MULTIHOMED_SERVER is undefined.
+ */
+#define SOCKD_ROUTE_FILE "/etc/sockd.route"
+
+/* Current SOCKS protocol version */
+#define SOCKS_VERSION 4
+
+#define CSTC_RELEASE "4.2 pre1"
+
+/*
+** Response commands/codes
+*/
+#define SOCKS_CONNECT 1
+#define SOCKS_BIND 2
+#define SOCKS_RESULT 90
+#define SOCKS_FAIL 91
+#define SOCKS_NO_IDENTD 92 /* Failed to connect to Identd on client machine */
+#define SOCKS_BAD_ID 93 /* Client's Identd reported a different user-id */
+
+#if defined(__alpha)
+typedef unsigned int u_int32;
+#else
+typedef unsigned long u_int32;
+#endif
+
+typedef struct {
+ u_int32 host; /* in network byte order */
+ unsigned short port; /* in network byte oreder */
+ unsigned char version;
+ unsigned char cmd;
+} Socks_t;
+
+/*
+ * Define NOT_THROUGH_INETD if you want a standalone SOCKS server,
+ * one which is not under the control of inetd.
+ * This is not recommended.
+ */
+/* #define NOT_THROUGH_INETD */
+
+/*
+ * Maximum number of concurrent clients a SOCKS server will support.
+ * Meaningful only if the server is not under the control
+ * of inetd, i.e., when NOT_THROUGH_INETD is defined.
+ */
+#define MAX_CLIENTS 5
+
+#ifdef SOLARIS
+/* for bcopy(), bzero() and bcmp() */
+#include "bstring.h"
+#endif
+
+/* Define NO_SYSLOG to suppress logging */
+/*
+#define NO_SYSLOG
+
+#if defined(NO_SYSLOG)
+# define syslog
+# define openlog
+#endif
+*/
+
+# define SYSLOG_FAC LOG_DAEMON
+# define LOG_LOW LOG_NOTICE
+# define LOG_HIGH LOG_ERR
diff --git a/network/socks/socks.cstc.4.2/lib/Makefile b/network/socks/socks.cstc.4.2/lib/Makefile
new file mode 100644
index 00000000..5c742544
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/Makefile
@@ -0,0 +1,113 @@
+#CC=gcc
+
+# Define RCMD and SUPPORT_RCMD if you want to use the library
+# for rlogin, rsh, and rcp.
+SUPPORT_RCMD=-DSUPPORT_RCMD
+RCMD=Rrcmd.o
+
+# Comment out next macro to produce library compatible with
+# clients SOCKSified for SOCKS.CSTC 4.1 and 4.0
+SHORTENED_RBIND=-DSHORTENED_RBIND
+
+# You should not have to define the next macro
+#NO_GUESSING_REMHOST=-DNO_GUESSING_REMHOST
+
+# Directory into which socks_clients's man page files will be installed:
+MAN_DEST_DIR=/usr/local/man
+
+# If you want to install the SOCKS library into /usr/locallib,
+# uncomment the next line:
+#LIB_DEST_DIR=/usr/locallib
+# Installing the library in /usr/locallib makes it possible to
+# use '-lsocks' with cc or ld command to search the library.
+# /usr/lib and /lib may also be used instead of /usr/local/lib.
+
+# Remember to include -Dindex=strchr in OTHER_CFLAGS if
+# you don't have index() (Sys-V camp)
+
+# SunOS should use
+OTHER_CFLAGS= $(SHORTENED_RBIND)
+#RANLIB=ranlib
+
+# IRIX should use
+#OTHER_CFLAGS=-cckr $(SHORTENED_RBIND)
+#RANLIB=/bin/true
+
+# AIX should use
+#OTHER_CFLAGS=-D_BSD -D_NONSTD_TYPES -D_NO_PROTO -DAIX $(SHORTENED_RBIND)
+#RANLIB=ranlib
+
+#For SOLARIS
+#OTHER_CFLAGS=-DSOLARIS -Dindex=strchr -Drindex=strrchr -DUSE_DIRENT $(SHORTENED_RBIND)
+#RANLIB=/bin/true
+
+# Interactive Systems Unix should use
+# OTHER_CFLAGS = -DISC $(SHORTENED_RBIND)
+
+# LINUX should use
+#CC=gcc
+#RESOLV_LIB=
+#OTHER_CFLAGS=-traditional -DLINUX $(SHORTENED_RBIND)
+
+# UnixWare should use
+#RESOLV_LIB=-lresolv -lnsl -lsocket
+#OTHER_CFLAGS= -DSOLARIS -Dindex=strchr -Drindex=strrchr -DUSE_DIRENT $(SHORTENED_RBIND)
+#RANLIB=/bin/true
+#INSTALL=bsdinstall
+
+# >>>---------------- Others:
+
+RANLIB=ranlib
+# Systems that do not need (and thus don't have) ranlib should use
+#RANLIB=/bin/true
+
+# <<<----------------
+
+OPTIMIZE=-g
+CFLAGS = -I../include ${OPTIMIZE} ${OTHER_CFLAGS} ${SUPPORT_RCMD} ${NO_GUESSING_REMHOST}
+
+# Comment out defintion of GETPASS if your system has problem
+# compiling it. The version built into your system will be used.
+# The getpass() function in most Unix systems truncate password
+# after 8 characters; the version provided here does not.
+# This only affects telnet and ftp with non-anonymous login.
+# Ftp with anonymous login allows long passwords regardless
+# of whether GETPASS is defined or not.
+GETPASS=getpass.o
+
+# The 'install' command is assumed to be the BSD variety (using -m to
+# set the file mode). If the default 'install' on your system doesn't
+# do that, you have to either specify an alternative one in the line below
+# (e.g., bsdinstall or /usr/ucb/install) or modify the install instructions.
+INSTALL= install
+
+#==============================================================================
+
+OBJS = Rconnect.o SendGetDst.o saddrtoname.o porttoserv.o check_cconf.o \
+ percent_x.o shell_cmd.o check_user.o $(GETPASS) $(RCMD)
+SRCS = Rconnect.c SendGetDst.c saddrtoname.c porttoserv.c check_cconf.c \
+ percent_x.c shell_cmd.c check_user.c getpass.c
+INC =../include/socks.h
+LIB = libsocks.a
+
+all: echocwd $(LIB)
+
+$(LIB): $(OBJS) $(INC)
+ rm -f $(LIB)
+ ar rc $(LIB) $(OBJS)
+ $(RANLIB) $(LIB)
+
+install: echocwd $(LIB)
+ -if [ -d $(LIB_DEST_DIR) ]; then \
+ ($(INSTALL) -m 644 $(LIB) $(LIB_DEST_DIR); \
+ $(RANLIB) -t $(LIB_DEST_DIR)/$(LIB)); fi
+
+install.man: echocwd
+ $(INSTALL) -m 444 ../doc/socks_clients.1 $(MAN_DEST_DIR)/man1
+ $(INSTALL) -m 444 ../doc/socks.conf.5 $(MAN_DEST_DIR)/man5
+
+clean: echocwd
+ rm -f $(OBJS) $(LIB) core
+
+echocwd:
+ @pwd
diff --git a/network/socks/socks.cstc.4.2/lib/Rconnect.c b/network/socks/socks.cstc.4.2/lib/Rconnect.c
new file mode 100644
index 00000000..460bbed8
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/Rconnect.c
@@ -0,0 +1,867 @@
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <pwd.h>
+#include <syslog.h>
+#if (defined(sun) && !defined(SOLARIS)) || defined(sgi)
+#include <strings.h>
+#else
+#include <string.h>
+#endif
+#include "socks.h"
+#ifdef LINUX
+#include <linux/time.h>
+#endif
+
+/* >>> K. Shackelford */
+#if defined(hpux) || defined(ultrix) || defined (__NetBSD__) || defined(AIX) || defined(__bsdi__) || defined(SCO)
+extern int h_errno;
+#endif
+/* <<< K.Shackelford */
+
+#include <signal.h>
+#include <sys/wait.h>
+
+#define NAMELEN 128
+char socks_dst_name[NAMELEN], socks_dst_serv[NAMELEN];
+char socks_src_name[NAMELEN], socks_src_user[NAMELEN], socks_real_user[NAMELEN];
+char *socks_def_server;
+char *socks_server;
+char *socks_serverlist;
+
+char socks_cmd[] = "connect";
+
+extern int errno;
+extern char *getenv();
+extern char *getlogin();
+static struct sockaddr_in cursin;
+u_int32 SocksHost;
+static unsigned short socks_port;
+static int socks_conn_sock = 0;
+static int socks_conn_init = 0;
+static unsigned short socks_conn_port = 0;
+static u_int32 socks_conn_host = 0;
+static int socks_conn_code = 0;
+static unsigned short socks_last_conn_port = 0;
+static u_int32 socks_last_conn_host = 0;
+static int socks_init_done = 0;
+
+struct sockaddr_in socks_nsin;
+static struct sockaddr_in me;
+static struct passwd *pw;
+static int direct = 0;
+
+extern char *porttoserv();
+extern char *saddrtoname();
+
+
+int check_result(code)
+char code;
+{
+ switch (code) {
+ case SOCKS_FAIL:
+/*
+ errno = ETIMEDOUT;
+*/
+ errno = ECONNREFUSED;
+ return -1;
+ case SOCKS_NO_IDENTD:
+ errno = ECONNREFUSED;
+ fprintf(stderr, "Error: SOCKS proxy server cannot connect to identd on your machine.\n");
+ return -1;
+ case SOCKS_BAD_ID:
+ errno = ECONNREFUSED;
+ fprintf(stderr, "Error: user-id does not agree with the one reported by identd on your machine.\n");
+ return -1;
+ default:
+ return 0;
+ }
+}
+
+/*
+ SOCKSinit() must be called once in the application program.
+ */
+
+SOCKSinit(Progname)
+char *Progname; /* name of the calling program, "rfinger", "rftp", etc. */
+{
+#ifdef SOCKS_DEFAULT_NS
+ static char defaultNS[] = SOCKS_DEFAULT_NS;
+#endif
+#ifdef SOCKS_DEFAULT_DNAME
+ static char defaultDNAME[] = SOCKS_DEFAULT_DNAME;
+#endif
+ static char defaultSERVER[] = SOCKS_DEFAULT_SERVER;
+ char *cp, *ns, *dp;
+ struct hostent *hp;
+ struct servent *sp;
+ int v,uid;
+
+/* >>> YDL 94/01/25 */
+ if (socks_init_done)
+ return;
+ socks_init_done = 1;
+/* <<< YDL 94/01/25 */
+ socks_port = htons(SOCKS_DEF_PORT);
+
+ bzero((char *)&cursin, sizeof(cursin));
+ bzero((char *)&socks_nsin, sizeof(socks_nsin));
+ bzero((char *)&me, sizeof(me));
+ /* skip the path if included in Progname */
+ if( (cp = rindex(Progname, '/')) == NULL)
+ cp = Progname;
+ else
+ cp++;
+
+#ifndef LOG_DAEMON
+ (void) openlog(cp, LOG_PID);
+#else
+ (void) openlog(cp, LOG_PID, SYSLOG_FAC);
+#endif
+
+ gethostname(socks_src_name, sizeof(socks_src_name));
+ if ( (hp = gethostbyname(socks_src_name)) == NULL ) {
+ fprintf (stderr, "gethostbyname(%s): error #%d\n",
+ socks_src_name, h_errno);
+ return (1);
+ }
+ bcopy(hp->h_addr_list[0], &me.sin_addr.s_addr, hp->h_length);
+
+#if !defined(DNS_THROUGH_NIS)
+
+ if ((ns = getenv("SOCKS_NS")) == NULL) {
+#ifdef SOCKS_DEFAULT_NS
+ ns = defaultNS;
+#else
+ ;
+#endif
+ }
+ if ((dp = getenv("SOCKS_DNAME")) == NULL) {
+#ifdef SOCKS_DEFAULT_DNAME
+ dp = defaultDNAME;
+#else
+ ;
+#endif
+ }
+
+ if ((ns != NULL) || (dp != NULL)) {
+ res_init();
+#ifdef sgi
+ sethostresorder("local:nis:bind");
+#endif
+ }
+
+ if (ns != NULL) {
+#ifdef ultrix
+ _res.ns_list[0].addr.sin_addr.s_addr = inet_addr(ns);
+#else
+ _res.nsaddr_list[0].sin_addr.s_addr = inet_addr(ns);
+#endif
+ _res.nscount = 1;
+ }
+ if (dp != NULL) {
+ strncpy(_res.defdname, dp, sizeof(_res.defdname)-1);
+ }
+
+/* >>> jon r. luini <jonl@hal.com> */
+/*
+#ifdef SOCKS_DEFAULT_DNAME
+ bzero (_res.defdname, sizeof (_res.defdname));
+
+ if ( (cp = getenv("SOCKS_DNAME")) != NULL )
+ {
+ strncpy (_res.defdname, cp, sizeof (_res.defdname)-1);
+ }
+ else
+ {
+ strncpy (_res.defdname, SOCKS_DEFAULT_DNAME,
+ sizeof (_res.defdname)-1);
+ }
+#endif
+*/
+/* <<< jon r. luini <jonl@hal.com> */
+
+#endif /* #if !defined(DNS_THROUGH_NIS) */
+
+ if ((socks_def_server = getenv("SOCKS_SERVER")) == NULL)
+ socks_def_server = defaultSERVER;
+ socks_server = socks_def_server;
+ if ((cp = getenv("SOCKS_BANNER")) != NULL) {
+ fprintf(stderr, "CSTC version %s SOCKS client. Default SOCKS server: %s\n",
+ CSTC_RELEASE, socks_def_server);
+ }
+
+ if ((hp = gethostbyname(socks_server)) == NULL) {
+ SocksHost = inet_addr(socks_server);
+ } else {
+ bcopy(hp->h_addr_list[0], &SocksHost, hp->h_length);
+ }
+
+ if ((sp = getservbyname("socks", "tcp")) != NULL)
+ socks_port = sp->s_port;
+
+ if ((cp = getlogin()) == NULL) {
+ if ((pw = getpwuid(uid=getuid())) == NULL) {
+ fprintf(stderr, "Unknown user-id %d\n",uid);
+ return (1);
+ }
+ cp = pw->pw_name;
+ }
+ strncpy(socks_real_user, cp, sizeof(socks_real_user));
+
+ if ((pw = getpwuid(uid=geteuid())) == NULL) {
+ fprintf(stderr, "Unknown user-id %d\n",uid);
+ return (1);
+ }
+ strncpy(socks_src_user, pw->pw_name, sizeof(socks_src_user));
+
+ socks_nsin.sin_family = AF_INET;
+ socks_nsin.sin_port = socks_port;
+ socks_nsin.sin_addr.s_addr = SocksHost;
+
+}
+
+
+int connect_sockd(sock, lport)
+int sock;
+int *lport;
+/* returns 0 if successfully connected to a SOCKS server,
+ returns -1 otherwise
+ */
+{
+#ifndef VERSATILE_CLIENTS
+ if (connect(sock, &socks_nsin, sizeof(struct sockaddr_in)) == 0)
+ return 0;
+ else {
+ syslog(LOG_LOW, "Failed to connect to sockd at %s: %m",
+ socks_server);
+ return -1;
+ }
+#else /* Now the version when VERSATILE_CLIENTS is defined */
+ int last = 0;
+ int new_sock;
+ struct hostent *hp;
+
+ while (socks_server = socks_serverlist) {
+ if (socks_serverlist = index(socks_serverlist, ','))
+ *socks_serverlist++ = '\0';
+ if ((hp = gethostbyname(socks_server)) == NULL)
+ socks_nsin.sin_addr.s_addr = inet_addr(socks_server);
+ else
+ bcopy(hp->h_addr_list[0], &socks_nsin.sin_addr, hp->h_length);
+ if (connect(sock, (struct sockaddr *)&socks_nsin, sizeof(struct sockaddr_in)) == 0)
+ return 0;
+ else {
+#ifdef SVR4
+ if ((errno == EISCONN) || (errno == EINPROGRESS) || (errno == EAGAIN))
+#else
+ if ((errno == EISCONN) || (errno == EINPROGRESS))
+#endif
+ return -1;
+ syslog(LOG_LOW, "Failed to connect to sockd at %s: %m",
+ socks_server);
+ if (!(socks_serverlist)) {
+ return -1;
+ }
+#if defined(SUPPORT_RCMD)
+ if ((*lport < IPPORT_RESERVED) && (*lport >= IPPORT_RESERVED/2))
+ new_sock = rresvport(lport);
+ else
+ new_sock = socket(PF_INET, SOCK_STREAM, 0);
+#else /* SUPPORT_RCMD is not defined */
+ new_sock = socket(PF_INET, SOCK_STREAM, 0);
+#endif /* #if defined(SUPPORT_RCMD) */
+ if (new_sock < 0) {
+ return -1;
+ }
+ if (dup2(new_sock, sock) < 0) {
+ close(new_sock);
+ return -1;
+ } else {
+ close(new_sock);
+ }
+ }
+ }
+ errno = ECONNREFUSED;
+ return -1;
+#endif /* #ifndef VERSATILE_CLIENTS */
+
+}
+
+static int send_src_user(s, user)
+int s;
+char *user;
+{
+ char *p = user;
+ int i, n, ret;
+ fd_set fds;
+ int fdsbits = s + 1;
+ struct timeval timeout;
+
+ i = strlen(user) + 1;
+ while ( i > 0) {
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+ timeout.tv_sec = 15;
+ timeout.tv_usec = 0;
+ if ((ret = select(fdsbits, NULL, &fds, NULL, &timeout)) < 0) {
+ return(-1);
+ }
+ if (ret == 0)
+ continue;
+ if((n = write(s, p, i)) <= 0) {
+ return(-2);
+ }
+ p += n;
+ i -= n;
+ }
+ return(0);
+}
+
+
+static int socksC_proto(s, dst)
+int s;
+Socks_t *dst;
+{
+ int sta;
+
+ if ((sta = SendDst(s, dst)) < 0) {
+ if (sta == -1)
+ perror("select in SendDst");
+ else
+ perror("write in SendDst");
+ return(sta);
+ }
+ if ((sta = send_src_user(s, socks_src_user)) < 0) {
+ if (sta == -1)
+ perror("select in send_src_user");
+ else
+ perror("write in send_src_user");
+ return(sta);
+ }
+ if ((sta = GetDst(s, dst)) < 0) {
+ if (sta == -1)
+ perror("select in GetDst");
+ else
+ perror("read in GetDst");
+ return(sta);
+ }
+ return(0);
+}
+
+static void quit_C_proto()
+{
+ exit(SOCKS_FAIL);
+}
+
+static void do_C_proto(sock, port, addr)
+int sock;
+unsigned short port;
+u_int32 addr;
+{
+ Socks_t dst;
+
+ signal(SIGALRM, quit_C_proto);
+ alarm(CLIENT_CONN_TIMEOUT);
+ dst.version = SOCKS_VERSION;
+ dst.cmd = SOCKS_CONNECT;
+ dst.port = port;
+ dst.host = addr;
+ if (socksC_proto(sock, &dst) < 0) {
+ alarm(0);
+ exit(SOCKS_FAIL);
+ }
+ alarm(0);
+ if ((dst.cmd == SOCKS_FAIL) || (dst.cmd == SOCKS_NO_IDENTD)
+ || (dst.cmd == SOCKS_BAD_ID)) {
+ exit(dst.cmd);
+ }
+ exit(SOCKS_RESULT);
+
+}
+
+
+Rconnect(sock, sin, size)
+int sock;
+struct sockaddr_in *sin;
+int size;
+{
+ Socks_t dst;
+ int i;
+ int res_ret, con_ret, con_errno;
+ int lport = 0;
+
+ int status, wait_ret, child_pid;
+
+ if (socks_init_done == 0)
+ SOCKSinit("SOCKSclient");
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 10\n");
+fprintf(stderr,"socks_conn_sock=%d, socks_conn_host=%ld, socks_conn_port=%d, socks_conn_init=%d\n", socks_conn_sock, socks_conn_host, socks_conn_port, socks_conn_init);
+fprintf(stderr,"sock=%d, sin->sin_addr.s_addr=%ld, sin->sin_port=%d\n", sock, sin->sin_addr.s_addr, sin->sin_port);
+#endif /* #ifdef DEBUG */
+
+ if ((sock != socks_conn_sock) || (sin->sin_port != socks_conn_port)
+ || (sin->sin_addr.s_addr != socks_conn_host)) {
+ if (socks_conn_init)
+ kill(socks_conn_init, SIGKILL);
+ socks_conn_code = 0;
+ socks_conn_init = 0;
+ strcpy(socks_cmd, "connect");
+ saddrtoname(&sin->sin_addr, socks_dst_name, sizeof(socks_dst_name));
+ porttoserv(sin->sin_port, socks_dst_serv, sizeof(socks_dst_serv));
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 100, Rconnect(%d, %s, %s)\n", sock, socks_dst_name, socks_dst_serv);
+#endif /* #ifdef DEBUG */
+ } else if (status = socks_conn_code) {
+ socks_conn_init = 0;
+ socks_conn_code = 0;
+ socks_conn_sock = 0;
+ socks_conn_port = 0;
+ socks_conn_host = 0;
+ res_ret = check_result(status);
+ if (status == SOCKS_RESULT) {
+ errno = EISCONN;
+ socks_last_conn_host = sin->sin_addr.s_addr;
+ socks_last_conn_port = sin->sin_port;
+ } else {
+ syslog(LOG_LOW, "Connection failed.\n");
+ }
+ return(-1);
+ } else if (socks_conn_init) {
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 200, Rconnect(%d, %s, %s)\n", sock, socks_dst_name, socks_dst_serv);
+#endif /* #ifdef DEBUG */
+ wait_ret = waitpid(socks_conn_init, &status, WNOHANG);
+ if (wait_ret == 0) {
+ errno = EALREADY;
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 300, ret=-1, errno=EALREADY\n");
+#endif /* #ifdef DEBUG */
+ return(-1);
+ } else if (wait_ret == socks_conn_init) {
+ socks_conn_init = 0;
+ socks_conn_code = 0;
+ socks_conn_sock = 0;
+ socks_conn_port = 0;
+ socks_conn_host = 0;
+ if (status & 0x00ff) {
+ kill(socks_conn_init, SIGKILL);
+ errno = ECONNREFUSED;
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 400, ret=-1, errno=ECONNREFUSED\n");
+#endif /* #ifdef DEBUG */
+ syslog(LOG_LOW, "Connection failed.\n");
+ return(-1);
+ } else {
+ status = (status >> 8) & 0x00ff;
+ res_ret = check_result(status);
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 500, ret=%d, status=%d\n", res_ret, status);
+#endif /* #ifdef DEBUG */
+ if (res_ret == 0) {
+ errno = EISCONN;
+ socks_last_conn_host = sin->sin_addr.s_addr;
+ socks_last_conn_port = sin->sin_port;
+ } else {
+ syslog(LOG_LOW, "Connection failed.\n");
+ }
+ return(-1);
+ }
+ } else {
+ kill(socks_conn_init, SIGKILL);
+ errno = ECONNREFUSED;
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 600, ret=-1, errno=ECONNREFUSED\n");
+#endif /* #ifdef DEBUG */
+ socks_conn_init = 0;
+ socks_conn_code = 0;
+ socks_conn_sock = 0;
+ socks_conn_port = 0;
+ socks_conn_host = 0;
+ syslog(LOG_LOW, "Connection failed.\n");
+ return(-1);
+ }
+ }
+
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 700, Rconnect(%d, %s, %s)\n", sock, socks_dst_name, socks_dst_serv);
+#endif /* #ifdef DEBUG */
+
+#ifdef VERSATILE_CLIENTS
+ direct = check_cconf(&me, sin);
+#ifdef DEBUG
+fprintf(stderr, "Rconnect() 800: direct = %d\n", direct);
+#endif /* #ifdef DEBUG */
+ if (direct < 0) {
+ syslog(LOG_LOW, "refused -- connect() from %s(%s) to %s (%s)",
+ socks_src_user, socks_real_user, socks_dst_name, socks_dst_serv);
+ errno = ECONNREFUSED;
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 900, ret=-1, errno=EALREADY\n");
+#endif /* #ifdef DEBUG */
+ return(-1);
+ }
+
+ if (direct == 1) {
+ syslog(LOG_LOW, "connect() directly from %s(%s) to %s (%s)",
+ socks_src_user, socks_real_user, socks_dst_name, socks_dst_serv);
+ con_ret = connect(sock, (struct sockaddr *)sin, size);
+ if (con_ret == 0) {
+ socks_last_conn_host = sin->sin_addr.s_addr;
+ socks_last_conn_port = sin->sin_port;
+ }
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 1000, ret=%d, ", con_ret);
+perror(" ");
+#endif /* #ifdef DEBUG */
+ return(con_ret);
+ }
+#endif /* #ifdef VERSATILE_CLIENTS */
+
+ con_ret = connect_sockd(sock, &lport);
+#ifdef DEBUG
+ fprintf(stderr, "con_ret=connect_sockd()=%d", con_ret);
+ if(con_ret < 0)
+ perror("");
+ else
+ fprintf(stderr,"\n");
+#endif /* #ifdef DEBUG */
+ if (con_ret == 0) {
+ syslog(LOG_LOW, "connect() from %s(%s) to %s (%s) using sockd at %s",
+ socks_src_user, socks_real_user, socks_dst_name, socks_dst_serv, socks_server);
+ dst.version = SOCKS_VERSION;
+ dst.cmd = SOCKS_CONNECT;
+ dst.port = sin->sin_port;
+ dst.host = sin->sin_addr.s_addr;
+ if (socksC_proto(sock, &dst) < 0) {
+ return(-1);
+ }
+ res_ret = check_result(dst.cmd);
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 1100, ret=%d, ", res_ret);
+perror(" ");
+#endif /* #ifdef DEBUG */
+ if (res_ret == 0) {
+ socks_last_conn_host = sin->sin_addr.s_addr;
+ socks_last_conn_port = sin->sin_port;
+ }
+ return(res_ret);
+ }
+ if ((con_ret < 0) && (errno != EINPROGRESS)) {
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 1200, ret=%d, ", con_ret);
+perror(" ");
+#endif /* #ifdef DEBUG */
+ return(-1);
+ }
+/*
+ con_errno = errno;
+*/
+ syslog(LOG_LOW, "connect() from %s(%s) to %s (%s) using sockd at %s",
+ socks_src_user, socks_real_user, socks_dst_name, socks_dst_serv, socks_server);
+
+ switch (child_pid = fork()) {
+ case -1:
+ perror("fork()");
+ errno = ECONNREFUSED;
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 1300, ret=-1, ");
+perror(" ");
+#endif /* #ifdef DEBUG */
+ return(-1);
+ case 0:
+ do_C_proto(sock, sin->sin_port, sin->sin_addr.s_addr);
+ default:
+ socks_conn_init = child_pid;
+ socks_conn_code = 0;
+ socks_conn_sock = sock;
+ socks_conn_port = sin->sin_port;
+ socks_conn_host = sin->sin_addr.s_addr;
+ errno = EINPROGRESS;
+#ifdef DEBUG
+fprintf(stderr, "Rconnect 1400, ret=-1 ");
+perror(" ");
+#endif /* #ifdef DEBUG */
+ return(-1);
+ }
+}
+
+/* >>> YDL 94/01/25 */
+#ifdef SHORTENED_RBIND
+Rbind(sock, sin, size)
+int sock;
+struct sockaddr_in *sin;
+int size;
+#else
+/*
+** Set up a bind for a remote host, add fill 'cursin' in with the
+** remote server information.
+** If using reserved port, the port must have already been reserved
+** through a rresvport() call.
+*/
+Rbind(sock, sin, size, dsthost)
+int sock;
+struct sockaddr_in *sin;
+int size;
+u_int32 dsthost; /* as in sin_addr.s_addr */
+#endif /* #ifdef SHORTENED_RBIND */
+/* <<< YDL 94/01/25 */
+{
+ Socks_t dst;
+ struct sockaddr_in psin;
+ int i;
+ int new_sock, lport;
+ u_int32 remhost;
+ int con_ret;
+ struct timeval tmo;
+ fd_set fds;
+
+ if (socks_init_done == 0)
+ SOCKSinit("SOCKSclient");
+ bzero((char *)&psin, sizeof(psin));
+ lport = ntohs(sin->sin_port);
+ strcpy(socks_cmd, "bind");
+#ifdef SHORTENED_RBIND
+# ifdef NO_GUESSING_REMHOST
+ remhost = 0L;
+ strcpy(socks_dst_name, "Unspecified.Host");
+# else
+ remhost = socks_last_conn_host;
+ saddrtoname(&remhost, socks_dst_name, sizeof(socks_dst_name));
+# endif /* # ifdef NO_GUESSING_REMHOST */
+#else
+ remhost = dsthost;
+ saddrtoname(&remhost, socks_dst_name, sizeof(socks_dst_name));
+#endif /* #ifdef SHORTENED_RBIND */
+ porttoserv(socks_last_conn_port, socks_dst_serv, sizeof(socks_dst_serv));
+#ifdef DEBUG
+fprintf(stderr, "Rbind 100, lport=%u, socks_dst_name=>%s<, socks_dst_serv=>%s<\n", lport, socks_dst_name, socks_dst_serv);
+fprintf(stderr, "Rbind(%d, %s, %s)\n", sock, socks_dst_name, socks_dst_serv);
+#endif /* #ifdef DEBUG */
+
+ psin.sin_addr.s_addr = remhost;
+ psin.sin_port = socks_last_conn_port;
+#ifdef VERSATILE_CLIENTS
+ direct = check_cconf(&me, &psin);
+#ifdef DEBUG
+fprintf(stderr, "Rbind() 200, direct = %d\n", direct);
+#endif /* #ifdef DEBUG */
+ if (direct < 0) {
+ syslog(LOG_LOW, "Refused -- bind() from %s(%s) for %s (%s)",
+ socks_src_user, socks_real_user, socks_dst_name, socks_dst_serv);
+ errno = ECONNREFUSED;
+ return -1;
+ }
+
+ if (direct == 1) {
+ syslog(LOG_LOW, "bind() directly from %s(%s) for %s (%s)",
+ socks_src_user, socks_real_user, socks_dst_name, socks_dst_serv);
+#ifdef DEBUG
+fprintf(stderr,"Rbind() 300, direct=1, lport=%u\n", lport);
+#endif /* #ifdef DEBUG */
+#if defined(SUPPORT_RCMD)
+ if ((lport >= IPPORT_RESERVED) || (lport < IPPORT_RESERVED/2))
+ return (bind(sock, (struct sockaddr *)sin, size));
+ else
+ return 0;
+#else /* SUPPORT_RCMD not defined */
+ return (bind(sock, (struct sockaddr *)sin, size));
+#endif /* #if defined(SUPPORT_RCMD) */
+ }
+#endif /* #ifdef VERSATILE_CLIENTS */
+
+ con_ret = connect_sockd(sock, &lport);
+ if (con_ret == 0) {
+ ;
+#ifdef SVR4
+ } else if ((errno == EINPROGRESS) || (errno == EAGAIN)) {
+#else
+ } else if (errno == EINPROGRESS) {
+#endif
+ while (1) {
+ tmo.tv_sec = 0;
+ tmo.tv_usec = 100000;
+ FD_ZERO(&fds);
+ FD_SET(sock, &fds);
+ select(sock+1, NULL, &fds, NULL, &tmo);
+ con_ret = connect(sock, (struct sockaddr *)&socks_nsin, sizeof(struct sockaddr_in));
+ if ((con_ret < 0) && (errno == EISCONN)) {
+ con_ret = 0;
+ break;
+#if defined(SVR4)
+ } else if ((con_ret < 0) && ((errno == EALREADY) ||
+ (errno == EAGAIN))) {
+#else /* !defined(SVR4) */
+ } else if ((con_ret < 0) && (errno == EALREADY)) {
+#endif /* #if defined(SVR4) */
+ continue;
+ } else
+ break;
+ }
+ }
+ if (con_ret < 0) {
+ syslog(LOG_LOW, "Failed -- bind() from %s(%s) for %s (%s)",
+ socks_src_user, socks_real_user, socks_dst_name, socks_dst_serv);
+ errno = ECONNREFUSED;
+ return -1;
+ }
+ syslog(LOG_LOW, "bind() from %s(%s) for %s (%s) using sockd at %s",
+ socks_src_user, socks_real_user, socks_dst_name, socks_dst_serv, socks_server);
+
+ dst.version = SOCKS_VERSION;
+ dst.cmd = SOCKS_BIND;
+ dst.port = socks_last_conn_port;
+ dst.host = remhost;
+ if (socksC_proto(sock, &dst) < 0)
+ return(-1);
+ cursin.sin_family = AF_INET;
+ cursin.sin_port = dst.port;
+ if (ntohl(dst.host) == INADDR_ANY)
+ cursin.sin_addr.s_addr = socks_nsin.sin_addr.s_addr;
+ else
+ cursin.sin_addr.s_addr = dst.host;
+/*
+ fprintf(stderr,"Rbind interface: %s, port: %u\n",
+ inet_ntoa(cursin.sin_addr), htons(cursin.sin_port));
+*/
+
+ return (check_result(dst.cmd));
+}
+
+/*
+** Stub routine since the listen will have alread succeded on the
+** server.
+*/
+Rlisten(s, n)
+int s, n;
+{
+#ifdef DEBUG
+ fprintf(stderr, "direct=%d, Rlisten(%d, %d)\n", direct, s, n);
+#endif
+#ifdef VERSATILE_CLIENTS
+ if (direct)
+ return (listen(s, n));
+#endif /* #ifdef VERSATILE_CLIENTS */
+
+ return 0;
+}
+
+/*
+** Well we know where we got a connection from.
+*/
+Rgetsockname(sock, sin, size)
+int sock;
+struct sockaddr_in *sin;
+int *size;
+{
+#ifdef DEBUG
+ saddrtoname(&sin->sin_addr, socks_dst_name, sizeof(socks_dst_name));
+ porttoserv(sin->sin_port, socks_dst_serv, sizeof(socks_dst_serv));
+ fprintf(stderr, "direct= %d, Rgetsockname(%d, %s, %s)\n",
+ direct, sock, socks_dst_name, socks_dst_serv);
+#endif
+#ifdef VERSATILE_CLIENTS
+ if (direct)
+ return (getsockname(sock, (struct sockaddr *)sin, size));
+#endif /* #ifdef VERSATILE_CLIENTS */
+
+ *size = sizeof(struct sockaddr_in);
+ *sin = cursin;
+
+ return 0;
+}
+
+/*
+** Do an accept, which is really a select for some data on
+** the present socket.
+*/
+Raccept(sock, sin, size)
+int sock;
+struct sockaddr_in *sin;
+int *size;
+{
+ fd_set fds;
+ Socks_t dst;
+ int fdsbits = sock + 1;
+
+#ifdef DEBUG
+ fprintf(stderr, "direct= %d, Raccept(%d, sin, size)\n",
+ direct, sock);
+#endif
+
+#ifdef VERSATILE_CLIENTS
+ if (direct)
+ return(accept(sock, (struct sockaddr *)sin, size));
+#endif /* #ifdef VERSATILE_CLIENTS */
+
+ FD_ZERO(&fds);
+ FD_SET(sock, &fds);
+
+ if (select(fdsbits, &fds, NULL, NULL, NULL) > 0)
+ if (FD_ISSET(sock, &fds)) {
+ GetDst(sock, &dst);
+ sin->sin_family = AF_INET;
+ sin->sin_port = dst.port;
+ sin->sin_addr.s_addr = dst.host;
+ return(dup(sock));
+ }
+ return -1;
+}
+
+int Rselect(width, readfds, writefds, exceptfds, timeout)
+int width;
+fd_set *readfds, *writefds, *exceptfds;
+struct timeval *timeout;
+{
+ int wait_ret, status;
+
+ if(!socks_conn_init ) {
+ return(select(width, readfds, writefds, exceptfds, timeout));
+ }
+
+ if (readfds != NULL)
+ FD_CLR(socks_conn_sock, readfds);
+ if (exceptfds != NULL)
+ FD_CLR(socks_conn_sock, exceptfds);
+ if ((writefds == NULL) || !FD_ISSET(socks_conn_sock, writefds))
+ return(select(width, readfds, writefds, exceptfds, timeout));
+
+ wait_ret = waitpid(socks_conn_init, &status, WNOHANG);
+ if (wait_ret == 0) {
+ FD_CLR(socks_conn_sock, writefds);
+ return(select(width, readfds, writefds, exceptfds, timeout));
+ } else if (wait_ret == socks_conn_init) {
+/*
+ socks_conn_init = 0;
+ socks_conn_sock = 0;
+ socks_conn_port = 0;
+ socks_conn_host = 0;
+*/
+ if (status & 0x00ff) {
+ kill(socks_conn_init, SIGKILL);
+ socks_conn_init = 0;
+ socks_conn_code = SOCKS_FAIL;
+ } else {
+ status = (status >> 8) & 0x00ff;
+ if (status == SOCKS_RESULT) {
+ socks_last_conn_host = socks_conn_host;
+ socks_last_conn_port = socks_conn_port;
+ }
+ socks_conn_init = 0;
+ socks_conn_code = status;
+ }
+ } else {
+ kill(socks_conn_init, SIGKILL);
+ socks_conn_init = 0;
+ socks_conn_code = SOCKS_FAIL;
+ }
+
+ return(select(width, readfds, writefds, exceptfds, timeout));
+}
diff --git a/network/socks/socks.cstc.4.2/lib/Rrcmd.c b/network/socks/socks.cstc.4.2/lib/Rrcmd.c
new file mode 100644
index 00000000..e08f91e3
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/Rrcmd.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rcmd.c 5.24 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: rcmd.c,v 1.4 1993/12/05 14:42:26 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
+
+Rrcmd(ahost, rport, locuser, remuser, cmd, fd2p)
+ char **ahost;
+ u_short rport;
+/*
+ const char *locuser, *remuser, *cmd;
+*/
+ char *locuser, *remuser, *cmd;
+ int *fd2p;
+{
+ int s, timo = 1, pid;
+ long oldmask;
+ struct sockaddr_in sin, from;
+ char c;
+ int lport = IPPORT_RESERVED - 1;
+ struct hostent hoste;
+ struct hostent *hp;
+ fd_set reads;
+
+ pid = getpid();
+ hp = gethostbyname(*ahost);
+ if (hp == 0) {
+ herror(*ahost);
+ return (-1);
+ }
+ bcopy(hp, &hoste, sizeof(struct hostent));
+ hp = &hoste;
+ *ahost = hp->h_name;
+ oldmask = sigblock(sigmask(SIGURG));
+ for (;;) {
+#ifdef DEBUG
+fprintf(stderr, "Rrcmd 100, lport = %d\n", lport);
+#endif /* #ifdef DEBUG */
+ s = rresvport(&lport);
+#ifdef DEBUG
+fprintf(stderr, "Rrcmd 200, s = %d\n", s);
+#endif /* #ifdef DEBUG */
+ if (s < 0) {
+ if (errno == EAGAIN)
+ fprintf(stderr, "socket: All ports in use\n");
+ else
+ perror("rcmd: socket");
+ sigsetmask(oldmask);
+ return (-1);
+ }
+#ifdef DEBUG
+fprintf(stderr, "Rrcmd 300\n");
+#endif /* #ifdef DEBUG */
+#if defined(hpux)
+ ioctl(s, FIOSSAIOOWN, pid);
+#else /* hpux not defined */
+ fcntl(s, F_SETOWN, pid);
+#endif /* #if defined(hpux) */
+ bzero((char *)&sin, sizeof sin);
+ sin.sin_family = hp->h_addrtype;
+ bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
+ sin.sin_port = rport;
+#ifdef DEBUG
+fprintf(stderr, "Rrcmd 400, sin.sin_family=%d, sin.sin_port=%u, sin.sin_addr=%s\n",sin.sin_family, ntohs(sin.sin_port), inet_ntoa(sin.sin_addr));
+#endif /* #ifdef DEBUG */
+ if (Rconnect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+ break;
+#ifdef DEBUG
+fprintf(stderr, "Rrcmd 500, Rconnect failed\n");
+#endif /* #ifdef DEBUG */
+ (void) close(s);
+ if (errno == EADDRINUSE) {
+ lport--;
+ continue;
+ }
+ if (errno == ECONNREFUSED && timo <= 16) {
+ sleep(timo);
+ timo *= 2;
+ continue;
+ }
+ if (hp->h_addr_list[1] != NULL) {
+ int oerrno = errno;
+
+ fprintf(stderr,
+ "connect to address %s: ", inet_ntoa(sin.sin_addr));
+ errno = oerrno;
+ perror(0);
+ hp->h_addr_list++;
+ bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
+ hp->h_length);
+ fprintf(stderr, "Trying %s...\n",
+ inet_ntoa(sin.sin_addr));
+ continue;
+ }
+ perror(hp->h_name);
+ sigsetmask(oldmask);
+ return (-1);
+ }
+ lport--;
+#ifdef DEBUG
+fprintf(stderr, "Rrcmd 600, f2dp=%u\n", fd2p);
+#endif /* #ifdef DEBUG */
+ if (fd2p == 0) {
+ write(s, "", 1);
+ lport = 0;
+ } else {
+ char num[8];
+ int s2 = rresvport(&lport), s3;
+ int len = sizeof (from);
+ struct sockaddr_in tsin;
+ int tlen = sizeof(tsin);
+
+#ifdef DEBUG
+fprintf(stderr, "Rrcmd 650, lport=%u\n", lport);
+#endif /* #ifdef DEBUG */
+ if (s2 < 0)
+ goto bad;
+ tsin.sin_family = AF_INET;
+ tsin.sin_addr.s_addr = INADDR_ANY;
+ tsin.sin_port = htons((u_short)lport);
+/*
+ s2 = socket(AF_INET, SOCK_STREAM, 0);
+*/
+ if (Rbind(s2, (struct sockaddr *)&tsin, sizeof(tsin),
+ sin.sin_addr.s_addr) < 0) {
+ perror("Rrcmd: Rbind() ");
+ (void) close(s2);
+ goto bad;
+ }
+ if (Rgetsockname(s2, (struct sockaddr *)&tsin, &tlen) < 0) {
+ perror("Rrcmd: Rgetsockname() ");
+ (void) close(s2);
+ goto bad;
+ }
+ Rlisten(s2, 1);
+/*
+ (void) sprintf(num, "%d", lport);
+*/
+ (void) sprintf(num, "%u", ntohs(tsin.sin_port));
+#ifdef DEBUG
+fprintf(stderr,"Rrcmd 800, num=>%s<\n", num);
+#endif /* #ifdef DEBUG */
+ if (write(s, num, strlen(num)+1) != strlen(num)+1) {
+ perror("write: setting up stderr");
+ (void) close(s2);
+ goto bad;
+ }
+ FD_ZERO(&reads);
+ FD_SET(s, &reads);
+ FD_SET(s2, &reads);
+ errno = 0;
+ if (select(32, &reads, 0, 0, 0) < 1 ||
+ !FD_ISSET(s2, &reads)) {
+ if (errno != 0)
+ perror("select: setting up stderr");
+ else
+ fprintf(stderr,
+ "select: protocol failure in circuit setup.\n");
+ (void) close(s2);
+ goto bad;
+ }
+#ifdef DEBUG
+fprintf(stderr,"Rrcmd 900, before Raccept()\n");
+#endif /* #ifdef DEBUG */
+ s3 = Raccept(s2, (struct sockaddr *)&from, &len);
+ (void) close(s2);
+ if (s3 < 0) {
+ perror("accept");
+ lport = 0;
+ goto bad;
+ }
+ *fd2p = s3;
+ from.sin_port = ntohs((u_short)from.sin_port);
+ if (from.sin_family != AF_INET ||
+ from.sin_port >= IPPORT_RESERVED ||
+ from.sin_port < IPPORT_RESERVED / 2) {
+ fprintf(stderr,
+ "socket: protocol failure in circuit setup.\n");
+ goto bad2;
+ }
+ }
+ (void) write(s, locuser, strlen(locuser)+1);
+ (void) write(s, remuser, strlen(remuser)+1);
+ (void) write(s, cmd, strlen(cmd)+1);
+ if (read(s, &c, 1) != 1) {
+ perror(*ahost);
+ goto bad2;
+ }
+ if (c != 0) {
+ while (read(s, &c, 1) == 1) {
+ (void) write(2, &c, 1);
+ if (c == '\n')
+ break;
+ }
+ goto bad2;
+ }
+ sigsetmask(oldmask);
+ return (s);
+bad2:
+ if (lport)
+ (void) close(*fd2p);
+bad:
+ (void) close(s);
+ sigsetmask(oldmask);
+ return (-1);
+}
+
diff --git a/network/socks/socks.cstc.4.2/lib/SendGetDst.c b/network/socks/socks.cstc.4.2/lib/SendGetDst.c
new file mode 100644
index 00000000..e119324a
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/SendGetDst.c
@@ -0,0 +1,102 @@
+#include <sys/types.h>
+#include <sys/time.h>
+#include "socks.h"
+#if defined(DEBUG)
+#include <sys/errno.h>
+extern int errno;
+#endif
+
+#define NULL ((char *)0)
+
+int SendDst(s, dst)
+int s;
+Socks_t *dst;
+{
+ char c[sizeof(Socks_t)];
+ char *p = c;
+ int i = sizeof(Socks_t), n, ret;
+ fd_set fds;
+ int fdsbits = s + 1;
+ struct timeval timeout;
+
+ c[0] = dst->version;
+ c[1] = dst->cmd;
+ bcopy(&dst->port, c+2, sizeof(dst->port));
+ bcopy(&dst->host, c+2+sizeof(dst->port), sizeof(dst->host));
+
+ while ( i > 0) {
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+ timeout.tv_sec = 15;
+ timeout.tv_usec = 0;
+ while ((ret = select(fdsbits, NULL, &fds, NULL, &timeout)) < 0) {
+/*
+ perror("select in SendDst");
+ exit(-1);
+*/
+#if defined(DEBUG)
+ if (errno != EINTR)
+#endif
+ return(-1);
+ }
+ if (ret == 0)
+ continue;
+ if((n = write(s, p, i)) <= 0) {
+/*
+ perror("write in SendDst");
+ exit(-1);
+*/
+ return (-2);
+ }
+ p += n;
+ i -= n;
+ }
+ return(0);
+}
+
+int GetDst(s, dst)
+int s;
+Socks_t *dst;
+{
+ char c[sizeof(Socks_t)];
+ char *p = c;
+ int i = sizeof(Socks_t), n, ret;
+ fd_set fds;
+ int fdsbits = s + 1;
+ struct timeval timeout;
+
+ while ( i > 0) {
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+ timeout.tv_sec = 15;
+ timeout.tv_usec = 0;
+ while ((ret = select(fdsbits, &fds, NULL, NULL, &timeout)) < 0) {
+/*
+ perror("select in GetDst");
+ exit(-1);
+*/
+#if defined(DEBUG)
+ if (errno != EINTR)
+#endif
+ return(-1);
+ }
+ if (ret == 0)
+ continue;
+ if((n = read(s, p, i)) <= 0) {
+/*
+ perror("read in GetDst");
+ exit(-1);
+*/
+ return(-2);
+ }
+ p += n;
+ i -= n;
+ }
+
+ dst->version = c[0];
+ dst->cmd = c[1];
+ bcopy(c+2, &dst->port, sizeof(dst->port));
+ bcopy(c+2+sizeof(dst->port), &dst->host, sizeof(dst->host));
+ return(0);
+}
+
diff --git a/network/socks/socks.cstc.4.2/lib/check_cconf.c b/network/socks/socks.cstc.4.2/lib/check_cconf.c
new file mode 100644
index 00000000..23ba368b
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/check_cconf.c
@@ -0,0 +1,258 @@
+#include <sys/types.h>
+#include <syslog.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <ctype.h>
+/* >>> YDL, 93/10/26 */
+#if (defined(sun) && !defined(SOLARIS)) || defined(sgi)
+#include <strings.h>
+#else
+#include <string.h>
+#endif
+/* <<< YDL< 93/10/26 */
+#include "socks.h"
+
+#define STREQ(a, b) (strcmp(a, b) == 0)
+
+#ifdef OLD_CONF_MASK
+static char conf_mask[] = OLD_CONF_MASK;
+#endif
+char *socks_conf = SOCKS_CONF;
+extern char *porttoserv();
+extern char *saddrtoname();
+extern void mkargs();
+extern int GetAddr();
+extern long GetPort();
+extern int check_user();
+extern char socks_src_user[];
+extern char *socks_server;
+extern struct sockaddr_in socks_nsin;
+extern u_int32 SocksHost;
+extern char *socks_def_server;
+extern char *socks_serverlist;
+
+check_cconf(src, dst)
+/* Return 0 if sockd should be used,
+ 1 if direct connection should be made,
+ -1 if the connection request should be denied.
+ */
+struct sockaddr_in *src, *dst;
+{
+ FILE *fd;
+ static char buf[1024];
+#ifdef TEST
+ char temp[1024];
+#endif
+ char *bp;
+ int linenum = 0, direct;
+ char *argv[10];
+ int argc;
+ u_int32 daddr, dmask;
+ unsigned short dport;
+ enum { e_lt, e_gt, e_eq, e_neq, e_le, e_ge, e_nil } tst;
+ char *userlist;
+ int next_arg;
+ unsigned short dst_sin_port = ntohs(dst->sin_port);
+ long p;
+ char *cmdp;
+ struct hostent *hp;
+ struct in_addr self;
+
+
+ self.s_addr = inet_addr("127.0.0.1");
+ if ((dst->sin_addr.s_addr == self.s_addr) || (dst->sin_addr.s_addr == 0))
+ return(1);
+ if ((fd = fopen(socks_conf, "r")) == NULL)
+ return(1);
+
+ while (fgets(buf, sizeof(buf) - 1, fd) != NULL) {
+ linenum++;
+#ifdef TEST
+ strcpy(temp, buf);
+#endif
+ /*
+ ** Comments start with a '#' anywhere on the line
+ */
+ cmdp = (char *)0;
+ if ((bp = index(buf, '\n')) != NULL)
+ *bp = '\0';
+ for (bp = buf; *bp != '\0'; bp++) {
+ if (*bp == ':') {
+ *bp++ = '\0';
+ cmdp = bp;
+ break;
+ } else if (*bp == '#') {
+ *bp = '\0';
+ break;
+ } else if (*bp == '\t')
+ *bp = ' ';
+ }
+
+ mkargs(buf, &argc, argv, 7);
+ if (argc == 0)
+ continue;
+ if ((argc < 3) || (argc > 7)) {
+#ifdef TEST
+ printf("Invalid entry at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid entry at line %d", linenum);
+#endif
+ continue;
+ }
+
+ next_arg = 1;
+ if (STREQ(argv[0], "sockd")) {
+ socks_serverlist = socks_def_server;
+ direct = 0;
+ if (strncmp(argv[next_arg], "@=", 2) == 0) {
+ socks_serverlist = argv[next_arg] + 2;
+ if(*socks_serverlist == '\0')
+/*
+ socks_serverlist = (char *)0;
+*/
+ socks_serverlist = socks_def_server;
+ next_arg++;
+ }
+ } else if (strncmp(argv[0], "sockd@", 6) == 0) {
+ direct = 0;
+ socks_serverlist = argv[0] + 6;
+ if (*socks_serverlist == '\0')
+/*
+ socks_serverlist = (char *)0;
+*/
+ socks_serverlist = socks_def_server;
+ } else if (STREQ(argv[0], "direct")) {
+ direct = 1;
+ } else if (STREQ(argv[0], "deny")) {
+ direct = -1;
+ } else {
+#ifdef TEST
+ printf("Invalid sockd/direct/deny field at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid sockd/direct/deny field at line %d", linenum);
+#endif
+ continue;
+ }
+
+ userlist = (char *)0;
+ if (strncmp(argv[next_arg], "*=", 2) == 0) {
+ if (argv[next_arg][2]) userlist = argv[next_arg] + 2;
+ next_arg++;
+ }
+ if(argc <= next_arg+1) {
+#ifdef TEST
+ printf("Invalid entry at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid entry at line %d", linenum);
+#endif
+ continue;
+ }
+ GetAddr(argv[next_arg++], &daddr);
+ GetAddr(argv[next_arg++], &dmask);
+ if (argc > next_arg + 1) {
+ if (STREQ(argv[next_arg], "eq"))
+ tst = e_eq;
+ else if (STREQ(argv[next_arg], "neq"))
+ tst = e_neq;
+ else if (STREQ(argv[next_arg], "lt"))
+ tst = e_lt;
+ else if (STREQ(argv[next_arg], "gt"))
+ tst = e_gt;
+ else if (STREQ(argv[next_arg], "le"))
+ tst = e_le;
+ else if (STREQ(argv[next_arg], "ge"))
+ tst = e_ge;
+ else {
+#ifdef TEST
+ printf("Invalid comparison at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid comparison at line %d", linenum);
+#endif
+ continue;
+ }
+
+ if (((p = GetPort(argv[next_arg+1])) < 0) ||
+ (p >= (1L << 16))) {
+#ifdef TEST
+ printf("Invalid port number at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid port number at line %d", linenum);
+#endif
+ continue;
+ } else {
+ dport = p;
+ }
+ } else {
+ tst = e_nil;
+ dport = 0;
+ }
+
+#ifdef DEBUG
+ {
+ char msg[1024];
+ if (userlist)
+ sprintf(msg,"%s %s 0x%08x 0x%08x %s %u",
+ argv[0], userlist, daddr, dmask,
+ tst == e_eq ? "==" :
+ tst == e_neq ? "!=" :
+ tst == e_lt ? "<" :
+ tst == e_gt ? ">" :
+ tst == e_le ? "<=" :
+ tst == e_ge ? ">=" : "NIL",
+ dport);
+ else
+ sprintf(msg,"%s 0x%08x 0x%08x %s %u",
+ argv[0], daddr, dmask,
+ tst == e_eq ? "==" :
+ tst == e_neq ? "!=" :
+ tst == e_lt ? "<" :
+ tst == e_gt ? ">" :
+ tst == e_le ? "<=" :
+ tst == e_ge ? ">=" : "NIL",
+ dport);
+ syslog(LOG_LOW, "%s", msg);
+ }
+#endif
+ /* comparisons of port numbers must be done in host order */
+
+#ifdef OLD_CONF_MASK
+ if((daddr & ~dmask) == (dst->sin_addr.s_addr & ~dmask) &&
+#else
+ if((daddr & dmask) == (dst->sin_addr.s_addr & dmask) &&
+#endif
+ check_user(userlist, socks_src_user)) {
+ if (tst == e_nil)
+ goto GotIt;
+ if ((tst == e_eq) && (dst_sin_port == dport))
+ goto GotIt;
+ if ((tst == e_neq) && (dst_sin_port != dport))
+ goto GotIt;
+ if ((tst == e_lt) && (dst_sin_port < dport))
+ goto GotIt;
+ if ((tst == e_gt) && (dst_sin_port > dport))
+ goto GotIt;
+ if ((tst == e_le) && (dst_sin_port <= dport))
+ goto GotIt;
+ if ((tst == e_ge) && (dst_sin_port >= dport))
+ goto GotIt;
+ }
+ }
+
+ fclose(fd);
+#ifdef TEST
+ printf("*** No match with any line. Access denied.\n");
+#endif
+ return -1;
+
+GotIt:
+#ifdef TEST
+ printf("Line %d: %s", linenum, temp);
+#endif
+ fclose(fd);
+ if (cmdp != (char *)0)
+ shell_cmd(cmdp, src, dst);
+ return direct;
+
+}
+
diff --git a/network/socks/socks.cstc.4.2/lib/check_user.c b/network/socks/socks.cstc.4.2/lib/check_user.c
new file mode 100644
index 00000000..c64a189d
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/check_user.c
@@ -0,0 +1,175 @@
+#include "socks.h"
+
+#include <netdb.h>
+/* >>> K. Shackelford */
+#if defined(hpux) || defined(AIX)
+#include <sys/types.h>
+#include <netinet/in.h>
+#endif
+/* <<< K. Shackelford */
+#include <stdio.h>
+#include <ctype.h>
+/* >>> YDL, 93/10/26 */
+#if (defined(sun) && !defined(SOLARIS)) || defined(sgi)
+#include <strings.h>
+#else
+#include <string.h>
+#endif
+
+#ifdef SOLARIS
+#include "bstring.h"
+#endif
+
+/* <<< YDL< 93/10/26 */
+extern char *porttoserv();
+extern char *saddrtoname();
+
+/*
+ * These functions are used by both Validate (for sockd)
+ * and check_cconf (for clients).
+ */
+
+/*
+** Simple 'mkargs' doesn't handle \, ", or '.
+*/
+void mkargs(cp, argc, argv, max)
+char *cp;
+int *argc;
+char *argv[];
+int max;
+{
+ *argc = 0;
+ while (isspace(*cp))
+ cp++;
+
+ while (*cp != '\0') {
+ argv[(*argc)++] = cp;
+ if (*argc >= max)
+ return;
+
+ while (!isspace(*cp) && (*cp != '\0'))
+ cp++;
+ while (isspace(*cp))
+ *cp++ = '\0';
+ }
+}
+
+/*
+** Get address, either numeric or dotted quad, or hex.
+ * Result is in network byte order.
+*/
+int GetAddr(name, addr)
+char *name;
+u_int32 *addr;
+{
+ struct hostent *hp;
+ struct netent *np;
+
+ if ((hp = gethostbyname(name)) != NULL) {
+ bcopy(hp->h_addr_list[0], addr, sizeof(*addr));
+ return *addr;
+ }
+ if ((np = getnetbyname(name)) != NULL) {
+ bcopy(&np->n_net, addr, sizeof(*addr));
+ return *addr;
+ }
+ return *addr = inet_addr(name);
+}
+
+long GetPort(name)
+char *name;
+/* result is in HOST byte order */
+{
+ struct servent *sp;
+
+ if ((sp = getservbyname(name, "tcp")) != NULL) {
+ return ntohs(sp->s_port);
+ }
+ if (!isdigit(*name))
+ return -1;
+ return atol(name);
+}
+
+
+int check_user(userlist, src_user)
+
+char *userlist, *src_user;
+
+/*
+ * Unless userlist is a null pointer, in which case all users are
+ * allowed (return 1), otherwise
+ * userlist is a nonempty string containing userids separated by
+ * commas, no other separators are allowed in the string.
+ * 94/03/02: if userlist starts with '/', it specifies a file
+ * containing userids.
+ *
+ * Return 1 if src_user is in the userlist;
+ * return 0 if not, or if userfile cannot be open.
+ */
+{
+ char *p, *q;
+
+ if (!(p = userlist)) {
+ return 1;
+ }
+ do {
+ if (q = index(p, ','))
+ *q++ = '\0';
+ if (*p == '/') {
+ switch (check_userfile(p, src_user)) {
+ case 1:
+ return 1;
+ case -1:
+ return 0;
+ default:
+ ;
+ }
+ } else if (strcmp(p, src_user) == 0) {
+ return 1;
+ }
+ } while ( p = q);
+
+ return 0;
+}
+
+#include <string.h>
+#include <syslog.h>
+
+int check_userfile(userfile, src_user)
+char *userfile, *src_user;
+/* return 1 if match, 0 otherwise */
+/* return -1 if cannot open file */
+{
+ FILE *fd;
+#define BUFLEN 1024
+ static char buf[BUFLEN];
+ char *bp;
+
+ if ((fd = fopen(userfile, "r")) == NULL) {
+/*
+#ifdef MONITOR
+ sendto(mon_sd, &mon_msg, socks_type1_len, 0, mon_un_addr, mon_un_len);
+ failure_mon(MON_ERR_NO_USERFILE);
+#endif
+*/
+ syslog(LOG_HIGH,"Unable to open userfile (%s)\n", userfile);
+ return (-1);
+ }
+
+ while (fgets(buf, BUFLEN, fd) != NULL) {
+ if ((bp = index(buf, '\n')) != NULL)
+ *bp = '\0';
+ if (( bp = index(buf, '#')) != NULL)
+ *bp = '\0';
+
+ for (bp = strtok(buf, " ,\t"); bp != NULL;
+ bp = strtok(NULL, " ,\t")) {
+ if (strcmp(bp, src_user) == 0) {
+ fclose(fd);
+ return 1;
+ }
+ }
+ }
+ fclose(fd);
+ return 0;
+}
diff --git a/network/socks/socks.cstc.4.2/lib/getpass.c b/network/socks/socks.cstc.4.2/lib/getpass.c
new file mode 100644
index 00000000..61c8efde
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/getpass.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getpass.c based on 5.3 (Berkeley) 9/22/88";
+#endif /* LIBC_SCCS and not lint */
+
+#if defined(__NetBSD__)
+#define USE_OLD_TTY
+#endif
+
+/* >>> Craig Metz */
+#if defined(LINUX)
+#define SVR3
+#endif
+/* <<< Craig Metz */
+
+#if defined(SOLARIS) || defined(hpux)
+#include <signal.h>
+#include <sgtty.h>
+#include <sys/ioctl.h>
+#else
+#ifdef SVR3
+#include <termio.h>
+#else
+#include <sys/ioctl.h>
+#endif
+#include <sys/signal.h>
+#endif
+#include <stdio.h>
+
+char *
+getpass(prompt)
+ char *prompt;
+{
+#ifdef SVR3
+ struct termio term_struct;
+ tcflag_t svflagval;
+#else
+ struct sgttyb ttyb;
+ int svflagval;
+#endif
+ register int ch;
+ register char *p;
+ FILE *fp, *outfp;
+#ifdef SOLARIS
+ sigset_t maskset;
+#else
+ long omask;
+#endif
+#define PASSWD_LEN 128
+ static char buf[PASSWD_LEN + 1];
+
+ /*
+ * read and write to /dev/tty if possible; else read from
+ * stdin and write to stderr.
+ */
+ if ((outfp = fp = fopen("/dev/tty", "w+")) == NULL) {
+ outfp = stderr;
+ fp = stdin;
+ }
+#ifdef SVR3
+ (void)ioctl(fileno(fp), TCGETA, &term_struct);
+ svflagval = term_struct.c_lflag;
+ term_struct.c_lflag &= ~ECHO;
+#else
+ (void)ioctl(fileno(fp), TIOCGETP, &ttyb);
+ svflagval = ttyb.sg_flags;
+ ttyb.sg_flags &= ~ECHO;
+#endif
+
+#ifdef SOLARIS
+ if (sigprocmask(0, (sigset_t *)0, &maskset) || sighold(SIGINT)) {
+ perror("Can't block SIGINT in getpass() ");
+ exit(1);
+ }
+#else
+ omask = sigblock(sigmask(SIGINT));
+#endif
+
+#ifdef SVR3
+ (void)ioctl(fileno(fp), TCSETA, &term_struct);
+#else
+ (void)ioctl(fileno(fp), TIOCSETP, &ttyb);
+#endif
+
+ fputs(prompt, outfp);
+ rewind(outfp); /* implied flush */
+ for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
+ if (p < buf + PASSWD_LEN)
+ *p++ = ch;
+ *p = '\0';
+ (void)write(fileno(outfp), "\n", 1);
+#ifdef SVR3
+ term_struct.c_lflag = svflagval;
+ (void)ioctl(fileno(fp), TCSETA, &term_struct);
+#else
+ ttyb.sg_flags = svflagval;
+ (void)ioctl(fileno(fp), TIOCSETP, &ttyb);
+#endif
+
+#ifdef SOLARIS
+ if (sigprocmask(SIG_SETMASK, &maskset, (sigset_t *)0)) {
+ perror("Can't restore signal mask in getpass() ");
+ exit(1);
+ }
+#else
+ (void)sigsetmask(omask);
+#endif
+ if (fp != stdin)
+ (void)fclose(fp);
+ return(buf);
+}
+
diff --git a/network/socks/socks.cstc.4.2/lib/percent_x.c b/network/socks/socks.cstc.4.2/lib/percent_x.c
new file mode 100644
index 00000000..db5d8760
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/percent_x.c
@@ -0,0 +1,110 @@
+ /*
+ * percent_x() takes a string and performs %x subsitutions.
+ * It aborts the program when the result of
+ * expansion would overflow the output buffer. Because the result of %<char>
+ * expansion is typically passed on to a shell process, characters that may
+ * confuse the shell are replaced by underscores.
+ *
+ * Diagnostics are reported through syslog(3).
+ *
+ * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * Adapted for use with SOCKS by Ying-Da Lee, NEC Systems Lab, CSTC
+ * ylee@syl.dl.nec.com
+ *
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#) percent_x.c 1.2 92/08/24 21:46:22";
+#endif
+
+/* System libraries. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <syslog.h>
+#include "socks.h"
+
+extern char *strncpy();
+extern char *strchr();
+extern void exit();
+
+extern char socks_src_name[], socks_src_user[];
+extern char socks_real_user[];
+extern char socks_dst_name[], socks_dst_serv[];
+extern char socks_cmd[];
+
+/* percent_x - do %<char> expansion, abort if result buffer is too small */
+
+void percent_x(result, result_len, str, src, dst, pid)
+char *result;
+int result_len;
+char *str;
+struct sockaddr_in *src, *dst;
+int pid;
+{
+ char *end = result + result_len - 1; /* end of result buffer */
+ char *expansion;
+ int expansion_len;
+ char pid_buf[10];
+ char port_buf[10];
+ static char ok_chars[] = "1234567890!@%-_=+\\:,./\
+abcdefghijklmnopqrstuvwxyz\
+ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ char *cp;
+
+ /*
+ * %A: the client domainname if known, IP address otherwise
+ * %a: the client IP address
+ * %c: "connect" or "bind"
+ * %p: the daemon or client program process id
+ * %S: the service name (ftp, telnet,etc.) if known, port number otherwise
+ * %s: the destination port number
+ * %U: for sockd, this is the username as reported by identd;
+ * for client program, this is the name used at login
+ * %u: for sockd, this is the username as reported by the client program;
+ * for client program, this is the username of the effective userid
+ * %Z: the destination domainname if known, IP address otherwise
+ * %z: the destination IP address
+ *
+ * %% becomes a %, and %other is ignored. We terminate with a diagnostic if
+ * we would overflow the result buffer. Characters that may confuse the
+ * shell are mapped to underscores.
+ */
+
+ while (*str) {
+ if (*str == '%') {
+ str++;
+ expansion =
+ *str == 'A' ? (str++, socks_src_name) :
+ *str == 'a' ? (str++, inet_ntoa(src->sin_addr)) :
+ *str == 'c' ? (str++, socks_cmd) :
+ *str == 'p' ? (str++, sprintf(pid_buf, "%d", pid), pid_buf) :
+ *str == 'S' ? (str++, socks_dst_serv) :
+ *str == 's' ? (str++, sprintf(port_buf, "%u", ntohs(dst->sin_port)), port_buf) :
+ *str == 'U' ? (str++, socks_real_user) :
+ *str == 'u' ? (str++, socks_src_user) :
+ *str == 'Z' ? (str++, socks_dst_name) :
+ *str == 'z' ? (str++, inet_ntoa(dst->sin_addr)) :
+ *str == '%' ? (str++, "%") :
+ *str == 0 ? "" : (str++, "");
+ expansion_len = strlen(expansion);
+ for (cp = expansion; *cp; cp++)
+ if (strchr(ok_chars, *cp) == 0)
+ *cp = '_';
+ } else {
+ expansion = str++;
+ expansion_len = 1;
+ }
+ if (result + expansion_len >= end) {
+ syslog(LOG_HIGH, "shell command too long: %30s...", result);
+ exit(0);
+ }
+ strncpy(result, expansion, expansion_len);
+ result += expansion_len;
+ }
+ *result = 0;
+}
diff --git a/network/socks/socks.cstc.4.2/lib/porttoserv.c b/network/socks/socks.cstc.4.2/lib/porttoserv.c
new file mode 100644
index 00000000..2da25bda
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/porttoserv.c
@@ -0,0 +1,20 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+char *porttoserv(sin_port, name, namelen)
+int sin_port; /* port number in network byte order */
+char *name;
+int namelen;
+{
+ struct servent *serv;
+ int port = ntohs(sin_port);
+
+ if ((serv = getservbyport(port, "tcp")) != (struct servent *)0)
+ strncpy(name, serv->s_name, namelen);
+ else
+ sprintf(name, "%u", port);
+ return(name);
+}
+
diff --git a/network/socks/socks.cstc.4.2/lib/saddrtoname.c b/network/socks/socks.cstc.4.2/lib/saddrtoname.c
new file mode 100644
index 00000000..aee0f56f
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/saddrtoname.c
@@ -0,0 +1,19 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+char *saddrtoname(addr, name, namelen)
+struct in_addr *addr;
+char *name;
+int namelen;
+{
+ struct hostent *host;
+
+ if ((host = gethostbyaddr((char *)addr, 4, AF_INET)) != (struct hostent *)0)
+ strncpy(name, host->h_name, namelen);
+ else
+ strncpy(name, inet_ntoa(*addr), namelen);
+ return(name);
+}
+
diff --git a/network/socks/socks.cstc.4.2/lib/shell_cmd.c b/network/socks/socks.cstc.4.2/lib/shell_cmd.c
new file mode 100644
index 00000000..579ca878
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/lib/shell_cmd.c
@@ -0,0 +1,112 @@
+ /*
+ * shell_cmd() takes a shell command template and performs %x substitutions.
+ * The result is executed
+ * by a /bin/sh child process, with standard input, standard output and
+ * standard error connected to /dev/null.
+ *
+ * Diagnostics are reported through syslog(3).
+ *
+ * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ *
+ * Adapted for use with SOCKS by Ying-Da Lee, NEC Systems Lab, CSTC
+ * ylee@syl.dl.nec.com
+ *
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#) shell_cmd.c 1.2 92/06/11 22:21:28";
+#endif
+
+/* System libraries. */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <syslog.h>
+#include "socks.h"
+
+extern char *strncpy();
+extern void closelog();
+extern void exit();
+
+/* Forward declarations. */
+
+static void do_child();
+
+/* shell_cmd - expand %<char> sequences and execute shell command */
+
+void shell_cmd(string, src, dst)
+char *string;
+struct sockaddr_in *src, *dst;
+{
+ char cmd[BUFSIZ];
+ static char alpha_num[] = "abcdefghijklmnopqrstuvwxyz\
+ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ int child_pid;
+ int wait_pid;
+ int daemon_pid = getpid();
+
+ percent_x(cmd, sizeof(cmd), string, src, dst, daemon_pid);
+ if (strpbrk(cmd, alpha_num) == NULL) {
+ syslog(LOG_HIGH, "error -- shell command \"%s\" contains no alphanumeric characters.", cmd);
+ return;
+ }
+
+ /*
+ * Most of the work is done within the child process, to minimize the
+ * risk of damage to the parent.
+ */
+
+ switch (child_pid = fork()) {
+ case -1: /* error */
+ syslog(LOG_HIGH, "error -- shell_cmd fork() %m");
+ break;
+ case 00: /* child */
+ do_child(daemon_pid, cmd);
+ /* NOTREACHED */
+ default: /* parent */
+ while ((wait_pid = wait((int *) 0)) != -1 && wait_pid != child_pid)
+ /* void */ ;
+ }
+}
+
+/* do_child - exec command with { stdin, stdout, stderr } to /dev/null */
+
+static void do_child(daemon_pid, command)
+int daemon_pid;
+char *command;
+{
+ char *error = 0;
+ int tmp_fd;
+
+ /*
+ * Close a bunch of file descriptors. The Ultrix inetd only passes stdin,
+ * but other inetd implementations set up stdout as well. Ignore errors.
+ */
+
+ closelog();
+ for (tmp_fd = 0; tmp_fd < 10; tmp_fd++)
+ (void) close(tmp_fd);
+
+ /* Set up new stdin, stdout, stderr, and exec the shell command. */
+
+ if (open("/dev/null", 2) != 0) {
+ error = "open /dev/null: %m";
+ } else if (dup(0) != 1 || dup(0) != 2) {
+ error = "dup: %m";
+ } else {
+ (void) execl("/bin/sh", "sh", "-c", command, (char *) 0);
+ error = "execl /bin/sh: %m";
+ }
+
+ /* We can reach the following code only if there was an error. */
+
+#ifdef LOG_DAEMON
+ (void) openlog("sockd", LOG_PID, SYSLOG_FAC);
+#else
+ (void) openlog("sockd", LOG_PID);
+#endif
+ syslog(LOG_HIGH, "Cannot execute shell command for pid %d", daemon_pid);
+ exit(0);
+}
diff --git a/network/socks/socks.cstc.4.2/libident/Makefile b/network/socks/socks.cstc.4.2/libident/Makefile
new file mode 100644
index 00000000..7b0c6e89
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/Makefile
@@ -0,0 +1,93 @@
+#
+# Makefile for the libident library
+
+# Remember to include -Dindex=strchr in OTHER_CFLAGS if
+# you don't have index() (Sys-V camp)
+
+# IRIX should have CCKR defined:
+#OTHER_CFLAGS=-cckr
+#RANLIB=/bin/true
+
+# AIX should use
+#OTHER_CFLAGS=-D_BSD -D_NONSTD_TYPES -D_NO_PROTO -DAIX
+#RANLIB=ranlib
+
+# Solaris should use
+#OTHER_CFLAGS=-DSOLARIS -Dindex=strchr -Drindex=strrchr -DUSE_DIRENT
+#RANLIB=/bin/true
+
+# Interactive Systems Unix should use
+# OTHER_CFLAGS = -DISC
+
+# LINUX should use
+#CC=gcc
+#RESOLV_LIB=
+#OTHER_CFLAGS=-traditional -DLINUX
+
+# UnixWare should use
+#RESOLV_LIB=-lresolv -lnsl -lsocket
+#OTHER_CFLAGS= -DSOLARIS -Dindex=strchr -Drindex=strrchr -DUSE_DIRENT
+#RANLIB=/bin/true
+#INSTALL=bsdinstall
+
+# >>>---------------- Others:
+
+# This is slightly tuned for a 4BSD system (like SunOS 4).
+# For systems that do not need (and therefore don't have) 'ranlib',
+# comment out the next line and use the line below.
+RANLIB=ranlib
+#RANLIB=/bin/true
+
+# <<<----------------
+
+# Set LIBDIR, INCDIR, and MANDIR to the direcories into which
+# the library (libident.a), the include file (ident.h), and
+# the man pages should be installed, respectively.
+# Comment out the correponding lines for the items you don't
+# want installed.
+# This is where you want to install the library
+LIBDIR=/usr/local/lib
+# And this is where the header file ident.h goes
+INCDIR=/usr/local/include
+# And the manual page
+MANDIR=/usr/local/man/man3
+
+OPTIMIZE=-g
+CFLAGS = ${OPTIMIZE} $(OTHER_CFLAGS)
+
+# The 'install' command is assumed to be the BSD variety (using -m to
+# set the file mode). If the default 'install' on your system doesn't
+# do that, you have to either specify an alternative one in the line below
+# (e.g., /usr/ucb/install) or modify the install instructions.
+INSTALL= install
+
+#=============================================================
+OBJS = ident.o id_open.o id_close.o id_query.o id_parse.o
+
+libident.a: echocwd $(OBJS)
+ -rm -f libident.a
+ ar cq libident.a $(OBJS)
+ $(RANLIB) libident.a
+
+ident.o: ident.c ident.h
+id_open.o: id_open.c ident.h
+id_close.o: id_close.c ident.h
+id_query.o: id_query.c ident.h
+id_parse.o: id_parse.c ident.h
+
+install: echocwd
+ -if [ -d $(LIBDIR) ]; then \
+ ($(INSTALL) -m 644 libident.a $(LIBDIR); \
+ $(RANLIB) -t $(LIBDIR)/libident.a); fi
+ -if [ -d $(INCDIR) ]; then \
+ $(INSTALL) -m 644 ident.h $(INCDIR); fi
+
+install.man: echocwd
+ -if [ -d $(MANDIR) ]; then \
+ $(INSTALL) -m 644 ident.3 $(MANDIR); fi
+
+clean: echocwd
+ -rm -f libident.a *~ core *.o \#*
+
+echocwd:
+ @pwd
diff --git a/network/socks/socks.cstc.4.2/libident/README b/network/socks/socks.cstc.4.2/libident/README
new file mode 100644
index 00000000..3fbfeb3b
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/README
@@ -0,0 +1,16 @@
+This is the second stab at a small library to interface to the Ident
+protocol server. Maybe this will work correctly on some machines.. :-)
+
+The ident-tester.c file is a small daemon (to be started from Inetd)
+that does an ident lookup on you if you telnet into it. Can be used
+to verify that your Ident server is working correctly.
+
+I'm currently running this "ident-tester" on port 114 at lysator.liu.se
+if you wish to test your server.
+
+/Peter Eriksson <pen@lysator.liu.se>, 1 Aug 1992
+
+This library now contains some higher-level routines, as well as a
+similar test program to test these (lookup-tester).
+
+/Pär Emanuelsson <pell@lysator.liu.se>, 4 April 1993
diff --git a/network/socks/socks.cstc.4.2/libident/id_close.c b/network/socks/socks.cstc.4.2/libident/id_close.c
new file mode 100644
index 00000000..7f5a1b89
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/id_close.c
@@ -0,0 +1,25 @@
+/*
+** id_close.c Close a connection to an IDENT server
+**
+** Author: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#include "ident.h"
+
+int id_close
+#ifdef __STDC__
+ (ident_t *id)
+#else
+ (id)
+ident_t *id;
+#endif
+{
+ int res;
+
+ res = close(id->fd);
+ free(id);
+
+ return res;
+}
+
+
diff --git a/network/socks/socks.cstc.4.2/libident/id_open.c b/network/socks/socks.cstc.4.2/libident/id_open.c
new file mode 100644
index 00000000..dabf3e70
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/id_open.c
@@ -0,0 +1,162 @@
+/*
+** id_open.c Establish/initiate a connection to an IDENT server
+**
+** Author: Peter Eriksson <pen@lysator.liu.se>
+** Fixes: Pdr Emanuelsson <pell@lysator.liu.se>
+*/
+
+
+#include <stdio.h>
+#include <errno.h>
+#include <memory.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/* SOLARIS */
+#if defined(__svr4__) || defined (SOLARIS) || defined(SCO)
+#include <fcntl.h>
+#endif
+
+/* LINUX */
+#ifdef LINUX
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#ifdef FNDLEAY /*watch out for a ?typo? in fcntl.h !? */
+#define FNDELAY FNDLEAY
+#endif
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+ int l_onoff; /* option on/off */
+ int l_linger; /* linger time */
+};
+#endif
+
+
+#include "ident.h"
+
+extern void *malloc __P((int size));
+
+
+ident_t *id_open
+#ifdef __STDC__
+ (struct in_addr *laddr, struct in_addr *faddr, struct timeval *timeout)
+#else
+ (laddr, faddr, timeout)
+struct in_addr *laddr;
+struct in_addr *faddr;
+struct timeval *timeout;
+#endif
+{
+ ident_t *id;
+ int res, tmperrno;
+ struct sockaddr_in sin_laddr, sin_faddr;
+ fd_set rs, ws, es;
+#if !defined(SO_DONTLINGER) || defined(SOLARIS)
+ struct linger linger;
+#endif
+
+#if defined(sgi) || defined (SOLARIS)
+ int on = 1;
+#endif
+
+ if ((id = (ident_t *) malloc(sizeof(*id))) == 0)
+ return 0;
+
+ if ((id->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ free(id);
+ return 0;
+ }
+
+ if (timeout)
+ {
+ if ((res = fcntl(id->fd, F_GETFL, 0)) < 0)
+ goto ERROR;
+
+ if (fcntl(id->fd, F_SETFL, res | FNDELAY) < 0)
+ goto ERROR;
+ }
+
+#if defined(SO_DONTLINGER) && !defined(SOLARIS)
+ if (setsockopt(id->fd, SOL_SOCKET, SO_DONTLINGER, 0, 0) < 0)
+ goto ERROR;
+#else
+ linger.l_onoff = 0;
+ linger.l_linger = 0;
+
+ if (setsockopt(id->fd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) < 0)
+ goto ERROR;
+#endif
+
+#if defined(sgi) || defined(SOLARIS)
+ if (setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on,
+ sizeof(on)) < 0)
+#else
+ if (setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
+#endif
+ goto ERROR;
+
+ id->buf[0] = '\0';
+
+ memset(&sin_laddr, 0, sizeof(sin_laddr));
+ sin_laddr.sin_family = AF_INET;
+ sin_laddr.sin_addr = *laddr;
+ sin_laddr.sin_port = 0;
+
+ if (bind(id->fd, (struct sockaddr *)&sin_laddr, sizeof(sin_laddr)) < 0)
+ goto ERROR;
+
+ memset(&sin_faddr, 0, sizeof(sin_faddr));
+ sin_faddr.sin_family = AF_INET;
+ sin_faddr.sin_addr = *faddr;
+ sin_faddr.sin_port = htons(IDPORT);
+
+ res = connect(id->fd, (struct sockaddr *)&sin_faddr, sizeof(sin_faddr));
+ if (res < 0 && errno != EINPROGRESS)
+ goto ERROR;
+
+ if (timeout)
+ {
+ FD_ZERO(&rs);
+ FD_ZERO(&ws);
+ FD_ZERO(&es);
+ FD_SET(id->fd, &rs);
+ FD_SET(id->fd, &ws);
+ FD_SET(id->fd, &es);
+
+ if ((res = select(FD_SETSIZE, &rs, &ws, &es, timeout)) < 0)
+ goto ERROR;
+
+ if (res == 0)
+ {
+ errno = ETIMEDOUT;
+ goto ERROR;
+ }
+
+ if (FD_ISSET(id->fd, &es))
+ goto ERROR;
+
+ if (!FD_ISSET(id->fd, &rs) && !FD_ISSET(id->fd, &ws))
+ goto ERROR;
+ }
+
+ return id;
+
+ERROR:
+ tmperrno = errno; /* Save, so close() won't erase it */
+ close(id->fd);
+ free(id);
+ errno = tmperrno;
+ return 0;
+}
+
diff --git a/network/socks/socks.cstc.4.2/libident/id_parse.c b/network/socks/socks.cstc.4.2/libident/id_parse.c
new file mode 100644
index 00000000..877ad7b3
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/id_parse.c
@@ -0,0 +1,236 @@
+/*
+** id_parse.c Receive and parse a reply from an IDENT server
+**
+** Author: Peter Eriksson <pen@lysator.liu.se>
+** Fiddling: Pär Emanuelsson <pell@lysator.liu.se>
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+
+#include "ident.h"
+
+/* >>> Ian Dunkin */
+#if defined(ultrix) || defined(AIX_PS2)
+char *strdup(s)
+char *s;
+{
+ char *malloc();
+ static char *p;
+
+ if ((p = malloc(strlen(s) + 1)) != NULL)
+ strcpy(p, s);
+ return(p);
+}
+#endif
+/* <<< Ian Dunkin */
+
+static char *xstrtok
+#ifdef __STDC__
+ (char *cp, char *cs, char *dc)
+#else
+ (cp, cs, dc)
+char *cp;
+char *cs;
+char *dc;
+#endif
+{
+ static char *bp = 0;
+
+ if (cp)
+ bp = cp;
+
+ /*
+ ** No delimitor cs - return whole buffer and point at end
+ */
+ if (!cs)
+ {
+ while (*bp)
+ bp++;
+ return cs;
+ }
+
+ /*
+ ** Skip leading spaces
+ */
+ while (isspace(*bp))
+ bp++;
+
+ /*
+ ** No token found?
+ */
+ if (!*bp)
+ return 0;
+
+ cp = bp;
+ while (*bp && !index(cs, *bp))
+ bp++;
+
+ /*
+ ** Remove trailing spaces
+ */
+ *dc = *bp;
+ for (dc = bp-1; dc > cp && isspace(*dc); dc--)
+ ;
+ *++dc = '\0';
+
+ bp++;
+
+ return cp;
+}
+
+
+int id_parse
+#ifdef __STDC__
+ (ident_t *id,
+ struct timeval *timeout,
+ int *lport,
+ int *fport,
+ char **identifier,
+ char **opsys,
+ char **charset)
+#else
+ (id, timeout, lport, fport, identifier, opsys, charset)
+ident_t *id;
+struct timeval *timeout;
+int *lport;
+int *fport;
+char **identifier;
+char **opsys;
+char **charset;
+#endif
+{
+ char c, *cp, *tmp_charset;
+ fd_set rs;
+ int pos, res, lp, fp;
+
+ errno = 0;
+
+ tmp_charset = 0;
+
+ if (!id) return -1;
+ if (lport) *lport = 0;
+ if (fport) *fport = 0;
+ if (identifier) *identifier = 0;
+ if (opsys) *opsys = 0;
+ if (charset) *charset = 0;
+
+ pos = strlen(id->buf);
+
+ if (timeout)
+ {
+ FD_ZERO(&rs);
+ FD_SET(id->fd, &rs);
+
+ if ((res = select(FD_SETSIZE, &rs, (fd_set *)0, (fd_set *)0, timeout)) < 0)
+ return -1;
+
+ if (res == 0)
+ {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ }
+
+ while (pos < sizeof(id->buf) &&
+ (res = read(id->fd, id->buf + pos, 1)) == 1 &&
+ id->buf[pos] != '\n')
+ pos++;
+
+ if (res < 0)
+ return -1;
+
+ if (res == 0)
+ {
+ errno = ENOTCONN;
+ return -1;
+ }
+
+ if (id->buf[pos] != '\n')
+ return 0;
+
+ id->buf[pos++] = '\0';
+
+ /*
+ ** Get first field (<lport> , <fport>)
+ */
+ cp = xstrtok(id->buf, ":", &c);
+ if (!cp)
+ return -2;
+
+ if (sscanf(cp, " %d , %d", &lp, &fp) != 2)
+ {
+ if (identifier) *identifier = strdup(cp);
+ return -2;
+ }
+
+ if (lport) *lport = lp;
+ if (fport) *fport = fp;
+
+ /*
+ ** Get second field (USERID or ERROR)
+ */
+ cp = xstrtok((char *)0, ":", &c);
+ if (!cp)
+ return -2;
+
+ if (strcmp(cp, "ERROR") == 0)
+ {
+ cp = xstrtok((char *)0, "\n\r", &c);
+ if (!cp)
+ return -2;
+
+ if (identifier) *identifier = strdup(cp);
+
+ return 2;
+ }
+ else if (strcmp(cp, "USERID") == 0)
+ {
+ /*
+ ** Get first subfield of third field <opsys>
+ */
+ cp = xstrtok((char *)0, ",:", &c);
+ if (!cp)
+ return -2;
+
+ if (opsys) *opsys = strdup(cp);
+
+ /*
+ ** We have a second subfield (<charset>)
+ */
+ if (c == ',')
+ {
+ cp = xstrtok((char *)0, ":", &c);
+ if (!cp)
+ return -2;
+
+ tmp_charset = cp;
+ if (charset) *charset = strdup(cp);
+
+ /*
+ ** We have even more subfields - ignore them
+ */
+ if (c == ',')
+ xstrtok((char *)0, ":", &c);
+ }
+
+ if (tmp_charset && strcmp(tmp_charset, "OCTET") == 0)
+ cp = xstrtok((char *)0, (char *)0, &c);
+ else
+ cp = xstrtok((char *)0, "\n\r", &c);
+
+ if (identifier) *identifier = strdup(cp);
+ return 1;
+ }
+ else
+ {
+ if (identifier) *identifier = strdup(cp);
+ return -3;
+ }
+}
diff --git a/network/socks/socks.cstc.4.2/libident/id_query.c b/network/socks/socks.cstc.4.2/libident/id_query.c
new file mode 100644
index 00000000..41b94cf0
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/id_query.c
@@ -0,0 +1,62 @@
+/*
+** id_query.c Transmit a query to an IDENT server
+**
+** Author: Peter Eriksson <pen@lysator.liu.se>
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+
+#include "ident.h"
+
+
+int id_query
+#ifdef __STDC__
+ (ident_t *id, int lport, int fport, struct timeval *timeout)
+#else
+ (id, lport, fport, timeout)
+ident_t *id;
+int lport;
+int fport;
+struct timeval *timeout;
+#endif
+{
+#if defined(SOLARIS) || defined(_SEQUENT_)
+ void (*old_sig)();
+#else
+ void *old_sig;
+#endif
+ int res;
+ char buf[80];
+ fd_set ws;
+
+ sprintf(buf, "%d , %d\r\n", lport, fport);
+
+ if (timeout)
+ {
+ FD_ZERO(&ws);
+ FD_SET(id->fd, &ws);
+
+ if ((res = select(FD_SETSIZE, (fd_set *)0, &ws, (fd_set *)0, timeout)) < 0)
+ return -1;
+
+ if (res == 0)
+ {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ }
+
+ old_sig = signal(SIGPIPE, SIG_IGN);
+
+ res = write(id->fd, buf, strlen(buf));
+
+ signal(SIGPIPE, old_sig);
+
+ return res;
+}
diff --git a/network/socks/socks.cstc.4.2/libident/ident-tester.c b/network/socks/socks.cstc.4.2/libident/ident-tester.c
new file mode 100644
index 00000000..052e27ff
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/ident-tester.c
@@ -0,0 +1,171 @@
+/*
+** ident-tester.c A small daemon that can be used to test Ident
+** servers
+**
+** Author: Peter Eriksson <pen@lysator.liu.se>, 10 Aug 1992
+*/
+
+#include <stdio.h>
+#include <netdb.h>
+#include <syslog.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "ident.h"
+
+/*
+** Return the name of the connecting host, or the IP number as a string.
+*/
+char *gethost(addr)
+ struct in_addr *addr;
+{
+ struct hostent *hp;
+
+
+ hp = gethostbyaddr(addr, sizeof(struct in_addr), AF_INET);
+ if (hp)
+ return hp->h_name;
+ else
+ return inet_ntoa(*addr);
+}
+
+
+main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ struct sockaddr_in laddr, faddr;
+ int len, res, lport, fport;
+ ident_t *id;
+ char *identifier, *opsys, *charset;
+
+
+ puts("Welcome to the IDENT server tester, version 1.7\r\n\r");
+ fflush(stdout);
+
+ len = sizeof(faddr);
+ getpeername(0, &faddr, &len);
+
+ len = sizeof(laddr);
+ getsockname(0, &laddr, &len);
+
+ printf("Connecting to Ident server at %s...\r\n", inet_ntoa(faddr.sin_addr));
+ fflush(stdout);
+
+#ifdef LOG_LOCAL3
+ openlog("tidentd", 0, LOG_LOCAL3);
+#else
+ openlog("tidentd", 0);
+#endif
+
+ id = id_open(&laddr.sin_addr, &faddr.sin_addr, NULL);
+ if (!id)
+ {
+ perror("id_open()");
+ fflush(stderr);
+ syslog(LOG_ERR, "Error: id_open(): host=%s, error=%m",
+ gethost(&faddr.sin_addr));
+ exit(1);
+ }
+
+ printf("Querying for lport %d, fport %d....\r\n",
+ (int) ntohs(faddr.sin_port),
+ (int) ntohs(laddr.sin_port));
+ fflush(stdout);
+
+ if (id_query(id, ntohs(faddr.sin_port), ntohs(laddr.sin_port), 0) < 0)
+ {
+ perror("id_query()");
+ fflush(stderr);
+ syslog(LOG_ERR, "Error: id_query(): host=%s, error=%m",
+ gethost(&faddr.sin_addr));
+ exit(1);
+ }
+
+ printf("Reading response data...\r\n");
+ fflush(stdout);
+
+ res = id_parse(id, NULL,
+ &lport, &fport,
+ &identifier,
+ &opsys,
+ &charset);
+
+ switch (res)
+ {
+ default:
+ perror("id_parse()");
+ syslog(LOG_ERR, "Error: id_parse(): host=%s, error=%m",
+ gethost(&faddr.sin_addr));
+ break;
+
+ case -2:
+ syslog(LOG_ERR, "Error: id_parse(): host=%s, Parse Error: %s",
+ gethost(&faddr.sin_addr),
+ identifier ? identifier : "<no information available>");
+
+ if (identifier)
+ printf("Parse error on reply:\n \"%s\"\n", identifier);
+ else
+ printf("Unidentifiable parse error on reply.\n");
+ break;
+
+ case -3:
+ syslog(LOG_ERR, "Error: id_parse(): host=%s, Illegal reply type: %s",
+ gethost(&faddr.sin_addr),
+ identifier);
+
+ printf("Parse error in reply: Illegal reply type: %s\n", identifier);
+ break;
+
+ case 0:
+ syslog(LOG_ERR, "Error: id_parse(): host=%s, NotReady",
+ gethost(&faddr.sin_addr));
+ puts("Not ready. This should not happen...\r");
+ break;
+
+ case 2:
+ syslog(LOG_INFO, "Reply: Error: host=%s, error=%s",
+ gethost(&faddr.sin_addr), identifier);
+
+ printf("Error response is:\r\n");
+ printf(" Lport........ %d\r\n", lport);
+ printf(" Fport........ %d\r\n", fport);
+ printf(" Error........ %s\r\n", identifier);
+ break;
+
+ case 1:
+ if (charset)
+ syslog(LOG_INFO,
+ "Reply: Userid: host=%s, opsys=%s, charset=%s, userid=%s",
+ gethost(&faddr.sin_addr), opsys, charset, identifier);
+ else
+ syslog(LOG_INFO, "Reply: Userid: host=%s, opsys=%s, userid=%s",
+ gethost(&faddr.sin_addr), opsys, identifier);
+
+ printf("Userid response is:\r\n");
+ printf(" Lport........ %d\r\n", lport);
+ printf(" Fport........ %d\r\n", fport);
+ printf(" Opsys........ %s\r\n", opsys);
+ printf(" Charset...... %s\r\n", charset ? charset : "<not specified>");
+ printf(" Identifier... %s\r\n", identifier);
+
+ if (id_query(id, ntohs(faddr.sin_port), ntohs(laddr.sin_port), 0) >= 0)
+ {
+ if (id_parse(id, NULL,
+ &lport, &fport,
+ &identifier,
+ &opsys,
+ &charset) == 1)
+ printf(" Multiquery... Enabled\r\n");
+ }
+ }
+
+ fflush(stdout);
+ sleep(1);
+ exit(0);
+}
+
diff --git a/network/socks/socks.cstc.4.2/libident/ident.3 b/network/socks/socks.cstc.4.2/libident/ident.3
new file mode 100644
index 00000000..8eb19658
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/ident.3
@@ -0,0 +1,276 @@
+.\" Pär Emanuelsson <pell@lysator.liu.se> 1993-03-28
+.ds : \h'\w'u'u/5'\z"\h'-\w'e'u/5'
+.TH IDENT 3N "4 April 1993" "Lysator ACS"
+.SH NAME
+ident_lookup, ident_id, ident_free, id_open, id_close, id_query, id_parse,
+id_fileno \- query remote IDENT server
+.SH SYNOPSIS
+.nf
+.B #include <ident.h>
+.LP
+.I High-level calls
+.LP
+.B IDENT *ident_lookup(int fd, int timeout)
+.LP
+.B char *ident_id(int fd, int timeout)
+.LP
+.B void ident_free(IDENT *id)
+.LP
+.I Low-level calls
+.LP
+.B id_t *id_open(laddr, faddr, timeout)
+.B struct in_addr *laddr, *faddr;
+.B struct timeval *timeout;
+.LP
+.B int id_close(id)
+.B id_t *id;
+.LP
+.B id_query(id, lport, fport, timeout)
+.B id_t *id;
+.B int lport, fport;
+.B struct timeval *timeout;
+.LP
+.B int id_parse(id, timeout, lport, fport, identifier,
+.B opsys, charset)
+.B id_t *id;
+.B struct timeval *timeout;
+.B int *lport, *fport;
+.B char **identifier, **opsys, **charset;
+.LP
+.B int id_fileno(id)
+.B id_t *id;
+.fi
+.SH DESCRIPTION
+.LP
+.B ident_lookup
+tries to connect to a remote
+.B IDENT
+server to establish the identity of the peer connected on
+.I fd,
+which should be a socket file descriptor.
+.I timeout
+is the longest permissible time to block waiting for an answer, and is
+given in seconds. A value of 0 (zero) means wait indefinitely (which in the
+most extreme case will normally be until the underlying network times out).
+.B ident_lookup
+returns a pointer to an
+.I IDENT
+struct, which has the following contents:
+.RS
+.LP
+.nf
+.ft B
+typedef struct {
+ int lport; /* Local port */
+ int fport; /* Far (remote) port */
+ char *identifier; /* Normally user name */
+ char *opsys; /* OS */
+ char *charset; /* Charset (what did you expect?) */
+} IDENT;
+.ft R
+.fi
+.RE
+.LP
+For a full description of the different fields, refer to
+.I RFC-1413.
+.LP
+All data returned by
+.B ident_lookup
+(including the
+.SM IDENT
+struct) points to malloc'd data, which can be freed with a call to
+.B ident_free.
+.B ident_lookup
+returns 0 on error or timeout. Presently, this should normally be taken to
+mean that the remote site is not running an
+.SM IDENT
+server, but it might naturally be caused by other network related problems
+as well.
+.B Note that
+all fields of the
+.SM IDENT
+struct need not necessarily be set.
+.LP
+.B ident_id
+takes the same parameters as
+.B ident_lookup
+but only returns a pointer to a malloc'd area containing the
+.I identifier
+string, which is probably the most wanted data from the
+.SM IDENT
+query.
+.LP
+.B ident_free
+frees all data areas associated with the
+.SM IDENT
+struct pointed to by
+.I id,
+including the struct itself.
+.LP
+.ce
+.I Low-level calls
+.LP
+The low-level calls can be used when greater flexibility is needed. For
+example, if non-blocking I/O is needed, or multiple queries to the
+same host are to be made.
+.LP
+.B id_open
+opens a connection to the remote
+.SM IDENT
+server referred to by
+.I faddr.
+The timeout is specified by
+.I timeout.
+A null-pointer means wait indefinitely, while a pointer to a
+zero-valued
+.I timeval
+struct sets non-blocking I/O, in the same way as for
+.B select(2).
+.B id_open
+returns a pointer to an
+.B id_t
+datum, which is an opaque structure to be used as future reference
+to the opened connection. When using non-blocking I/O it might however
+be useful to access the underlying socket file descriptior, which
+can be gotten at through the
+.B id_fileno
+macro described below.
+.LP
+.B id_close
+closes the connection opened with
+.B id_open
+and frees all data associated with
+.I id.
+.LP
+.B id_query
+sends off a query to a remote
+.SM IDENT
+server.
+.I lport
+and
+.I fport
+are sent to the server to identify the connection for which
+identification is needed.
+.I timeout
+is given as for
+.B id_open.
+If successful,
+.B id_query
+returns the number of bytes sent to the remote server. If not, -1 is
+returned and
+.B errno
+is set.
+.LP
+.B id_parse
+parses the reply to a query sent off by
+.B id_query
+and returns information to the locations pointed to by
+.I lport, fport, identifier, opsys
+and
+.I charset.
+For string data
+.I (identifier, opsys
+and
+.I charset)
+pointers to malloc'd space are returned.
+.LP
+.B id_parse
+returns:
+.RS
+.TP
+ 1
+If completely successful.
+.TP
+-3
+Illegal reply type from remote server.
+.I identifier
+is set to the illegal reply.
+.TP
+-2
+Cannot parse the reply from the server.
+.I identifier
+is normally set to the illegal reply.
+.TP
+-1
+On general errors or timeout.
+.TP
+ 0
+When non-blocking mode is set and
+.B id_parse
+has not finished parsing the reply from the remote server.
+.TP
+ 2
+Indicates the query/reply were successful, but the remote server
+experienced some error.
+.I identifier
+is set to the error message from the remote server.
+.RE
+.LP
+For all errors,
+.I errno
+is set as appropriate.
+.LP
+.B id_fileno
+is a macro that takes an
+.B id_t
+handle and returns the actual socket file descriptor used for
+the connection to the remote server.
+.SH ERRORS
+.TP 15
+ETIMEDOUT
+The call timed out and non-blocking I/O was not set.
+.SH EXAMPLES
+.LP
+Here's an example how to handle the reply from id_reply() in
+the case that non-blocking I/O is set. Note that id_reply() will
+return 0 as long as it's not finished parsing a reply.
+.LP
+.RS
+.nf
+.nj
+int rcode;
+
+ ...
+
+idp = id_open(...)
+
+ ...
+
+while ((rcode = id_parse(idp, timeout,
+ &lport, &fport, &id, &op, &cs)) == 0)
+ ;
+
+if (rcode < 0)
+{
+ if (rcode == ETIMEDOUT)
+ foo(); /* Lookup timed out */
+ else
+ bar(); /* Fatal error */
+}
+else if (rcode == 1)
+{
+ /* Valid USERID protocol reply */
+}
+else if (rcode == 2)
+{
+ /* Protocol ERROR reply */
+}
+.fi
+.RE
+.SH SEE ALSO
+RFC-1413, socket(2), select(2)
+.SH AUTHORS
+Peter Eriksson
+.I <pen@lysator.liu.se>
+.br
+P\*:ar Emanuelsson
+.I <pell@lysator.liu.se>
+.SH BUGS
+For
+.B ident_lookup
+and
+.B ident_id
+the blocking time in extreme cases might be as much as three times
+the value given in the
+.I timeout
+parameter.
diff --git a/network/socks/socks.cstc.4.2/libident/ident.c b/network/socks/socks.cstc.4.2/libident/ident.c
new file mode 100644
index 00000000..335fb09e
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/ident.c
@@ -0,0 +1,139 @@
+/*
+** ident.c High-level calls to the ident lib
+**
+** Author: Pär Emanuelsson <pell@lysator.liu.se>
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+
+#include "ident.h"
+
+#if defined(AIX_PS2) || defined(ultrix)
+extern char *strdup(char *);
+#endif
+
+/* Do a complete ident query and return result */
+
+IDENT *ident_lookup
+#ifdef __STDC__
+ (int fd,
+ int timeout)
+#else
+ (fd, timeout)
+ int fd; int timeout;
+#endif
+{
+ struct sockaddr_in localaddr, remoteaddr;
+ int len, res;
+ ident_t *id;
+ struct timeval timout;
+ IDENT *ident=0;
+
+ len = sizeof(remoteaddr);
+ if (getpeername(fd, (struct sockaddr *)&remoteaddr, &len) < 0)
+ return 0;
+
+ len = sizeof(localaddr);
+ if (getsockname(fd, (struct sockaddr *)&localaddr, &len) < 0)
+ return 0;
+
+ timout.tv_sec = timeout; timout.tv_usec = 0;
+
+ if (timeout)
+ id = id_open(&localaddr.sin_addr, &remoteaddr.sin_addr, &timout);
+ else
+ id = id_open(&localaddr.sin_addr, &remoteaddr.sin_addr, (struct timeval *)0);
+
+ if (!id) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if (timeout)
+ res = id_query(id,
+ ntohs(remoteaddr.sin_port),
+ ntohs(localaddr.sin_port),
+ &timout);
+ else
+ res = id_query(id,
+ ntohs(remoteaddr.sin_port),
+ ntohs(localaddr.sin_port),
+ (struct timeval *) 0);
+
+ if (res < 0) {
+ id_close(id);
+ return 0;
+ }
+
+ ident = (IDENT *) malloc(sizeof(IDENT));
+ if (!ident) {
+ id_close(id);
+ return 0;
+ }
+
+ if (timeout)
+ res = id_parse(id, &timout,
+ &ident->lport,
+ &ident->fport,
+ &ident->identifier,
+ &ident->opsys,
+ &ident->charset);
+ else
+ res = id_parse(id, (struct timeval *) 0,
+ &ident->lport,
+ &ident->fport,
+ &ident->identifier,
+ &ident->opsys,
+ &ident->charset);
+
+ if (res != 1) {
+ free(ident);
+ id_close(id);
+ return 0;
+ }
+
+ id_close(id);
+ return ident; /* At last! */
+}
+
+char *ident_id
+#ifdef __STDC__
+ (int fd,
+ int timeout)
+#else
+(fd, timeout)
+ int fd; int timeout;
+#endif
+{
+ IDENT *ident;
+ char *id=0;
+
+ ident = ident_lookup(fd, timeout);
+ if (ident && ident->identifier && *ident->identifier)
+ id = strdup(ident->identifier);
+ ident_free(ident);
+ return id;
+}
+
+void ident_free
+#ifdef __STDC__
+ (IDENT *id)
+#else
+ (id)
+ IDENT *id;
+#endif
+{
+ if (!id) return;
+ if (id->identifier) free(id->identifier);
+ if (id->opsys) free(id->opsys);
+ if (id->charset) free(id->charset);
+ free(id);
+}
diff --git a/network/socks/socks.cstc.4.2/libident/ident.h b/network/socks/socks.cstc.4.2/libident/ident.h
new file mode 100644
index 00000000..d40bf568
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/ident.h
@@ -0,0 +1,88 @@
+/*
+** ident.h
+**
+** Author: Peter Eriksson <pen@lysator.liu.se>
+** Intruder: Pär Emanuelsson <pell@lysator.liu.se>
+*/
+
+#ifndef __IDENT_H__
+#define __IDENT_H__
+
+#ifdef __P
+# undef __P
+#endif
+
+#ifdef __STDC__
+# define __P(AL) AL
+#else
+# define __P(AL) ()
+#endif
+
+/*
+ * Sigh, GCC v2 complains when using undefined struct tags
+ * in function prototypes...
+ */
+#if defined(__GNUC__) && !defined(IPPROTO_IP)
+# define __STRUCT_IN_ADDR_P void *
+#else
+# define __STRUCT_IN_ADDR_P struct in_addr *
+#endif
+
+#if defined(__GNUC__) && !defined(DST_NONE)
+# define __STRUCT_TIMEVAL_P void *
+#else
+# define __STRUCT_TIMEVAL_P struct timeval *
+#endif
+
+
+#ifndef IDBUFSIZE
+# define IDBUFSIZE 2048
+#endif
+
+#ifndef IDPORT
+# define IDPORT 113
+#endif
+
+typedef struct
+{
+ int fd;
+ char buf[IDBUFSIZE];
+} ident_t;
+
+typedef struct {
+ int lport; /* Local port */
+ int fport; /* Far (remote) port */
+ char *identifier; /* Normally user name */
+ char *opsys; /* OS */
+ char *charset; /* Charset (what did you expect?) */
+} IDENT; /* For higher-level routines */
+
+/* Low-level calls and macros */
+#define id_fileno(ID) ((ID)->fd)
+
+extern ident_t * id_open __P((__STRUCT_IN_ADDR_P laddr,
+ __STRUCT_IN_ADDR_P faddr,
+ __STRUCT_TIMEVAL_P timeout));
+
+extern int id_close __P((ident_t *id));
+
+extern int id_query __P((ident_t *id,
+ int lport,
+ int fport,
+ __STRUCT_TIMEVAL_P timeout));
+
+extern int id_parse __P((ident_t *id,
+ __STRUCT_TIMEVAL_P timeout,
+ int *lport,
+ int *fport,
+ char **identifier,
+ char **opsys,
+ char **charset));
+
+/* High-level calls */
+extern IDENT *ident_lookup __P((int fd, int timeout));
+
+extern char *ident_id __P((int fd, int timeout));
+
+void ident_free __P((IDENT *id));
+#endif
diff --git a/network/socks/socks.cstc.4.2/libident/lookup-tester.c b/network/socks/socks.cstc.4.2/libident/lookup-tester.c
new file mode 100644
index 00000000..da55814b
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/libident/lookup-tester.c
@@ -0,0 +1,57 @@
+/*
+** lookup-tester.c Tests the high-level ident calls.
+**
+** Author: Pär Emanuelsson <pell@lysator.liu.se>, 28 March 1993
+*/
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include "ident.h"
+
+main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ IDENT *ident;
+ char *user;
+
+ chdir("/tmp");
+
+ puts("Welcome to the other IDENT server tester, version 1.0\r\n\r");
+
+ puts("Testing ident_lookup...\r\n\r");
+ fflush(stdout);
+
+ ident = ident_lookup(fileno(stdin), 30);
+
+ if (!ident)
+ perror("ident");
+ else {
+ printf("IDENT response is:\r\n");
+ printf(" Lport........ %d\r\n", ident->lport);
+ printf(" Fport........ %d\r\n", ident->fport);
+ printf(" Opsys........ %s\r\n", ident->opsys);
+ printf(" Charset...... %s\r\n",
+ ident->charset ? ident->charset : "<not specified>");
+ printf(" Identifier... %s\r\n", ident->identifier);
+ }
+
+ ident_free(ident);
+
+ puts("\r\nTesting ident_id...\r\n\r");
+ fflush(stdout);
+
+ user = ident_id(fileno(stdin), 30);
+
+ if (user)
+ printf("IDENT response is identifier = %s\r\n", user);
+ else
+ puts("IDENT lookup failed!\r");
+
+ fflush(stdout);
+ sleep(1);
+ exit(0);
+}
+
diff --git a/network/socks/socks.cstc.4.2/make.out b/network/socks/socks.cstc.4.2/make.out
new file mode 100644
index 00000000..fca9ebab
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/make.out
@@ -0,0 +1,121 @@
+(cd lib; make CC="cc" GETPASS="getpass.o" \
+ OPTIMIZE="-g" \
+ RCMD="" SUPPORT_RCMD="" \
+ DNS_THROUGH_NIS="" \
+ OTHER_CFLAGS=" -DSHORTENED_RBIND -DCOMPAT " \
+ RANLIB="ranlib")
+/projects/insg/socks.cstc.4.2.pre1/lib
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c Rconnect.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c SendGetDst.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c saddrtoname.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c porttoserv.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c check_cconf.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c percent_x.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c shell_cmd.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c check_user.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c getpass.c
+rm -f libsocks.a
+ar rc libsocks.a Rconnect.o SendGetDst.o saddrtoname.o porttoserv.o check_cconf.o percent_x.o shell_cmd.o check_user.o getpass.o
+ranlib libsocks.a
+(cd libident; make CC="cc" OTHER_CFLAGS=" -DSHORTENED_RBIND -DCOMPAT " \
+ OPTIMIZE="-g" RANLIB="ranlib")
+/projects/insg/socks.cstc.4.2.pre1/libident
+cc -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c ident.c
+cc -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c id_open.c
+cc -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c id_close.c
+cc -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c id_query.c
+cc -g -DSHORTENED_RBIND -DCOMPAT -target sun4 -c id_parse.c
+rm -f libident.a
+ar cq libident.a ident.o id_open.o id_close.o id_query.o id_parse.o
+ranlib libident.a
+(cd sockd; make CC="cc" RESOLV_LIB="-lresolv" \
+ OPTIMIZE="-g" \
+ SOCKS_LIB="/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a" SUPPORT_RCMD="" \
+ IDENT_LIB="/projects/insg/socks.cstc.4.2.pre1/libident/libident.a" \
+ OTHER_CFLAGS=" -DSHORTENED_RBIND -DCOMPAT ")
+/projects/insg/socks.cstc.4.2.pre1/sockd
+cc -I../include -I../libident -g -DSHORTENED_RBIND -DCOMPAT -o sockd sockd.c /projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a /projects/insg/socks.cstc.4.2.pre1/libident/libident.a -lresolv
+cc -I../include -I../libident -g -DSHORTENED_RBIND -DCOMPAT -DTEST -o test_sockd_conf sockd.c /projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a -lresolv
+cc -I../include -I../libident -g -DSHORTENED_RBIND -DCOMPAT -o flip_cfmasks flip_cfmasks.c /projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a -lresolv
+(cd rfinger; make CC="cc" WHOIS_SERVER=-DWHOIS_SERVER\'=\"rs.internic.net\"\' \
+ OPTIMIZE="-g" SOCKS="-Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect" \
+ RESOLV_LIB="-lresolv" SOCKS_LIB="/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a" \
+ OTHER_CFLAGS=" -DSHORTENED_RBIND -DCOMPAT ")
+/projects/insg/socks.cstc.4.2.pre1/rfinger
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -target sun4 -c finger.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -o rfinger finger.o /projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a -lresolv
+cc -DWHOIS_SERVER'="rs.internic.net"' -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -o rwhois finger.c /projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a -lresolv
+(cd rftp; make CC="cc" SOCKS_LIB="/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a" \
+ OPTIMIZE="-g" SOCKS="-Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect" \
+ RESOLV_LIB="-lresolv" \
+ OTHER_CFLAGS=" -DSHORTENED_RBIND -DCOMPAT ")
+/projects/insg/socks.cstc.4.2.pre1/rftp
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -target sun4 -c cmds.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -target sun4 -c cmdtab.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -target sun4 -c ftp.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -target sun4 -c glob.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -target sun4 -c main.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -target sun4 -c ruserpass.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -target sun4 -c domacro.c
+cc -I../include -g -DSHORTENED_RBIND -DCOMPAT -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -o rftp cmds.o cmdtab.o ftp.o glob.o main.o ruserpass.o domacro.o /projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a -lresolv
+(cd rtelnet; make CC="cc" OS="sun4.1" SOCKS_LIB="/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a" \
+ OPTIMIZE="-g" SOCKS="-Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect" \
+ RESOLV_LIB="-lresolv" \
+ OTHER_CFLAGS=" -DSHORTENED_RBIND -DCOMPAT ")
+/projects/insg/socks.cstc.4.2.pre1/rtelnet
+cd libtelnet; make sun4.1 CC="cc" OTHER_CFLAGS="-DSHORTENED_RBIND -DCOMPAT" SOCKS="-Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect" SOCKS_LIB=/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a RESOLV_LIB="-lresolv" OPTIMIZE="-g"
+make -f ../Config.local WHAT= CC=cc OPTIMIZE=-g SOCKS=-Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect SOCKS_LIB=/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a RESOLV_LIB=-lresolv sun4.1
+make -f Makefile.generic \
+ LIBS="/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a -ltermcap ../libtelnet/libtelnet.a -lresolv" \
+ LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
+ ../libtelnet/libtelnet.a" \
+ DEST=/usr/ucb \
+ DEFINES="-DFILIO_H -DTERMCAP -DUSE_TERMIO \
+ -DKLUDGELINEMODE -DSTREAMS \
+ -DAUTHENTICATE \
+ -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS " \
+ INCLUDES="-I.. -I../../include" \
+ LIB_OBJ="getent.o strerror.o setenv.o herror.o" \
+ LIB_SRC="getent.c strerror.c setenv.c herror.c" \
+ AR=ar ARFLAGS=cq RANLIB=ranlib \
+ LIBEXEC=/usr/etc/in.telnetd \
+ CC="cc" LCCFLAGS="-g"
+cc -g -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -I.. -I../../include -target sun4 -c auth.c
+cc -g -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -I.. -I../../include -target sun4 -c encrypt.c
+cc -g -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -I.. -I../../include -target sun4 -c genget.c
+cc -g -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -I.. -I../../include -target sun4 -c misc.c
+cc -g -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -I.. -I../../include -target sun4 -c enc_des.c
+cc -g -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -I.. -I../../include -target sun4 -c getent.c
+cc -g -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -I.. -I../../include -target sun4 -c strerror.c
+cc -g -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -I.. -I../../include -target sun4 -c setenv.c
+cc -g -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -I.. -I../../include -target sun4 -c herror.c
+rm -f libtelnet.a
+ar cq libtelnet.a auth.o encrypt.o genget.o misc.o enc_des.o getent.o strerror.o setenv.o herror.o
+ranlib libtelnet.a
+cd telnet; make sun4.1 CC="cc" OTHER_CFLAGS="-DSHORTENED_RBIND -DCOMPAT" SOCKS="-Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect" SOCKS_LIB=/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a RESOLV_LIB="-lresolv" OPTIMIZE="-g"
+make -f ../Config.local WHAT= CC=cc OPTIMIZE=-g SOCKS=-Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect SOCKS_LIB=/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a RESOLV_LIB=-lresolv sun4.1
+make -f Makefile.generic \
+ LIBS="/projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a -ltermcap ../libtelnet/libtelnet.a -lresolv" \
+ LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
+ ../libtelnet/libtelnet.a" \
+ DEST=/usr/ucb \
+ DEFINES="-DFILIO_H -DTERMCAP -DUSE_TERMIO \
+ -DKLUDGELINEMODE -DSTREAMS \
+ -DAUTHENTICATE \
+ -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS " \
+ INCLUDES="-I.. -I../../include" \
+ LIB_OBJ="getent.o strerror.o setenv.o herror.o" \
+ LIB_SRC="getent.c strerror.c setenv.c herror.c" \
+ AR=ar ARFLAGS=cq RANLIB=ranlib \
+ LIBEXEC=/usr/etc/in.telnetd \
+ CC="cc" LCCFLAGS="-g"
+cc -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -target sun4 -c authenc.c
+cc -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -target sun4 -c commands.c
+cc -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -target sun4 -c main.c
+cc -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -target sun4 -c network.c
+cc -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -target sun4 -c ring.c
+cc -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -target sun4 -c sys_bsd.c
+cc -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -target sun4 -c telnet.c
+cc -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -target sun4 -c terminal.c
+cc -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS -target sun4 -c utilities.c
+cc -o ../rtelnet -g -I.. -I../../include -DFILIO_H -DTERMCAP -DUSE_TERMIO -DKLUDGELINEMODE -DSTREAMS -DAUTHENTICATE -Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect -DDIAGNOSTICS authenc.o commands.o main.o network.o ring.o sys_bsd.o telnet.o terminal.o utilities.o /projects/insg/socks.cstc.4.2.pre1/lib/libsocks.a -ltermcap ../libtelnet/libtelnet.a -lresolv
diff --git a/network/socks/socks.cstc.4.2/rfinger/Makefile b/network/socks/socks.cstc.4.2/rfinger/Makefile
new file mode 100644
index 00000000..120f2123
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/rfinger/Makefile
@@ -0,0 +1,97 @@
+#CC=gcc
+
+# Directory into which rfinger and rwhois programs will be installed:
+CLIENTS_BIN_DIR=/usr/local/bin
+
+# Directory into which man page files will be installed:
+MAN_DEST_DIR=/usr/local/man
+
+# make SOCKSified client
+SOCKS_LIB =../lib/libsocks.a
+SOCKS=-DSOCKS
+# or
+#SOCKS=-Dconnect=Rconnect -Dgetsockname=Rgetsockname -Dlisten=Rlisten -Daccept=Raccept -Drcmd=Rrcmd -Dbind=Rbind -Dselect=Rselect
+
+# Remember to include -Dindex=strchr in OTHER_CFLAGS if
+# you don't have index() (Sys-V camp)
+
+# SunOS should use
+#RESOLV_LIB=-lresolv
+OTHER_CFLAGS= $(SHORTENED_RBIND)
+
+# IRIX should use
+#RESOLV_LIB=-lsun
+#OTHER_CFLAGS=-cckr $(SHORTENED_RBIND)
+
+# AIX should use
+#RESOLV_LIB=-lbsd
+#OTHER_CFLAGS=-D_BSD -D_NONSTD_TYPES -D_NO_PROTO -DAIX $(SHORTENED_RBIND)
+
+# SOLARIS should use
+#RESOLV_LIB=-lresolv -lnsl -lsocket
+#OTHER_CFLAGS=-DSOLARIS -Dindex=strchr -Drindex=strrchr -DUSE_DIRENT $(SHORTENED_RBIND)
+
+# Interactive Systems Unix should use
+# OTHER_CFLAGS = -DISC $(SHORTENED_RBIND)
+
+# LINUX should use
+#CC=gcc
+#RESOLV_LIB=
+#OTHER_CFLAGS=-traditional -DLINUX $(SHORTENED_RBIND)
+
+# UnixWare should use
+#RESOLV_LIB=-lresolv -lnsl -lsocket
+#OTHER_CFLAGS= -DSOLARIS -Dindex=strchr -Drindex=strrchr -DUSE_DIRENT $(SHORTENED_RBIND)
+#INSTALL=/usr/ucb/install
+
+# >>>---------------- Others:
+
+# Define RESOLV_LIB if your system (e.g., SunOS before 4.1.1)
+# doesn't search resolver library automatically.
+# Leave it undefined otherwise.
+# If your compiler or loader complains about _res_init being
+# an undefined symbol, then you must define RESOLV_LIB.
+#RESOLV_LIB= -lresolv
+
+# <<<----------------
+
+# The Internet Whois server; used to be nic.ddn.mil.
+WHOIS_SERVER= -DWHOIS_SERVER'="rs.internic.net"'
+
+OPTIMIZE=-g
+CFLAGS = -I../include ${OPTIMIZE} ${OTHER_CFLAGS} ${SOCKS}
+
+# The 'install' command is assumed to be the BSD variety (using -m to
+# set the file mode). If the default 'install' on your system doesn't
+# do that, you have to either specify an alternative one in the line below
+# (e.g., /usr/ucb/install) or modify the install instructions.
+INSTALL= install
+
+#==============================================================================
+
+OBJ = finger.o
+SRC = finger.c
+
+all: echocwd rfinger rwhois
+
+rfinger: $(OBJ) $(SOCKS_LIB)
+ $(CC) $(CFLAGS) -o $@ $(OBJ) $(SOCKS_LIB) $(RESOLV_LIB)
+
+rwhois: $(SRC) $(SOCKS_LIB)
+ $(CC) $(WHOIS_SERVER) $(CFLAGS) -o $@ $(SRC) $(SOCKS_LIB) $(RESOLV_LIB)
+
+install: echocwd rfinger rwhois
+ $(INSTALL) -m 111 rfinger $(CLIENTS_BIN_DIR)
+ $(INSTALL) -m 111 rwhois $(CLIENTS_BIN_DIR)
+
+install.man: echocwd
+ $(INSTALL) -m 444 ../doc/socks_clients.1 $(MAN_DEST_DIR)/man1
+ $(INSTALL) -m 444 ../doc/socks.conf.5 $(MAN_DEST_DIR)/man5
+ $(INSTALL) -m 444 ../doc/rfinger.1 $(MAN_DEST_DIR)/man1
+ $(INSTALL) -m 444 ../doc/rwhois.1 $(MAN_DEST_DIR)/man1
+
+clean: echocwd
+ rm -f $(OBJ) rwhois rfinger core
+
+echocwd:
+ @pwd
diff --git a/network/socks/socks.cstc.4.2/rfinger/finger.c b/network/socks/socks.cstc.4.2/rfinger/finger.c
new file mode 100644
index 00000000..1c3809d3
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/rfinger/finger.c
@@ -0,0 +1,145 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <sys/file.h>
+#include <errno.h>
+#include "socks.h"
+
+#if defined(SOCKS)
+#define connect Rconnect
+#endif
+
+extern int errno;
+extern char *strrchr();
+char *Progname;
+extern char *getenv();
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ char buf[1024];
+ unsigned long l;
+ struct sockaddr_in sin;
+ struct hostent *hp;
+ struct servent *sp;
+ extern int optind;
+ extern char *optarg;
+ int c, v, n, i;
+ int s;
+ extern int optind;
+ FILE *in;
+ char *cp;
+#ifdef WHOIS_SERVER
+ char *service = "whois", *host = WHOIS_SERVER;
+#else
+ char *service = "finger", *host = "localhost";
+#endif
+ struct in_addr dstaddr[21];
+
+ if ((Progname = strrchr(argv[0], '/')) == NULL)
+ Progname = argv[0];
+ else
+ Progname++;
+
+#if defined(SOCKS) || defined(connect)
+ SOCKSinit(Progname);
+#endif
+
+#ifdef WHOIS_SERVER
+ while ((i = getopt(argc,argv,"h:")) != EOF) {
+ switch (i) {
+ case 'h':
+ host = optarg;
+ break;
+ default:
+ fprintf(stderr,"Usage: %s [-h host] name\n", Progname);
+ exit(1);
+ }
+ }
+#endif
+
+ buf[0] = '\0';
+#if defined(LINUX)
+ for (i = 1; i < argc; i++)
+#else
+ for (i = optind; i < argc; i++)
+#endif
+ strcat(buf, argv[i]);
+
+#ifndef WHOIS_SERVER
+ if ((cp = strrchr(buf, '@')) != NULL) {
+ *cp = '\0';
+ host = cp + 1;
+ } else {
+ if ((cp = getenv("ORIG_FINGER")) == NULL)
+ cp = ORIG_FINGER;
+ execvp(cp, argv);
+ fprintf(stderr, "Unable to run %s\n", cp);
+ exit(1);
+ }
+#endif
+
+ sin.sin_family = AF_INET;
+
+
+ if ((sp = getservbyname(service, "tcp")) == NULL) {
+ if ((v = atoi(service)) == 0) {
+ fprintf(stderr, "%s: unknown service '%s'\n",
+ Progname, service);
+ exit(1);
+ }
+ sin.sin_port = htons((short) v);
+ } else {
+ sin.sin_port = sp->s_port;
+ }
+
+ if ((hp = gethostbyname(host)) == NULL) {
+ if ((l = inet_addr(host)) == -1) {
+ fprintf(stderr, "%s: unknown host '%s'\n",
+ Progname, host);
+ exit(1);
+ }
+/* you are out of luck if your system doesn't use 2's complement in
+ integer representation */
+ sin.sin_addr.s_addr = l ;
+ } else {
+ for (i = 0; (i < 20) && *hp->h_addr_list;
+ i++, hp->h_addr_list++)
+ bcopy(*hp->h_addr_list, &(dstaddr[i].s_addr), hp->h_length);
+ dstaddr[i].s_addr = 0;
+ i = 0;
+ sin.sin_addr.s_addr = dstaddr[i++].s_addr;
+ }
+
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ fprintf(stderr, "%s: ", Progname);
+ perror("socket");
+ exit(1);
+ }
+
+ while (connect(s, &sin, sizeof(sin)) < 0) {
+ if ((errno == ETIMEDOUT) && (hp != NULL) &&
+ ((sin.sin_addr.s_addr = dstaddr[i++].s_addr) != 0)) {
+ continue;
+ }
+ fprintf(stderr, "%s: ", Progname);
+ perror("connect");
+ exit(1);
+ }
+
+ strcat(buf, "\r\n");
+
+ if (write(s,buf,strlen(buf)) < 0) {
+ fprintf(stderr, "%s: ", Progname);
+ perror("write");
+ }
+
+ while ((n = read(s, buf, sizeof(buf) - 1)) > 0) {
+ write(1, buf, n);
+ }
+
+ close(s);
+}
diff --git a/network/socks/socks.cstc.4.2/sockd/Makefile b/network/socks/socks.cstc.4.2/sockd/Makefile
new file mode 100644
index 00000000..f9c22cd9
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/sockd/Makefile
@@ -0,0 +1,105 @@
+#CC=gcc
+
+SOCKS_LIB=../lib/libsocks.a
+IDENT_LIB=../libident/libident.a
+
+# Directory into which sockd and test_sockd_conf programs
+# will be installed:
+SERVER_BIN_DIR=/usr/etc
+
+# Directory into which the man page files of sockd and test_sockd_conf
+# will be installed:
+MAN_DEST_DIR=/usr/local/man
+
+INC=../include/socks.h
+
+# Uncomment next line to support Rbind() without the extra 'remhost' arg.
+SHORTENED_RBIND=-DSHORTENED_RBIND
+
+# Remember to include -Dindex=strchr in OTHER_CFLAGS if
+# you don't have index() (Sys-V camp)
+
+# Define FOR_PS if your system is not SYSV and you want to have the
+# command 'ps' show some details of sockd's activity.
+FOR_PS=-DFOR_PS
+
+# SunOS should use
+#RESOLV_LIB=-lresolv
+OTHER_CFLAGS=$(SHORTENED_RBIND)
+
+# IRIX should use
+#OTHER_CFLAGS=-cckr $(SHORTENED_RBIND)
+#RESOLV_LIB=-lsun
+
+# HPUX should use
+#OTHER_CFLAGS=-Ac $(SHORTENED_RBIND)
+
+# AIX should use
+#RESOLV_LIB=-lbsd
+#OTHER_CFLAGS=-D_BSD -D_NONSTD_TYPES -D_NO_PROTO -DAIX $(SHORTENED_RBIND)
+
+# SOLARIS should use
+#RESOLV_LIB=-lresolv -lnsl -lsocket
+#OTHER_CFLAGS=-DSOLARIS -Dindex=strchr -Drindex=strrchr -DUSE_DIRENT $(SHORTENED_RBIND)
+
+# Interactive Systems Unix should use
+# OTHER_CFLAGS = -DISC $(SHORTENED_RBIND)
+
+# LINUX should use
+#CC=gcc
+#RESOLV_LIB=
+#OTHER_CFLAGS=-traditional -DLINUX $(SHORTENED_RBIND)
+
+# UnixWare should use
+#RESOLV_LIB=-lresolv -lnsl -lsocket
+#OTHER_CFLAGS= -DSOLARIS -Dindex=strchr -Drindex=strrchr -DUSE_DIRENT $(SHORTENED_RBIND)
+#RANLIB=/bin/true
+#INSTALL=bsdinstall
+
+# define SUPPORT_RCMD to build a server that can handle SOCKSified
+# rlogin, rsh, and rcp.
+SUPPORT_RCMD=-DSUPPORT_RCMD
+
+OPTIMIZE=-g
+CFLAGS = -I../include -I../libident ${OPTIMIZE} ${OTHER_CFLAGS} ${SUPPORT_RCMD}
+
+# The 'install' command is assumed to be the BSD variety (using -m to
+# set the file mode). If the default 'install' on your system doesn't
+# do that, you have to either specify an alternative one in the line below
+# (e.g., /usr/ucb/install) or modify the install instructions.
+INSTALL= install
+
+#==================================================
+
+SRC=sockd.c
+OBJ=sockd.o
+PROG=sockd test_sockd_conf flip_cfmasks
+
+all: echocwd $(PROG)
+
+sockd: $(SRC) $(INC) $(SOCKS_LIB) $(IDENT_LIB)
+ $(CC) $(CFLAGS) -o $@ $(SRC) $(SOCKS_LIB) $(IDENT_LIB) $(RESOLV_LIB)
+
+test_sockd_conf: $(SRC) $(INC) $(SOCKS_LIB)
+ $(CC) $(CFLAGS) -DTEST -o $@ $(SRC) $(SOCKS_LIB) $(RESOLV_LIB)
+
+flip_cfmasks: flip_cfmasks.c $(INC) $(SOCKS_LIB)
+ $(CC) $(CFLAGS) -o $@ flip_cfmasks.c $(SOCKS_LIB) $(RESOLV_LIB)
+
+install: echocwd sockd test_sockd_conf
+ $(INSTALL) -m 111 sockd $(SERVER_BIN_DIR)
+ $(INSTALL) -m 111 test_sockd_conf $(SERVER_BIN_DIR)
+ $(INSTALL) -m 111 flip_cfmasks $(SERVER_BIN_DIR)
+
+install.man: echocwd
+ $(INSTALL) -m 444 ../doc/sockd.8 $(MAN_DEST_DIR)/man8
+ $(INSTALL) -m 444 ../doc/test_sockd_conf.8 $(MAN_DEST_DIR)/man8
+ $(INSTALL) -m 444 ../doc/sockd.conf.5 $(MAN_DEST_DIR)/man5
+ $(INSTALL) -m 444 ../doc/sockd.route.5 $(MAN_DEST_DIR)/man5
+
+
+clean: echocwd
+ rm -f $(OBJ) $(PROG) core
+
+echocwd:
+ @pwd
diff --git a/network/socks/socks.cstc.4.2/sockd/flip_cfmasks.c b/network/socks/socks.cstc.4.2/sockd/flip_cfmasks.c
new file mode 100644
index 00000000..0c0c8cc0
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/sockd/flip_cfmasks.c
@@ -0,0 +1,167 @@
+/*
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/signal.h>
+#include <syslog.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+*/
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <stdio.h>
+/*
+#include <ctype.h>
+*/
+#include <string.h>
+#include <sys/wait.h>
+#include "socks.h"
+
+extern int GetAddr();
+extern char *inet_ntoa();
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ FILE *infile, *outfile, *tempout;
+ char *tempfn;
+ static char buf[1024];
+ char temp[1024];
+ char lineout[1024];
+ char *bp;
+ int linenum = 0;
+ struct in_addr smask, dmask;
+ char *cmdp, *commentp;
+ int child_pid, wait_pid, exitcode;
+
+ if (argc != 3) {
+ fprintf(stderr," Usage: %s input_file output_file\n", argv[0]);
+ exit(1);
+ }
+
+ if ((infile = fopen(argv[1], "r")) == NULL) {
+ fprintf(stderr,"Unable to open input file %s\n", argv[1]);
+ exit(1);
+ }
+
+ if ((tempout = fopen(tempfn = tmpnam(NULL), "w")) == NULL) {
+ fprintf(stderr, "Unable to create temporary file.\n");
+ exit(1);
+ }
+
+ while (fgets(buf, sizeof(buf) - 1, infile) != NULL) {
+ linenum++;
+ /*
+ ** Comments start with a '#' anywhere on the line
+ */
+ cmdp = (char *)0;
+ commentp = (char *)0;
+ if ((bp = strchr(buf, '\n')) != NULL)
+ *bp = '\0';
+ strcpy(temp, buf);
+ for (bp = buf; *bp; bp++) {
+ if (*bp == ':') {
+ *bp++ = '\0';
+ cmdp = bp;
+ break;
+ } else if (*bp == '#') {
+ *bp++ = '\0';
+ commentp = bp;
+ break;
+ }
+ }
+ if ((bp = strtok(buf, " \t")) == NULL) {
+ fprintf(tempout,"%s\n", temp);
+ continue;
+ }
+
+ strcpy(lineout, bp);
+ if ((bp = strtok(NULL, " \t")) == NULL)
+ goto badline;
+ strcat(lineout, "\t");
+ strcat(lineout, bp);
+ if (strncmp(bp, "@=", 2) == 0) {
+ if ((bp = strtok(NULL, " \t")) == NULL)
+ goto badline;
+ strcat(lineout, "\t");
+ strcat(lineout, bp);
+ }
+ if (strncmp(bp, "*=", 2) == 0) {
+ if ((bp = strtok(NULL, " \t")) == NULL)
+ goto badline;
+ strcat(lineout, "\t");
+ strcat(lineout, bp);
+ }
+ if ((bp = strtok(NULL, " \t")) == NULL)
+ goto badline;
+ GetAddr(bp, &smask);
+ smask.s_addr = ~smask.s_addr;
+ strcat(lineout, " ");
+ strcat(lineout, inet_ntoa(smask));
+ if ((bp = strtok(NULL, " \t")) == NULL)
+ goto printline;
+ if (strcmp(bp, "eq") && strcmp(bp, "neq") && strcmp(bp, "lt")
+ && strcmp(bp, "gt") && strcmp(bp, "le")
+ && strcmp(bp, "ge")) {
+ strcat(lineout, "\t");
+ strcat(lineout, bp);
+ if ((bp = strtok(NULL, " \t")) == NULL)
+ goto badline;
+ GetAddr(bp, &dmask);
+ dmask.s_addr = ~dmask.s_addr;
+ strcat(lineout, " ");
+ strcat(lineout, inet_ntoa(dmask));
+ }
+ if ((bp = strtok(NULL, " \t")) == NULL)
+ goto printline;
+ strcat(lineout, "\t");
+ strcat(lineout, bp);
+ if ((bp = strtok(NULL, " \t")) == NULL)
+ goto badline;
+ strcat(lineout, " ");
+ strcat(lineout, bp);
+printline:
+ if (cmdp != NULL) {
+ strcat(lineout, " :");
+ strcat(lineout, cmdp);
+ }
+ if (commentp != NULL) {
+ strcat(lineout, " #");
+ strcat(lineout, commentp);
+ }
+ fprintf(tempout, "%s\n", lineout);
+ continue;
+
+badline:
+ fprintf(stderr, "Invalid entry at line %d:\n%s\n", linenum, temp);
+ fprintf(tempout, "%s\n", temp);
+ continue;
+ }
+
+ fclose(infile);
+ fclose(tempout);
+
+/* Fork to do cp */
+ switch (child_pid = fork()) {
+ case 0:
+ sprintf(lineout, "cp %s %s", tempfn, argv[2]);
+ execl("/bin/sh", "sh", "-c", lineout, (char *)0);
+ case -1:
+ fprintf(stderr,"Uable to save to file %s. Results saved in file %s\n", argv[2], tempfn);
+ exit(1);
+ default:
+ while ((wait_pid = wait(&exitcode)) != -1 && wait_pid != child_pid)
+ ;
+ if (exitcode) {
+ fprintf(stderr,"Uable to save to file %s. Results saved in file %s\n", argv[2], tempfn);
+ exit(1);
+ }
+ unlink(tempfn);
+ exit(0);
+ }
+
+
+
+}
+
diff --git a/network/socks/socks.cstc.4.2/sockd/sockd.c b/network/socks/socks.cstc.4.2/sockd/sockd.c
new file mode 100644
index 00000000..5364cf67
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/sockd/sockd.c
@@ -0,0 +1,1182 @@
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/signal.h>
+#include <syslog.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <ctype.h>
+#if (defined(sun) && !defined(SOLARIS)) || defined(sgi)
+#include <strings.h>
+#else
+#include <string.h>
+#endif
+#if defined(SUPPORT_RCMD)
+#include <fcntl.h>
+#endif
+#include "socks.h"
+
+#include "ident.h"
+#define IDENTD_TIMEOUT 15 /* 15 seconds */
+static int use_identd = 0;
+
+#define STREQ(a, b) (strcmp(a, b) == 0)
+
+char socks_cmd[] = "connect";
+
+#ifdef OLD_CONF_MASK
+static char conf_mask[] = OLD_CONF_MASK;
+#endif
+static char *sockd_conf = SOCKD_CONF;
+static char server_version[] = "4.1";
+static unsigned short socks_port;
+static unsigned short socks_client_port;
+extern char *porttoserv();
+extern char *saddrtoname();
+extern void mkargs();
+extern int GetAddr();
+extern long GetPort();
+extern int check_user();
+#define NAMELEN 128
+char socks_src_name[NAMELEN], socks_src_user[NAMELEN];
+char socks_real_user[NAMELEN];
+char socks_dst_name[NAMELEN], socks_dst_serv[NAMELEN];
+
+static char log_msg[1024];
+
+#ifdef DEBUG
+static char buf[1024];
+#endif
+
+#ifndef TEST
+
+ static u_int32 from_in = 0L, from_out = 0L;
+
+/*
+** Current version for response messages
+*/
+int Version = 0;
+
+void die()
+{
+ syslog(LOG_LOW, "timed-out -- %s", log_msg);
+ exit(1);
+}
+
+
+#ifdef FOR_PS
+main(argc, argv, envp)
+int argc;
+char *argv[];
+char *envp[];
+#else /* FOR_PS not defined */
+main(argc, argv)
+int argc;
+char *argv[];
+#endif /* #ifdef FOR_PS */
+{
+ char c;
+ int inp, in, out, nindex=0;
+ int i, n, len = sizeof(struct sockaddr_in);
+ struct sockaddr_in sin, from, dstsin;
+ int fromlen = sizeof(struct sockaddr_in);
+ Socks_t dst;
+ int one = 1;
+ struct servent *sp;
+ int permit;
+
+#if defined(FOR_PS) && !defined(SYSV)
+#define MAXUSERENVIRON 100
+ char *UserEnviron[MAXUSERENVIRON+1]; /* saved user environment */
+ extern char **environ;
+ char ps_buf[1024];
+ char **Argv = NULL; /* pointer to argument vector */
+ char *LastArgv = NULL; /* end of argv */
+#define newstr(s) strcpy(malloc(strlen(s) + 1), s)
+
+ for (i = 0; i < MAXUSERENVIRON && envp[i] != NULL; i++)
+ UserEnviron[i] = newstr(envp[i]);
+ UserEnviron[i] = NULL;
+ environ = UserEnviron;
+
+ /*
+ ** Save start and extent of argv for setproctitle.
+ */
+
+ Argv = argv;
+ if (i > 0)
+ LastArgv = envp[i - 1] + strlen(envp[i - 1]);
+ else
+ LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
+#endif /* FOR_PS && !SYSV */
+
+ socks_port = htons(SOCKS_DEF_PORT);
+ bzero((char *)&sin, sizeof(sin));
+ bzero((char *)&from, sizeof(from));
+ bzero((char *)&dstsin, sizeof(dstsin));
+
+ if (argc >= 2) {
+ if (strcmp(argv[1],"-ver") == 0) {
+#ifdef MULTIHOMED_SERVER
+ printf("\tCSTC multi-homed SOCKS proxy server version %s.\n", CSTC_RELEASE);
+#else /* MULTIHOMED_SERVER not defined */
+ printf("\tCSTC single-homed SOCKS proxy server version %s.\n", CSTC_RELEASE);
+#endif /* #ifdef MULTIHOMED_SERVER */
+
+#if defined(SUPPORT_RCMD)
+ printf("\tSupports clients that use Rrcmd().\n");
+#else /* SUPPORT_RCMD not defined */
+ printf("\tDoes not support clients that use Rrcmd().\n");
+#endif /* #if defined(SUPPORT_RCMD) */
+ exit(1);
+ } else if (strcmp(argv[1], "-i") == 0)
+ use_identd = 1;
+ else if (strcmp(argv[1], "-I") == 0)
+ use_identd = 2; /* strict use of identd */
+ else ;
+ }
+ strcpy(socks_real_user,"unknown");
+
+ if ((sp = getservbyname("socks", "tcp")) != NULL)
+ socks_port = sp->s_port;
+
+#ifndef LOG_DAEMON
+ (void) openlog("sockd", LOG_PID);
+#else
+ (void) openlog("sockd", LOG_PID, SYSLOG_FAC);
+#endif
+
+#ifdef NOT_THROUGH_INETD
+ inp = socket(AF_INET, SOCK_STREAM, 0);
+ sin.sin_family = AF_INET;
+ sin.sin_port = socks_port;
+ sin.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if (bind(inp, &sin, sizeof(sin)) < 0) {
+ syslog(LOG_LOW, "error -- main bind() %m");
+ exit(1);
+ }
+
+ if (listen(inp, MAX_CLIENTS) < 0) {
+ syslog(LOG_LOW, "error -- main listen() %m");
+ exit(1);
+ }
+
+ if ((in = accept(inp, &sin, &len)) < 0) {
+ syslog(LOG_LOW, "error -- main accept() %m");
+ exit(1);
+ }
+#else
+ in = dup(0);
+#endif
+
+ if (getpeername(in, (struct sockaddr *)&from, &fromlen) < 0) {
+ syslog(LOG_LOW, "error -- unable to get client address.");
+ exit(1);
+ }
+ socks_client_port = ntohs(from.sin_port);
+#ifdef DEBUG
+ syslog(LOG_LOW, "socks_client_port=%u", socks_client_port);
+#endif /* #ifdef DEBUG */
+
+ saddrtoname(&from.sin_addr, socks_src_name, sizeof(socks_src_name));
+
+ if (GetDst(in, &dst) < 0) {
+ syslog(LOG_LOW, "Error in GetDst: %m; from host %s", socks_src_name);
+ exit(1);
+ }
+
+ if (dst.version != SOCKS_VERSION) {
+ syslog(LOG_LOW, "error -- wrong version (0x%2x) from host %s.",
+ dst.version, socks_src_name);
+ exit(1);
+ }
+
+ if (dst.cmd != SOCKS_CONNECT && dst.cmd != SOCKS_BIND) {
+ syslog(LOG_LOW, "error -- undefined command (0x%2x) from host %s",
+ dst.cmd, socks_src_name);
+ exit(1);
+ }
+
+ dstsin.sin_family = AF_INET;
+ dstsin.sin_addr.s_addr = dst.host;
+ dstsin.sin_port = dst.port;
+
+ while (read(in, &c, 1) == 1)
+ if (c == '\0')
+ break;
+ else {
+ if (nindex < sizeof(socks_src_user) - 1)
+ socks_src_user[nindex++] = c;
+ }
+ socks_src_user[nindex] = '\0';
+ if (dstsin.sin_addr.s_addr == 0)
+ strcpy(socks_dst_name, "Unspecified.Host");
+ else
+ saddrtoname(&dstsin.sin_addr, socks_dst_name, sizeof(socks_dst_name));
+ porttoserv(dstsin.sin_port, socks_dst_serv, sizeof(socks_dst_serv));
+
+ permit = Validate(&from, &dstsin, in, use_identd);
+ if (dst.cmd == SOCKS_CONNECT) {
+ strcpy(socks_cmd, "connect");
+ sprintf(log_msg, "Connect from %s(%s)@%s to %s (%s)",
+ socks_src_user, socks_real_user, socks_src_name, socks_dst_name, socks_dst_serv);
+#ifdef FOR_PS
+ sprintf(ps_buf, "%s: %s(c) to %s",
+ socks_src_user, socks_dst_serv, socks_dst_name);
+ setproctitle(ps_buf, Argv, LastArgv);
+#endif /* #ifdef FOR_PS */
+
+ } else {
+ strcpy(socks_cmd, "bind");
+ sprintf(log_msg, "Bind from %s(%s)@%s for %s",
+ socks_src_user, socks_real_user, socks_src_name, socks_dst_name, socks_dst_serv);
+#ifdef FOR_PS
+ sprintf(ps_buf, "%s: %s(b) to %s",
+ socks_src_user, socks_dst_serv, socks_dst_name);
+ setproctitle(ps_buf, Argv, LastArgv);
+#endif /* #ifdef FOR_PS */
+ }
+ if (permit == 1)
+ ;
+ else if (permit == 0) {
+ syslog(LOG_LOW, "refused -- %s", log_msg);
+ exit(1);
+ } else if (permit == -1) {
+ syslog(LOG_LOW, "cannot connect to identd on %s", socks_src_name);
+ } else if (permit == -2) {
+ syslog(LOG_LOW, "refused -- %s", log_msg);
+ syslog(LOG_LOW, "cannot connect to identd on %s", socks_src_name);
+ dst.cmd = SOCKS_NO_IDENTD;
+ SendDst(in, &dst);
+ exit(1);
+ } else if (permit == -3) {
+ syslog(LOG_LOW, "refused -- %s", log_msg);
+ syslog(LOG_LOW, "*Alert*: real user is %s, not %s", socks_real_user, socks_src_user);
+ dst.cmd = SOCKS_BAD_ID;
+ SendDst(in, &dst);
+ exit(1);
+ } else {
+ syslog(LOG_HIGH, "refused -- %s", log_msg);
+ syslog(LOG_HIGH, "Unexpected result from Validate");
+ exit(1);
+ }
+
+
+#ifdef DEBUG
+ strcpy(buf, inet_ntoa(from.sin_addr));
+ syslog(LOG_LOW,"USER:%s, SRC:%s, DST:%s, PORT:%u",
+ socks_src_user, buf, inet_ntoa(dstsin.sin_addr),
+ ntohs(dstsin.sin_port));
+#endif
+
+ /*
+ ** Kill a connecting off if bind or connect takes too
+ ** long to complete
+ */
+ signal(SIGALRM, die);
+ /*alarm(60*5);*/ /* 5 minutes */
+ alarm(60*2);
+
+ if (dst.cmd == SOCKS_CONNECT) {
+ DoConnect(in, &dst);
+ }
+ if (dst.cmd == SOCKS_BIND) {
+ DoNewBind(in, &dst);
+ }
+}
+
+socks_fail(str, in, ndst)
+char *str;
+int in;
+Socks_t *ndst;
+{
+ syslog(LOG_LOW, "failed -- %s. Error code: %s %m", log_msg, str);
+ ndst->cmd = SOCKS_FAIL;
+ SendDst(in, ndst);
+ exit(1);
+}
+
+
+/*
+** Actually connect a socket to the outside world,
+*/
+DoConnect(in, dst)
+int in;
+Socks_t *dst;
+{
+ int out;
+ struct sockaddr_in sin;
+ Socks_t ndst;
+ int outport = IPPORT_RESERVED - 1;
+ int turnon = 1;
+
+ bzero((char *)&sin, sizeof(sin));
+#if defined(SO_OOBINLINE)
+ setsockopt(in, SOL_SOCKET, SO_OOBINLINE, &turnon, sizeof(turnon));
+#endif
+#if defined(SUPPORT_RCMD)
+#ifdef DEBUG
+ syslog(LOG_LOW, "DoConnect(): client port=%u", socks_client_port);
+#endif /* #ifdef DEBUG */
+ if ((socks_client_port < IPPORT_RESERVED) &&
+ (socks_client_port >= IPPORT_RESERVED/2)) {
+ if ((out = rresvport(&outport)) < 0)
+ socks_fail("rresvport()", in, &ndst);
+#if defined(hpux)
+ ioctl(out, FIOSSAIOOWN, getpid());
+#else /* hpux not defined */
+ fcntl(out, F_SETOWN, getpid());
+#endif /* #if defined(hpux) */
+ } else if ((out = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ socks_fail("socket()", in, &ndst);
+#else /* SUPPORT_RCMD is not defined */
+ if ((out = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ socks_fail("socket()", in, &ndst);
+#endif /* #if defined(SUPPORT_RCMD) */
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = dst->port;
+ sin.sin_addr.s_addr = dst->host;
+
+ ndst.version = Version;
+ ndst.cmd = SOCKS_RESULT;
+
+ if (connect(out, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) < 0)
+ socks_fail("connect()", in, &ndst);
+
+ syslog(LOG_LOW, "connected -- %s", log_msg);
+#if defined(SO_OOBINLINE)
+ setsockopt(out, SOL_SOCKET, SO_OOBINLINE, &turnon, sizeof(turnon));
+#endif
+ SendDst(in, &ndst);
+ Pump(in, out);
+ syslog(LOG_LOW, "terminated -- %s.", log_msg);
+ syslog(LOG_LOW, "%lu bytes from %s, %lu bytes from %s", from_in, socks_src_name, from_out, socks_dst_name);
+}
+
+/*
+** Set up a socket to be connected to from the outside world.
+** diffrence between this an the Version1 protocal is that
+** the socket has to be bound from a specific host that
+** is passed.
+*/
+DoNewBind(in, dst)
+int in;
+Socks_t *dst;
+{
+ u_int32 sockd_route();
+ int new, out, len = sizeof(struct sockaddr_in);
+ struct sockaddr_in sin;
+ Socks_t ndst;
+ char dsthost[16];
+ char socks_dst_name[NAMELEN], socks_dst_serv[NAMELEN];
+ int outport = IPPORT_RESERVED - 1;
+ int turnon = 1;
+
+ bzero((char *)&sin, sizeof(sin));
+#if defined(SO_OOBINLINE)
+ setsockopt(in, SOL_SOCKET, SO_OOBINLINE, &turnon, sizeof(turnon));
+#endif
+
+ sin.sin_family = AF_INET;
+ ndst.version = Version;
+ ndst.cmd = SOCKS_RESULT;
+ sin.sin_port = htons(0);
+#ifdef MULTIHOMED_SERVER
+ sin.sin_addr.s_addr = sockd_route(dst->host);
+#else
+ sin.sin_addr.s_addr = htonl(INADDR_ANY);
+#endif
+
+#if defined(SUPPORT_RCMD)
+#ifdef DEBUG
+ syslog(LOG_LOW, "DoNewBind(): client port=%u", socks_client_port);
+#endif /* #ifdef DEBUG */
+ if ((socks_client_port < IPPORT_RESERVED) && (socks_client_port >= IPPORT_RESERVED/2)){
+ if((out = rresvport(&outport)) < 0)
+ socks_fail("rresrvport()", in, &ndst);
+#ifdef DEBUG
+ syslog(LOG_LOW, "DoNewBind(): outport=%d", outport);
+#endif /* #ifdef DEBUG */
+#if defined(hpux)
+ ioctl(out, FIOSSAIOOWN, getpid());
+#else /* hpux not defined */
+ fcntl(out, F_SETOWN, getpid());
+#endif /* #if defined(hpux) */
+ sin.sin_port = htons((short)outport);
+#ifdef DEBUG
+ syslog(LOG_LOW, "DoNewBind(): sin.sin_addr=%s, sin.sin_port=%u",
+ inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+#endif /* #ifdef DEBUG */
+ } else {
+#endif /* #if defined(SUPPORT_RCMD) */
+ if ((out = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ socks_fail("socket()", in, &ndst);
+
+ if (bind(out, (struct sockaddr *)&sin, sizeof(sin)) < 0)
+ socks_fail("bind()", in, &ndst);
+ if (getsockname(out, (struct sockaddr *)&sin, &len) < 0)
+ socks_fail("getsockname()", in, &ndst);
+#if defined(SUPPORT_RCMD)
+ }
+#endif /* if defined(SUPPORT_RCMD) */
+
+ ndst.port = sin.sin_port;
+ ndst.host = sin.sin_addr.s_addr;
+
+ if (listen(out, 1) < 0)
+ socks_fail("listen()", in, &ndst);
+
+#if defined(SO_OOBINLINE)
+ setsockopt(new, SOL_SOCKET, SO_OOBINLINE, &turnon, sizeof(turnon));
+#endif
+ SendDst(in, &ndst);
+
+ len = sizeof(struct sockaddr_in);
+ if ((new = accept(out, (struct sockaddr *)&sin, &len)) < 0)
+ socks_fail("accept()", in, &ndst);
+ close(out);
+
+ if (sin.sin_addr.s_addr == 0)
+ strcpy(socks_dst_name, "Unspecified.Host");
+ else
+ saddrtoname(&sin.sin_addr, socks_dst_name, sizeof(socks_dst_name));
+ porttoserv(sin.sin_port, socks_dst_serv, sizeof(socks_dst_serv));
+
+#ifdef SHORTENED_RBIND
+ if ((dst->host != 0L) && (sin.sin_addr.s_addr != dst->host)) {
+#else
+ if (sin.sin_addr.s_addr != dst->host) {
+#endif
+/*
+#if defined(SOLARIS) || defined(NeXT) || defined(_SEQUENT_)
+*/
+ {
+ struct in_addr inaddr;
+
+ inaddr.s_addr = dst->host;
+ strncpy(dsthost, inet_ntoa(inaddr), sizeof(dsthost));
+ }
+/*
+#else
+ strncpy(dsthost, inet_ntoa(&dst->host), sizeof(dsthost));
+#endif
+*/
+ syslog(LOG_LOW, "failed -- %s. Error: connected to wrong host %s (%s)",
+ log_msg, socks_dst_name, socks_dst_serv);
+ ndst.cmd = SOCKS_FAIL;
+ SendDst(in, &ndst);
+ exit(1);
+ }
+
+ syslog(LOG_LOW, "connected -- %s (%s)", log_msg, socks_dst_serv);
+ ndst.port = sin.sin_port;
+ ndst.host = sin.sin_addr.s_addr;
+ SendDst(in, &ndst);
+ Pump(in, new);
+ syslog(LOG_LOW, "terminated -- %s (%s).", log_msg, socks_dst_serv);
+ syslog(LOG_LOW, "%lu bytes from %s, %lu bytes from %s", from_in, socks_src_name, from_out, socks_dst_name);
+}
+
+/*
+** Now just pump the packets/character through..
+*/
+Pump(in, out)
+int in, out;
+{
+ static char buf[4096];
+ fd_set fds;
+ int n, fdsbits;
+ static struct timeval tout = { SOCKS_TIMEOUT, 0 };
+/* >>> Andy McFadden fadden@uts.amdahl.com */
+ struct linger ling; /* for linger */
+ int length; /* for linger */
+
+ alarm(0);
+
+ /*
+ * ATM: use SO_LINGER so it won't hang up on client
+ */
+ ling.l_onoff = 1; /* turn it on */
+ ling.l_linger = /*3*/ 10;
+ length = sizeof(ling);
+ if (setsockopt(in, SOL_SOCKET, SO_LINGER, &ling, length) < 0)
+ perror("setsockopt (SO_LINGER) in");
+ if (setsockopt(out, SOL_SOCKET, SO_LINGER, &ling, length) < 0)
+ perror("setsockopt (SO_LINGER) out");
+/* <<< Andy McFadden fadden@uts.amdahl.com */
+
+ FD_ZERO(&fds);
+ if (in > out)
+ fdsbits = in + 1;
+ else
+ fdsbits = out +1;
+
+ while (1) {
+ tout.tv_sec = SOCKS_TIMEOUT;
+ tout.tv_usec = 0;
+ FD_SET(in, &fds);
+ FD_SET(out, &fds);
+ if ((n = select(fdsbits, &fds, NULL,NULL, &tout)) > 0) {
+ if (FD_ISSET(in, &fds)) {
+ if ((n = read(in, buf, sizeof buf)) > 0) {
+ from_in += n;
+ if (write(out, buf, n) < 0) {
+ goto bad;
+ }
+ } else {
+ goto bad;
+ }
+ }
+ if (FD_ISSET(out, &fds)) {
+ if ((n = read(out, buf, sizeof buf)) > 0) {
+ from_out += n;
+ if (write(in, buf, n) < 0) {
+ goto bad;
+ }
+ } else {
+ goto bad;
+ }
+ }
+ } else {
+ if (n != 0)
+ syslog(LOG_LOW, "select %m\n");
+ goto bad;
+ }
+ }
+
+bad:
+ ; /* Make the goto happy */
+}
+
+
+#ifdef FOR_PS
+
+/*
+** SETPROCTITLE -- set process title for ps
+**
+** Parameters:
+** fmt -- a printf style format string.
+** a, b, c -- possible parameters to fmt.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Clobbers argv of our main procedure so ps(1) will
+** display the title.
+**
+** Stolen from IDA Sendmail - I don't think it's UCB code.
+*/
+
+/*VARARGS1*/
+setproctitle(buf, Argv, LastArgv)
+char *buf;
+char **Argv, *LastArgv;
+{
+#if defined(FOR_PS) && !defined(SYSV)
+ register char *p;
+ register int i;
+
+ /* make ps print "(sockd)" */
+ p = Argv[0];
+ *p++ = '-';
+
+ i = strlen(buf);
+ if (i > LastArgv - p - 2)
+ {
+ i = LastArgv - p - 2;
+ buf[i] = '\0';
+ }
+ (void) strcpy(p, buf);
+ p += i;
+ while (p < LastArgv)
+ *p++ = ' ';
+#endif /* FOR_PS && !SYSV */
+}
+#endif /* #ifdef FOR_PS */
+
+#endif /* #ifndef TEST */
+
+#ifdef MULTIHOMED_SERVER
+
+static char *sockd_route_file = SOCKD_ROUTE_FILE;
+
+u_int32 sockd_route(dsthost)
+u_int32 dsthost;
+{
+ FILE *fd;
+ static char buf[1024];
+#ifdef TEST
+ char temp[1024];
+#endif
+ char *bp;
+ int linenum = 0;
+ char *argv[3];
+ int argc;
+ u_int32 interface, destip, destmask;
+
+#ifdef TEST
+ fprintf(stderr,"==== Checking routing file (%s)...\n", sockd_route_file);
+#endif
+
+ if ((fd = fopen(sockd_route_file, "r")) == NULL) {
+#ifdef TEST
+ fprintf(stderr, "Unable to open routing file (%s)\n", sockd_route_file);
+ return(0);
+#else
+ syslog(LOG_HIGH, "Unable to open routing file (%s)", sockd_route_file);
+ exit(1);
+#endif
+ }
+
+ while (fgets(buf, sizeof(buf) - 1, fd) != NULL) {
+ linenum++;
+#ifdef TEST
+ strcpy(temp, buf);
+#endif
+ /* Comment starts with # anywhere in the line */
+ if ((bp = index(buf, '\n')) != NULL)
+ *bp ='\0';
+ for (bp = buf; *bp; bp++ ) {
+ if (*bp == '#') {
+ *bp = '\0';
+ break;
+ } else if (*bp == '\t')
+ *bp = ' ';
+ }
+ mkargs(buf, &argc, argv, 3);
+ if (argc == 0)
+ continue;
+ if (argc != 3) {
+#ifdef TEST
+ fprintf(stderr, "Invalid entry at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid entry at line %d", linenum);
+#endif
+ continue;
+ }
+ GetAddr(argv[0], &interface);
+ GetAddr(argv[1], &destip);
+ GetAddr(argv[2], &destmask);
+#ifdef OLD_CONF_MASK
+ if ((destip & ~destmask) == (dsthost & ~destmask)) {
+#else
+ if ((destip & destmask) == (dsthost & destmask)) {
+#endif
+#ifdef TEST
+ fprintf(stderr, "Line %d: %s", linenum, temp);
+#endif
+ fclose(fd);
+ return(interface);
+ }
+ }
+ fclose(fd);
+#ifdef TEST
+/*
+# if defined(SOLARIS) || defined(NeXT) || defined(_SEQUENT_)
+*/
+ {
+ struct in_addr inaddr;
+
+ inaddr.s_addr = dsthost;
+ fprintf(stderr, "***Cannot find appropriate interface to communicate with %s\n", inet_ntoa(inaddr));
+ }
+/*
+# else
+ fprintf(stderr, "***Cannot find appropriate interface to communicate with %s\n", inet_ntoa(&dsthost));
+# endif
+*/
+ return(0);
+#else
+/*
+# if defined(SOLARIS) || defined(NeXT) || defined(_SEQUENT_)
+*/
+ {
+ struct in_addr inaddr;
+
+ inaddr.s_addr = dsthost;
+ syslog(LOG_HIGH, "***Cannot find appropriate interface to communicate with %s\n", inet_ntoa(inaddr));
+ }
+/*
+# else
+ syslog(LOG_HIGH, "***Cannot find appropriate interface to communicate with %s\n", inet_ntoa(&dsthost));
+# endif
+*/
+ exit(1);
+#endif
+}
+
+#endif /* #ifdef MULTIHOMED_SERVER */
+
+check_sp_conf(fd, s, src, dst)
+FILE *fd;
+char *s;
+struct sockaddr_in *src, *dst;
+{
+ char buf[1024], *p;
+#ifdef TEST
+ int linenum = 0;
+#endif
+ while (fgets(buf, sizeof(buf) - 1, fd) != NULL) {
+ if ((p = index(buf, '\n')) != NULL)
+ *p = '\0';
+#ifdef TEST
+ linenum++;
+#endif
+ if (strncmp(s, buf, strlen(s)) == 0) {
+#ifdef TEST
+ fprintf(stderr,"Line %d: %s\n", linenum, buf);
+#endif
+ shell_cmd(buf+strlen(s), src, dst);
+ break;
+ }
+ }
+ return;
+}
+
+Validate(src, dst, in, identd)
+struct sockaddr_in *src, *dst;
+int in;
+int identd;
+{
+ FILE *fd;
+ static char buf[1024];
+#ifdef TEST
+ char temp[1024];
+#endif
+ char *bp;
+ int linenum = 0, permit;
+ char *argv[10];
+ int argc;
+ u_int32 saddr, smask, daddr, dmask;
+ unsigned short dport;
+ enum { e_lt, e_gt, e_eq, e_neq, e_le, e_ge, e_nil } tst;
+ char *userlist;
+ int next_arg;
+ unsigned short dst_sin_port = ntohs(dst->sin_port); /* dst->sin_port in host byte order */
+ long p;
+ char *cmdp;
+ int use_identd;
+ IDENT *ident_lookup(), *idp;
+
+
+ if ((fd = fopen(sockd_conf, "r")) == NULL) {
+#ifdef TEST
+ fprintf(stderr,"Unable to open config file (%s)\n", sockd_conf);
+#else /* #ifdef TEST */
+ syslog(LOG_HIGH, "Unable to open config file (%s)", sockd_conf);
+#endif /* #ifdef TEST */
+
+ return 0;
+ }
+ while (fgets(buf, sizeof(buf) - 1, fd) != NULL) {
+ linenum++;
+ use_identd = identd;
+#ifdef TEST
+ strcpy(temp, buf);
+#endif
+ /*
+ ** Comments start with a '#' anywhere on the line
+ */
+ cmdp = (char *)0;
+ if ((bp = index(buf, '\n')) != NULL)
+ *bp = '\0';
+ for (bp = buf; *bp != '\0'; bp++) {
+ if (*bp == ':') {
+ *bp++ = '\0';
+ cmdp = bp;
+ break;
+ } else if (*bp == '#') {
+ *bp = '\0';
+ break;
+ } else if (*bp == '\t')
+ *bp = ' ';
+ }
+
+ mkargs(buf, &argc, argv, 8);
+ if (argc == 0)
+ continue;
+ if ((argc < 3) || (argc > 9)) {
+#ifdef TEST
+ fprintf(stderr, "Invalid entry at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid entry at line %d", linenum);
+#endif
+ continue;
+ }
+
+ if (STREQ(argv[0], "permit")) {
+ permit = 1;
+ } else if (STREQ(argv[0], "deny")) {
+ permit = 0;
+ } else {
+#ifdef TEST
+ fprintf(stderr, "Invalid permit/deny field at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid permit/deny field at line %d", linenum);
+#endif
+ continue;
+ }
+
+ userlist = (char *)0;
+ next_arg = 1;
+
+ if (strncmp(argv[next_arg], "?=", 2) == 0) {
+ switch (argv[next_arg++][2]) {
+#ifdef TEST
+ case 'I':
+ case 'i':
+ break;
+#else /* TEST not defined */
+ case 'I':
+ use_identd = 2;
+ break;
+ case 'i':
+ use_identd = 1;
+ break;
+#endif /* #ifdef TEST */
+ case 'n':
+ case '\0':
+ use_identd = 0;
+ break;
+ default:
+#ifdef TEST
+ fprintf(stderr, "Invalid ?= field at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid ?= field at line %d", linenum);
+#endif
+ continue;
+ }
+ }
+ if (strncmp(argv[next_arg], "*=", 2) == 0) {
+ if (argv[next_arg][2]) userlist = argv[next_arg] + 2;
+ next_arg++;
+ }
+ if(argc <= next_arg+1) {
+#ifdef TEST
+ fprintf(stderr, "Invalid entry at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid entry at line %d", linenum);
+#endif
+ continue;
+ }
+
+ GetAddr(argv[next_arg++], &saddr);
+ GetAddr(argv[next_arg++], &smask);
+
+ if ((argc > next_arg + 1) &&
+ !(STREQ(argv[next_arg], "eq") || STREQ(argv[next_arg], "neq") ||
+ STREQ(argv[next_arg], "lt") || STREQ(argv[next_arg], "gt") ||
+ STREQ(argv[next_arg], "le") || STREQ(argv[next_arg], "ge"))) {
+ GetAddr(argv[next_arg++], &daddr);
+ GetAddr(argv[next_arg++], &dmask);
+
+ } else {
+ daddr = 0;
+#ifdef OLD_CONF_MASK
+ dmask = ~0;
+#else
+ dmask = 0;
+#endif
+ }
+ if (argc > next_arg + 1) {
+ if (STREQ(argv[next_arg], "eq"))
+ tst = e_eq;
+ else if (STREQ(argv[next_arg], "neq"))
+ tst = e_neq;
+ else if (STREQ(argv[next_arg], "lt"))
+ tst = e_lt;
+ else if (STREQ(argv[next_arg], "gt"))
+ tst = e_gt;
+ else if (STREQ(argv[next_arg], "le"))
+ tst = e_le;
+ else if (STREQ(argv[next_arg], "ge"))
+ tst = e_ge;
+ else {
+#ifdef TEST
+ fprintf(stderr, "Invalid comparison at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid comparison at line %d", linenum);
+#endif
+ continue;
+ }
+
+ if (((p = GetPort(argv[next_arg+1])) < 0) ||
+ (p >= (1L << 16))) {
+#ifdef TEST
+ fprintf(stderr, "Invalid port number at line %d\n", linenum);
+#else
+ syslog(LOG_LOW, "Invalid port number at line %d", linenum);
+#endif
+ continue;
+ } else {
+ dport = p;
+ }
+ } else {
+ tst = e_nil;
+ dport = 0;
+ }
+
+#ifdef DEBUG
+ {
+ char msg[1024];
+ if (userlist)
+ sprintf(msg,"%s %s 0x%08x 0x%08x 0x%08x 0x%08x %s %u",
+ permit ? "permit" : "deny",
+ userlist,
+ saddr, smask, daddr, dmask,
+ tst == e_eq ? "==" :
+ tst == e_neq ? "!=" :
+ tst == e_lt ? "<" :
+ tst == e_gt ? ">" :
+ tst == e_le ? "<=" :
+ tst == e_ge ? ">=" : "NIL",
+ dport);
+ else
+ sprintf(msg,"%s 0x%08x 0x%08x 0x%08x 0x%08x %s %u",
+ permit ? "permit" : "deny",
+ saddr, smask, daddr, dmask,
+ tst == e_eq ? "==" :
+ tst == e_neq ? "!=" :
+ tst == e_lt ? "<" :
+ tst == e_gt ? ">" :
+ tst == e_le ? "<=" :
+ tst == e_ge ? ">=" : "NIL",
+ dport);
+ syslog(LOG_LOW, "%s", msg);
+ }
+#endif
+ /* comparisons of port numbers must be done in host order */
+
+#ifdef OLD_CONF_MASK
+ if((saddr & ~smask) == (src->sin_addr.s_addr & ~smask) &&
+ (daddr & ~dmask) == (dst->sin_addr.s_addr & ~dmask) &&
+#else
+ if((saddr & smask) == (src->sin_addr.s_addr & smask) &&
+ (daddr & dmask) == (dst->sin_addr.s_addr & dmask) &&
+#endif
+ check_user(userlist, socks_src_user)) {
+ if (tst == e_nil)
+ goto GotIt;
+ if ((tst == e_eq) && (dst_sin_port == dport))
+ goto GotIt;
+ if ((tst == e_neq) && (dst_sin_port != dport))
+ goto GotIt;
+ if ((tst == e_lt) && (dst_sin_port < dport))
+ goto GotIt;
+ if ((tst == e_gt) && (dst_sin_port > dport))
+ goto GotIt;
+ if ((tst == e_le) && (dst_sin_port <= dport))
+ goto GotIt;
+ if ((tst == e_ge) && (dst_sin_port >= dport))
+ goto GotIt;
+ }
+ }
+
+ fclose(fd);
+#ifdef TEST
+ fprintf(stderr, "*** No match with any line. Access denied.\n");
+#endif
+ return 0;
+
+GotIt:
+#ifdef TEST
+ fprintf(stderr, "Line %d: %s", linenum, temp);
+ fseek(fd, 0L, 0);
+ if(permit && use_identd)
+ permit = use_identd;
+ if (permit == -3)
+ check_sp_conf(fd, "#BAD_ID:", src, dst);
+ else if ((permit == -1) || (permit == -2))
+ check_sp_conf(fd, "#NO_IDENTD:", src, dst);
+
+#else /* # TEST not defined */
+ if ((use_identd == 0) || (permit == 0)) {
+ fclose(fd);
+ if (cmdp != (char *)0) {
+ shell_cmd(cmdp, src, dst);
+ }
+ return permit;
+ }
+ fseek(fd, 0L, 0);
+ if ((idp = ident_lookup(in, IDENTD_TIMEOUT)) == ((IDENT *)0)) {
+ check_sp_conf(fd, "#NO_IDENTD:", src, dst);
+ permit = -use_identd;
+ } else {
+ strncpy(socks_real_user, idp->identifier, sizeof(socks_real_user));
+ if (strcmp(socks_src_user, socks_real_user)) {
+#if defined(SUPPORT_RCMD)
+ if ((socks_client_port >= IPPORT_RESERVED) ||
+ (socks_client_port < IPPORT_RESERVED/2) ||
+ strcmp(socks_src_user, "root")) {
+#endif /* #if defined(SUPPORT_RCMD) */
+ permit = -3;
+#if defined(SUPPORT_RCMD)
+ }
+#endif /* #if defined(SUPPORT_RCMD) */
+ }
+ }
+ ident_free(idp);
+#endif /* #ifdef TEST */
+ fclose(fd);
+ if ((permit >= -1) && cmdp)
+ shell_cmd(cmdp, src, dst);
+ return permit;
+}
+
+/*-------------------------------------------------*/
+
+#ifdef TEST
+
+char *testpname;
+
+error_and_quit()
+{
+#ifdef MULTIHOMED_SERVER
+ fprintf(stderr, "Usage:\n%s [-i] [-I] [-B] [-R route_file] [-C conf_file] user src_addr dst_addr {service,port}\n", testpname);
+#else
+ fprintf(stderr, "Usage:\n%s [-i] [-I] [-B] [-C conf_file] user src_addr dst_addr {service,port}\n", testpname);
+#endif
+ exit(-1);
+}
+
+main(argc, argv)
+int argc;
+char *argv[];
+
+/*
+ * test_sockd_conf [-i] [-I] [-B] [-R route_file] [-C conf_file] user src_addr dst_addr {service,port}
+ *
+ * Prints out the line in configuration file that are examined and
+ * whether the access is permitted or denied. Sets exit status code
+ * to 1 for permit, 0 for deny, -1 for error in command line.
+ */
+
+{
+ int next = 1;
+ long p;
+ u_short port;
+ struct sockaddr_in from, dstsin;
+ char log_msg[1024];
+ char command = SOCKS_CONNECT;
+ int sim_id = 0;
+ char buf[1024];
+ int permit;
+ int in = 0;
+
+ bzero((char *)&from, sizeof(from));
+ bzero((char *)&dstsin, sizeof(dstsin));
+ if(testpname = rindex(argv[0], '/'))
+ ++testpname;
+ else
+ testpname = argv[0];
+
+ while (--argc && (argv[next][0] == '-')) {
+ switch (argv[next++][1]) {
+ case 'B':
+ sim_id = -3;
+ break;
+ case 'C':
+ if (--argc) {
+ sockd_conf =argv[next++];
+ break;
+ } else
+ error_and_quit();
+ case 'I':
+ sim_id = -2;
+ break;
+#ifdef MULTIHOMED_SERVER
+ case 'R':
+ if (--argc) {
+ sockd_route_file =argv[next++];
+ break;
+ } else
+ error_and_quit();
+#endif
+ case 'i':
+ sim_id = -1;
+ break;
+ default:
+ error_and_quit();
+ }
+ }
+
+ if (argc != 4)
+ error_and_quit();
+
+ strncpy(socks_src_user, argv[next++], sizeof(socks_src_user));
+ GetAddr(argv[next++], &from.sin_addr.s_addr);
+ GetAddr(argv[next++], &dstsin.sin_addr.s_addr);
+ if (((p = GetPort(argv[next])) < 0) || (p >= (1L << 16))) {
+ fprintf(stderr, "%s: Unknown service or illegal port number '%s'\n",testpname, argv[next]);
+ exit(-1);
+ }
+ dstsin.sin_port = htons(port = p);
+
+ if (sim_id)
+ strcpy(socks_real_user,"unknown");
+ else
+ strcpy(socks_real_user, socks_src_user);
+
+ saddrtoname(&from.sin_addr, socks_src_name, sizeof(socks_src_name));
+ saddrtoname(&dstsin.sin_addr, socks_dst_name, sizeof(socks_dst_name));
+ porttoserv(dstsin.sin_port, socks_dst_serv, sizeof(socks_dst_serv));
+ sprintf(log_msg, "connect from %s(%s)@%s to %s (%s)",
+ socks_src_user, socks_real_user, socks_src_name, socks_dst_name, socks_dst_serv);
+#ifdef LOG_DAEMON
+ openlog(testpname, LOG_PID, SYSLOG_FAC);
+#else
+ openlog(testpname, LOG_PID);
+#endif
+
+ strcpy(buf, inet_ntoa(from.sin_addr));
+ fprintf(stderr, "USER:%s, SRC:%s, DST:%s, PORT:%u\n",
+ socks_src_user, buf, inet_ntoa(dstsin.sin_addr),
+ ntohs(dstsin.sin_port));
+
+ permit = Validate(&from, &dstsin, in, sim_id);
+
+ switch (permit) {
+ case 0:
+ syslog(LOG_LOW, "refused -- %s", log_msg);
+ exit(0);
+ case -3:
+ syslog(LOG_LOW, "*Alert*: real user is %s, not %s", socks_real_user, socks_src_user);
+ syslog(LOG_LOW, "refused -- %s", log_msg);
+ fprintf(stderr, "Access denied: bad user-id.\n");
+ exit(0);
+ case -2:
+ syslog(LOG_LOW, "cannot connect to identd on %s", socks_src_name);
+ syslog(LOG_LOW, "refused -- %s", log_msg);
+ fprintf(stderr, "Access denied: cannot verify user-id.\n");
+ exit(0);
+ case -1:
+ syslog(LOG_LOW, "cannot connect to identd on %s", socks_src_name);
+ break;
+ case 1:
+ break;
+ default:
+ syslog(LOG_HIGH, "refused -- %s", log_msg);
+ syslog(LOG_HIGH, "Unexpected result from Validate");
+ exit(0);
+ }
+#ifdef MULTIHOMED_SERVER
+ if (sockd_route(dstsin.sin_addr.s_addr)) {
+#endif /* #ifdef MULTIHOMED_SERVER */
+ syslog(LOG_LOW, "connected -- %s", log_msg);
+ exit(1);
+#ifdef MULTIHOMED_SERVER
+ } else {
+ syslog(LOG_LOW, "refused -- %s", log_msg);
+ exit(0);
+ }
+#endif /* #ifdef MULTIHOMED_SERVER */
+
+}
+
+#endif /* #ifdef TEST */
diff --git a/network/socks/socks.cstc.4.2/sockd/sockd.conf.sample b/network/socks/socks.cstc.4.2/sockd/sockd.conf.sample
new file mode 100644
index 00000000..00a9f9cc
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/sockd/sockd.conf.sample
@@ -0,0 +1,5 @@
+# replace 'client_IP' below with an actual IP address before trying it
+permit client_IP 255.255.255.255
+deny 0.0.0.0 0.0.0.0 : /usr/ucb/finger @%A | /usr/ucb/mail -s 'SOCKD: rejected -- from %u@%A to host %Z (service %S)' root
+#BAD_ID: /usr/ucb/finger @%A | /usr/ucb/mail -s '%U pretends to be %u on host %A' root@%A root
+#NO_IDENTD: /usr/ucb/mail -s 'Please run identd on %A' %u@%A root@%A
diff --git a/network/socks/socks.cstc.4.2/sockd/test.csh b/network/socks/socks.cstc.4.2/sockd/test.csh
new file mode 100755
index 00000000..9eb44a96
--- /dev/null
+++ b/network/socks/socks.cstc.4.2/sockd/test.csh
@@ -0,0 +1,154 @@
+#! /bin/csh
+
+echo "deny *=bonnie,clyde 128.12.6.0 255.255.255.0 : /usr/ucb/mail -s 'Rejected SOCKS access by %u' $USER" >! junk.conf
+echo 'permit *=ylee 128.12.6.4 255.255.255.255 137.12.0.0 255.255.0.0' >> junk.conf
+echo 'deny 128.12.0.0 255.255.0.0 eq telnet' >> junk.conf
+echo 'permit 128.12.0.0 255.255.0.0' >> junk.conf
+echo "#NO_IDENTD: /usr/ucb/mail -s 'please run identd on %A' $USER" >> junk.conf
+echo "#BAD_ID: /usr/ucb/mail -s '%U pretends to be %u on %A' $USER" >> junk.conf
+#
+set prog=./test_sockd_conf
+
+strings $prog |egrep -s route_file
+if ( $status != 0 ) then
+ set aa=1
+ set opt=""
+else
+ set aa=0
+ set opt = (-R junk.route)
+ echo "129.10.1.2 10.0.0.0 255.0.0.0" >! junk.route
+ echo "129.10.7.10 137.12.0.0 255.255.0.0" >> junk.route
+ echo "129.10.254.1 0.0.0.0 0.0.0.0" >> junk.route
+endif
+
+set a=($prog $opt -C junk.conf clyde 128.12.6.34 112.3.24.1 ftp)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:clyde, SRC:128.12.6.34, DST:112.3.24.1, PORT:21"
+echo "Line 1: deny *=bonnie,clyde 128.12.6.0 255.255.255.0 : /usr/ucb/mail -s 'Rejected SOCKS access by %u' $USER"
+echo "A mail message is sent to $USER with the subject line 'Rejected SOCKS"
+echo "access by clyde'."
+echo "================================================"
+
+set a=($prog $opt -C junk.conf ylee 128.12.6.4 137.12.4.15 telnet)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:ylee, SRC:128.12.6.4, DST:137.12.4.15, PORT:23"
+echo 'Line 2: permit *=ylee 128.12.6.4 255.255.255.255 137.12.0.0 255.255.0.0'
+if ( $aa == 0 ) then
+ echo "==== Checking routing file (junk.route)..."
+ echo "Line 2: 129.10.7.10 137.12.0.0 255.255.0.0"
+endif
+echo "================================================"
+
+set a=($prog $opt -C junk.conf jane 128.12.2.13 137.12.4.15 telnet)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:jane, SRC:128.12.2.13, DST:137.12.4.15, PORT:23"
+echo "Line 3: deny 128.12.0.0 255.255.0.0 eq telnet"
+echo "================================================"
+
+set a=($prog $opt -C junk.conf jim 128.12.6.4 126.87.13.2 telnet)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:jim, SRC:128.12.6.4, DST:126.87.13.2, PORT:23"
+echo "Line 3: deny 128.12.0.0 255.255.0.0 eq telnet"
+echo "================================================"
+
+set a=($prog $opt -C junk.conf ylee 128.12.6.4 126.87.13.2 ftp)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:ylee, SRC:128.12.6.4, DST:126.87.13.2, PORT:21"
+echo "Line 4: permit 128.12.0.0 255.255.0.0"
+if ( $aa == 0 ) then
+ echo "==== Checking routing file (junk.route)..."
+ echo "Line 3: 129.10.254.1 0.0.0.0 0.0.0.0"
+endif
+echo "================================================"
+
+set a=($prog $opt -C junk.conf sam 128.12.36.7 10.53.23.1 70)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:sam, SRC:128.12.36.7, DST:10.53.23.1, PORT:70"
+echo "Line 4: permit 128.12.0.0 255.255.0.0"
+if ( $aa == 0 ) then
+ echo "==== Checking routing file (junk.route)..."
+ echo "Line 1: 129.10.1.2 10.0.0.0 255.0.0.0"
+endif
+echo "================================================"
+
+set a=($prog $opt -C junk.conf don 23.2.6.127 10.53.23.1 70)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:don, SRC:23.2.6.127, DST:10.53.23.1, PORT:70"
+echo "*** No match with any line. Access denied."
+echo "================================================"
+
+set a=($prog $opt -C junk.conf clyde 128.12.1.62 112.3.24.1 ftp)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:clyde, SRC:128.12.1.62, DST:112.3.24.1, PORT:21"
+echo "Line 4: permit 128.12.0.0 255.255.0.0"
+if ( $aa == 0 ) then
+ echo "==== Checking routing file (junk.route)..."
+ echo "Line 3: 129.10.254.1 0.0.0.0 0.0.0.0"
+endif
+echo "================================================"
+
+set a=($prog $opt -C junk.conf -I joe 128.12.6.4 126.87.13.2 ftp)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:joe, SRC:128.12.6.4, DST:126.87.13.2, PORT:21"
+echo "Line 4: permit 128.12.0.0 255.255.0.0"
+echo "Line 5: #NO_IDENTD: /usr/ucb/mail -s 'please run identd on %a' $USER"
+echo "Access denied: cannot verify user-id."
+echo "A mail message is sent to $USER of the host 128.12.6.4 with the"
+echo "subject line 'please run identd on 128.12.6.4'."
+echo "================================================"
+
+set a=($prog $opt -C junk.conf -i joe 128.12.6.4 126.87.13.2 ftp)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:joe, SRC:128.12.6.4, DST:126.87.13.2, PORT:21"
+echo "Line 4: permit 128.12.0.0 0.0.255.255"
+echo "Line 5: #NO_IDENTD: /usr/ucb/mail -s 'please run identd on %a' $USER"
+if ( $aa == 0 ) then
+ echo "==== Checking routing file (junk.route)..."
+ echo "Line 3: 129.10.254.1 0.0.0.0 0.0.0.0"
+endif
+echo "A mail message is sent to $USER of the host 128.12.6.4 with the"
+echo "subject line 'please run identd on 128.12.6.4'."
+echo "================================================"
+
+set a=($prog $opt -C junk.conf -i jim 128.12.6.4 126.87.13.2 telnet)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:jim, SRC:128.12.6.4, DST:126.87.13.2, PORT:23"
+#echo "Line 5: #NO_IDENTD: /usr/ucb/mail -s 'please run identd on %a' $USER"
+echo "Line 3: deny 128.12.0.0 0.0.255.255 eq telnet"
+echo "A mail message is sent to $USER of the host 128.12.6.4 with the"
+echo "subject line 'please run identd on 128.12.6.4'."
+echo "================================================"
+
+set a=($prog $opt -C junk.conf -B joe 128.12.6.4 126.87.13.2 ftp)
+echo $a
+$a
+echo '-------------- should produce:'
+echo "USER:joe, SRC:128.12.6.4, DST:126.87.13.2, PORT:21"
+echo "Line 4: permit 128.12.0.0 255.255.0.0"
+echo "Line 6: #BAD_ID: /usr/ucb/mail -s '%U pretends to be %u on %A' $USER"
+echo "Access denied: bad user-id."
+echo "A mail message is sent to $USER with the"
+echo "subject line 'unknown pretends to be joe on 128.12.6.4'."
+echo "================================================"
diff --git a/network/suggest/client/suggapi.c b/network/suggest/client/suggapi.c
new file mode 100644
index 00000000..c17db3cb
--- /dev/null
+++ b/network/suggest/client/suggapi.c
@@ -0,0 +1,414 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: suggapi.c
+*
+* Author: Yuri Sadykov
+*
+* Version Creation Date: 08/14/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Implementation of API for Suggest service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+*/
+
+#include <ncbinet.h>
+#include "suggapi.h"
+
+/*****************************************************************************
+ * Global variables
+ */
+static NI_HandPtr svcp = NULL;
+static Boolean num_attached = 0;
+static NI_DispatcherPtr dispatcher;
+static AsnIoPtr pAsnIn = NULL;
+static AsnIoPtr pAsnOut = NULL;
+static Boolean bSendFini = TRUE;
+
+/*****************************************************************************
+ * Function prototipes
+ */
+static Boolean
+NetInit PROTO((void));
+
+static SuggestResponsePtr
+NetSuggestReadAsn PROTO((void));
+
+static void
+ErrorFromServer PROTO((SuggestErrorPtr pError));
+
+static Boolean
+NetFini PROTO((void));
+
+
+/******************************************************************************\
+ * Exported functionts which are in API
+\******************************************************************************/
+
+/*============================================================================*\
+ * Function:
+ * SuggestInit
+ *
+ * Purpose:
+ * Initializes Suggest API
+ *
+ * Parameters:
+ * none
+ *
+ * Return:
+ * TRUE if successful, FALSE otherwise
+ *
+\*----------------------------------------------------------------------------*/
+Boolean
+SuggestInit(void)
+{
+ SuggestRequestPtr pRequest;
+ SuggestResponsePtr pResponse;
+
+/* myNetInit = SuggestInit;
+*/
+ if (!NetInit())
+ return FALSE;
+
+ svcp = NI_GenericGetService(dispatcher, NULL, "SUGGEST", "Suggest", TRUE);
+ if (svcp == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "NI_ServiceGet [%s] (%s)",
+ ni_errlist[ni_errno], ni_errtext);
+ SuggestFini();
+
+ return FALSE;
+ }
+
+ pAsnIn = svcp->raip;
+ pAsnOut = svcp->waip;
+
+ pRequest = ValNodeNew(NULL);
+ pRequest->choice = SuggestRequest_init;
+ SuggestRequestAsnWrite (pRequest, pAsnOut, NULL);
+ AsnIoReset(pAsnOut);
+ SuggestRequestFree(pRequest);
+
+ if ((pResponse = NetSuggestReadAsn()) == NULL)
+ {
+ return FALSE;
+ }
+
+ if (pResponse->choice == SuggestResponse_error) {
+ ErrorFromServer(pResponse->data.ptrvalue);
+ if (((SuggestErrorPtr)pResponse->data.ptrvalue)->level
+ == Suggest_error_level_fatal)
+ bSendFini = FALSE;
+ SuggestFini();
+ SuggestResponseFree(pResponse->data.ptrvalue);
+
+ return FALSE;
+ }
+
+ pResponse->data.ptrvalue = NULL;
+ SuggestResponseFree(pResponse);
+
+ return TRUE;
+}
+
+/*============================================================================*\
+ * Function:
+ * SuggestFini
+ *
+ * Purpose:
+ * Frees all resources allocated by the API.
+ *
+ * Parameters:
+ * none
+ *
+ * Return:
+ * TRUE if successful, FALSE otherwise
+ *
+\*----------------------------------------------------------------------------*/
+Boolean
+SuggestFini(void)
+{
+ short erract;
+ ErrDesc err;
+ Boolean retval = TRUE;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ if (pAsnOut != NULL && pAsnIn != NULL && bSendFini)
+ {
+ SuggestRequestPtr pReq;
+ SuggestResponsePtr pResp;
+
+ pReq = ValNodeNew(NULL);
+ pReq->choice = SuggestRequest_fini;
+ SuggestRequestAsnWrite(pReq, pAsnOut, NULL);
+ AsnIoReset(pAsnOut);
+ SuggestRequestFree(pReq);
+
+ if ((pResp = NetSuggestReadAsn()) == NULL) {
+ retval = FALSE;
+ } else {
+ pResp->data.ptrvalue = NULL;
+ SuggestResponseFree(pResp);
+ retval = TRUE;
+ }
+ }
+
+ NetFini();
+
+ ErrSetOpts(erract, 0);
+ ErrFetch(&err);
+
+ return retval;
+}
+
+/*============================================================================*\
+ * Function:
+ * SuggestFindIntervals
+ *
+ * Purpose:
+ *
+ *
+ * Parameters:
+ * pIntervals - pointer to SuggestIntervals structure which contains
+ * the data for processing;
+ *
+ * Return:
+ * pointer to SeqAnnot structure which will contain the result of
+ * the processing or NULL if error occured.
+ *
+ * Note:
+ * SuggestResponse structure can contain an error from Suggest Server, so
+ * if this function returns not NULL it does not mean that all right. The
+ * caller of this function should check the structure on errors.
+ *
+ * This function does not free input structure pointed pIntervals.
+ *
+\*----------------------------------------------------------------------------*/
+SeqAnnotPtr SuggestFindIntervals(SuggestIntervalsPtr pIntervals)
+{
+ SuggestRequestPtr pReq;
+ SuggestResponsePtr pResp;
+ SeqAnnotPtr pSeqAnnot;
+
+ if (pIntervals == NULL)
+ return NULL;
+
+ /* Create request and send it to the server
+ */
+ pReq = ValNodeNew(NULL);
+ if (pReq == NULL)
+ return NULL;
+
+ pReq->choice = SuggestRequest_intervals;
+ pReq->data.ptrvalue = pIntervals;
+ SuggestRequestAsnWrite(pReq, pAsnOut, NULL);
+ AsnIoReset(pAsnOut);
+
+ pReq->data.ptrvalue = NULL; /* The function doesn't free input data */
+ SuggestRequestFree(pReq);
+
+ /* Read response from the server
+ */
+ pResp = NetSuggestReadAsn();
+ if (pResp == NULL)
+ return NULL;
+
+ if (pResp->choice == SuggestResponse_error) {
+ /* Error occured on server's side, report it
+ */
+ ErrorFromServer(pResp->data.ptrvalue);
+ SuggestResponseFree(pResp);
+
+ return NULL;
+ }
+
+ pSeqAnnot = pResp->data.ptrvalue;
+ pResp->data.ptrvalue = NULL;
+ SuggestResponseFree(pResp);
+
+ return pSeqAnnot;
+}
+
+
+/******************************************************************************\
+ * Internal functions which specific to internal implementation of the API
+\******************************************************************************/
+
+/*============================================================================*\
+ * Function:
+ * NetInit
+ *
+ * Purpose:
+ *
+ *
+ * Parameters:
+ * none
+ *
+ * Return:
+ * TRUE if successful, FALSE otherwise
+ *
+\*----------------------------------------------------------------------------*/
+static Boolean
+NetInit(void)
+{
+ if (num_attached++ > 0)
+ return TRUE;
+
+ return ((dispatcher = NI_GenericInit(NULL, NULL, TRUE, NULL, 0)) != NULL);
+}
+
+/*============================================================================*\
+ * Function:
+ * NetSuggestReadAsn
+ *
+ * Purpose:
+ * Reads SuggestResponse from network file.
+ *
+ * Parameters:
+ * none
+ *
+ * Return:
+ * Pointer to read SuggestResponse structure.
+ *
+\*----------------------------------------------------------------------------*/
+static SuggestResponsePtr
+NetSuggestReadAsn(void)
+{
+ SuggestResponsePtr pSuggResp;
+ short erract;
+ ErrDesc err;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err); /* clear any pending error */
+
+ pSuggResp = SuggestResponseAsnRead(pAsnIn, NULL);
+
+ if (ErrFetch(&err))
+ {
+ ErrPost(CTX_UNKNOWN, 1, "Null message read from server");
+ }
+ ErrSetOpts(erract, 0);
+
+ return pSuggResp;
+}
+
+/*============================================================================*\
+ * Function:
+ * ErrorFromServer
+ *
+ * Purpose:
+ * Reports message on error which was send by suggest server
+ *
+ * Parameters:
+ * pError - pointer on SuggestError structure which was sent
+ * by the server;
+ *
+ * Return:
+ * none
+ *
+\*----------------------------------------------------------------------------*/
+static void
+ErrorFromServer(SuggestErrorPtr pError)
+{
+ char *pchErrorType;
+ ErrSev errSev;
+
+ if (pError == NULL)
+ return;
+
+ switch (pError->level) {
+ case Suggest_error_level_none:
+ return;
+
+ case Suggest_error_level_info:
+ pchErrorType = "INFO";
+ errSev = SEV_INFO;
+ break;
+
+ case Suggest_error_level_warn:
+ pchErrorType = "WARNING";
+ errSev = SEV_WARNING;
+ break;
+
+ case Suggest_error_level_error:
+ pchErrorType = "ERROR";
+ errSev = SEV_ERROR;
+ break;
+
+ case Suggest_error_level_fatal:
+ pchErrorType = "FATAL";
+ errSev = SEV_ERROR;
+ break;
+ }
+
+ ErrPostEx(errSev, 0, 0, "%s from Suggest Server: %s",
+ pchErrorType, pError->msg);
+}
+
+/*============================================================================*\
+ * Function:
+ * NetFini
+ *
+ * Purpose:
+ *
+ *
+ * Parameters:
+ *
+ *
+ * Return:
+ * TRUE if successful, FALSE otherwise
+ *
+\*----------------------------------------------------------------------------*/
+static Boolean
+NetFini(void)
+{
+ if (num_attached > 0)
+ num_attached--;
+
+ if (num_attached == 0)
+ {
+ NI_ServiceDisconnect(svcp);
+ svcp = NULL;
+ NI_EndServices (dispatcher);
+ dispatcher = NULL;
+ }
+
+ return TRUE;
+}
diff --git a/network/suggest/client/suggapi.h b/network/suggest/client/suggapi.h
new file mode 100644
index 00000000..bc68f562
--- /dev/null
+++ b/network/suggest/client/suggapi.h
@@ -0,0 +1,71 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: suggapi.h
+*
+* Author: Yuri Sadykov
+*
+* Version Creation Date: 08/14/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Header file for API for Suggest service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+*/
+
+#ifndef __suggapi_h__
+#define __suggapi_h__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef _NCBI_Seq_
+#include <objseq.h>
+#endif /* _NCBI_Seq_ */
+
+#ifndef _suggen_
+#include "suggen.h"
+#endif /* _suggen_ */
+
+Boolean SuggestInit PROTO((void));
+Boolean SuggestFini PROTO((void));
+SeqAnnotPtr SuggestFindIntervals PROTO((SuggestIntervalsPtr pIntervals));
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#endif /* __suggapi_h__ */
diff --git a/network/suggest/client/suggcli.c b/network/suggest/client/suggcli.c
new file mode 100644
index 00000000..36b9748c
--- /dev/null
+++ b/network/suggest/client/suggcli.c
@@ -0,0 +1,87 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: suggcli.c
+*
+* Author: Yuri Sadykov
+*
+* Version Creation Date: 08/14/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Demo of using API for Suggest service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+*/
+
+#include <ncbi.h>
+#include "suggapi.h"
+
+Int2 Main()
+{
+ AsnIoPtr pAsnIn;
+ AsnIoPtr pAsnOut;
+ SeqAnnotPtr pSeqAnnot;
+ SuggestIntervalsPtr pIntervals;
+
+ pAsnIn = AsnIoOpen("test.in", "r");
+ if (pAsnIn == NULL)
+ exit(1);
+
+ pAsnOut = AsnIoOpen("test.out", "w");
+ if (pAsnOut == NULL)
+ exit(2);
+
+ if (!SuggestInit())
+ exit(3);
+
+ pIntervals = SuggestIntervalsAsnRead(pAsnIn, NULL);
+ if (pIntervals == NULL)
+ exit(4);
+
+ pSeqAnnot = SuggestFindIntervals(pIntervals);
+ if (pSeqAnnot == NULL)
+ exit(5);
+
+ SeqAnnotAsnWrite(pSeqAnnot, pAsnOut, NULL);
+ AsnIoReset(pAsnOut);
+
+ AsnIoClose(pAsnOut);
+ AsnIoClose(pAsnIn);
+
+ if (!SuggestFini())
+ exit(6);
+
+ return 0;
+}
diff --git a/network/suggest/client/suggen.c b/network/suggest/client/suggen.c
new file mode 100644
index 00000000..bd3255ef
--- /dev/null
+++ b/network/suggest/client/suggen.c
@@ -0,0 +1,1005 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: suggen.c
+*
+* Author: Yuri Sadykov
+*
+* Version Creation Date: 08/14/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+*/
+
+#define NLM_GENERATED_CODE_PROTO
+
+#include "sugprefx.h"
+#include "suggen.h"
+
+static Boolean loaded = FALSE;
+
+#include "sugmap.h"
+
+#ifndef NLM_EXTERN_LOADS
+#define NLM_EXTERN_LOADS {}
+#endif
+
+Boolean LIBCALL
+suggenAsnLoad(void)
+{
+
+ if ( ! loaded) {
+ NLM_EXTERN_LOADS
+
+ if ( ! AsnLoad ())
+ return FALSE;
+ loaded = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/**************************************************
+* Generated object loaders for Module NCBI-Suggest
+* Generated using ASNCODE Revision: 4.0 at Aug 16, 1995 2:17 PM
+*
+**************************************************/
+
+
+/**************************************************
+*
+* SuggestRequestFree()
+*
+**************************************************/
+
+SuggestRequestPtr LIBCALL
+SuggestRequestFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case SuggestRequest_intervals:
+ SuggestIntervalsFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* SuggestRequestAsnRead()
+*
+**************************************************/
+
+SuggestRequestPtr LIBCALL
+SuggestRequestAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* SuggestRequest ::= (self contained) */
+ atp = AsnReadId(aip, amp, SUGGEST_REQUEST);
+ } else {
+ atp = AsnLinkType(orig, SUGGEST_REQUEST); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == SUGGEST_REQUEST_init) {
+ choice = SuggestRequest_init;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == SUGGEST_REQUEST_intervals) {
+ choice = SuggestRequest_intervals;
+ func = (AsnReadFunc) SuggestIntervalsAsnRead;
+ }
+ else if (atp == SUGGEST_REQUEST_fini) {
+ choice = SuggestRequest_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* SuggestRequestAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+SuggestRequestAsnWrite(SuggestRequestPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, SUGGEST_REQUEST); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case SuggestRequest_init:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, SUGGEST_REQUEST_init, &av);
+ break;
+ case SuggestRequest_intervals:
+ writetype = SUGGEST_REQUEST_intervals;
+ func = (AsnWriteFunc) SuggestIntervalsAsnWrite;
+ break;
+ case SuggestRequest_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, SUGGEST_REQUEST_fini, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* SuggestIntervalsNew()
+*
+**************************************************/
+
+SuggestIntervalsPtr LIBCALL
+SuggestIntervalsNew(void)
+{
+ SuggestIntervalsPtr ptr = MemNew((size_t) sizeof(SuggestIntervals));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* SuggestIntervalsFree()
+*
+**************************************************/
+
+SuggestIntervalsPtr LIBCALL
+SuggestIntervalsFree(SuggestIntervalsPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ SuggestParametersFree(ptr -> params);
+ SeqEntryFree(ptr -> dna);
+ SeqEntryFree(ptr -> protein);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* SuggestIntervalsAsnRead()
+*
+**************************************************/
+
+SuggestIntervalsPtr LIBCALL
+SuggestIntervalsAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ SuggestIntervalsPtr ptr;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* SuggestIntervals ::= (self contained) */
+ atp = AsnReadId(aip, amp, SUGGEST_INTERVALS);
+ } else {
+ atp = AsnLinkType(orig, SUGGEST_INTERVALS);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = SuggestIntervalsNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == SUGGEST_INTERVALS_params) {
+ ptr -> params = SuggestParametersAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SUGGEST_INTERVALS_dna) {
+ ptr -> dna = SeqEntryAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SUGGEST_INTERVALS_protein) {
+ ptr -> protein = SeqEntryAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SUGGEST_INTERVALS_code) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> code = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = SuggestIntervalsFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* SuggestIntervalsAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+SuggestIntervalsAsnWrite(SuggestIntervalsPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, SUGGEST_INTERVALS); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> params != NULL) {
+ if ( ! SuggestParametersAsnWrite(ptr -> params, aip, SUGGEST_INTERVALS_params)) {
+ goto erret;
+ }
+ }
+ if (ptr -> dna != NULL) {
+ if ( ! SeqEntryAsnWrite(ptr -> dna, aip, SUGGEST_INTERVALS_dna)) {
+ goto erret;
+ }
+ }
+ if (ptr -> protein != NULL) {
+ if ( ! SeqEntryAsnWrite(ptr -> protein, aip, SUGGEST_INTERVALS_protein)) {
+ goto erret;
+ }
+ }
+ av.intvalue = ptr -> code;
+ retval = AsnWrite(aip, SUGGEST_INTERVALS_code, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* SuggestParametersNew()
+*
+**************************************************/
+
+SuggestParametersPtr LIBCALL
+SuggestParametersNew(void)
+{
+ SuggestParametersPtr ptr = MemNew((size_t) sizeof(SuggestParameters));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* SuggestParametersFree()
+*
+**************************************************/
+
+SuggestParametersPtr LIBCALL
+SuggestParametersFree(SuggestParametersPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* SuggestParametersAsnRead()
+*
+**************************************************/
+
+SuggestParametersPtr LIBCALL
+SuggestParametersAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ SuggestParametersPtr ptr;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* SuggestParameters ::= (self contained) */
+ atp = AsnReadId(aip, amp, SUGGEST_PARAMETERS);
+ } else {
+ atp = AsnLinkType(orig, SUGGEST_PARAMETERS);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = SuggestParametersNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == SUGGEST_PARAMETERS_size) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> size = av.intvalue;
+ ptr -> OBbits__ |= 1<<0;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SUGGEST_PARAMETERS_begin_search) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> begin_search = av.intvalue;
+ ptr -> OBbits__ |= 1<<1;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SUGGEST_PARAMETERS_end_search) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> end_search = av.intvalue;
+ ptr -> OBbits__ |= 1<<2;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SUGGEST_PARAMETERS_term_stop) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> term_stop = av.boolvalue;
+ ptr -> OBbits__ |= 1<<3;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = SuggestParametersFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* SuggestParametersAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+SuggestParametersAsnWrite(SuggestParametersPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, SUGGEST_PARAMETERS); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> size || (ptr -> OBbits__ & (1<<0) )){ av.intvalue = ptr -> size;
+ retval = AsnWrite(aip, SUGGEST_PARAMETERS_size, &av);
+ }
+ if (ptr -> begin_search || (ptr -> OBbits__ & (1<<1) )){ av.intvalue = ptr -> begin_search;
+ retval = AsnWrite(aip, SUGGEST_PARAMETERS_begin_search, &av);
+ }
+ if (ptr -> end_search || (ptr -> OBbits__ & (1<<2) )){ av.intvalue = ptr -> end_search;
+ retval = AsnWrite(aip, SUGGEST_PARAMETERS_end_search, &av);
+ }
+ if (ptr -> term_stop || (ptr -> OBbits__ & (1<<3) )){ av.boolvalue = ptr -> term_stop;
+ retval = AsnWrite(aip, SUGGEST_PARAMETERS_term_stop, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* SuggestErrorNew()
+*
+**************************************************/
+
+SuggestErrorPtr LIBCALL
+SuggestErrorNew(void)
+{
+ SuggestErrorPtr ptr = MemNew((size_t) sizeof(SuggestError));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* SuggestErrorFree()
+*
+**************************************************/
+
+SuggestErrorPtr LIBCALL
+SuggestErrorFree(SuggestErrorPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> msg);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* SuggestErrorAsnRead()
+*
+**************************************************/
+
+SuggestErrorPtr LIBCALL
+SuggestErrorAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ SuggestErrorPtr ptr;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* SuggestError ::= (self contained) */
+ atp = AsnReadId(aip, amp, SUGGEST_ERROR);
+ } else {
+ atp = AsnLinkType(orig, SUGGEST_ERROR);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = SuggestErrorNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == SUGGEST_ERROR_level) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> level = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == SUGGEST_ERROR_msg) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> msg = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = SuggestErrorFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* SuggestErrorAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+SuggestErrorAsnWrite(SuggestErrorPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, SUGGEST_ERROR); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> level;
+ retval = AsnWrite(aip, SUGGEST_ERROR_level, &av);
+ if (ptr -> msg != NULL) {
+ av.ptrvalue = ptr -> msg;
+ retval = AsnWrite(aip, SUGGEST_ERROR_msg, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* SuggestResponseFree()
+*
+**************************************************/
+
+SuggestResponsePtr LIBCALL
+SuggestResponseFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case SuggestResponse_error:
+ SuggestErrorFree(anp -> data.ptrvalue);
+ break;
+ case SuggestResponse_intervals:
+ SeqAnnotFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* SuggestResponseAsnRead()
+*
+**************************************************/
+
+SuggestResponsePtr LIBCALL
+SuggestResponseAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* SuggestResponse ::= (self contained) */
+ atp = AsnReadId(aip, amp, SUGGEST_RESPONSE);
+ } else {
+ atp = AsnLinkType(orig, SUGGEST_RESPONSE); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == SUGGEST_RESPONSE_init) {
+ choice = SuggestResponse_init;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == SUGGEST_RESPONSE_error) {
+ choice = SuggestResponse_error;
+ func = (AsnReadFunc) SuggestErrorAsnRead;
+ }
+ else if (atp == SUGGEST_RESPONSE_intervals) {
+ choice = SuggestResponse_intervals;
+ func = (AsnReadFunc) SeqAnnotAsnRead;
+ }
+ else if (atp == SUGGEST_RESPONSE_fini) {
+ choice = SuggestResponse_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* SuggestResponseAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL
+SuggestResponseAsnWrite(SuggestResponsePtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! suggenAsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, SUGGEST_RESPONSE); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case SuggestResponse_init:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, SUGGEST_RESPONSE_init, &av);
+ break;
+ case SuggestResponse_error:
+ writetype = SUGGEST_RESPONSE_error;
+ func = (AsnWriteFunc) SuggestErrorAsnWrite;
+ break;
+ case SuggestResponse_intervals:
+ writetype = SUGGEST_RESPONSE_intervals;
+ func = (AsnWriteFunc) SeqAnnotAsnWrite;
+ break;
+ case SuggestResponse_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, SUGGEST_RESPONSE_fini, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
diff --git a/network/suggest/client/suggen.h b/network/suggest/client/suggen.h
new file mode 100644
index 00000000..249d9409
--- /dev/null
+++ b/network/suggest/client/suggen.h
@@ -0,0 +1,174 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: suggen.h
+*
+* Author: Yuri Sadykov
+*
+* Version Creation Date: 08/14/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+*
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+*/
+
+#ifndef _suggen_
+#define _suggen_
+
+#ifdef __cplusplus
+extern "C" { /* } */
+#endif
+
+
+/**************************************************
+*
+* Generated objects for Module NCBI-Suggest
+* Generated using ASNCODE Revision: 4.0 at Aug 16, 1995 2:17 PM
+*
+**************************************************/
+
+Boolean LIBCALL
+suggenAsnLoad PROTO((void));
+typedef ValNodePtr SuggestRequestPtr;
+typedef ValNode SuggestRequest;
+#define SuggestRequest_init 1
+#define SuggestRequest_intervals 2
+#define SuggestRequest_fini 3
+
+
+SuggestRequestPtr LIBCALL SuggestRequestFree PROTO ((SuggestRequestPtr ));
+SuggestRequestPtr LIBCALL SuggestRequestAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL SuggestRequestAsnWrite PROTO (( SuggestRequestPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* SuggestIntervals
+*
+**************************************************/
+#ifndef _SUGGEST_
+typedef struct struct_Suggest_intervals {
+ Uint4 OBbits__;
+ struct struct_Suggest_parameters PNTR params;
+ ValNodePtr dna;
+ ValNodePtr protein;
+ Int4 code;
+} SuggestIntervals, PNTR SuggestIntervalsPtr;
+#endif
+
+
+SuggestIntervalsPtr LIBCALL SuggestIntervalsFree PROTO ((SuggestIntervalsPtr ));
+SuggestIntervalsPtr LIBCALL SuggestIntervalsNew PROTO (( void ));
+SuggestIntervalsPtr LIBCALL SuggestIntervalsAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL SuggestIntervalsAsnWrite PROTO (( SuggestIntervalsPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* SuggestParameters
+*
+**************************************************/
+#ifndef _SUGGEST_
+typedef struct struct_Suggest_parameters {
+ Uint4 OBbits__;
+#define OB__Suggest_parameters_size 0
+
+ Int4 size;
+#define OB__Suggest_parameters_begin_search 1
+
+ Int4 begin_search;
+#define OB__Suggest_parameters_end_search 2
+
+ Int4 end_search;
+#define OB__Suggest_parameters_term_stop 3
+
+ Uint1 term_stop;
+} SuggestParameters, PNTR SuggestParametersPtr;
+#endif
+
+
+SuggestParametersPtr LIBCALL SuggestParametersFree PROTO ((SuggestParametersPtr ));
+SuggestParametersPtr LIBCALL SuggestParametersNew PROTO (( void ));
+SuggestParametersPtr LIBCALL SuggestParametersAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL SuggestParametersAsnWrite PROTO (( SuggestParametersPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* SuggestError
+*
+**************************************************/
+#ifndef _SUGGEST_
+typedef struct struct_Suggest_error {
+ Uint4 OBbits__;
+ Uint2 level;
+ /* following #defines are for enumerated type, not used by object loaders */
+#define Suggest_error_level_none 0
+#define Suggest_error_level_info 1
+#define Suggest_error_level_warn 2
+#define Suggest_error_level_error 3
+#define Suggest_error_level_fatal 4
+
+ CharPtr msg;
+} SuggestError, PNTR SuggestErrorPtr;
+#endif
+
+
+SuggestErrorPtr LIBCALL SuggestErrorFree PROTO ((SuggestErrorPtr ));
+SuggestErrorPtr LIBCALL SuggestErrorNew PROTO (( void ));
+SuggestErrorPtr LIBCALL SuggestErrorAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL SuggestErrorAsnWrite PROTO (( SuggestErrorPtr , AsnIoPtr, AsnTypePtr));
+
+typedef ValNodePtr SuggestResponsePtr;
+typedef ValNode SuggestResponse;
+#define SuggestResponse_init 1
+#define SuggestResponse_error 2
+#define SuggestResponse_intervals 3
+#define SuggestResponse_fini 4
+
+
+SuggestResponsePtr LIBCALL SuggestResponseFree PROTO ((SuggestResponsePtr ));
+SuggestResponsePtr LIBCALL SuggestResponseAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL SuggestResponseAsnWrite PROTO (( SuggestResponsePtr , AsnIoPtr, AsnTypePtr));
+
+#ifdef __cplusplus
+/* { */ }
+#endif
+
+#endif /* _suggen_ */
diff --git a/network/suggest/client/suggest.asn b/network/suggest/client/suggest.asn
new file mode 100644
index 00000000..910ad605
--- /dev/null
+++ b/network/suggest/client/suggest.asn
@@ -0,0 +1,67 @@
+--$Revision: 6.0 $
+--********************************************************************
+--
+-- Network SUGGEST Archive message formats
+-- Sirotkin 7/95
+-- Sadykov 8/95
+--
+--*********************************************************************
+--
+-- suggest.asn
+--
+--*********************************************************************
+
+NCBI-Suggest DEFINITIONS ::=
+BEGIN
+
+IMPORTS Seq-entry FROM NCBI-Seqset
+ -- Genetic-code FROM NCBI-Seqfeat
+ Seq-annot FROM NCBI-Sequence;
+
+ --**********************************
+ -- requests
+ --
+
+Suggest-request ::= CHOICE {
+ init NULL , -- DlInit
+ intervals Suggest-intervals , -- What suggest does
+ fini NULL -- DlFini
+}
+
+Suggest-intervals ::= SEQUENCE {
+ params Suggest-parameters OPTIONAL,
+ dna Seq-entry,
+ protein Seq-entry,
+ code INTEGER
+}
+
+Suggest-parameters ::= SEQUENCE {
+ size INTEGER OPTIONAL, -- Minimum size of match to see
+ begin-search INTEGER OPTIONAL, -- where on combined interval to begin search
+ end-search INTEGER OPTIONAL,
+ term-stop BOOLEAN OPTIONAL
+}
+
+Suggest-error ::= SEQUENCE {
+ level ENUMERATED {
+ none (0), -- not an error, just a message
+ info (1), -- informational error
+ warn (2),
+ error (3),
+ fatal (4)
+ },
+ msg VisibleString OPTIONAL
+}
+
+ --**********************************
+ -- responses
+ --
+
+Suggest-response ::= CHOICE {
+ init NULL , -- DlInit
+ error Suggest-error, -- Error code
+ intervals Seq-annot, -- suggested intervals
+ fini NULL -- DlFini
+}
+
+END
diff --git a/network/suggest/client/sugprefx.h b/network/suggest/client/sugprefx.h
new file mode 100644
index 00000000..7b9e6a08
--- /dev/null
+++ b/network/suggest/client/sugprefx.h
@@ -0,0 +1,2 @@
+#define NLM_EXTERN_LOADS { SeqAlignAsnLoad (); SeqAsnLoad (); }
+#include <sequtil.h>
diff --git a/network/suggest/server/suggsrv.c b/network/suggest/server/suggsrv.c
new file mode 100644
index 00000000..7e74ad45
--- /dev/null
+++ b/network/suggest/server/suggsrv.c
@@ -0,0 +1,430 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: suggsrv.c
+*
+* Author: Yuri Sadykov
+*
+* Version Creation Date: 08/14/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Implementation of Suggest server. Here it is only server specific
+* part, mainly related with reading of requests from a client and writing
+* responces. The implementaion of the processing of data is in suggest.c
+* and adjust.c
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: suggsrv.c,v $
+* Revision 6.0 1997/08/25 18:40:59 madden
+* Revision changed to 6.0
+*
+* Revision 1.6 1996/07/09 21:40:29 epstein
+* add kludge Nlm_Main() to allow program to be built with shared libs
+*
+ * Revision 1.5 1995/12/12 18:52:54 kans
+ * now uses functions in suggslp.c
+ *
+ * Revision 1.4 1995/11/27 21:03:40 sad
+ * Fixed error related with initializing global structure;
+ *
+ * Fixed error while writing interval's fields from and to, which had
+ * values less then required;
+ *
+ * Added writing strand values in output intervals;
+ *
+ * Now all intervals with the same product are within single feature;
+ *
+*/
+
+#include <ncbinet.h>
+#include <seqport.h>
+#include <suggslp.h>
+#include <suggen.h>
+
+/*****************************************************************************
+ * External function prototipes
+ */
+
+/*****************************************************************************
+ * Function prototipes
+ */
+static Boolean
+ServeClient(AsnIoPtr pAsnIn, AsnIoPtr pAsnOut);
+
+static SuggestErrorPtr
+GetLastSuggestError(void);
+
+static MsgAnswer LIBCALLBACK
+SuggestMessageHook(MsgKey msgKey, ErrSev errSev,
+ const char *pchCaption, const char *pchMessage);
+
+static void
+SetSuggestMessageHook(void);
+
+static void
+RestoreMessageHook(void);
+
+static SuggestErrorPtr
+GetLastSuggestError(void);
+
+static void
+ClearSuggestError(void);
+
+/*============================================================================*\
+ * Function:
+ * main
+ *
+ * Purpose:
+ * Entry point. This function is for suggest if it is built as a server.
+ *
+ * Parameters:
+ * Only one option to the application is acceptable "-d" which means that
+ * the application must running without network capability and input and output
+ * of data are through the local files. It's very convinient for debugging.
+ *
+ * Return:
+ * Error code
+\*----------------------------------------------------------------------------*/
+int
+main(int argc, char *argv[])
+{
+ int iArg;
+ int iReadTimeout;
+ Boolean bDebug = FALSE;
+ AsnIoPtr pAsnIoIn;
+ AsnIoPtr pAsnIoOut;
+ Char achBuff[100];
+ NI_HandPtr pHand;
+
+ if (argc > 1) {
+ iArg = 1;
+ if (StrCmp(argv[1], "-d") == 0) {
+ iArg++;
+ bDebug = TRUE;
+ }
+ }
+
+ if (bDebug) {
+ /* For debugging of the server only.
+ * Read and write local files only, no communication
+ * with clients.
+ */
+ pAsnIoIn = AsnIoOpen("suggsrv.in", "r");
+ pAsnIoOut = AsnIoOpen("suggsrv.out", "w");
+ } else {
+ /* Send acknowledgment--all right
+ */
+ NI_ServerACK();
+
+ /* Create connection with client, i.e. input and output
+ */
+ pHand = NI_OpenASNIO();
+
+ /* this read-timeout is effectively an idle timeout for
+ * the server process; the process will terminate upon
+ * read-timeout
+ */
+ GetAppParam("NCBI", "NET_SRV", "SERV_INACT_TIMER",
+ "10", achBuff, sizeof(achBuff));
+ iReadTimeout = atoi(achBuff) * 60; /* param is minutes */
+ MsgSetReadTimeout(pHand, iReadTimeout);
+ pAsnIoIn = pHand->raip;
+ pAsnIoOut = pHand->waip;
+ }
+
+ suggestOut.bServer = TRUE;
+
+ /* Serve a client
+ */
+ while (ServeClient(pAsnIoIn, pAsnIoOut))
+ ;
+
+ AsnIoClose(pAsnIoIn);
+ AsnIoClose(pAsnIoOut);
+}
+
+/*****************************************************************************\
+ * Function:
+ * ServeClient
+ *
+ * Purpose:
+ * Reads one request from a client and sends to it the result of
+ * processing.
+ *
+ * Parameter:
+ * pAsnIoIn - input file from which the request are read;
+ * pAsnIoOut - output file to which
+ *
+ * Return:
+ * FALSE if nothing more to process or error occured and farther
+ * processing is not possible, otherwise TRUE.
+ *
+\*****************************************************************************/
+static Boolean
+ServeClient(AsnIoPtr pAsnIn, AsnIoPtr pAsnOut)
+{
+ short iErrAct;
+ ErrDesc err;
+ Boolean bOnceMore = TRUE;
+ Uint2 errLevel;
+ SuggestErrorPtr pSError;
+ SuggestRequestPtr pReq;
+ SuggestResponsePtr pResp;
+ SuggestIntervalsPtr pSIntervals;
+
+ /* Encountering EOF on reading is a "normal" occurence,
+ * and does not merit an error message
+ */
+ ErrGetOpts(&iErrAct, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err); /* clear any pending error, which can be ignored */
+
+ pReq = SuggestRequestAsnRead (pAsnIn, NULL);
+
+ if (ErrFetch(&err)) {
+ ErrPostEx(SEV_ERROR, 1, 1, "Error encountered on AsnReadId %d", err);
+
+ return FALSE;
+ }
+
+ ErrSetOpts(iErrAct, 0);
+
+ if (pReq == NULL) {
+ ErrPostEx(SEV_ERROR, 1, 1, "Null AsnReadId");
+
+ return FALSE;
+ }
+
+ switch (pReq->choice) {
+ case SuggestRequest_init: /* Initializing */
+ pResp = ValNodeNew(NULL);
+ SetSuggestMessageHook();
+ if (InitSuggest()) {
+ /* Init successful, send OK.
+ */
+ pResp->choice = SuggestResponse_init;
+ pResp->data.ptrvalue = NULL;
+ } else {
+ /* Error while init, send error
+ */
+ pResp->choice = SuggestResponse_error;
+ pResp->data.ptrvalue = (Pointer)GetLastSuggestError();
+ bOnceMore = FALSE; /* Cancel farther processing */
+ }
+ SuggestResponseAsnWrite(pResp, pAsnOut, NULL);
+ RestoreMessageHook();
+ pResp->data.ptrvalue = NULL; /* It's not necessary to free
+ * SuggestError structure.
+ */
+ SuggestResponseFree(pResp);
+ pReq->data.ptrvalue = NULL;
+ break;
+
+ case SuggestRequest_intervals: /* What this server does */
+ pSIntervals = pReq->data.ptrvalue;
+
+ pResp = ValNodeNew(NULL);
+ SetSuggestMessageHook();
+
+ /* The main task of this application, process the data
+ */
+ SuggestClientService (pSIntervals);
+
+ /* Check for error while the processing
+ */
+ pSError = GetLastSuggestError();
+ errLevel = pSError->level;
+
+ if (errLevel == Suggest_error_level_error ||
+ errLevel == Suggest_error_level_fatal)
+ {
+ /* Fatal error occurs, send error message to athe client
+ * and flags that the application must exit
+ */
+ pResp->choice = SuggestResponse_error;
+ pResp->data.ptrvalue = GetLastSuggestError();
+ if (errLevel == Suggest_error_level_fatal)
+ bOnceMore = FALSE;
+
+/**** SeqAnnotFree(suggestOut.out.pSeqAnnot); */
+ } else {
+ pResp->choice = SuggestResponse_intervals;
+ pResp->data.ptrvalue = suggestOut.out.pSeqAnnot;
+ }
+
+ SuggestResponseAsnWrite(pResp, pAsnOut, NULL);
+ RestoreMessageHook();
+ SuggestResponseFree(pResp);
+ suggestOut.out.pSeqAnnot = NULL;
+ break;
+
+ case SuggestRequest_fini: /* Deinitializing */
+ pResp = ValNodeNew(NULL);
+ pResp->choice = SuggestResponse_fini;
+ pResp->data.ptrvalue = NULL;
+ SuggestResponseAsnWrite(pResp, pAsnOut, NULL);
+ SuggestResponseFree(pResp);
+ pReq->data.ptrvalue = NULL;
+ bOnceMore = FALSE;
+ break;
+
+ default:
+ /* All request types must be processed.
+ * No default processing.
+ */
+ ASSERT(FALSE);
+ }
+
+ AsnIoReset(pAsnOut);
+ SuggestRequestFree(pReq); /* free read request */
+
+ return bOnceMore;
+}
+
+static MsgAnswer LIBCALLBACK
+SuggestMessageHook(MsgKey msgKey, ErrSev errSev,
+ const char *pchCaption, const char *pchMessage)
+{
+ switch (errSev) {
+ case MSG_ERROR:
+ suggestError.level = Suggest_error_level_error;
+ break;
+
+ case MSG_FATAL:
+ suggestError.level = Suggest_error_level_fatal;
+ break;
+ }
+
+ if (suggestError.msg != NULL)
+ MemFree(suggestError.msg);
+
+ suggestError.msg = StringSave(pchMessage);
+
+ return ANS_NONE;
+}
+
+/*============================================================================*\
+ * Function:
+ * SetSuggesstMessageHook
+ *
+ * Purpose:
+ * Sets hook function for intercepting all calls to Message
+ *
+ * Parameters:
+ * None
+ *
+ * Return:
+ * None
+ *
+\*----------------------------------------------------------------------------*/
+static void
+SetSuggestMessageHook(void)
+{
+ fOldMsgHook = SetMessageHook(SuggestMessageHook);
+ ClearSuggestError();
+}
+
+/*============================================================================*\
+ * Function:
+ * RestoreMessageHook
+ *
+ * Purpose:
+ * Resotore old hook function.
+ *
+ * Parameters:
+ * none
+ *
+ * Return:
+ * none
+ *
+\*----------------------------------------------------------------------------*/
+static void
+RestoreMessageHook(void)
+{
+ fOldMsgHook = SetMessageHook(fOldMsgHook);
+ ClearSuggestError();
+}
+
+/*============================================================================*\
+ * Function:
+ * GetLastSuggestError
+ *
+ * Purpose:
+ *
+ *
+ * Parameters:
+ * none
+ *
+ * Return:
+ * pointer to SuggestError structure, which contains information about
+ * last error.
+ *
+\*----------------------------------------------------------------------------*/
+static SuggestErrorPtr
+GetLastSuggestError(void)
+{
+ return &suggestError;
+}
+
+/*============================================================================*\
+ * Function:
+ * ClearSuggestError
+ *
+ * Purpose:
+ * Sets last error to a state which corresponds to no error.
+ *
+ * Parameters:
+ * none
+ *
+ * Return:
+ * none
+ *
+\*----------------------------------------------------------------------------*/
+static void
+ClearSuggestError(void)
+{
+ suggestError.level = Suggest_error_level_none;
+ if (suggestError.msg != NULL)
+ MemFree(suggestError.msg);
+
+ suggestError.msg = NULL;
+}
+
+Int2
+Nlm_Main(void)
+{
+ fprintf(stderr,"Kludge main executed in file %s", __FILE__);
+ exit (1);
+}
diff --git a/network/suggest/stdalone/suggalon.c b/network/suggest/stdalone/suggalon.c
new file mode 100644
index 00000000..4913cdd6
--- /dev/null
+++ b/network/suggest/stdalone/suggalon.c
@@ -0,0 +1,559 @@
+/*
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: suggalon.c
+*
+* Author: Yuri Sadykov
+*
+* Version Creation Date: 08/14/95
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* Implementation of Suggest application as a standalone version. Here it
+* is only part, mainly related with reading data for processing and
+* outputting of result of processing. The implementaion of the processing
+* of data is in suggest.c and adjust.c
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+*/
+
+#include <ncbi.h>
+#include "suggest.h"
+
+/*****************************************************************************
+ * Extern globals
+ */
+extern SuggestOutput suggestOut;
+extern SuggestRec suggestRec;
+extern IntPtr intlist;
+
+extern Char *dna_seq;
+extern Int4 dna_len;
+extern Char *rev_seq;
+
+/*****************************************************************************
+ * External function prototipes
+ */
+
+/*****************************************************************************
+ * Defines
+ */
+#define TOTARG 9
+#define NUMARG 9
+
+/*****************************************************************************
+ * Global variables
+ */
+static Args myargs [TOTARG] = {
+ { "Sequence File", "stdin", NULL, NULL, FALSE, 'i', ARG_FILE_IN, 0.0, 0, NULL},
+ { "Output File", "stdout", NULL, NULL, FALSE, 'o', ARG_FILE_OUT, 0.0, 0, NULL},
+ { "Genetic Code", "0", NULL, NULL, FALSE, 'g', ARG_INT, 0.0, 0, NULL},
+ { "Minimum Value", "-1", NULL, NULL, FALSE, 'l', ARG_INT, 0.0, 0, NULL},
+ { "Maximum Value", "0", NULL, NULL, FALSE, 'u', ARG_INT, 0.0, 0, NULL},
+ { "Min Exon Override - default set by program", "0", NULL, NULL,
+ FALSE, 'x', ARG_INT, 0.0, 0, NULL},
+ { "Terminal Stop", "T", NULL, NULL, FALSE, 't', ARG_BOOLEAN, 0.0, 0, NULL},
+ { "Sequin Format", "F", NULL, NULL, FALSE, 's', ARG_BOOLEAN, 0.0, 0, NULL},
+ { "Reverse", "F", NULL, NULL, TRUE, 'r', ARG_BOOLEAN, 0.0, 0, NULL}
+};
+
+static Char inputFile [PATH_MAX];
+static Char outputFile [PATH_MAX];
+
+static Char empty [3];
+
+/*****************************************************************************
+ * Function prototipes
+ */
+
+
+/*****************************************************************************
+*
+* ReadNextChar (f)
+* Reads the next character in a file, returning '\0' if end of file
+*
+*****************************************************************************/
+
+static Char ReadNextChar (FILE *f)
+
+{
+ Char ch;
+ int getcrsult;
+
+ ch = '\0';
+ if (f != NULL) {
+ getcrsult = fgetc (f);
+ ch = (Char) getcrsult;
+ if (getcrsult == EOF && feof (f)) {
+ ch = '\0';
+ }
+ }
+ return ch;
+}
+
+/*****************************************************************************
+*
+* ReadNextLine (f, str, maxsize)
+* Reads the next line in a file, returning FALSE if end of file
+*
+*****************************************************************************/
+
+static Boolean ReadNextLine (FILE *f, CharPtr str, size_t maxsize)
+
+{
+ Boolean done;
+ Char ch;
+ Int2 count;
+
+ done = FALSE;
+ if (f != NULL && str != NULL && maxsize > 0) {
+ str [0] = '\0';
+ count = 0;
+ ch = ReadNextChar (f);
+ while (ch != '\n' && ch != '\r' && ch != '\0') {
+ if (count < (Int2) maxsize && ch != '\0') {
+ str [count] = ch;
+ count++;
+ }
+ ch = ReadNextChar (f);
+ }
+ if (count <= (Int2) maxsize) {
+ str [count] = '\0';
+ }
+ done = (Boolean) (! feof (f));
+ }
+ return done;
+}
+
+/*****************************************************************************
+*
+* Get_Sequence (f, seqrp)
+* Gets a sequence from a file, recording the sequence and segment
+* lengths in ByteStores, and returning the final character string and
+* total length
+*
+*****************************************************************************/
+
+static void Get_Sequence (FILE *f, SeqRecPtr seqrp)
+
+{
+ Char ch;
+ CharPtr chptr;
+ Boolean goOn;
+ IdRecPtr last;
+ Int4 len;
+ Char str [256];
+ IdRecPtr this;
+ Int4 total;
+
+ if (f != NULL && seqrp != NULL) {
+ if (seqrp->rawSeq == NULL) {
+ seqrp->rawSeq = BSNew (1000);
+ }
+ if (seqrp->segLens == NULL) {
+ seqrp->segLens = BSNew (10);
+ }
+ len = 0;
+ total = 0;
+ goOn = TRUE;
+ while (goOn && ReadNextLine (f, str, sizeof (str))) {
+ if (str [0] == '&') {
+ goOn = FALSE;
+ } else if (str [0] == '!') {
+ goOn = FALSE;
+ } else if (str [0] == '>') {
+ if (len > 0) {
+ if (seqrp->lookForStop) {
+ BSPutByte (seqrp->rawSeq, (Int2) '*');
+ len++;
+ }
+ BSWrite (seqrp->segLens, &len, sizeof (Int4));
+ total += len;
+ len = 0;
+ }
+ chptr = StringChr (str, ' ');
+ if (chptr != NULL) {
+ *chptr = '\0';
+ }
+ if (seqrp->ids != NULL) {
+ last = seqrp->ids;
+ while (last->next != NULL) {
+ last = last->next;
+ }
+ this = MemNew (sizeof (IdRec));
+ if (this != NULL) {
+ this->id.accn = StringSave (str + 1);
+ }
+ last->next = this;
+ } else {
+ last = MemNew (sizeof (IdRec));
+ if (last != NULL) {
+ last->id.accn = StringSave (str + 1);
+ }
+ seqrp->ids = last;
+ }
+ } else if (str [0] != '\0') {
+ chptr = str;
+ while (*chptr != '\0') {
+ ch = TO_UPPER (*chptr);
+ if (ch >= 'A' && ch <= 'Z') {
+ if (seqrp->nuc) {
+ if (ch == 'U') {
+ ch = 'T';
+ }
+ if (StringChr ("BDEFHIJKLMOPQRSUVWXYZ", ch) == NULL) {
+ BSPutByte (seqrp->rawSeq, (Int2) ch);
+ len++;
+ }
+ } else {
+ if (StringChr ("JOU", ch) == NULL) {
+ BSPutByte (seqrp->rawSeq, (Int2) ch);
+ len++;
+ }
+ }
+ }
+ chptr++;
+ }
+ }
+ }
+ if (seqrp->nuc) {
+ BSPutByte (seqrp->rawSeq, (Int2) 'N');
+ BSPutByte (seqrp->rawSeq, (Int2) 'N');
+ BSPutByte (seqrp->rawSeq, (Int2) 'N');
+ len += 3;
+ }
+ if (len > 0) {
+ if (seqrp->lookForStop) {
+ BSPutByte (seqrp->rawSeq, (Int2) '*');
+ len++;
+ }
+ BSWrite (seqrp->segLens, &len, sizeof (Int4));
+ total += len;
+ len = 0;
+ }
+ if (total > 0) {
+ seqrp->sequence = BSMerge (seqrp->rawSeq, NULL);
+ seqrp->length = total;
+ } else {
+ seqrp->sequence = NULL;
+ seqrp->length = 0;
+ }
+ }
+}
+
+
+/*****************************************************************************
+*
+* Get_DNA (f, sugrp)
+* Gets a nucleotide sequence from a file
+*
+*****************************************************************************/
+
+static void Get_DNA (FILE *f, SuggestRecPtr sugrp)
+
+{
+ if (f != NULL && sugrp != NULL) {
+ sugrp->nucleotide.rawSeq = NULL;
+ sugrp->nucleotide.segLens = NULL;
+ sugrp->nucleotide.ids = NULL;
+ sugrp->nucleotide.sequence = NULL;
+ sugrp->nucleotide.length = 0L;
+ sugrp->nucleotide.nuc = TRUE;
+ sugrp->nucleotide.lookForStop = FALSE;
+ Get_Sequence (f, &(sugrp->nucleotide));
+ }
+}
+
+/*****************************************************************************
+*
+* Get_Protein (f, sugrp)
+* Gets a protein sequence from a file
+*
+*****************************************************************************/
+
+static void Get_Protein (FILE *f, SuggestRecPtr sugrp)
+
+{
+ if (f != NULL && sugrp != NULL) {
+ sugrp->protein.rawSeq = NULL;
+ sugrp->protein.segLens = NULL;
+ sugrp->protein.ids = NULL;
+ sugrp->protein.sequence = NULL;
+ sugrp->protein.length = 0L;
+ sugrp->protein.nuc = FALSE;
+ sugrp->protein.lookForStop = sugrp->lookForStop;
+ Get_Sequence (f, &(sugrp->protein));
+ }
+}
+
+/*****************************************************************************
+*
+* Get_Params (void)
+* Get command line arguments
+*
+*****************************************************************************/
+
+
+static Boolean Get_Params (void)
+
+{
+ FILE *f;
+ FILE *g;
+ Int4 i;
+ Int2 j;
+ Int4 len;
+ Int4 num_nuc;
+ Int4 num_prt;
+
+ if (GetArgs ("suggest", NUMARG, myargs)) {
+ if (NUMARG == TOTARG && myargs [8].intvalue) {
+ suggestRec.lookForStop = (Boolean) (myargs [6].intvalue);
+ StringNCpy (inputFile, myargs [0].strvalue, sizeof (inputFile));
+ if (inputFile [0] == '\0') {
+ StringCpy (inputFile, "stdin");
+ }
+ StringNCpy (outputFile, myargs [1].strvalue, sizeof (outputFile));
+ if (outputFile [0] == '\0') {
+ StringCpy (outputFile, "stdout");
+ }
+ f = FileOpen (inputFile, "r");
+ if (f != NULL) {
+ Get_DNA (f, &suggestRec);
+ FileClose (f);
+ dna_seq = suggestRec.nucleotide.sequence;
+ dna_len = StringLen (dna_seq);
+ if (dna_len > 3 && dna_seq != NULL) {
+ dna_len -= 3;
+ dna_seq [dna_len] = '\0';
+ }
+ rev_seq = MemNew(dna_len+1);
+ if (rev_seq != NULL) {
+ reverse (dna_len);
+ f = FileOpen (outputFile, "w");
+ if (f != NULL) {
+ j = 0;
+ for (i = 0; i < dna_len; i++) {
+ fputc ((int) (rev_seq [i]), f);
+ j++;
+ if (j >= 50) {
+ fputc ((int) '\n', f);
+ j = 0;
+ }
+ }
+ if (j > 0) {
+ fputc ((int) '\n', f);
+ }
+ FileClose (f);
+ }
+ }
+ }
+ } else {
+ suggestRec.lookForStop = (Boolean) (myargs [6].intvalue);
+ StringNCpy (inputFile, myargs [0].strvalue, sizeof (inputFile));
+ if (inputFile [0] == '\0') {
+ StringCpy (inputFile, "stdin");
+ }
+ StringNCpy (outputFile, myargs [1].strvalue, sizeof (outputFile));
+ if (outputFile [0] == '\0') {
+ StringCpy (outputFile, "stdout");
+ }
+ f = FileOpen (inputFile, "r");
+ if (f != NULL) {
+ g = FileOpen (outputFile, "w");
+ if (g != NULL) {
+ suggestOut.out.fileOut = g;
+ while (! feof (f)) {
+ if ((Boolean) (myargs [7].intvalue)) {
+ Get_DNA (f, &suggestRec);
+ Get_Protein (f, &suggestRec);
+ } else {
+ Get_Protein (f, &suggestRec);
+ Get_DNA (f, &suggestRec);
+ }
+ Get_Genetic_Code (myargs [2].intvalue, &suggestRec);
+ suggestRec.minVal = (myargs [3].intvalue);
+ suggestRec.maxVal = (myargs [4].intvalue);
+ suggestRec.minExon = (myargs [5].intvalue);
+
+ ProcessData(&suggestOut);
+ }
+ FileClose (g);
+ }
+ FileClose (f);
+ }
+ }
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/*****************************************************************************
+*
+* Get_Prot_ID (sugrp, num)
+* Gets a protein id
+*
+*****************************************************************************/
+
+static CharPtr Get_Prot_ID (Int2 num)
+
+{
+ CharPtr str;
+ IdRecPtr this;
+
+ empty [0] = 'x';
+ empty [1] = '\0';
+ str = empty;
+ this = suggestRec.protein.ids;
+ while (num > 0 && this != NULL) {
+ num--;
+ this = this->next;
+ }
+ if (this != NULL) {
+ str = this->id.accn;
+ }
+ return str;
+}
+
+/*****************************************************************************
+*
+* Get_Nuc_ID (sugrp, num)
+* Gets a nucleotide id
+*
+*****************************************************************************/
+
+static CharPtr Get_Nuc_ID (Int2 num)
+
+{
+ CharPtr str;
+ IdRecPtr this;
+
+ empty [0] = 'x';
+ empty [1] = '\0';
+ str = empty;
+ this = suggestRec.nucleotide.ids;
+ while (num > 0 && this != NULL) {
+ num--;
+ this = this->next;
+ }
+ if (this != NULL) {
+ str = this->id.accn;
+ }
+ return str;
+}
+
+void
+OutProteinID(SuggestOutputPtr pSuggestOut, Int2 num)
+{
+ FilePuts(">", pSuggestOut->out.fileOut);
+ FilePuts(Get_Prot_ID(num), pSuggestOut->out.fileOut);
+ FilePuts("\n\n", pSuggestOut->out.fileOut);
+}
+
+void
+OutLocation(SuggestOutputPtr pSuggestOut, Int4 num_nuc)
+{
+ Int4 i = 0;
+ Int4 j = 0;
+ FILE *f = pSuggestOut->out.fileOut;
+ Char str[128];
+ IntPtr thisInt = intlist;
+
+ while (thisInt != NULL) {
+ if (i == 0) {
+ if (thisInt->next != NULL) {
+ FilePuts ("FT CDS join(", f);
+ } else {
+ FilePuts ("FT CDS ", f);
+ }
+ } else if (j == 0) {
+ FilePuts ("FT ", f);
+ }
+ if (thisInt->orient == MinusStrand) {
+ if (thisInt->next != NULL && num_nuc > 1) {
+ sprintf (str, "complement(%s:%ld..%ld)",
+ (CharPtr)Get_Nuc_ID((Int2)(thisInt->id)),
+ (long)thisInt->from, (long)thisInt->to);
+ } else {
+ sprintf (str, "complement(%ld..%ld)", (long)thisInt->from,
+ (long)thisInt->to);
+ }
+ } else {
+ if (thisInt->next != NULL && num_nuc > 1) {
+ sprintf (str, "%s:%ld..%ld",
+ (CharPtr)Get_Nuc_ID((Int2)(thisInt->id)),
+ (long)thisInt->from, (long)thisInt->to);
+ } else {
+ sprintf (str, "%ld..%ld", (long)thisInt->from,
+ (long)thisInt->to);
+ }
+ }
+ FilePuts (str, f);
+ j++;
+ if (j >= 3) {
+ if (thisInt->next != NULL) {
+ FilePuts (",\n", f);
+ }
+ j = 0;
+ } else {
+ if (thisInt->next != NULL) {
+ FilePuts (",", f);
+ }
+ }
+ thisInt = thisInt->next;
+ i++;
+ }
+ if (i > 1)
+ FilePuts (")\n\n\n", f);
+ else
+ FilePuts ("\n\n\n", f);
+}
+
+/*****************************************************************************
+*
+* Main (void)
+* Main program to test Suggest_Intervals
+*
+*****************************************************************************/
+Int2
+Main (void)
+{
+ if (!InitSuggest())
+ return 1;
+
+ if (!Get_Params ())
+ return 1;
+
+ return 0;
+}
diff --git a/network/taxon1/client/fscproc.c b/network/taxon1/client/fscproc.c
new file mode 100644
index 00000000..d23573d9
--- /dev/null
+++ b/network/taxon1/client/fscproc.c
@@ -0,0 +1,731 @@
+/*----------------*/
+
+#include <stdlib.h>
+#include <ncbi.h>
+#include <taxinc.h>
+#include <tax0.h>
+#define REALTAXsyb
+
+#define MAX_ORG_LIST 10
+
+#define BUFF_SIZE 16
+#define TAX_READ 0
+#define TAX_WRITE 1
+
+static int my_timer= -1;
+
+static char hit_name[256];
+
+static struct t_or_buff {
+ Int4 tax_id;
+ OrgRefPtr p_org_ref;
+ int timer;
+ char div[16];
+ char embl[4];
+ int is_species;
+} or_buff[BUFF_SIZE];
+
+static Boolean we_want_synonyms= 0;
+
+Boolean tax1_setSynonyms(Boolean on_off)
+{
+ Boolean ret;
+
+ ret= we_want_synonyms;
+ we_want_synonyms= on_off;
+ return ret;
+}
+
+static void lockBuff(int mode)
+{
+ mode= mode;
+}
+
+static void unlockBuff()
+{
+}
+
+static void initBuff()
+{
+ int i;
+
+ my_timer= 0;
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ or_buff[i].tax_id= 0;
+ or_buff[i].p_org_ref= NULL;
+ }
+}
+
+static ValNodePtr bldDBId(Int4 id)
+{
+ ValNodePtr dbnode;
+ DbtagPtr dbtag;
+ ObjectIdPtr object_id;
+
+ /* populate tax_id */
+ dbnode= ValNodeNew(NULL);
+ dbnode->data.ptrvalue= dbtag= DbtagNew();
+ dbtag->db = StringSave("taxon");
+ dbtag->tag= object_id= ObjectIdNew();
+ object_id->str= NULL;
+ object_id->id = id;
+ return dbnode;
+}
+
+/* mark synonyms (name begins with '~') */
+static void markSynonym(ValNodePtr syn)
+{
+ CharPtr name;
+ Int2 i;
+
+ for(;syn != NULL; syn= syn->next) {
+ name= syn->data.ptrvalue;
+ if(*name != '~') {
+ syn->choice= 0;
+ }
+ else {
+ syn->choice= 1;
+ for(i= 0; name[i] != '\0'; i++) {
+ name[i]= name[i+1];
+ }
+ }
+ }
+}
+
+static void loadInBuff(Int4 id)
+{
+ int i, k= -1;
+ Int4 t= my_timer + 1;
+ Int4 bt;
+
+ if(my_timer < 0) {
+ initBuff();
+ t= my_timer+1;
+ }
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if(or_buff[i].tax_id == 0) {
+ k= i;
+ break;
+ }
+ if(or_buff[i].timer < t) {
+ t= or_buff[i].timer;
+ k= i;
+ }
+ }
+
+ if(k >= 0) {
+ if(or_buff[k].p_org_ref != NULL) OrgRefFree(or_buff[k].p_org_ref);
+ or_buff[k].tax_id= id;
+ or_buff[k].p_org_ref= Tax0GetRef(-id);
+ or_buff[k].timer= ++my_timer;
+ or_buff[k].is_species= -1;
+ if((or_buff[k].p_org_ref != NULL) && (or_buff[k].p_org_ref->syn != NULL)) {
+ markSynonym(or_buff[k].p_org_ref->syn);
+ }
+ }
+}
+
+static Boolean getDivSpecFromOrgName(OrgNamePtr onp, int* is_spec, CharPtr div)
+{
+ Boolean has_div= FALSE;
+ Boolean has_is_spec= FALSE;
+
+ if(onp == NULL) return FALSE;
+
+ if(onp->div != NULL) {
+ div= StringNCpy(div, onp->div, 16);
+ has_div= TRUE;
+ }
+ switch(onp->choice) {
+ case 1: /* binomial name */
+ case 2: /* virus name */
+ *is_spec= 1;
+ has_is_spec= TRUE;
+ break;
+ case 5: /* partial name */
+ *is_spec= 0;
+ has_is_spec= FALSE; /*TRUE;*/
+ break;
+ default:
+ *is_spec= -1;
+ }
+ return has_div & has_is_spec;
+}
+
+static void loadComplete(Int4 id)
+{
+ int i;
+ TaxCompleteListPtr tclp;
+ TaxonIdName tinp;
+
+ if(my_timer < 0) initBuff();
+
+ lockBuff(TAX_WRITE);
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if(or_buff[i].tax_id == id) {
+ or_buff[i].timer= ++my_timer;
+ if(!getDivSpecFromOrgName(or_buff[i].p_org_ref->orgname, &or_buff[i].is_species, or_buff[i].div)) {
+
+ tinp.choice= TaxonIdName_id;
+ tinp.data.intvalue= id;
+ tclp= Tax0GetComplete(&tinp);
+ if((tclp != NULL) && (tclp->num > 0) && (tclp->info != NULL)) {
+ or_buff[i].is_species= tclp->info->is_species_level;
+ if(tclp->info->gb_div != NULL) StringNCpy(or_buff[i].div, tclp->info->gb_div, 16);
+ else or_buff[i].div[0]= '\0';
+ /*if(tclp->info->embl_code != NULL) StringNCpy(or_buff[i].embl, tclp->info->embl_code, 4);
+ else*/ or_buff[i].embl[0]= '\0';
+ TaxCompleteListFree(tclp);
+ }
+ }
+ break;
+ }
+ }
+ unlockBuff();
+}
+
+static OrgRefPtr getFromBuff(Int4 id, int* is_sp, CharPtr div, CharPtr embl)
+{
+ int i;
+ OrgRefPtr orp= NULL;
+
+ if(my_timer < 0) initBuff();
+
+ lockBuff(TAX_READ);
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if(or_buff[i].tax_id == id) {
+ or_buff[i].timer= ++my_timer;
+ orp= or_buff[i].p_org_ref;
+ if(is_sp != NULL) *is_sp= or_buff[i].is_species;
+ if(div != NULL) StringCpy(div, or_buff[i].div);
+ if(embl != NULL) StringCpy(embl, ""/*or_buff[i].embl*/);
+ break;
+ }
+ }
+ unlockBuff();
+ return orp;
+}
+
+OrgRefPtr tax1_getOrgRef(Int4 tax_id, int* is_species, CharPtr div, CharPtr embl_cde)
+{
+ OrgRefPtr orp;
+
+
+ if((orp= getFromBuff(tax_id, is_species, div, embl_cde)) == NULL) {
+ /* organism is not in buffer already */
+ lockBuff(TAX_WRITE);
+ loadInBuff(tax_id);
+ unlockBuff();
+
+ orp= getFromBuff(tax_id, is_species, div, embl_cde);
+ }
+ if((orp != NULL) && (is_species != NULL) && (*is_species == -1)) {
+ /* we need, but we don't have is_species, div and embl_cde in buffer */
+ loadComplete(tax_id);
+ orp= getFromBuff(tax_id, is_species, div, embl_cde);
+ }
+ return orp;
+
+}
+
+static Int4 findIdInBuff(CharPtr orgname)
+{
+ int i;
+ OrgRefPtr orp;
+ ValNodePtr vnp;
+ Int4 id= 0;
+
+ lockBuff(TAX_READ);
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if((or_buff[i].tax_id > 0) && (or_buff[i].p_org_ref != NULL)) {
+ orp= or_buff[i].p_org_ref;
+ if((orp->taxname != NULL) && (StringICmp(orp->taxname, orgname) == 0)) {
+ id= or_buff[i].tax_id;
+ break;
+ }
+ if((orp->common != NULL) && (StringICmp(orp->common, orgname) == 0)) {
+ id= or_buff[i].tax_id;
+ break;
+ }
+ for(vnp= orp->syn; vnp != NULL; vnp= vnp->next) {
+ if((vnp->data.ptrvalue != NULL) && (StringICmp(vnp->data.ptrvalue, orgname) == 0)) {
+ id= or_buff[i].tax_id;
+ break;
+ }
+ }
+ if(id != 0) break;
+ }
+ }
+ unlockBuff();
+ return id;
+}
+
+/***************************************************
+ * Get tax_id by organism name
+ * returns:
+ * tax_id if one node found
+ * 0 no organism found
+ * -tax_id if more than one node found
+ */
+Int4 tax1_getTaxIdByName(CharPtr orgname)
+{
+ TaxonIdListPtr tilp;
+ TaxonName tn;
+ Int4 tax_id;
+
+ if((tax_id= findIdInBuff(orgname)) > 0) {
+ StringNCpy(hit_name, orgname, 256);
+ return tax_id;
+ }
+
+ tn.data.ptrvalue= orgname;
+ tn.choice= TaxonName_taxname;
+ tilp= Tax0GetTaxId(&tn);
+ if(tilp == NULL) return 0;
+ if(tilp->_num_ids == 0) {
+ tax_id= 0;
+ }
+ else if(tilp->_num_ids == 1) {
+ tax_id= tilp->ids[0];
+ }
+ else {
+ tax_id= -tilp->ids[0];
+ }
+ TaxonIdListFree(tilp);
+ StringNCpy(hit_name, orgname, 256);
+ return tax_id;
+}
+
+
+/***************************************************
+ * Get all tax_id by organism name
+ * returns:
+ * Number of tax ids found
+ */
+Int4 tax1_getAllTaxIdByName(CharPtr orgname, Int4 **Ids_out)
+{
+ TaxonName tn;
+ TaxonIdListPtr id_list;
+ Int4 nof_ids= 0;
+
+ tn.data.ptrvalue= orgname;
+ tn.choice= TaxonName_taxname;
+
+ id_list= Tax0GetTaxId(&tn);
+ if(id_list == NULL) return 0;
+
+ if(id_list->_num_ids > 0) {
+ *Ids_out= MemNew(id_list->_num_ids * sizeof(Int4));
+ MemCopy(*Ids_out, id_list->ids, id_list->_num_ids * sizeof(Int4));
+ nof_ids= id_list->_num_ids;
+ }
+
+ TaxonIdListFree(id_list);
+ return nof_ids;
+}
+
+
+static CharPtr getSearchName(OrgModPtr omp)
+{
+ while(omp != NULL) {
+ if(omp->subtype == 254) {
+ return omp->subname;
+ }
+ omp= omp->next;
+ }
+ return NULL;
+}
+
+Int4 tax1_getTaxIdByOrgRef(OrgRefPtr orgRef)
+{
+ Int4 tax_id, id;
+ ValNodePtr synonym;
+ CharPtr search_name;
+
+ tax_id= id= 0;
+
+ if((orgRef->orgname != NULL) && (orgRef->orgname->mod != NULL) &&
+ ((search_name= getSearchName(orgRef->orgname->mod)) != NULL)) {
+ tax_id= tax1_getTaxIdByName(search_name);
+ if(tax_id > 0) return tax_id;
+ else tax_id = 0;
+ }
+
+ if(orgRef->taxname != NULL) tax_id= tax1_getTaxIdByName(orgRef->taxname);
+ if(tax_id > 0) return tax_id;
+ if(orgRef->common != NULL) id= tax1_getTaxIdByName(orgRef->common);
+ if(id > 0) return id;
+
+ if(tax_id == 0) tax_id= id;
+
+ if(orgRef->syn != NULL) {
+ id= 0;
+
+ for(synonym= orgRef->syn; (synonym != NULL) && (id < 1); synonym= synonym->next) {
+ id= tax1_getTaxIdByName(synonym->data.ptrvalue);
+ }
+ }
+
+ return (id > 0)? id : tax_id;
+
+}
+
+static void cleanOrgName(OrgNamePtr onp)
+{
+ if(onp->lineage != NULL) MemFree(onp->lineage);
+ /* if(onp->mod != NULL) OrgModSetFree(onp->mod); */
+ if(onp->div != NULL) MemFree(onp->div);
+ if(onp->next != NULL) OrgNameSetFree(onp->next);
+ if(onp->data != NULL) {
+ switch(onp->choice) {
+ case 1: /* binomial name */
+ BinomialOrgNameFree(onp->data);
+ break;
+ case 2: /* virus name */
+ MemFree(onp->data);
+ break;
+ case 5: /* partial name */
+ TaxElementSetFree(onp->data);
+ break;
+ }
+ }
+}
+
+
+static BinomialOrgNamePtr copyBinomial(BinomialOrgNamePtr src)
+{
+ BinomialOrgNamePtr dst;
+
+ if(src == NULL) return NULL;
+
+ dst= BinomialOrgNameNew();
+ dst->genus= (src->genus != NULL)? StringSave(src->genus) : NULL;
+ dst->species= (src->species != NULL)? StringSave(src->species) : NULL;
+ dst->subspecies= (src->subspecies != NULL)? StringSave(src->subspecies) : NULL;
+
+ return dst;
+}
+
+static TaxElementPtr copyPartial(TaxElementPtr src)
+{
+ TaxElementPtr dst;
+
+ if(src == NULL) return NULL;
+
+ dst= TaxElementNew();
+ dst->fixed_level= src->fixed_level;
+ dst->level= (src->level != NULL)? StringSave(src->level) : NULL;
+ dst->name= (src->name != NULL)? StringSave(src->name) : NULL;
+ dst->next= (src->next != NULL)? copyPartial(src->next) : NULL;
+ return dst;
+}
+
+static OrgModPtr copyOrgMod(OrgModPtr src)
+{
+#if 0
+ OrgModPtr dst;
+
+ if(src == NULL) return NULL;
+
+ dst= OrgModNew();
+ dst->subtype= src->subtype;
+ dst->subname= (src->subname != NULL)? StringSave(src->subname) : NULL;
+ dst->attrib= (src->attrib != NULL)? StringSave(src->attrib) : NULL;
+ dst->next= (src->next != NULL)? copyOrgMod(src->next) : NULL;
+
+ return dst;
+#endif
+ return NULL;
+}
+
+static Int4 extractId(DbtagPtr dbtag)
+{
+ ObjectIdPtr object_id;
+
+ if((dbtag == NULL) || ((object_id= dbtag->tag) == NULL)) return 0;
+ return object_id->id;
+}
+
+static ValNodePtr removeDbtag(ValNodePtr vnp)
+{
+ ValNodePtr vnn, vnf, vnl= NULL;
+ DbtagPtr dbtag;
+
+ for(vnf= vnp; vnp != NULL; vnp= vnn) {
+ dbtag= vnp->data.ptrvalue;
+ vnn= vnp->next;
+ if(dbtag == NULL) return NULL;
+ if(StringCmp(dbtag->db, "taxon") == 0) {
+ /* taxon tag, remove it */
+ if(vnl == NULL) {
+ vnf= vnn;
+ }
+ else {
+ vnl->next= vnn;
+ }
+ DbtagFree(dbtag);
+ MemFree(vnp);
+ }
+ else {
+ vnl= vnp;
+ }
+ }
+ return vnf;
+}
+
+
+static void bldOrgRefOut(OrgRefPtr dst, OrgRefPtr src, Int4 tax_id)
+{
+ ValNodePtr vnp, vnl;
+ DbtagPtr dbtag;
+ ObjectIdPtr object_id;
+ OrgNamePtr onp;
+
+ dst->taxname= StringSave(src->taxname);
+ dst->common= (src->common != NULL)? StringSave(src->common) : NULL;
+
+ /* populate tax_id */
+ vnp= ValNodeNew(NULL);
+ if (dst->db != NULL) {
+ dst->db= removeDbtag(dst->db);
+ }
+ vnp->next= dst->db;
+ dst->db= vnp;
+ vnp->data.ptrvalue= dbtag= DbtagNew();
+ dbtag->db = StringSave("taxon");
+ dbtag->tag= object_id= ObjectIdNew();
+ object_id->str= NULL;
+ object_id->id = extractId(src->db->data.ptrvalue);
+
+ /* copy the synonym list */
+ dst->syn= NULL; vnl= NULL;
+
+ if(we_want_synonyms) {
+ for(vnp= src->syn; vnp != NULL; vnp= vnp->next) {
+ vnl= ValNodeNew(vnl);
+ vnl->choice= vnp->choice;
+ vnl->data.ptrvalue= StringSave(vnp->data.ptrvalue);
+ if(dst->syn == NULL) dst->syn= vnl;
+ }
+ }
+
+ /* copy orgname */
+ if(dst->orgname == NULL) dst->orgname= onp= OrgNameNew();
+ else onp= dst->orgname;
+
+ onp->choice= src->orgname->choice;
+
+ switch(src->orgname->choice) {
+ case 1: /*binomial*/
+ onp->data= copyBinomial(src->orgname->data);
+ break;
+ case 2: /* virus */
+ onp->data= (src->orgname->data != NULL)? StringSave(src->orgname->data) : NULL;
+ break;
+ case 5: /* partial */
+ onp->data= copyPartial(src->orgname->data);
+ break;
+ default: /* can't handle */
+ onp->data= NULL;
+ }
+
+ if(onp->mod == NULL) onp->mod= copyOrgMod(src->orgname->mod);
+ onp->lineage= (src->orgname->lineage != NULL)? StringSave(src->orgname->lineage) : NULL;
+ onp->gcode= src->orgname->gcode;
+ onp->mgcode= src->orgname->mgcode;
+ onp->div= (src->orgname->div != NULL) ? StringSave(src->orgname->div) : NULL;
+}
+
+static void populateReplaced(OrgRefPtr orp, CharPtr oldName)
+{
+ OrgNamePtr onp;
+ OrgModPtr omp;
+
+ if((orp->taxname != NULL) && (StringICmp(orp->taxname, oldName) == 0)) return;
+ if((orp->common != NULL) && (StringICmp(orp->common, oldName) == 0)) return;
+
+ /* organism name was changed */
+ onp= orp->orgname;
+ if((onp != NULL) && (getSearchName(onp->mod) == NULL)) {
+ omp= OrgModNew();
+ omp->next= onp->mod;
+ omp->subtype= 254;
+ omp->subname= StringSave(oldName);
+ onp->mod= omp;
+ }
+}
+
+Taxon1DataPtr tax1_lookup(OrgRefPtr inp_orgRef, int merge)
+{
+ Taxon1DataPtr res;
+ Int4 tax_id;
+ OrgRefPtr db_orgRef;
+ int is_species;
+
+ tax_id= tax1_getTaxIdByOrgRef(inp_orgRef);
+ if(tax_id <= 0) return NULL;
+ res= Taxon1DataNew();
+ res->div= MemNew(16);
+ res->embl_code= MemNew(4);
+ db_orgRef= tax1_getOrgRef(tax_id, &is_species, res->div, res->embl_code);
+ res->embl_code[0]= '\0';
+ if(db_orgRef == NULL) {
+ Taxon1DataFree(res);
+ return NULL;
+ }
+
+ res->is_species_level= is_species;
+ if(merge) {
+ /* we have to merge old orgref with new one */
+ res->org= inp_orgRef;
+ /* clean-up old information */
+ if(inp_orgRef->taxname != NULL) MemFree(inp_orgRef->taxname);
+ if(inp_orgRef->common != NULL) MemFree(inp_orgRef->common);
+ if(inp_orgRef->syn != NULL) ValNodeFreeData(inp_orgRef->syn);
+ if(inp_orgRef->orgname != NULL) cleanOrgName(inp_orgRef->orgname);
+ }
+ else {
+ /* make new orgref */
+ res->org= OrgRefNew();
+ res->org->db= NULL;
+ res->org->orgname= NULL;
+ }
+ /* fill-up orgref based on db_orgRef */
+ bldOrgRefOut(res->org, db_orgRef, tax_id);
+ populateReplaced(res->org, hit_name);
+ return res;
+}
+
+
+Taxon1DataPtr tax1_getbyid(Int4 tax_id)
+{
+ Taxon1DataPtr res;
+ OrgRefPtr db_orgRef;
+ int is_species;
+
+ if(tax_id <= 0) return NULL;
+ res= Taxon1DataNew();
+ res->div= MemNew(16);
+ res->embl_code= MemNew(4);
+ db_orgRef= tax1_getOrgRef(tax_id, &is_species, res->div, res->embl_code);
+ res->embl_code[0]= '\0';
+ if(db_orgRef == NULL) {
+ Taxon1DataFree(res);
+ return NULL;
+ }
+
+ /* make new orgref */
+ res->org= OrgRefNew();
+ res->org->db= NULL;
+ res->org->orgname= NULL;
+ res->is_species_level= is_species;
+
+ /* fill-up orgref based on db_orgRef */
+ bldOrgRefOut(res->org, db_orgRef, tax_id);
+ return res;
+}
+
+Boolean tax1_init()
+{
+ initBuff();
+ return Tax0Init();
+}
+
+void tax1_fini()
+{
+ Tax0Fini();
+}
+
+Int4 tax1_getParent(Int4 id_tax)
+{
+ TaxonIdListPtr tilp;
+ Int4 res= 0;
+
+ if((tilp= Tax0GetParents(id_tax)) != NULL) {
+ if(tilp->_num_ids > 0) res= tilp->ids[0];
+ TaxonIdListFree(tilp);
+ }
+
+ return res;
+}
+
+int tax1_getChildren(Int4 id_tax, Int4** ids_out)
+{
+ int n= 0;
+ TaxonIdListPtr tilp;
+
+ *ids_out= NULL;
+ if((tilp= Tax0GetChildren(id_tax)) != NULL) {
+ if(tilp->_num_ids > 0) *ids_out= tilp->ids;
+ n= tilp->_num_ids;
+ tilp->_num_ids= 0;
+ tilp->ids= NULL;
+ TaxonIdListFree(tilp);
+ }
+ return n;
+}
+
+/* find the nearest ancestor for two nodes */
+Int4 tax1_join(Int4 taxid1, Int4 taxid2)
+{
+ TaxonIdListPtr tilp1, tilp2;
+ Int4 res= 0;
+ Int2 i, j;
+
+ if(taxid1 == taxid2) return taxid1;
+
+ tilp1= Tax0GetParents(-taxid1);
+ if(tilp1 == NULL) return 1;
+ if(tilp1->_num_ids < 1) {
+ TaxonIdListFree(tilp1);
+ return 1;
+ }
+
+ for(i= 0; i < tilp1->_num_ids; i++) {
+ if(tilp1->ids[i] == taxid2) {
+ TaxonIdListFree(tilp1);
+ return taxid2;
+ }
+ }
+
+ tilp2= Tax0GetParents(-taxid2);
+ if(tilp2 == NULL) {
+ TaxonIdListFree(tilp1);
+ return 1;
+ }
+ if(tilp2->_num_ids >= 1) {
+ for(i= 0; i < tilp2->_num_ids; i++) {
+ if(tilp2->ids[i] == taxid1) {
+ res= taxid1;
+ break;
+ }
+ }
+
+ if(res == 0) {
+ for(i= 0; i < tilp1->_num_ids; i++) {
+ taxid1= tilp1->ids[i];
+ for(j= 0; j < tilp2->_num_ids; j++) {
+ if(tilp2->ids[j] == taxid1) {
+ res= taxid1;
+ break;
+ }
+ }
+ if(res) break;
+ }
+ }
+
+ }
+
+ TaxonIdListFree(tilp2);
+ TaxonIdListFree(tilp1);
+ return ((res > 0)? res : 1);
+}
+
+
+
+
diff --git a/network/taxon1/client/objtaxc0.c b/network/taxon1/client/objtaxc0.c
new file mode 100644
index 00000000..1d83c847
--- /dev/null
+++ b/network/taxon1/client/objtaxc0.c
@@ -0,0 +1,1470 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: objtaxc0.c,v $
+* Revision 6.0 1997/08/25 18:41:13 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1996/07/03 18:47:42 epstein
+* eliminate double-quotes in favor of angle-brackets
+*
+ * Revision 5.0 1996/05/28 14:15:13 ostell
+ * Set to revision 5.0
+ *
+ * Revision 1.1 1996/03/06 17:05:19 soussov
+ * Initial revision
+ *
+*/
+
+#include <asn.h>
+#include <ncbi.h>
+#include <objfeat.h>
+
+#ifdef NLM_OBJ_INCL
+#include NLM_OBJ_INCL
+#endif
+#include <objtaxc0.h>
+
+static Boolean loaded = FALSE;
+
+#include <asntaxon.h>
+
+#ifndef NLM_EXTERN_LOADS
+#define NLM_EXTERN_LOADS {}
+#endif
+
+static Boolean _AsnLoad(void)
+{
+
+ if ( ! loaded) {
+ NLM_EXTERN_LOADS
+
+ if ( ! AsnLoad ())
+ return FALSE;
+ loaded = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/**************************************************
+*
+* Generated object loaders for Module NCBI-Taxon0
+*
+**************************************************/
+
+
+/**************************************************
+*
+* Taxon0ReqFree()
+*
+**************************************************/
+Taxon0ReqPtr LIBCALL Taxon0ReqFree ( Taxon0ReqPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ {Pointer pt = ptr -> data.ptrvalue;
+ switch (ptr -> choice){
+ case Taxon0Req_getid :
+ TaxonNameFree(pt);
+ break;
+ case Taxon0Req_getcomplete :
+ TaxonIdNameFree(pt);
+ break;
+ }}
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonNameFree()
+*
+**************************************************/
+TaxonNamePtr LIBCALL TaxonNameFree ( TaxonNamePtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ {Pointer pt = ptr -> data.ptrvalue;
+ switch (ptr -> choice){
+ case TaxonName_taxname :
+ case TaxonName_common :
+ case TaxonName_tax_synonym :
+ case TaxonName_com_synonym :
+ MemFree(pt);
+ break;
+ }}
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonIdNameFree()
+*
+**************************************************/
+TaxonIdNamePtr LIBCALL TaxonIdNameFree ( TaxonIdNamePtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ {Pointer pt = ptr -> data.ptrvalue;
+ switch (ptr -> choice){
+ case TaxonIdName_name :
+ MemFree(pt);
+ break;
+ }}
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* Taxon0RespFree()
+*
+**************************************************/
+Taxon0RespPtr LIBCALL Taxon0RespFree ( Taxon0RespPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ {Pointer pt = ptr -> data.ptrvalue;
+ switch (ptr -> choice){
+ case Taxon0Resp_getid :
+ TaxonIdListFree(pt);
+ break;
+ case Taxon0Resp_getref :
+ OrgRefFree(pt);
+ break;
+ case Taxon0Resp_gettaxon :
+ TaxonIdListFree(pt);
+ break;
+ case Taxon0Resp_getgeneticcode :
+ GeneticCodeListFree(pt);
+ break;
+ case Taxon0Resp_gettaxonline :
+ case Taxon0Resp_getdivision :
+ MemFree(pt);
+ break;
+ case Taxon0Resp_getcomplete :
+ TaxCompleteListFree(pt);
+ break;
+ }}
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonIdListFree()
+*
+**************************************************/
+TaxonIdListPtr LIBCALL TaxonIdListFree ( TaxonIdListPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ MemFree(ptr -> ids);
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* GeneticCodeListFree()
+*
+**************************************************/
+GeneticCodeListPtr LIBCALL GeneticCodeListFree ( GeneticCodeListPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxCompleteListFree()
+*
+**************************************************/
+TaxCompleteListPtr LIBCALL TaxCompleteListFree ( TaxCompleteListPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ TaxCompleteFree( ptr -> info);
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonIdFree()
+*
+**************************************************/
+TaxonIdPtr LIBCALL TaxonIdFree ( TaxonIdPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxCompleteFree()
+*
+**************************************************/
+TaxCompletePtr LIBCALL TaxCompleteFree ( TaxCompletePtr head_ptr)
+{
+ TaxCompletePtr ptr, hold_ptr;
+
+ if (head_ptr == NULL) return NULL;
+
+ for (ptr = head_ptr; ptr; ptr = hold_ptr){
+ hold_ptr = ptr -> next;
+ MemFree(ptr -> sciname);
+ MemFree(ptr -> comname);
+ MemFree(ptr -> synonyms);
+ MemFree(ptr -> name_gc);
+ MemFree(ptr -> name_mgc);
+ MemFree(ptr -> gb_div);
+ MemFree(ptr -> embl_code);
+ MemFree(ptr -> lineage);
+ MemFree(ptr);
+ }
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonIdListNew()
+*
+**************************************************/
+
+TaxonIdListPtr LIBCALL
+TaxonIdListNew()
+{
+
+ return (TaxonIdListPtr) MemNew(sizeof(TaxonIdList));
+
+}
+
+
+
+/**************************************************
+*
+* GeneticCodeListNew()
+*
+**************************************************/
+
+GeneticCodeListPtr LIBCALL
+GeneticCodeListNew()
+{
+
+ return (GeneticCodeListPtr) MemNew(sizeof(GeneticCodeList));
+
+}
+
+
+
+/**************************************************
+*
+* TaxCompleteListNew()
+*
+**************************************************/
+
+TaxCompleteListPtr LIBCALL
+TaxCompleteListNew()
+{
+
+ return (TaxCompleteListPtr) MemNew(sizeof(TaxCompleteList));
+
+}
+
+
+
+/**************************************************
+*
+* TaxonIdNew()
+*
+**************************************************/
+
+TaxonIdPtr LIBCALL
+TaxonIdNew()
+{
+
+ return (TaxonIdPtr) MemNew(sizeof(TaxonId));
+
+}
+
+
+
+/**************************************************
+*
+* TaxCompleteNew()
+*
+**************************************************/
+
+TaxCompletePtr LIBCALL
+TaxCompleteNew()
+{
+
+ return (TaxCompletePtr) MemNew(sizeof(TaxComplete));
+
+}
+
+
+
+/**************************************************
+*
+* Taxon0ReqAsnRead()
+*
+**************************************************/
+Taxon0ReqPtr LIBCALL Taxon0ReqAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr vnp;
+ Uint1 choice ;
+ AsnReadFunc func;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON0_REQ);
+ else
+ atp = AsnLinkType(orig, TAXON0_REQ);
+ if(atp == NULL) return NULL;
+
+ vnp = ValNodeNew(NULL);
+ if (vnp == NULL) goto erret;
+ if ( AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ if ( (atp = AsnReadId(aip, amp, atp)) == NULL) goto erret;
+ func = NULL;
+ if (atp == TAXON0_REQ_init){
+ choice = Taxon0Req_init;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getid){
+ choice = Taxon0Req_getid;
+ func = (AsnReadFunc) TaxonNameAsnRead;
+ }
+ else
+ if (atp == TAXON0_REQ_getref){
+ choice = Taxon0Req_getref;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getchildren){
+ choice = Taxon0Req_getchildren;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getparents){
+ choice = Taxon0Req_getparents;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getgeneticcode){
+ choice = Taxon0Req_getgeneticcode;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_gettaxonline){
+ choice = Taxon0Req_gettaxonline;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getdivision){
+ choice = Taxon0Req_getdivision;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getcomplete){
+ choice = Taxon0Req_getcomplete;
+ func = (AsnReadFunc) TaxonIdNameAsnRead;
+ }
+ else
+ if (atp == TAXON0_REQ_fini){
+ choice = Taxon0Req_fini;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ goto erret;
+ vnp -> choice = choice;
+ if (func != NULL)
+ vnp -> data.ptrvalue = (*func) (aip,atp);
+ret:
+ AsnUnlinkType(orig);
+ return vnp;
+erret:
+ vnp=Taxon0ReqFree(vnp);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonNameAsnRead()
+*
+**************************************************/
+TaxonNamePtr LIBCALL TaxonNameAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr vnp;
+ Uint1 choice ;
+ AsnReadFunc func;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON_NAME);
+ else
+ atp = AsnLinkType(orig, TAXON_NAME);
+ if(atp == NULL) return NULL;
+
+ vnp = ValNodeNew(NULL);
+ if (vnp == NULL) goto erret;
+ if ( AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ if ( (atp = AsnReadId(aip, amp, atp)) == NULL) goto erret;
+ func = NULL;
+ if (atp == TAXON_NAME_taxname){
+ choice = TaxonName_taxname;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON_NAME_common){
+ choice = TaxonName_common;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON_NAME_tax_synonym){
+ choice = TaxonName_tax_synonym;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON_NAME_com_synonym){
+ choice = TaxonName_com_synonym;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ goto erret;
+ vnp -> choice = choice;
+ if (func != NULL)
+ vnp -> data.ptrvalue = (*func) (aip,atp);
+ret:
+ AsnUnlinkType(orig);
+ return vnp;
+erret:
+ vnp=TaxonNameFree(vnp);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdNameAsnRead()
+*
+**************************************************/
+TaxonIdNamePtr LIBCALL TaxonIdNameAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr vnp;
+ Uint1 choice ;
+ AsnReadFunc func;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON_ID_NAME);
+ else
+ atp = AsnLinkType(orig, TAXON_ID_NAME);
+ if(atp == NULL) return NULL;
+
+ vnp = ValNodeNew(NULL);
+ if (vnp == NULL) goto erret;
+ if ( AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ if ( (atp = AsnReadId(aip, amp, atp)) == NULL) goto erret;
+ func = NULL;
+ if (atp == TAXON_ID_NAME_id){
+ choice = TaxonIdName_id;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON_ID_NAME_name){
+ choice = TaxonIdName_name;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ goto erret;
+ vnp -> choice = choice;
+ if (func != NULL)
+ vnp -> data.ptrvalue = (*func) (aip,atp);
+ret:
+ AsnUnlinkType(orig);
+ return vnp;
+erret:
+ vnp=TaxonIdNameFree(vnp);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Taxon0RespAsnRead()
+*
+**************************************************/
+Taxon0RespPtr LIBCALL Taxon0RespAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr vnp;
+ Uint1 choice ;
+ AsnReadFunc func;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON0_RESP);
+ else
+ atp = AsnLinkType(orig, TAXON0_RESP);
+ if(atp == NULL) return NULL;
+
+ vnp = ValNodeNew(NULL);
+ if (vnp == NULL) goto erret;
+ if ( AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ if ( (atp = AsnReadId(aip, amp, atp)) == NULL) goto erret;
+ func = NULL;
+ if (atp == TAXON0_RESP_error){
+ choice = Taxon0Resp_error;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_RESP_init){
+ choice = Taxon0Resp_init;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_RESP_getid){
+ choice = Taxon0Resp_getid;
+ func = (AsnReadFunc) TaxonIdListAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_getref){
+ choice = Taxon0Resp_getref;
+ func = (AsnReadFunc) OrgRefAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_gettaxon){
+ choice = Taxon0Resp_gettaxon;
+ func = (AsnReadFunc) TaxonIdListAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_getgeneticcode){
+ choice = Taxon0Resp_getgeneticcode;
+ func = (AsnReadFunc) GeneticCodeListAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_gettaxonline){
+ choice = Taxon0Resp_gettaxonline;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_RESP_getdivision){
+ choice = Taxon0Resp_getdivision;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_RESP_getcomplete){
+ choice = Taxon0Resp_getcomplete;
+ func = (AsnReadFunc) TaxCompleteListAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_fini){
+ choice = Taxon0Resp_fini;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ goto erret;
+ vnp -> choice = choice;
+ if (func != NULL)
+ vnp -> data.ptrvalue = (*func) (aip,atp);
+ret:
+ AsnUnlinkType(orig);
+ return vnp;
+erret:
+ vnp=Taxon0RespFree(vnp);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdListAsnRead()
+*
+**************************************************/
+TaxonIdListPtr LIBCALL TaxonIdListAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ TaxonIdListPtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON_ID_LIST);
+ else
+ atp = AsnLinkType(orig, TAXON_ID_LIST);
+ if(atp == NULL) return NULL;
+
+ ptr = TaxonIdListNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == TAXON_ID_LIST_ids)
+ {
+ AsnTypePtr now_atp;
+ ValNodePtr current;
+ ValNodePtr head = NULL;
+ ValNodePtr prev = NULL;
+ Int4 _num_ = 0;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* START_STUCT */
+ goto erret;
+
+ now_atp = atp;
+
+ while ((now_atp = AsnReadId(aip, amp, now_atp)) != atp){
+ if (now_atp == NULL) goto erret;
+
+ current = ValNodeNew(prev);
+ AsnReadVal(aip, now_atp, & current -> data);
+ _num_ ++;
+ if (current == NULL) goto erret;
+
+ if (head == NULL)
+ head = current;
+ else
+ prev -> next = current;
+ prev=current;
+ }
+ if (AsnReadVal(aip, atp, &av) <=0) /* END_STRUCT */ goto erret;
+ ptr -> _num_ids = _num_;
+ ptr -> ids = MemNew( _num_ * sizeof (Pointer) );
+ for (_num_ = 0, current = head; current; current = current -> next, _num_ ++){
+ (ptr -> ids) [_num_] = current -> data.intvalue;
+ }
+ ValNodeFree(head);
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=TaxonIdListFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* GeneticCodeListAsnRead()
+*
+**************************************************/
+GeneticCodeListPtr LIBCALL GeneticCodeListAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ GeneticCodeListPtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, GENETICCODELIST);
+ else
+ atp = AsnLinkType(orig, GENETICCODELIST);
+ if(atp == NULL) return NULL;
+
+ ptr = GeneticCodeListNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == GENETICCODELIST_genomic){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->genomic = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == GENETICCODELIST_mitochondrial){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->mitochondrial = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=GeneticCodeListFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxCompleteListAsnRead()
+*
+**************************************************/
+TaxCompleteListPtr LIBCALL TaxCompleteListAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ TaxCompleteListPtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAX_COMPLETE_LIST);
+ else
+ atp = AsnLinkType(orig, TAX_COMPLETE_LIST);
+ if(atp == NULL) return NULL;
+
+ ptr = TaxCompleteListNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == TAX_COMPLETE_LIST_num){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->num = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_LIST_info)
+ {
+ AsnTypePtr now_atp;
+ TaxCompletePtr current;
+ TaxCompletePtr head = NULL;
+ TaxCompletePtr prev = NULL;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* START_STUCT */
+ goto erret;
+
+ now_atp = atp;
+
+ while ((now_atp = AsnReadId(aip, amp, now_atp)) != atp){
+ if (now_atp == NULL) goto erret;
+
+ current= TaxCompleteAsnRead(aip, now_atp);
+ if (current == NULL) goto erret;
+
+ if (head == NULL)
+ head = current;
+ else
+ prev -> next = current;
+ prev=current;
+ }
+ if (AsnReadVal(aip, atp, &av) <=0) /* END_STRUCT */ goto erret;
+ ptr -> info = head;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=TaxCompleteListFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdAsnRead()
+*
+**************************************************/
+TaxonIdPtr LIBCALL TaxonIdAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ TaxonIdPtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON_ID);
+ else
+ atp = AsnLinkType(orig, TAXON_ID);
+ if(atp == NULL) return NULL;
+
+ ptr = TaxonIdNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == TAXON_ID_id){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->id = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=TaxonIdFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxCompleteAsnRead()
+*
+**************************************************/
+TaxCompletePtr LIBCALL TaxCompleteAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ TaxCompletePtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAX_COMPLETE);
+ else
+ atp = AsnLinkType(orig, TAX_COMPLETE);
+ if(atp == NULL) return NULL;
+
+ ptr = TaxCompleteNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == TAX_COMPLETE_sciname){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->sciname = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_comname){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->comname = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_synonyms){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->synonyms = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_id_gc){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->id_gc = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_name_gc){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->name_gc = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_id_mgc){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->id_mgc = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_name_mgc){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->name_mgc = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_gb_div){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->gb_div = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_embl_code){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->embl_code = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_lineage){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->lineage = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_is_species_level){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->is_species_level = (Uint1)av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=TaxCompleteFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Taxon0ReqAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL Taxon0ReqAsnWrite (Taxon0ReqPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+ AsnWriteFunc func;
+ AsnTypePtr writetype = NULL;
+ Pointer pnt;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON0_REQ);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ av.ptrvalue = (Pointer) ptr;
+ if (! AsnWriteChoice(aip, atp, ptr -> choice, & av)) goto erret;
+ pnt = ptr -> data.ptrvalue;
+ av.intvalue = ptr -> data.intvalue;
+ switch (ptr -> choice){
+ case Taxon0Req_init :
+ retval = AsnWrite(aip, TAXON0_REQ_init, &av); break;
+ case Taxon0Req_getid :
+ writetype = TAXON0_REQ_getid;
+ func = (AsnWriteFunc) TaxonNameAsnWrite;
+ break;
+ case Taxon0Req_getref :
+ retval = AsnWrite(aip, TAXON0_REQ_getref, &av); break;
+ case Taxon0Req_getchildren :
+ retval = AsnWrite(aip, TAXON0_REQ_getchildren, &av); break;
+ case Taxon0Req_getparents :
+ retval = AsnWrite(aip, TAXON0_REQ_getparents, &av); break;
+ case Taxon0Req_getgeneticcode :
+ retval = AsnWrite(aip, TAXON0_REQ_getgeneticcode, &av); break;
+ case Taxon0Req_gettaxonline :
+ retval = AsnWrite(aip, TAXON0_REQ_gettaxonline, &av); break;
+ case Taxon0Req_getdivision :
+ retval = AsnWrite(aip, TAXON0_REQ_getdivision, &av); break;
+ case Taxon0Req_getcomplete :
+ writetype = TAXON0_REQ_getcomplete;
+ func = (AsnWriteFunc) TaxonIdNameAsnWrite;
+ break;
+ case Taxon0Req_fini :
+ retval = AsnWrite(aip, TAXON0_REQ_fini, &av); break;
+ }
+ if (writetype != NULL)
+ retval = (*func) (pnt, aip,writetype);
+ret:
+ AsnUnlinkType(orig);
+ return retval;
+erret:
+ ptr=Taxon0ReqFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonNameAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxonNameAsnWrite (TaxonNamePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+ AsnWriteFunc func;
+ AsnTypePtr writetype = NULL;
+ Pointer pnt;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON_NAME);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ av.ptrvalue = (Pointer) ptr;
+ if (! AsnWriteChoice(aip, atp, ptr -> choice, & av)) goto erret;
+ pnt = ptr -> data.ptrvalue;
+ av.intvalue = ptr -> data.intvalue;
+ switch (ptr -> choice){
+ case TaxonName_taxname :
+ retval = AsnWrite(aip, TAXON_NAME_taxname, &av); break;
+ case TaxonName_common :
+ retval = AsnWrite(aip, TAXON_NAME_common, &av); break;
+ case TaxonName_tax_synonym :
+ retval = AsnWrite(aip, TAXON_NAME_tax_synonym, &av); break;
+ case TaxonName_com_synonym :
+ retval = AsnWrite(aip, TAXON_NAME_com_synonym, &av); break;
+ }
+ if (writetype != NULL)
+ retval = (*func) (pnt, aip,writetype);
+ret:
+ AsnUnlinkType(orig);
+ return retval;
+erret:
+ ptr=TaxonNameFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdNameAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxonIdNameAsnWrite (TaxonIdNamePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+ AsnWriteFunc func;
+ AsnTypePtr writetype = NULL;
+ Pointer pnt;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON_ID_NAME);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ av.ptrvalue = (Pointer) ptr;
+ if (! AsnWriteChoice(aip, atp, ptr -> choice, & av)) goto erret;
+ pnt = ptr -> data.ptrvalue;
+ av.intvalue = ptr -> data.intvalue;
+ switch (ptr -> choice){
+ case TaxonIdName_id :
+ retval = AsnWrite(aip, TAXON_ID_NAME_id, &av); break;
+ case TaxonIdName_name :
+ retval = AsnWrite(aip, TAXON_ID_NAME_name, &av); break;
+ }
+ if (writetype != NULL)
+ retval = (*func) (pnt, aip,writetype);
+ret:
+ AsnUnlinkType(orig);
+ return retval;
+erret:
+ ptr=TaxonIdNameFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Taxon0RespAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL Taxon0RespAsnWrite (Taxon0RespPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+ AsnWriteFunc func;
+ AsnTypePtr writetype = NULL;
+ Pointer pnt;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON0_RESP);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ av.ptrvalue = (Pointer) ptr;
+ if (! AsnWriteChoice(aip, atp, ptr -> choice, & av)) goto erret;
+ pnt = ptr -> data.ptrvalue;
+ av.intvalue = ptr -> data.intvalue;
+ switch (ptr -> choice){
+ case Taxon0Resp_error :
+ retval = AsnWrite(aip, TAXON0_RESP_error, &av); break;
+ case Taxon0Resp_init :
+ retval = AsnWrite(aip, TAXON0_RESP_init, &av); break;
+ case Taxon0Resp_getid :
+ writetype = TAXON0_RESP_getid;
+ func = (AsnWriteFunc) TaxonIdListAsnWrite;
+ break;
+ case Taxon0Resp_getref :
+ writetype = TAXON0_RESP_getref;
+ func = (AsnWriteFunc) OrgRefAsnWrite;
+ break;
+ case Taxon0Resp_gettaxon :
+ writetype = TAXON0_RESP_gettaxon;
+ func = (AsnWriteFunc) TaxonIdListAsnWrite;
+ break;
+ case Taxon0Resp_getgeneticcode :
+ writetype = TAXON0_RESP_getgeneticcode;
+ func = (AsnWriteFunc) GeneticCodeListAsnWrite;
+ break;
+ case Taxon0Resp_gettaxonline :
+ retval = AsnWrite(aip, TAXON0_RESP_gettaxonline, &av); break;
+ case Taxon0Resp_getdivision :
+ retval = AsnWrite(aip, TAXON0_RESP_getdivision, &av); break;
+ case Taxon0Resp_getcomplete :
+ writetype = TAXON0_RESP_getcomplete;
+ func = (AsnWriteFunc) TaxCompleteListAsnWrite;
+ break;
+ case Taxon0Resp_fini :
+ retval = AsnWrite(aip, TAXON0_RESP_fini, &av); break;
+ }
+ if (writetype != NULL)
+ retval = (*func) (pnt, aip,writetype);
+ret:
+ AsnUnlinkType(orig);
+ return retval;
+erret:
+ ptr=Taxon0RespFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdListAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxonIdListAsnWrite (TaxonIdListPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON_ID_LIST);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ if (ptr -> ids != NULL){
+ if (! AsnOpenStruct (aip, TAXON_ID_LIST_ids, (Pointer) ptr -> ids))
+ goto erret;
+
+ {Int4 _num_ ;
+ for( _num_ = 0; _num_ < ptr -> _num_ids; _num_ ++){
+ av.intvalue = (ptr -> ids) [_num_];
+ if ( ! AsnWrite(aip, TAXON_ID_LIST_ids_E, & av)) goto erret;
+ }}
+
+ if (! AsnCloseStruct (aip, TAXON_ID_LIST_ids, (Pointer) ptr -> ids))
+ goto erret;
+ }
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
+
+
+/**************************************************
+*
+* GeneticCodeListAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL GeneticCodeListAsnWrite (GeneticCodeListPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, GENETICCODELIST);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ av.intvalue = (int) ptr -> genomic;
+ if ( ! AsnWrite(aip,GENETICCODELIST_genomic, &av)) goto erret;
+ av.intvalue = (int) ptr -> mitochondrial;
+ if ( ! AsnWrite(aip,GENETICCODELIST_mitochondrial, &av)) goto erret;
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
+
+
+/**************************************************
+*
+* TaxCompleteListAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxCompleteListAsnWrite (TaxCompleteListPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAX_COMPLETE_LIST);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ av.intvalue = (int) ptr -> num;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_LIST_num, &av)) goto erret;
+ if (ptr -> info != NULL){
+ if (! AsnOpenStruct (aip, TAX_COMPLETE_LIST_info, (Pointer) ptr -> info))
+ goto erret;
+
+ {TaxCompletePtr current;
+ for(current=ptr -> info; current; current = current -> next){
+ if ( ! TaxCompleteAsnWrite(current,aip,TAX_COMPLETE_LIST_info_E)) goto erret;
+ }}
+
+ if (! AsnCloseStruct (aip, TAX_COMPLETE_LIST_info, (Pointer) ptr -> info))
+ goto erret;
+ }
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
+
+
+/**************************************************
+*
+* TaxonIdAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxonIdAsnWrite (TaxonIdPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON_ID);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ av.intvalue = (int) ptr -> id;
+ if ( ! AsnWrite(aip,TAXON_ID_id, &av)) goto erret;
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
+
+
+/**************************************************
+*
+* TaxCompleteAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxCompleteAsnWrite (TaxCompletePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAX_COMPLETE);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ if (ptr -> sciname != NULL){
+ av.ptrvalue = (Pointer) ptr -> sciname;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_sciname, &av)) goto erret;
+ }
+ if (ptr -> comname != NULL){
+ av.ptrvalue = (Pointer) ptr -> comname;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_comname, &av)) goto erret;
+ }
+ if (ptr -> synonyms != NULL){
+ av.ptrvalue = (Pointer) ptr -> synonyms;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_synonyms, &av)) goto erret;
+ }
+ av.intvalue = (int) ptr -> id_gc;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_id_gc, &av)) goto erret;
+ if (ptr -> name_gc != NULL){
+ av.ptrvalue = (Pointer) ptr -> name_gc;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_name_gc, &av)) goto erret;
+ }
+ av.intvalue = (int) ptr -> id_mgc;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_id_mgc, &av)) goto erret;
+ if (ptr -> name_mgc != NULL){
+ av.ptrvalue = (Pointer) ptr -> name_mgc;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_name_mgc, &av)) goto erret;
+ }
+ if (ptr -> gb_div != NULL){
+ av.ptrvalue = (Pointer) ptr -> gb_div;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_gb_div, &av)) goto erret;
+ }
+ if (ptr -> embl_code != NULL){
+ av.ptrvalue = (Pointer) ptr -> embl_code;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_embl_code, &av)) goto erret;
+ }
+ if (ptr -> lineage != NULL){
+ av.ptrvalue = (Pointer) ptr -> lineage;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_lineage, &av)) goto erret;
+ }
+ av.boolvalue = (int) ptr -> is_species_level;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_is_species_level, &av)) goto erret;
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
diff --git a/network/taxon1/client/objtaxc0.h b/network/taxon1/client/objtaxc0.h
new file mode 100644
index 00000000..73003e59
--- /dev/null
+++ b/network/taxon1/client/objtaxc0.h
@@ -0,0 +1,213 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: objtaxc0.h,v $
+* Revision 6.0 1997/08/25 18:41:16 madden
+* Revision changed to 6.0
+*
+* Revision 5.0 1996/05/28 14:15:13 ostell
+* Set to revision 5.0
+*
+ * Revision 1.1 1996/03/06 17:05:19 soussov
+ * Initial revision
+ *
+ * Revision 4.0 1995/07/26 13:55:46 ostell
+ * force revision to 4.0
+ *
+ * Revision 1.4 1995/05/17 17:58:27 epstein
+ * add RCS log revision history
+ *
+*/
+
+
+
+/**************************************************
+*
+* Generated objects for Module NCBI-Taxon0
+*
+**************************************************/
+
+
+/**************************************************
+*
+* Taxon0Req
+*
+**************************************************/
+typedef ValNode Taxon0Req;
+typedef ValNodePtr Taxon0ReqPtr;
+#define Taxon0Req_init 1 /* NULL */
+#define Taxon0Req_getid 2 /* Taxon-name */
+#define Taxon0Req_getref 3 /* INTEGER */
+#define Taxon0Req_getchildren 4 /* INTEGER */
+#define Taxon0Req_getparents 5 /* INTEGER */
+#define Taxon0Req_getgeneticcode 6 /* INTEGER */
+#define Taxon0Req_gettaxonline 7 /* INTEGER */
+#define Taxon0Req_getdivision 8 /* INTEGER */
+#define Taxon0Req_getcomplete 9 /* Taxon-id-name */
+#define Taxon0Req_fini 10 /* NULL */
+
+
+Taxon0ReqPtr LIBCALL Taxon0ReqFree PROTO ((Taxon0ReqPtr ));
+Taxon0ReqPtr LIBCALL Taxon0ReqAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL Taxon0ReqAsnWrite PROTO (( Taxon0ReqPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxonName
+*
+**************************************************/
+typedef ValNode TaxonName;
+typedef ValNodePtr TaxonNamePtr;
+#define TaxonName_taxname 1 /* VisibleString */
+#define TaxonName_common 2 /* VisibleString */
+#define TaxonName_tax_synonym 3 /* VisibleString */
+#define TaxonName_com_synonym 4 /* VisibleString */
+
+
+TaxonNamePtr LIBCALL TaxonNameFree PROTO ((TaxonNamePtr ));
+TaxonNamePtr LIBCALL TaxonNameAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxonNameAsnWrite PROTO (( TaxonNamePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxonIdName
+*
+**************************************************/
+typedef ValNode TaxonIdName;
+typedef ValNodePtr TaxonIdNamePtr;
+#define TaxonIdName_id 1 /* INTEGER */
+#define TaxonIdName_name 2 /* VisibleString */
+
+
+TaxonIdNamePtr LIBCALL TaxonIdNameFree PROTO ((TaxonIdNamePtr ));
+TaxonIdNamePtr LIBCALL TaxonIdNameAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxonIdNameAsnWrite PROTO (( TaxonIdNamePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* Taxon0Resp
+*
+**************************************************/
+typedef ValNode Taxon0Resp;
+typedef ValNodePtr Taxon0RespPtr;
+#define Taxon0Resp_error 1 /* INTEGER */
+#define Taxon0Resp_init 2 /* NULL */
+#define Taxon0Resp_getid 3 /* Taxon-id-list */
+#define Taxon0Resp_getref 4 /* Org-ref */
+#define Taxon0Resp_gettaxon 5 /* Taxon-id-list */
+#define Taxon0Resp_getgeneticcode 6 /* GeneticCodeList */
+#define Taxon0Resp_gettaxonline 7 /* VisibleString */
+#define Taxon0Resp_getdivision 8 /* VisibleString */
+#define Taxon0Resp_getcomplete 9 /* Tax-complete-list */
+#define Taxon0Resp_fini 10 /* NULL */
+
+
+Taxon0RespPtr LIBCALL Taxon0RespFree PROTO ((Taxon0RespPtr ));
+Taxon0RespPtr LIBCALL Taxon0RespAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL Taxon0RespAsnWrite PROTO (( Taxon0RespPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxonIdList
+*
+**************************************************/
+typedef struct struct_Taxon_id_list {
+ Int4 _num_ids;
+ Int4 PNTR ids;
+} TaxonIdList, PNTR TaxonIdListPtr;
+
+
+TaxonIdListPtr LIBCALL TaxonIdListFree PROTO ((TaxonIdListPtr ));
+TaxonIdListPtr LIBCALL TaxonIdListNew PROTO (( void ));
+TaxonIdListPtr LIBCALL TaxonIdListAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxonIdListAsnWrite PROTO (( TaxonIdListPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* GeneticCodeList
+*
+**************************************************/
+typedef struct struct_GeneticCodeList {
+ Int4 genomic;
+ Int4 mitochondrial;
+} GeneticCodeList, PNTR GeneticCodeListPtr;
+
+
+GeneticCodeListPtr LIBCALL GeneticCodeListFree PROTO ((GeneticCodeListPtr ));
+GeneticCodeListPtr LIBCALL GeneticCodeListNew PROTO (( void ));
+GeneticCodeListPtr LIBCALL GeneticCodeListAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL GeneticCodeListAsnWrite PROTO (( GeneticCodeListPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxonId
+*
+**************************************************/
+typedef struct struct_Taxon_id {
+ Int4 id;
+} TaxonId, PNTR TaxonIdPtr;
+
+
+TaxonIdPtr LIBCALL TaxonIdFree PROTO ((TaxonIdPtr ));
+TaxonIdPtr LIBCALL TaxonIdNew PROTO (( void ));
+TaxonIdPtr LIBCALL TaxonIdAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxonIdAsnWrite PROTO (( TaxonIdPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxComplete
+*
+**************************************************/
+typedef struct struct_Tax_complete {
+ struct struct_Tax_complete PNTR next;
+ CharPtr sciname;
+ CharPtr comname;
+ CharPtr synonyms;
+ Int4 id_gc;
+ CharPtr name_gc;
+ Int4 id_mgc;
+ CharPtr name_mgc;
+ CharPtr gb_div;
+ CharPtr embl_code;
+ CharPtr lineage;
+ Uint1 is_species_level;
+} TaxComplete, PNTR TaxCompletePtr;
+
+
+TaxCompletePtr LIBCALL TaxCompleteFree PROTO ((TaxCompletePtr ));
+TaxCompletePtr LIBCALL TaxCompleteNew PROTO (( void ));
+TaxCompletePtr LIBCALL TaxCompleteAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxCompleteAsnWrite PROTO (( TaxCompletePtr , AsnIoPtr, AsnTypePtr));
+
+
+/**************************************************
+*
+* TaxCompleteList
+*
+**************************************************/
+typedef struct struct_Tax_complete_list {
+ Int4 num;
+ TaxCompletePtr info;
+} TaxCompleteList, PNTR TaxCompleteListPtr;
+
+
+TaxCompleteListPtr LIBCALL TaxCompleteListFree PROTO ((TaxCompleteListPtr ));
+TaxCompleteListPtr LIBCALL TaxCompleteListNew PROTO (( void ));
+TaxCompleteListPtr LIBCALL TaxCompleteListAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxCompleteListAsnWrite PROTO (( TaxCompleteListPtr , AsnIoPtr, AsnTypePtr));
+
diff --git a/network/taxon1/client/tax0.c b/network/taxon1/client/tax0.c
new file mode 100644
index 00000000..fdbbbb84
--- /dev/null
+++ b/network/taxon1/client/tax0.c
@@ -0,0 +1,616 @@
+/* tax0.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: tax0.c
+*
+* Author: Soussov
+*
+* Version Creation Date: 01/22/96
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* API for Taxonomy Archive service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: tax0.c,v $
+* Revision 6.0 1997/08/25 18:41:19 madden
+* Revision changed to 6.0
+*
+* Revision 5.2 1996/07/03 19:02:47 kans
+* removed inclusion of taxerr.h
+*
+ * Revision 5.1 1996/07/03 18:46:16 epstein
+ * eliminate double-quotes in favor of angle-brackets and eliminate mappings.h
+ *
+ * Revision 5.0 1996/05/28 14:15:13 ostell
+ * Set to revision 5.0
+ *
+ * Revision 1.1 1996/03/06 17:05:19 soussov
+ * Initial revision
+ *
+*/
+
+/** for ErrPostEx() ****/
+
+static char *this_module = "tax0";
+
+#ifdef THIS_MODULE
+#undef THIS_MODULE
+#endif
+
+#define THIS_MODULE this_module
+static char *this_file = __FILE__;
+#define THIS_FILE this_file
+
+#include <ncbinet.h>
+#include <objall.h>
+#include <objfeat.h>
+#include <tax0.h>
+#include <taxinc.h>
+
+static Taxon0RespPtr NetTaxArchReadAsn PROTO((void));
+static Boolean ReestablishNetTaxArch PROTO((void));
+static Boolean NetInit PROTO((void));
+static Boolean ForceNetInit PROTO((void));
+static Boolean NetFini PROTO((void));
+static Boolean GenericReestablishNet PROTO((CharPtr svcName, Boolean showErrs));
+
+static TaxonIdListPtr s_TaxArchGetTaxId PROTO((TaxonNamePtr tnp));
+static Pointer s_TaxArchAccessServer PROTO((Int4 id_tax, Int2 request, Int2 resp));
+static Pointer s_TaxArchGetFromServer PROTO((Int4 id_tax, Int2 req, Int2 resp));
+
+static NI_HandPtr svcp = NULL;
+static AsnIoPtr asnin = NULL;
+static AsnIoPtr asnout = NULL;
+Taxon0ReqPtr taxrp;
+Taxon0RespPtr taxbp;
+static Boolean num_attached = 0;
+static Boolean reallyFinal = TRUE;
+static NI_DispatcherPtr dispatcher;
+static Boolean (*myNetInit) PROTO((void));
+
+/*****************************************************************************
+*
+* Tax0Init ()
+*
+*****************************************************************************/
+
+Boolean Tax0Init (void)
+
+{
+ DataVal av;
+
+ myNetInit = Tax0Init;
+
+ if (! NetInit())
+ return FALSE;
+
+ svcp = NI_GenericGetService(dispatcher, NULL, "TAXONOMY", "Taxonomy", TRUE);
+ if (svcp == NULL)
+ {
+ ErrPostEx(SEV_ERROR, 0, 0, "NI_ServiceGet [%s] (%s)", ni_errlist[ni_errno], ni_errtext);
+ Tax0Fini();
+ return FALSE;
+ }
+
+ asnin = svcp->raip;
+ asnout = svcp->waip;
+
+ /**********************************************************/
+
+ taxrp = ValNodeNew(NULL);
+ taxrp->choice = Taxon0Req_init;
+ Taxon0ReqAsnWrite (taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon0ReqFree (taxrp);
+
+ if ((taxbp = NetTaxArchReadAsn()) == NULL)
+ {
+ return FALSE;
+ }
+ else
+ {
+ taxbp->data.ptrvalue = NULL;
+ Taxon0RespFree (taxbp);
+ return TRUE;
+ }
+}
+
+/*****************************************************************************
+*
+* Tax0Fini ()
+*
+*****************************************************************************/
+
+static Boolean s_TaxArchFini (void)
+
+{
+ Boolean retval = TRUE;
+
+ if (asnout != NULL && asnin != NULL)
+ {
+ taxrp = ValNodeNew(NULL);
+ taxrp->choice = Taxon0Req_fini;
+ Taxon0ReqAsnWrite (taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon0ReqFree (taxrp);
+
+ if ((taxbp = NetTaxArchReadAsn()) == NULL)
+ {
+ retval = FALSE;
+ }
+ else
+ {
+ taxbp->data.ptrvalue = NULL;
+ Taxon0RespFree (taxbp);
+ }
+ }
+
+ NetFini();
+
+ return retval;
+}
+
+/* the only thing done here is to suppress errors */
+
+Boolean Tax0Fini (void)
+
+{
+ short erract;
+ ErrDesc err;
+ Boolean retval;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ retval = s_TaxArchFini();
+
+ ErrSetOpts(erract, 0);
+ ErrFetch(&err);
+
+ return retval;
+}
+
+
+/*****************************************************************************
+*
+* s_TaxArchGetTaxComplete ()
+*
+*****************************************************************************/
+static
+TaxCompleteListPtr s_TaxArchGetTaxComplete( TaxonIdNamePtr tinp )
+{
+ Taxon0ReqPtr taxrp;
+ TaxCompleteListPtr tclp = NULL;
+
+ taxrp = ValNodeNew( NULL );
+ taxrp->choice = Taxon0Req_getcomplete;
+ taxrp->data.ptrvalue = (Pointer) tinp;
+ Taxon0ReqAsnWrite( taxrp, asnout, NULL );
+ AsnIoReset( asnout );
+ taxrp->data.ptrvalue = NULL;
+ Taxon0ReqFree ( taxrp );
+
+ if ( ( taxbp = NetTaxArchReadAsn() ) == NULL )
+ return NULL;
+
+ if ( taxbp->choice != Taxon0Resp_getcomplete )
+ {
+ Taxon0RespFree( taxbp );
+ return NULL;
+ }
+ tclp = (TaxCompleteListPtr) (taxbp->data.ptrvalue);
+ taxbp->data.ptrvalue = NULL;
+ Taxon0RespFree( taxbp );
+
+ return tclp;
+}
+
+
+/*****************************************************************************
+*
+* s_TaxArchGetTaxId ()
+*
+*****************************************************************************/
+static
+TaxonIdListPtr s_TaxArchGetTaxId( TaxonNamePtr tnp )
+{
+ Taxon0ReqPtr taxrp;
+ TaxonIdListPtr tilp = NULL;
+
+ taxrp = ValNodeNew( NULL );
+ taxrp->choice = Taxon0Req_getid;
+ taxrp->data.ptrvalue = (Pointer) tnp;
+ Taxon0ReqAsnWrite( taxrp, asnout, NULL );
+ AsnIoReset( asnout );
+ taxrp->data.ptrvalue = NULL;
+ Taxon0ReqFree ( taxrp );
+
+ if ( ( taxbp = NetTaxArchReadAsn() ) == NULL )
+ return NULL;
+
+ if ( taxbp->choice != Taxon0Resp_getid )
+ {
+ Taxon0RespFree( taxbp );
+ return NULL;
+ }
+ tilp = (TaxonIdListPtr) (taxbp->data.ptrvalue);
+ taxbp->data.ptrvalue = NULL;
+ Taxon0RespFree( taxbp );
+
+ return tilp;
+}
+
+
+TaxonIdListPtr Tax0GetTaxId( TaxonNamePtr tnp )
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ TaxonIdListPtr tilp = NULL;
+
+ for (i = 0; i < TAXARCH_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetTaxArch())
+ break;
+ }
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tilp = s_TaxArchGetTaxId( tnp );
+
+ ErrSetOpts(erract, 0);
+ if (! ErrFetch(&err))
+ break; /* success */
+ }
+
+ return( tilp );
+}
+
+/*****************************************************************************
+*
+* s_TaxArchAccessServer ()
+*
+*****************************************************************************/
+static
+Pointer s_TaxArchAccessServer( Int4 id_tax, Int2 request, Int2 resp )
+{
+ Taxon0ReqPtr taxrp;
+ Pointer retptr = NULL;
+
+ taxrp = ValNodeNew( NULL );
+ taxrp->choice = request;
+ taxrp->data.intvalue = id_tax;
+ Taxon0ReqAsnWrite( taxrp, asnout, NULL );
+ AsnIoReset( asnout );
+ Taxon0ReqFree ( taxrp );
+
+ if ( ( taxbp = NetTaxArchReadAsn() ) == NULL )
+ return NULL;
+
+ if ( taxbp->choice != resp )
+ {
+ Taxon0RespFree( taxbp );
+ return NULL;
+ }
+
+ retptr = taxbp->data.ptrvalue;
+ taxbp->data.ptrvalue = NULL; /* for clean free */
+ Taxon0RespFree( taxbp );
+
+ return retptr;
+}
+
+/*****************************************************************************
+*
+* s_TaxArchGetFromServer()
+*
+*****************************************************************************/
+static
+Pointer s_TaxArchGetFromServer( Int4 id_tax, Int2 req, Int2 resp )
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Pointer retptr = NULL;
+
+ for (i = 0; i < TAXARCH_SERV_RETRIES; i++)
+ {
+ if (i > 0)
+ {
+ if (! ReestablishNetTaxArch())
+ break;
+ }
+
+ ErrGetOpts( &erract, NULL );
+ ErrSetOpts( ERR_IGNORE, 0 );
+ ErrFetch( &err );
+
+ retptr = s_TaxArchAccessServer( id_tax, req, resp );
+
+ ErrSetOpts( erract, 0 );
+ if (! ErrFetch( &err ) )
+ break; /* success */
+ }
+
+ return( retptr );
+}
+
+/*****************************************************************************
+*
+* Tax0GetChildren ()
+*
+*****************************************************************************/
+
+TaxonIdListPtr Tax0GetChildren( Int4 id_tax )
+{
+ TaxonIdListPtr tilp = NULL;
+
+ tilp = (TaxonIdListPtr) s_TaxArchGetFromServer( id_tax,
+ Taxon0Req_getchildren, Taxon0Resp_gettaxon );
+ return( tilp );
+}
+
+/*****************************************************************************
+*
+* Tax0GetParents ()
+*
+*****************************************************************************/
+
+TaxonIdListPtr Tax0GetParents( Int4 id_tax )
+{
+ TaxonIdListPtr tilp = NULL;
+
+ tilp = (TaxonIdListPtr) s_TaxArchGetFromServer( id_tax,
+ Taxon0Req_getparents, Taxon0Resp_gettaxon );
+ return( tilp );
+}
+
+
+/*****************************************************************************
+*
+* Tax0GetRef ()
+*
+*****************************************************************************/
+
+OrgRefPtr Tax0GetRef( Int4 id_tax )
+{
+ OrgRefPtr orp = NULL;
+
+ orp = (OrgRefPtr) s_TaxArchGetFromServer( id_tax,
+ Taxon0Req_getref, Taxon0Resp_getref );
+ return( orp );
+}
+
+
+/*****************************************************************************
+*
+* Tax0GetComplete ()
+*
+*****************************************************************************/
+
+TaxCompleteListPtr Tax0GetComplete( TaxonIdNamePtr tinp )
+{
+ TaxCompleteListPtr tclp = NULL;
+ TaxCompletePtr tcp;
+ int i;
+
+ tclp = (TaxCompleteListPtr) s_TaxArchGetTaxComplete( tinp );
+
+ if (tclp == NULL) {
+ return NULL;
+ }
+
+ for ( i = 0, tcp = tclp->info; i < tclp->num; tcp = tcp->next, i++ ) {
+ if ( tcp->comname[0] == '\0') tcp->comname = MemFree(tcp->comname);
+ if ( tcp->synonyms[0] == '\0') tcp->synonyms = MemFree(tcp->synonyms);
+ if ( tcp->name_gc[0] == '\0') tcp->name_gc = MemFree(tcp->name_gc);
+ if ( tcp->name_mgc[0] == '\0') tcp->name_mgc = MemFree(tcp->name_mgc);
+ if ( tcp->gb_div[0] == '\0') tcp->gb_div = MemFree(tcp->gb_div);
+ if ( tcp->embl_code[0]== '\0') tcp->embl_code = MemFree(tcp->embl_code);
+ }
+ return( tclp );
+}
+
+/*****************************************************************************
+*
+* NetTaxArchReadAsn ()
+*
+*****************************************************************************/
+
+static Taxon0RespPtr NetTaxArchReadAsn(void)
+{
+ Taxon0RespPtr taxbp;
+ short erract;
+ ErrDesc err;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err); /* clear any pending error */
+
+ taxbp = Taxon0RespAsnRead(asnin, NULL);
+
+ if (ErrFetch(&err))
+ {
+ ErrPost (CTX_UNKNOWN, 1, "Null message read from server");
+ }
+ ErrSetOpts(erract, 0);
+
+ return taxbp;
+}
+
+/*****************************************************************************
+*
+* ReestablishNetTaxArch ()
+*
+*****************************************************************************/
+
+static Boolean ReestablishNetTaxArch(void)
+{
+ return GenericReestablishNet("Taxonomy", TRUE);
+}
+
+/*****************************************************************************
+*
+* GenericReestablishNet ()
+*
+*****************************************************************************/
+
+static Boolean GenericReestablishNet(CharPtr svcName, Boolean showErrs)
+{
+ MonitorPtr mon = NULL;
+ Boolean retval;
+ CharPtr buf;
+
+ buf = MemNew(2 * StrLen(svcName) + 60);
+
+ if (showErrs) {
+ sprintf (buf, "Re-establishing %s Service", svcName);
+ mon = MonitorStrNew(buf, 40);
+ sprintf (buf, "Requesting %s service", svcName);
+ MonitorStrValue(mon, buf);
+ }
+ NetFini();
+ retval = TRUE;
+
+ if (! myNetInit())
+ {
+ sprintf (buf, "%s get failed; re-contacting dispatcher", svcName);
+ MonitorStrValue(mon, buf);
+ retval = FALSE;
+ if (ForceNetInit())
+ { /* successfully established contact w/dispatcher */
+ sprintf (buf, "%s get failed; re-requesting %s service",
+ svcName, svcName);
+ MonitorStrValue(mon, buf);
+ retval = myNetInit();
+ }
+ else {
+ ErrPost(CTX_UNKNOWN, 1, "Unable to re-contact dispatcher");
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+ }
+
+ MonitorFree(mon);
+
+ if (! retval )
+ {
+ sprintf (buf, "Unable to re-establish %s service", svcName);
+ ErrPost(CTX_UNKNOWN, 1, buf);
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+
+ MemFree(buf);
+ return retval;
+}
+
+/*****************************************************************************
+*
+* NetInit ()
+*
+*****************************************************************************/
+
+static Boolean
+NetInit(void)
+{
+ if (num_attached++ > 0)
+ return TRUE;
+
+ return ((dispatcher = NI_GenericInit(NULL, NULL, TRUE, NULL, 0)) != NULL);
+}
+
+
+/*****************************************************************************
+*
+* ForceNetInit ()
+*
+*****************************************************************************/
+
+static Boolean ForceNetInit(void)
+{
+ Boolean retval;
+
+ reallyFinal = FALSE;
+ num_attached = 0; /* force re-attempt to contact dispatcher */
+ retval = NetInit();
+ reallyFinal = TRUE;
+
+ return retval;
+}
+
+/*****************************************************************************
+*
+* NetFini ()
+*
+*****************************************************************************/
+
+static Boolean NetFini(void)
+{
+ if (num_attached > 0)
+ num_attached--;
+
+ if (num_attached == 0)
+ {
+ NI_ServiceDisconnect(svcp);
+ svcp = NULL;
+ NI_EndServices (dispatcher);
+ dispatcher = NULL;
+ }
+
+ return TRUE;
+}
+
+
+OrgRefPtr TaxArchGetRef(Int4 id_tax)
+{
+ Taxon1DataPtr res;
+ OrgRefPtr orp;
+
+ res= tax1_getbyid(id_tax);
+ if(res == NULL) return NULL;
+ orp= res->org;
+ res->org= NULL;
+ Taxon1DataFree(res);
+ return orp;
+}
+
diff --git a/network/taxon1/client/tax0.h b/network/taxon1/client/tax0.h
new file mode 100644
index 00000000..f6436e6a
--- /dev/null
+++ b/network/taxon1/client/tax0.h
@@ -0,0 +1,79 @@
+/* tax0.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: tax0.h
+*
+* Author: Vladimir Soussov
+*
+* Version Creation Date: 01/22/96
+*
+* $Revision: 6.0 $
+*
+* File Description:
+* API for Taxonomy Archive service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: tax0.h,v $
+* Revision 6.0 1997/08/25 18:41:23 madden
+* Revision changed to 6.0
+*
+* Revision 5.1 1996/07/03 18:48:42 epstein
+* eliminate double-quotes in favor of angle-brackets
+*
+ * Revision 5.0 1996/05/28 14:15:13 ostell
+ * Set to revision 5.0
+ *
+ * Revision 1.1 1996/03/06 17:05:19 soussov
+ * Initial revision
+ *
+*/
+
+#include <ncbi.h>
+#include <asn.h>
+#include <objfeat.h>
+#include <objtaxc0.h>
+
+Boolean Tax0Init PROTO((void));
+Boolean Tax0Fini PROTO((void));
+
+TaxonIdListPtr Tax0GetTaxId PROTO((TaxonNamePtr tnp));
+TaxonIdListPtr Tax0GetChildren PROTO((Int4 id_tax));
+TaxonIdListPtr Tax0GetParents PROTO((Int4 id_tax));
+OrgRefPtr Tax0GetRef PROTO((Int4 id_tax));
+TaxCompleteListPtr Tax0GetComplete PROTO((TaxonIdNamePtr tinp));
+
+/* # of retries to get a server */
+#define TAXARCH_SERV_RETRIES 2
+
+#define MAXIDLIST 1 /* was 50 */
+
diff --git a/network/taxon1/common/asntax1.h b/network/taxon1/common/asntax1.h
new file mode 100644
index 00000000..b970959e
--- /dev/null
+++ b/network/taxon1/common/asntax1.h
@@ -0,0 +1,172 @@
+/***********************************************************************
+*
+**
+* Automatic header module from ASNTOOL
+*
+************************************************************************/
+
+#ifndef _ASNTOOL_
+#include <asn.h>
+#endif
+
+static char * asnfilename = "asntax1.h11";
+static AsnValxNode avnx[5] = {
+ {20,"none" ,0,0.0,&avnx[1] } ,
+ {20,"info" ,1,0.0,&avnx[2] } ,
+ {20,"warn" ,2,0.0,&avnx[3] } ,
+ {20,"error" ,3,0.0,&avnx[4] } ,
+ {20,"fatal" ,4,0.0,NULL } };
+
+static AsnType atx[70] = {
+ {401, "Org-ref" ,1,0,0,0,0,0,1,0,NULL,NULL,NULL,0,&atx[1]} ,
+ {402, "Taxon1-req" ,1,0,0,0,0,0,0,0,NULL,&atx[26],&atx[2],0,&atx[20]} ,
+ {0, "init" ,128,0,0,0,0,0,0,0,NULL,&atx[3],NULL,0,&atx[4]} ,
+ {305, "NULL" ,0,5,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "findname" ,128,1,0,0,0,0,0,0,NULL,&atx[5],NULL,0,&atx[6]} ,
+ {323, "VisibleString" ,0,26,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "getdesignator" ,128,2,0,0,0,0,0,0,NULL,&atx[5],NULL,0,&atx[7]} ,
+ {0, "getunique" ,128,3,0,0,0,0,0,0,NULL,&atx[5],NULL,0,&atx[8]} ,
+ {0, "getidbyorg" ,128,4,0,0,0,0,0,0,NULL,&atx[0],NULL,0,&atx[9]} ,
+ {0, "getorgnames" ,128,5,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[11]} ,
+ {302, "INTEGER" ,0,2,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "getcde" ,128,6,0,0,0,0,0,0,NULL,&atx[3],NULL,0,&atx[12]} ,
+ {0, "getranks" ,128,7,0,0,0,0,0,0,NULL,&atx[3],NULL,0,&atx[13]} ,
+ {0, "getdivs" ,128,8,0,0,0,0,0,0,NULL,&atx[3],NULL,0,&atx[14]} ,
+ {0, "getgcs" ,128,9,0,0,0,0,0,0,NULL,&atx[3],NULL,0,&atx[15]} ,
+ {0, "getlineage" ,128,10,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[16]} ,
+ {0, "getchildren" ,128,11,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[17]} ,
+ {0, "getbyid" ,128,12,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[18]} ,
+ {0, "lookup" ,128,13,0,0,0,0,0,0,NULL,&atx[0],NULL,0,&atx[19]} ,
+ {0, "getorgmod" ,128,14,0,0,0,0,0,0,NULL,&atx[20],NULL,0,&atx[25]} ,
+ {403, "Taxon1-info" ,1,0,0,0,0,0,0,0,NULL,&atx[24],&atx[21],0,&atx[27]} ,
+ {0, "ival1" ,128,0,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[22]} ,
+ {0, "ival2" ,128,1,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[23]} ,
+ {0, "sval" ,128,2,0,1,0,0,0,0,NULL,&atx[5],NULL,0,NULL} ,
+ {311, "SEQUENCE" ,0,16,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "fini" ,128,15,0,0,0,0,0,0,NULL,&atx[3],NULL,0,NULL} ,
+ {315, "CHOICE" ,0,-1,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {404, "Taxon1-resp" ,1,0,0,0,0,0,0,0,NULL,&atx[26],&atx[28],0,&atx[29]} ,
+ {0, "error" ,128,0,0,0,0,0,0,0,NULL,&atx[29],NULL,0,&atx[33]} ,
+ {405, "Taxon1-error" ,1,0,0,0,0,0,0,0,NULL,&atx[24],&atx[30],0,&atx[36]} ,
+ {0, "level" ,128,0,0,0,0,0,0,0,NULL,&atx[31],&avnx[0],0,&atx[32]} ,
+ {310, "ENUMERATED" ,0,10,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "msg" ,128,1,0,1,0,0,0,0,NULL,&atx[5],NULL,0,NULL} ,
+ {0, "init" ,128,1,0,0,0,0,0,0,NULL,&atx[3],NULL,0,&atx[34]} ,
+ {0, "findname" ,128,2,0,0,0,0,0,0,NULL,&atx[41],&atx[35],0,&atx[42]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[36],NULL,0,NULL} ,
+ {406, "Taxon1-name" ,1,0,0,0,0,0,0,0,NULL,&atx[24],&atx[37],0,&atx[60]} ,
+ {0, "taxid" ,128,0,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[38]} ,
+ {0, "cde" ,128,1,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[39]} ,
+ {0, "oname" ,128,2,0,1,0,0,0,0,NULL,&atx[5],NULL,0,&atx[40]} ,
+ {0, "uname" ,128,3,0,1,0,0,0,0,NULL,&atx[5],NULL,0,NULL} ,
+ {314, "SET OF" ,0,17,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "getdesignator" ,128,3,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[43]} ,
+ {0, "getunique" ,128,4,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[44]} ,
+ {0, "getidbyorg" ,128,5,0,0,0,0,0,0,NULL,&atx[10],NULL,0,&atx[45]} ,
+ {0, "getorgnames" ,128,6,0,0,0,0,0,0,NULL,&atx[41],&atx[46],0,&atx[47]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[36],NULL,0,NULL} ,
+ {0, "getcde" ,128,7,0,0,0,0,0,0,NULL,&atx[41],&atx[48],0,&atx[49]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[20],NULL,0,NULL} ,
+ {0, "getranks" ,128,8,0,0,0,0,0,0,NULL,&atx[41],&atx[50],0,&atx[51]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[20],NULL,0,NULL} ,
+ {0, "getdivs" ,128,9,0,0,0,0,0,0,NULL,&atx[41],&atx[52],0,&atx[53]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[20],NULL,0,NULL} ,
+ {0, "getgcs" ,128,10,0,0,0,0,0,0,NULL,&atx[41],&atx[54],0,&atx[55]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[20],NULL,0,NULL} ,
+ {0, "getlineage" ,128,11,0,0,0,0,0,0,NULL,&atx[41],&atx[56],0,&atx[57]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[20],NULL,0,NULL} ,
+ {0, "getchildren" ,128,12,0,0,0,0,0,0,NULL,&atx[41],&atx[58],0,&atx[59]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[20],NULL,0,NULL} ,
+ {0, "getbyid" ,128,13,0,0,0,0,0,0,NULL,&atx[60],NULL,0,&atx[66]} ,
+ {407, "Taxon1-data" ,1,0,0,0,0,0,0,0,NULL,&atx[24],&atx[61],0,NULL} ,
+ {0, "org" ,128,0,0,1,0,0,0,0,NULL,&atx[0],NULL,0,&atx[62]} ,
+ {0, "div" ,128,1,0,0,0,0,0,0,NULL,&atx[5],NULL,0,&atx[63]} ,
+ {0, "embl-code" ,128,2,0,0,0,0,0,0,NULL,&atx[5],NULL,0,&atx[64]} ,
+ {0, "is-species-level" ,128,3,0,0,0,0,0,0,NULL,&atx[65],NULL,0,NULL} ,
+ {301, "BOOLEAN" ,0,1,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
+ {0, "lookup" ,128,14,0,0,0,0,0,0,NULL,&atx[60],NULL,0,&atx[67]} ,
+ {0, "getorgmod" ,128,15,0,0,0,0,0,0,NULL,&atx[41],&atx[68],0,&atx[69]} ,
+ {0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[20],NULL,0,NULL} ,
+ {0, "fini" ,128,16,0,0,0,0,0,0,NULL,&atx[3],NULL,0,NULL} };
+
+static AsnModule ampx[1] = {
+ { "NCBI-Taxon1" , "asntax1.h11",&atx[0],NULL,NULL,0,0} };
+
+static AsnValxNodePtr avn = avnx;
+static AsnTypePtr at = atx;
+static AsnModulePtr amp = ampx;
+
+
+
+/**************************************************
+*
+* Defines for Module NCBI-Taxon1
+*
+**************************************************/
+
+#define TAXON1_REQ &at[1]
+#define TAXON1_REQ_init &at[2]
+#define TAXON1_REQ_findname &at[4]
+#define TAXON1_REQ_getdesignator &at[6]
+#define TAXON1_REQ_getunique &at[7]
+#define TAXON1_REQ_getidbyorg &at[8]
+#define TAXON1_REQ_getorgnames &at[9]
+#define TAXON1_REQ_getcde &at[11]
+#define TAXON1_REQ_getranks &at[12]
+#define TAXON1_REQ_getdivs &at[13]
+#define TAXON1_REQ_getgcs &at[14]
+#define TAXON1_REQ_getlineage &at[15]
+#define TAXON1_REQ_getchildren &at[16]
+#define TAXON1_REQ_getbyid &at[17]
+#define TAXON1_REQ_lookup &at[18]
+#define TAXON1_REQ_getorgmod &at[19]
+#define TAXON1_REQ_fini &at[25]
+
+#define TAXON1_INFO &at[20]
+#define TAXON1_INFO_ival1 &at[21]
+#define TAXON1_INFO_ival2 &at[22]
+#define TAXON1_INFO_sval &at[23]
+
+#define TAXON1_RESP &at[27]
+#define TAXON1_RESP_error &at[28]
+#define TAXON1_RESP_init &at[33]
+#define TAXON1_RESP_findname &at[34]
+#define TAXON1_RESP_findname_E &at[35]
+#define TAXON1_RESP_getdesignator &at[42]
+#define TAXON1_RESP_getunique &at[43]
+#define TAXON1_RESP_getidbyorg &at[44]
+#define TAXON1_RESP_getorgnames &at[45]
+#define TAXON1_RESP_getorgnames_E &at[46]
+#define TAXON1_RESP_getcde &at[47]
+#define TAXON1_RESP_getcde_E &at[48]
+#define TAXON1_RESP_getranks &at[49]
+#define TAXON1_RESP_getranks_E &at[50]
+#define TAXON1_RESP_getdivs &at[51]
+#define TAXON1_RESP_getdivs_E &at[52]
+#define TAXON1_RESP_getgcs &at[53]
+#define TAXON1_RESP_getgcs_E &at[54]
+#define TAXON1_RESP_getlineage &at[55]
+#define TAXON1_RESP_getlineage_E &at[56]
+#define TAXON1_RESP_getchildren &at[57]
+#define TAXON1_RESP_getchildren_E &at[58]
+#define TAXON1_RESP_getbyid &at[59]
+#define TAXON1_RESP_lookup &at[66]
+#define TAXON1_RESP_getorgmod &at[67]
+#define TAXON1_RESP_getorgmod_E &at[68]
+#define TAXON1_RESP_fini &at[69]
+
+#define TAXON1_ERROR &at[29]
+#define TAXON1_ERROR_level &at[30]
+#define TAXON1_ERROR_msg &at[32]
+
+#define TAXON1_NAME &at[36]
+#define TAXON1_NAME_taxid &at[37]
+#define TAXON1_NAME_cde &at[38]
+#define TAXON1_NAME_oname &at[39]
+#define TAXON1_NAME_uname &at[40]
+
+#define TAXON1_DATA &at[60]
+#define TAXON1_DATA_org &at[61]
+#define TAXON1_DATA_div &at[62]
+#define TAXON1_DATA_embl_code &at[63]
+#define TAXON1_DATA_is_species_level &at[64]
diff --git a/network/taxon1/common/checkid.c b/network/taxon1/common/checkid.c
new file mode 100644
index 00000000..7efcc4b3
--- /dev/null
+++ b/network/taxon1/common/checkid.c
@@ -0,0 +1,157 @@
+/* checkid.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: checkid.c
+*
+* Author: Vladimir Soussov
+*
+* File Description: check OrgRef integrity function
+*
+*
+* $Log: checkid.c,v $
+* Revision 6.0 1997/08/25 18:41:26 madden
+* Revision changed to 6.0
+*
+* Revision 1.1 1997/04/29 16:03:02 soussov
+* Initial revision
+*
+*
+*/
+
+#include <ncbi.h>
+#include <taxinc.h>
+
+static Int4 get_tax_id(ValNodePtr dbnode)
+{
+ DbtagPtr dbtag;
+ ObjectIdPtr object_id;
+
+ while(dbnode != NULL) {
+ dbtag= dbnode->data.ptrvalue;
+ if(StringICmp(dbtag->db, "taxon") == 0) {
+ object_id= dbtag->tag;
+ return object_id->id;
+ }
+ dbnode= dbnode->next;
+ }
+ return 0;
+}
+
+Uint2 CheckTaxId(OrgRefPtr orp, CharPtr ** msg_out)
+{
+ Int4 tax_id;
+ Taxon1DataPtr tdp;
+ CharPtr* msg_arr= NULL;
+ CharPtr msg;
+ Uint2 n= 0;
+
+ if(orp == NULL) {
+ msg= StringSave("WARNING\t empty OrgRef");
+ msg_arr= MemNew(sizeof(CharPtr));
+ *msg_arr= msg;
+ *msg_out= msg_arr;
+ return 1;
+ }
+
+ tax_id= get_tax_id(orp->db);
+
+ if(tax_id > 0) {
+ /* check this tax_id */
+ tdp= tax1_getbyid(tax_id);
+ if(tdp == NULL) {
+ /* taxonomy id was killed */
+ msg= MemNew(80);
+ sprintf(msg,
+ "ERROR\t taxid %d is killed in taxonomy database but exists in entry",
+ tax_id);
+ msg_arr= MemNew(sizeof(CharPtr));
+ *msg_arr= msg;
+ *msg_out= msg_arr;
+ return 1;
+ }
+
+ /* check that tax_id still correct */
+ if(orp->taxname == NULL) {
+ msg= StringSave("WARNING\t empty taxname in OrgRef");
+ msg_arr= MemNew(sizeof(CharPtr));
+ *msg_arr= msg;
+ *msg_out= msg_arr;
+ return 1;
+ }
+
+ if(StringICmp(orp->taxname, tdp->org->taxname) != 0) {
+ msg= MemNew(256);
+ sprintf(msg,
+ "WARNING: taxname in OrgRef <%s> is differ from the name in taxonomy <%s> tax_id=%d",
+ orp->taxname, tdp->org->taxname, tax_id);
+ msg_arr= MemNew(sizeof(CharPtr));
+ *msg_arr= msg;
+ *msg_out= msg_arr;
+ return 1;
+ }
+ return 0;
+ }
+
+ /* we have no tax_id */
+ msg= StringSave("WARNING\t no taxid in OrgRef");
+ *msg_out= msg_arr= MemNew(3*sizeof(CharPtr));
+ msg_arr[0]= msg;
+ n= 1;
+ tdp= tax1_lookup(orp, 0);
+ if(tdp == NULL) {
+ /* no such organism */
+ msg= MemNew(256);
+ sprintf(msg,"WARNING\t organism not found [scientific name <%s> common name <%s>]",
+ (orp->taxname == NULL)? "" : orp->taxname,
+ (orp->common == NULL)? "" : orp->common);
+ msg_arr[1]= msg;
+ return 2;
+ }
+
+ tax_id= get_tax_id(tdp->org->db);
+ msg= MemNew(80);
+ sprintf(msg, "INFO\t OrgRef should be mapped to <%s> tax_id=%d",
+ tdp->org->taxname, tax_id);
+ msg_arr[1]= msg;
+ n= 2;
+
+ if(orp->taxname == NULL) {
+ msg= MemNew(256);
+ sprintf(msg,"WARNING\t taxname <%s> does not exist in original OrgRef",
+ tdp->org->taxname);
+ msg_arr[2]= msg;
+ n= 3;
+ }
+ else if(StringICmp(orp->taxname, tdp->org->taxname) != 0) {
+ msg= MemNew(256);
+ sprintf(msg,
+ "WARNING: taxname in OrgRef <%s> is differ from the name in taxonomy <%s> tax_id=%d",
+ orp->taxname, tdp->org->taxname, tax_id);
+ msg_arr[2]= msg;
+ n= 3;
+ }
+
+ return n;
+}
diff --git a/network/taxon1/common/objtax1.c b/network/taxon1/common/objtax1.c
new file mode 100644
index 00000000..5de8b2c4
--- /dev/null
+++ b/network/taxon1/common/objtax1.c
@@ -0,0 +1,1451 @@
+#include <asn.h>
+
+#define NLM_GENERATED_CODE_PROTO
+
+#include <tax1map.h>
+#include <objtax1.h>
+
+static Boolean loaded = FALSE;
+
+#include <asntax1.h>
+
+#ifndef NLM_EXTERN_LOADS
+#define NLM_EXTERN_LOADS {}
+#endif
+
+NLM_EXTERN Boolean LIBCALL
+objtax1AsnLoad(void)
+{
+
+ if ( ! loaded) {
+ NLM_EXTERN_LOADS
+
+ if ( ! AsnLoad ())
+ return FALSE;
+ loaded = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/**************************************************
+* Generated object loaders for Module NCBI-Taxon1
+* Generated using ASNCODE Revision: 6.0 at Feb 2, 1998 4:16 PM
+*
+**************************************************/
+
+
+/**************************************************
+*
+* Taxon1ReqFree()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1ReqPtr LIBCALL
+Taxon1ReqFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case Taxon1Req_findname:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case Taxon1Req_getdesignator:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case Taxon1Req_getunique:
+ MemFree(anp -> data.ptrvalue);
+ break;
+ case Taxon1Req_getidbyorg:
+ OrgRefFree(anp -> data.ptrvalue);
+ break;
+ case Taxon1Req_lookup:
+ OrgRefFree(anp -> data.ptrvalue);
+ break;
+ case Taxon1Req_getorgmod:
+ Taxon1InfoFree(anp -> data.ptrvalue);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* Taxon1ReqAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1ReqPtr LIBCALL
+Taxon1ReqAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Taxon1Req ::= (self contained) */
+ atp = AsnReadId(aip, amp, TAXON1_REQ);
+ } else {
+ atp = AsnLinkType(orig, TAXON1_REQ); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == TAXON1_REQ_init) {
+ choice = Taxon1Req_init;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == TAXON1_REQ_findname) {
+ choice = Taxon1Req_findname;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == TAXON1_REQ_getdesignator) {
+ choice = Taxon1Req_getdesignator;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == TAXON1_REQ_getunique) {
+ choice = Taxon1Req_getunique;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.ptrvalue = av.ptrvalue;
+ }
+ else if (atp == TAXON1_REQ_getidbyorg) {
+ choice = Taxon1Req_getidbyorg;
+ func = (AsnReadFunc) OrgRefAsnRead;
+ }
+ else if (atp == TAXON1_REQ_getorgnames) {
+ choice = Taxon1Req_getorgnames;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == TAXON1_REQ_getcde) {
+ choice = Taxon1Req_getcde;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == TAXON1_REQ_getranks) {
+ choice = Taxon1Req_getranks;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == TAXON1_REQ_getdivs) {
+ choice = Taxon1Req_getdivs;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == TAXON1_REQ_getgcs) {
+ choice = Taxon1Req_getgcs;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == TAXON1_REQ_getlineage) {
+ choice = Taxon1Req_getlineage;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == TAXON1_REQ_getchildren) {
+ choice = Taxon1Req_getchildren;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == TAXON1_REQ_getbyid) {
+ choice = Taxon1Req_getbyid;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == TAXON1_REQ_lookup) {
+ choice = Taxon1Req_lookup;
+ func = (AsnReadFunc) OrgRefAsnRead;
+ }
+ else if (atp == TAXON1_REQ_getorgmod) {
+ choice = Taxon1Req_getorgmod;
+ func = (AsnReadFunc) Taxon1InfoAsnRead;
+ }
+ else if (atp == TAXON1_REQ_fini) {
+ choice = Taxon1Req_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Taxon1ReqAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+Taxon1ReqAsnWrite(Taxon1ReqPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, TAXON1_REQ); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case Taxon1Req_init:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_init, &av);
+ break;
+ case Taxon1Req_findname:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_findname, &av);
+ break;
+ case Taxon1Req_getdesignator:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getdesignator, &av);
+ break;
+ case Taxon1Req_getunique:
+ av.ptrvalue = anp->data.ptrvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getunique, &av);
+ break;
+ case Taxon1Req_getidbyorg:
+ writetype = TAXON1_REQ_getidbyorg;
+ func = (AsnWriteFunc) OrgRefAsnWrite;
+ break;
+ case Taxon1Req_getorgnames:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getorgnames, &av);
+ break;
+ case Taxon1Req_getcde:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getcde, &av);
+ break;
+ case Taxon1Req_getranks:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getranks, &av);
+ break;
+ case Taxon1Req_getdivs:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getdivs, &av);
+ break;
+ case Taxon1Req_getgcs:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getgcs, &av);
+ break;
+ case Taxon1Req_getlineage:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getlineage, &av);
+ break;
+ case Taxon1Req_getchildren:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getchildren, &av);
+ break;
+ case Taxon1Req_getbyid:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_getbyid, &av);
+ break;
+ case Taxon1Req_lookup:
+ writetype = TAXON1_REQ_lookup;
+ func = (AsnWriteFunc) OrgRefAsnWrite;
+ break;
+ case Taxon1Req_getorgmod:
+ writetype = TAXON1_REQ_getorgmod;
+ func = (AsnWriteFunc) Taxon1InfoAsnWrite;
+ break;
+ case Taxon1Req_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, TAXON1_REQ_fini, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* Taxon1InfoNew()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1InfoPtr LIBCALL
+Taxon1InfoNew(void)
+{
+ Taxon1InfoPtr ptr = MemNew((size_t) sizeof(Taxon1Info));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* Taxon1InfoFree()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1InfoPtr LIBCALL
+Taxon1InfoFree(Taxon1InfoPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> sval);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* Taxon1InfoAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1InfoPtr LIBCALL
+Taxon1InfoAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ Taxon1InfoPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Taxon1Info ::= (self contained) */
+ atp = AsnReadId(aip, amp, TAXON1_INFO);
+ } else {
+ atp = AsnLinkType(orig, TAXON1_INFO);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = Taxon1InfoNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == TAXON1_INFO_ival1) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> ival1 = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAXON1_INFO_ival2) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> ival2 = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAXON1_INFO_sval) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> sval = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = Taxon1InfoFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* Taxon1InfoAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+Taxon1InfoAsnWrite(Taxon1InfoPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, TAXON1_INFO); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> ival1;
+ retval = AsnWrite(aip, TAXON1_INFO_ival1, &av);
+ av.intvalue = ptr -> ival2;
+ retval = AsnWrite(aip, TAXON1_INFO_ival2, &av);
+ if (ptr -> sval != NULL) {
+ av.ptrvalue = ptr -> sval;
+ retval = AsnWrite(aip, TAXON1_INFO_sval, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* Taxon1RespFree()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1RespPtr LIBCALL
+Taxon1RespFree(ValNodePtr anp)
+{
+ Pointer pnt;
+
+ if (anp == NULL) {
+ return NULL;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ default:
+ break;
+ case Taxon1Resp_error:
+ Taxon1ErrorFree(anp -> data.ptrvalue);
+ break;
+ case Taxon1Resp_findname:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) Taxon1NameFree);
+ break;
+ case Taxon1Resp_getorgnames:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) Taxon1NameFree);
+ break;
+ case Taxon1Resp_getcde:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) Taxon1InfoFree);
+ break;
+ case Taxon1Resp_getranks:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) Taxon1InfoFree);
+ break;
+ case Taxon1Resp_getdivs:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) Taxon1InfoFree);
+ break;
+ case Taxon1Resp_getgcs:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) Taxon1InfoFree);
+ break;
+ case Taxon1Resp_getlineage:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) Taxon1InfoFree);
+ break;
+ case Taxon1Resp_getchildren:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) Taxon1InfoFree);
+ break;
+ case Taxon1Resp_getbyid:
+ Taxon1DataFree(anp -> data.ptrvalue);
+ break;
+ case Taxon1Resp_lookup:
+ Taxon1DataFree(anp -> data.ptrvalue);
+ break;
+ case Taxon1Resp_getorgmod:
+ AsnGenericUserSeqOfFree((Pointer) pnt, (AsnOptFreeFunc) Taxon1InfoFree);
+ break;
+ }
+ return MemFree(anp);
+}
+
+
+/**************************************************
+*
+* Taxon1RespAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1RespPtr LIBCALL
+Taxon1RespAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr anp;
+ Uint1 choice;
+ Boolean isError = FALSE;
+ Boolean nullIsError = FALSE;
+ AsnReadFunc func;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Taxon1Resp ::= (self contained) */
+ atp = AsnReadId(aip, amp, TAXON1_RESP);
+ } else {
+ atp = AsnLinkType(orig, TAXON1_RESP); /* link in local tree */
+ }
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ anp = ValNodeNew(NULL);
+ if (anp == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */
+ goto erret;
+ }
+
+ func = NULL;
+
+ atp = AsnReadId(aip, amp, atp); /* find the choice */
+ if (atp == NULL) {
+ goto erret;
+ }
+ if (atp == TAXON1_RESP_error) {
+ choice = Taxon1Resp_error;
+ func = (AsnReadFunc) Taxon1ErrorAsnRead;
+ }
+ else if (atp == TAXON1_RESP_init) {
+ choice = Taxon1Resp_init;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ else if (atp == TAXON1_RESP_findname) {
+ choice = Taxon1Resp_findname;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) Taxon1NameAsnRead, (AsnOptFreeFunc) Taxon1NameFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == TAXON1_RESP_getdesignator) {
+ choice = Taxon1Resp_getdesignator;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == TAXON1_RESP_getunique) {
+ choice = Taxon1Resp_getunique;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == TAXON1_RESP_getidbyorg) {
+ choice = Taxon1Resp_getidbyorg;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.intvalue = av.intvalue;
+ }
+ else if (atp == TAXON1_RESP_getorgnames) {
+ choice = Taxon1Resp_getorgnames;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) Taxon1NameAsnRead, (AsnOptFreeFunc) Taxon1NameFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == TAXON1_RESP_getcde) {
+ choice = Taxon1Resp_getcde;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) Taxon1InfoAsnRead, (AsnOptFreeFunc) Taxon1InfoFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == TAXON1_RESP_getranks) {
+ choice = Taxon1Resp_getranks;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) Taxon1InfoAsnRead, (AsnOptFreeFunc) Taxon1InfoFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == TAXON1_RESP_getdivs) {
+ choice = Taxon1Resp_getdivs;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) Taxon1InfoAsnRead, (AsnOptFreeFunc) Taxon1InfoFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == TAXON1_RESP_getgcs) {
+ choice = Taxon1Resp_getgcs;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) Taxon1InfoAsnRead, (AsnOptFreeFunc) Taxon1InfoFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == TAXON1_RESP_getlineage) {
+ choice = Taxon1Resp_getlineage;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) Taxon1InfoAsnRead, (AsnOptFreeFunc) Taxon1InfoFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == TAXON1_RESP_getchildren) {
+ choice = Taxon1Resp_getchildren;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) Taxon1InfoAsnRead, (AsnOptFreeFunc) Taxon1InfoFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == TAXON1_RESP_getbyid) {
+ choice = Taxon1Resp_getbyid;
+ func = (AsnReadFunc) Taxon1DataAsnRead;
+ }
+ else if (atp == TAXON1_RESP_lookup) {
+ choice = Taxon1Resp_lookup;
+ func = (AsnReadFunc) Taxon1DataAsnRead;
+ }
+ else if (atp == TAXON1_RESP_getorgmod) {
+ choice = Taxon1Resp_getorgmod;
+ anp -> data.ptrvalue =
+ AsnGenericUserSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) Taxon1InfoAsnRead, (AsnOptFreeFunc) Taxon1InfoFree);
+ if (isError && anp -> data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+ else if (atp == TAXON1_RESP_fini) {
+ choice = Taxon1Resp_fini;
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ anp->data.boolvalue = av.boolvalue;
+ }
+ anp->choice = choice;
+ if (func != NULL)
+ {
+ anp->data.ptrvalue = (* func)(aip, atp);
+ if (aip -> io_failure) goto erret;
+
+ if (nullIsError && anp->data.ptrvalue == NULL) {
+ goto erret;
+ }
+ }
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return anp;
+
+erret:
+ anp = MemFree(anp);
+ aip -> io_failure = TRUE;
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Taxon1RespAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+Taxon1RespAsnWrite(Taxon1RespPtr anp, AsnIoPtr aip, AsnTypePtr orig)
+
+{
+ DataVal av;
+ AsnTypePtr atp, writetype = NULL;
+ Pointer pnt;
+ AsnWriteFunc func = NULL;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad())
+ return FALSE;
+ }
+
+ if (aip == NULL)
+ return FALSE;
+
+ atp = AsnLinkType(orig, TAXON1_RESP); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+
+ av.ptrvalue = (Pointer)anp;
+ if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {
+ goto erret;
+ }
+
+ pnt = anp->data.ptrvalue;
+ switch (anp->choice)
+ {
+ case Taxon1Resp_error:
+ writetype = TAXON1_RESP_error;
+ func = (AsnWriteFunc) Taxon1ErrorAsnWrite;
+ break;
+ case Taxon1Resp_init:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, TAXON1_RESP_init, &av);
+ break;
+ case Taxon1Resp_findname:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) Taxon1NameAsnWrite, aip, TAXON1_RESP_findname, TAXON1_RESP_findname_E);
+ break;
+ case Taxon1Resp_getdesignator:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, TAXON1_RESP_getdesignator, &av);
+ break;
+ case Taxon1Resp_getunique:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, TAXON1_RESP_getunique, &av);
+ break;
+ case Taxon1Resp_getidbyorg:
+ av.intvalue = anp->data.intvalue;
+ retval = AsnWrite(aip, TAXON1_RESP_getidbyorg, &av);
+ break;
+ case Taxon1Resp_getorgnames:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) Taxon1NameAsnWrite, aip, TAXON1_RESP_getorgnames, TAXON1_RESP_getorgnames_E);
+ break;
+ case Taxon1Resp_getcde:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) Taxon1InfoAsnWrite, aip, TAXON1_RESP_getcde, TAXON1_RESP_getcde_E);
+ break;
+ case Taxon1Resp_getranks:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) Taxon1InfoAsnWrite, aip, TAXON1_RESP_getranks, TAXON1_RESP_getranks_E);
+ break;
+ case Taxon1Resp_getdivs:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) Taxon1InfoAsnWrite, aip, TAXON1_RESP_getdivs, TAXON1_RESP_getdivs_E);
+ break;
+ case Taxon1Resp_getgcs:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) Taxon1InfoAsnWrite, aip, TAXON1_RESP_getgcs, TAXON1_RESP_getgcs_E);
+ break;
+ case Taxon1Resp_getlineage:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) Taxon1InfoAsnWrite, aip, TAXON1_RESP_getlineage, TAXON1_RESP_getlineage_E);
+ break;
+ case Taxon1Resp_getchildren:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) Taxon1InfoAsnWrite, aip, TAXON1_RESP_getchildren, TAXON1_RESP_getchildren_E);
+ break;
+ case Taxon1Resp_getbyid:
+ writetype = TAXON1_RESP_getbyid;
+ func = (AsnWriteFunc) Taxon1DataAsnWrite;
+ break;
+ case Taxon1Resp_lookup:
+ writetype = TAXON1_RESP_lookup;
+ func = (AsnWriteFunc) Taxon1DataAsnWrite;
+ break;
+ case Taxon1Resp_getorgmod:
+ retval = AsnGenericUserSeqOfAsnWrite((Pointer) pnt, (AsnWriteFunc) Taxon1InfoAsnWrite, aip, TAXON1_RESP_getorgmod, TAXON1_RESP_getorgmod_E);
+ break;
+ case Taxon1Resp_fini:
+ av.boolvalue = anp->data.boolvalue;
+ retval = AsnWrite(aip, TAXON1_RESP_fini, &av);
+ break;
+ }
+ if (writetype != NULL) {
+ retval = (* func)(pnt, aip, writetype); /* write it out */
+ }
+ if (!retval) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+/**************************************************
+*
+* Taxon1ErrorNew()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1ErrorPtr LIBCALL
+Taxon1ErrorNew(void)
+{
+ Taxon1ErrorPtr ptr = MemNew((size_t) sizeof(Taxon1Error));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* Taxon1ErrorFree()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1ErrorPtr LIBCALL
+Taxon1ErrorFree(Taxon1ErrorPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> msg);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* Taxon1ErrorAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1ErrorPtr LIBCALL
+Taxon1ErrorAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ Taxon1ErrorPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Taxon1Error ::= (self contained) */
+ atp = AsnReadId(aip, amp, TAXON1_ERROR);
+ } else {
+ atp = AsnLinkType(orig, TAXON1_ERROR);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = Taxon1ErrorNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == TAXON1_ERROR_level) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> level = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAXON1_ERROR_msg) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> msg = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = Taxon1ErrorFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* Taxon1ErrorAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+Taxon1ErrorAsnWrite(Taxon1ErrorPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, TAXON1_ERROR); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> level;
+ retval = AsnWrite(aip, TAXON1_ERROR_level, &av);
+ if (ptr -> msg != NULL) {
+ av.ptrvalue = ptr -> msg;
+ retval = AsnWrite(aip, TAXON1_ERROR_msg, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* Taxon1NameNew()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1NamePtr LIBCALL
+Taxon1NameNew(void)
+{
+ Taxon1NamePtr ptr = MemNew((size_t) sizeof(Taxon1Name));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* Taxon1NameFree()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1NamePtr LIBCALL
+Taxon1NameFree(Taxon1NamePtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ MemFree(ptr -> oname);
+ MemFree(ptr -> uname);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* Taxon1NameAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1NamePtr LIBCALL
+Taxon1NameAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ Taxon1NamePtr ptr;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Taxon1Name ::= (self contained) */
+ atp = AsnReadId(aip, amp, TAXON1_NAME);
+ } else {
+ atp = AsnLinkType(orig, TAXON1_NAME);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = Taxon1NameNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == TAXON1_NAME_taxid) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> taxid = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAXON1_NAME_cde) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> cde = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAXON1_NAME_oname) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> oname = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAXON1_NAME_uname) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> uname = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = Taxon1NameFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* Taxon1NameAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+Taxon1NameAsnWrite(Taxon1NamePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, TAXON1_NAME); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ av.intvalue = ptr -> taxid;
+ retval = AsnWrite(aip, TAXON1_NAME_taxid, &av);
+ av.intvalue = ptr -> cde;
+ retval = AsnWrite(aip, TAXON1_NAME_cde, &av);
+ if (ptr -> oname != NULL) {
+ av.ptrvalue = ptr -> oname;
+ retval = AsnWrite(aip, TAXON1_NAME_oname, &av);
+ }
+ if (ptr -> uname != NULL) {
+ av.ptrvalue = ptr -> uname;
+ retval = AsnWrite(aip, TAXON1_NAME_uname, &av);
+ }
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
+
+
+/**************************************************
+*
+* Taxon1DataNew()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1DataPtr LIBCALL
+Taxon1DataNew(void)
+{
+ Taxon1DataPtr ptr = MemNew((size_t) sizeof(Taxon1Data));
+
+ return ptr;
+
+}
+
+
+/**************************************************
+*
+* Taxon1DataFree()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1DataPtr LIBCALL
+Taxon1DataFree(Taxon1DataPtr ptr)
+{
+
+ if(ptr == NULL) {
+ return NULL;
+ }
+ OrgRefFree(ptr -> org);
+ MemFree(ptr -> div);
+ MemFree(ptr -> embl_code);
+ return MemFree(ptr);
+}
+
+
+/**************************************************
+*
+* Taxon1DataAsnRead()
+*
+**************************************************/
+NLM_EXTERN
+Taxon1DataPtr LIBCALL
+Taxon1DataAsnRead(AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean isError = FALSE;
+ AsnReadFunc func;
+ Taxon1DataPtr ptr;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return NULL;
+ }
+ }
+
+ if (aip == NULL) {
+ return NULL;
+ }
+
+ if (orig == NULL) { /* Taxon1Data ::= (self contained) */
+ atp = AsnReadId(aip, amp, TAXON1_DATA);
+ } else {
+ atp = AsnLinkType(orig, TAXON1_DATA);
+ }
+ /* link in local tree */
+ if (atp == NULL) {
+ return NULL;
+ }
+
+ ptr = Taxon1DataNew();
+ if (ptr == NULL) {
+ goto erret;
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */
+ goto erret;
+ }
+
+ atp = AsnReadId(aip,amp, atp);
+ func = NULL;
+
+ if (atp == TAXON1_DATA_org) {
+ ptr -> org = OrgRefAsnRead(aip, atp);
+ if (aip -> io_failure) {
+ goto erret;
+ }
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAXON1_DATA_div) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> div = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAXON1_DATA_embl_code) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> embl_code = av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAXON1_DATA_is_species_level) {
+ if ( AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ ptr -> is_species_level = av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+
+ if (AsnReadVal(aip, atp, &av) <= 0) {
+ goto erret;
+ }
+ /* end struct */
+
+ret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return ptr;
+
+erret:
+ aip -> io_failure = TRUE;
+ ptr = Taxon1DataFree(ptr);
+ goto ret;
+}
+
+
+
+/**************************************************
+*
+* Taxon1DataAsnWrite()
+*
+**************************************************/
+NLM_EXTERN Boolean LIBCALL
+Taxon1DataAsnWrite(Taxon1DataPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ Boolean retval = FALSE;
+
+ if (! loaded)
+ {
+ if (! objtax1AsnLoad()) {
+ return FALSE;
+ }
+ }
+
+ if (aip == NULL) {
+ return FALSE;
+ }
+
+ atp = AsnLinkType(orig, TAXON1_DATA); /* link local tree */
+ if (atp == NULL) {
+ return FALSE;
+ }
+
+ if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
+ if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {
+ goto erret;
+ }
+
+ if (ptr -> org != NULL) {
+ if ( ! OrgRefAsnWrite(ptr -> org, aip, TAXON1_DATA_org)) {
+ goto erret;
+ }
+ }
+ if (ptr -> div != NULL) {
+ av.ptrvalue = ptr -> div;
+ retval = AsnWrite(aip, TAXON1_DATA_div, &av);
+ }
+ if (ptr -> embl_code != NULL) {
+ av.ptrvalue = ptr -> embl_code;
+ retval = AsnWrite(aip, TAXON1_DATA_embl_code, &av);
+ }
+ av.boolvalue = ptr -> is_species_level;
+ retval = AsnWrite(aip, TAXON1_DATA_is_species_level, &av);
+ if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {
+ goto erret;
+ }
+ retval = TRUE;
+
+erret:
+ AsnUnlinkType(orig); /* unlink local tree */
+ return retval;
+}
+
diff --git a/network/taxon1/common/objtax1.h b/network/taxon1/common/objtax1.h
new file mode 100644
index 00000000..987ec7b1
--- /dev/null
+++ b/network/taxon1/common/objtax1.h
@@ -0,0 +1,173 @@
+#ifndef _objtax1_
+#define _objtax1_
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+
+#ifdef __cplusplus
+extern "C" { /* } */
+#endif
+
+
+/**************************************************
+*
+* Generated objects for Module NCBI-Taxon1
+* Generated using ASNCODE Revision: 6.0 at Feb 2, 1998 4:16 PM
+*
+**************************************************/
+
+NLM_EXTERN Boolean LIBCALL
+objtax1AsnLoad PROTO((void));
+typedef ValNodePtr Taxon1ReqPtr;
+typedef ValNode Taxon1Req;
+#define Taxon1Req_init 1
+#define Taxon1Req_findname 2
+#define Taxon1Req_getdesignator 3
+#define Taxon1Req_getunique 4
+#define Taxon1Req_getidbyorg 5
+#define Taxon1Req_getorgnames 6
+#define Taxon1Req_getcde 7
+#define Taxon1Req_getranks 8
+#define Taxon1Req_getdivs 9
+#define Taxon1Req_getgcs 10
+#define Taxon1Req_getlineage 11
+#define Taxon1Req_getchildren 12
+#define Taxon1Req_getbyid 13
+#define Taxon1Req_lookup 14
+#define Taxon1Req_getorgmod 15
+#define Taxon1Req_fini 16
+
+
+NLM_EXTERN Taxon1ReqPtr LIBCALL Taxon1ReqFree PROTO ((Taxon1ReqPtr ));
+NLM_EXTERN Taxon1ReqPtr LIBCALL Taxon1ReqAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL Taxon1ReqAsnWrite PROTO (( Taxon1ReqPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* Taxon1Info
+*
+**************************************************/
+typedef struct struct_Taxon1_info {
+ struct struct_Taxon1_info PNTR next;
+ Int4 ival1;
+ Int4 ival2;
+ CharPtr sval;
+} Taxon1Info, PNTR Taxon1InfoPtr;
+
+
+NLM_EXTERN Taxon1InfoPtr LIBCALL Taxon1InfoFree PROTO ((Taxon1InfoPtr ));
+NLM_EXTERN Taxon1InfoPtr LIBCALL Taxon1InfoNew PROTO (( void ));
+NLM_EXTERN Taxon1InfoPtr LIBCALL Taxon1InfoAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL Taxon1InfoAsnWrite PROTO (( Taxon1InfoPtr , AsnIoPtr, AsnTypePtr));
+
+typedef ValNodePtr Taxon1RespPtr;
+typedef ValNode Taxon1Resp;
+#define Taxon1Resp_error 1
+#define Taxon1Resp_init 2
+#define Taxon1Resp_findname 3
+#define Taxon1Resp_getdesignator 4
+#define Taxon1Resp_getunique 5
+#define Taxon1Resp_getidbyorg 6
+#define Taxon1Resp_getorgnames 7
+#define Taxon1Resp_getcde 8
+#define Taxon1Resp_getranks 9
+#define Taxon1Resp_getdivs 10
+#define Taxon1Resp_getgcs 11
+#define Taxon1Resp_getlineage 12
+#define Taxon1Resp_getchildren 13
+#define Taxon1Resp_getbyid 14
+#define Taxon1Resp_lookup 15
+#define Taxon1Resp_getorgmod 16
+#define Taxon1Resp_fini 17
+
+
+NLM_EXTERN Taxon1RespPtr LIBCALL Taxon1RespFree PROTO ((Taxon1RespPtr ));
+NLM_EXTERN Taxon1RespPtr LIBCALL Taxon1RespAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL Taxon1RespAsnWrite PROTO (( Taxon1RespPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* Taxon1Error
+*
+**************************************************/
+typedef struct struct_Taxon1_error {
+ Uint2 level;
+ /* following #defines are for enumerated type, not used by object loaders */
+#define Taxon1_error_level_none 0
+#define Taxon1_error_level_info 1
+#define Taxon1_error_level_warn 2
+#define Taxon1_error_level_error 3
+#define Taxon1_error_level_fatal 4
+
+ CharPtr msg;
+} Taxon1Error, PNTR Taxon1ErrorPtr;
+
+
+NLM_EXTERN Taxon1ErrorPtr LIBCALL Taxon1ErrorFree PROTO ((Taxon1ErrorPtr ));
+NLM_EXTERN Taxon1ErrorPtr LIBCALL Taxon1ErrorNew PROTO (( void ));
+NLM_EXTERN Taxon1ErrorPtr LIBCALL Taxon1ErrorAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL Taxon1ErrorAsnWrite PROTO (( Taxon1ErrorPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* Taxon1Name
+*
+**************************************************/
+typedef struct struct_Taxon1_name {
+ struct struct_Taxon1_name PNTR next;
+ Int4 taxid;
+ Int4 cde;
+ CharPtr oname;
+ CharPtr uname;
+} Taxon1Name, PNTR Taxon1NamePtr;
+
+
+NLM_EXTERN Taxon1NamePtr LIBCALL Taxon1NameFree PROTO ((Taxon1NamePtr ));
+NLM_EXTERN Taxon1NamePtr LIBCALL Taxon1NameNew PROTO (( void ));
+NLM_EXTERN Taxon1NamePtr LIBCALL Taxon1NameAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL Taxon1NameAsnWrite PROTO (( Taxon1NamePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* Taxon1Data
+*
+**************************************************/
+typedef struct struct_Taxon1_data {
+ struct struct_Org_ref PNTR org;
+ CharPtr div;
+ CharPtr embl_code;
+ Uint1 is_species_level;
+} Taxon1Data, PNTR Taxon1DataPtr;
+
+
+NLM_EXTERN Taxon1DataPtr LIBCALL Taxon1DataFree PROTO ((Taxon1DataPtr ));
+NLM_EXTERN Taxon1DataPtr LIBCALL Taxon1DataNew PROTO (( void ));
+NLM_EXTERN Taxon1DataPtr LIBCALL Taxon1DataAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+NLM_EXTERN Boolean LIBCALL Taxon1DataAsnWrite PROTO (( Taxon1DataPtr , AsnIoPtr, AsnTypePtr));
+
+#ifdef __cplusplus
+/* { */ }
+#endif
+
+#endif /* _objtax1_ */
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
diff --git a/network/taxon1/common/tax1map.h b/network/taxon1/common/tax1map.h
new file mode 100644
index 00000000..c584c62e
--- /dev/null
+++ b/network/taxon1/common/tax1map.h
@@ -0,0 +1,16 @@
+/****************************
+ * tax1map.h
+ *
+ * we need this file to overcome the asntool
+ *
+ */
+
+#ifndef TAX1MAP_H_DONE
+#define TAX1MAP_H_DONE
+
+#include <ncbi.h>
+#include <objfeat.h>
+
+#define struct_Org_ref orgref
+
+#endif
diff --git a/network/taxon1/common/taxinc.h b/network/taxon1/common/taxinc.h
new file mode 100644
index 00000000..a859c344
--- /dev/null
+++ b/network/taxon1/common/taxinc.h
@@ -0,0 +1,153 @@
+/*****************************************
+ * File: taxinc.h
+ * Description: taxon1 API
+ */
+
+#ifndef TAXINC_H_DONE
+#define TAXINC_H_DONE
+
+#include <ncbi.h>
+#include <objfeat.h>
+
+#define struct_Org_ref orgref
+
+#include <objtax1.h>
+
+/* API functions prototypes */
+
+/*---------------------------------------------
+ * Taxon1 server init
+ * Returns: TRUE - OK
+ * FALSE - Can't open taxonomy database
+ */
+Boolean tax1_init(void);
+
+/*---------------------------------------------
+ * Taxon1 server fini (frees memory)
+ */
+
+void tax1_fini(void);
+
+/*---------------------------------------------
+ * Get organism by tax_id
+ * Returns: pointer to Taxon1Data if organism exists
+ * NULL - if tax_id wrong
+ *
+ * typedef struct struct_Taxon1_data {
+ * OrgRefPtr org;
+ * CharPtr div; genbank division ("MAM", "VIR", "PHG", ...)
+ * CharPtr embl_code; in common case first letters from genus-species pair
+ * Uint1 is_species_level; 1 if node on species level or below
+ * } Taxon1Data, PNTR Taxon1DataPtr;
+ *
+ * NOTE:
+ * Caller gets his own copy of OrgRef structure.
+ */
+
+Taxon1DataPtr tax1_getbyid(Int4 tax_id);
+
+/*----------------------------------------------
+ * Get organism by OrgRef
+ * Returns: pointer to Taxon1Data if organism exists
+ * NULL - if no such organism in taxonomy database
+ *
+ * NOTE:
+ * 1. This functions uses the following data from inp_orgRef to find organism
+ * in taxonomy database. It uses taxname first. If no organism was found (or multiple nodes found)
+ * then it tryes to find organism using common name. If nothing found, then it tryes to find
+ * organism using synonyms. tax1_lookup never uses tax_id to find organism.
+ * 2. If merge == 0 this function makes the new copy of OrgRef structure and puts into it data
+ * from taxonomy database.
+ * If merge != 0 this function updates inp_orgRef structure.
+ */
+Taxon1DataPtr tax1_lookup(OrgRefPtr inp_orgRef, int merge);
+
+/*-----------------------------------------------
+ * Get tax_id by OrgRef
+ * Returns: tax_id - if organism found
+ * 0 - no organism found
+ * -tax_id - if multiple nodes found (where tax_id is id of one of the nodes)
+ * NOTE:
+ * This function uses the same information from inp_orgRef as a tax1_lookup
+ */
+Int4 tax1_getTaxIdByOrgRef(OrgRefPtr inp_orgRef);
+
+/*----------------------------------------------
+ * Get tax_id by organism name
+ * Returns: tax_id - if organism found
+ * 0 - no organism found
+ * -tax_id - if multiple nodes found (where tax_id is id of one of the nodes)
+ * NOTE:
+ * orgname can be a regular expression.
+ */
+Int4 tax1_getTaxIdByName(CharPtr orgname);
+Int4 tax1_findTaxIdByName(CharPtr orgname); /* standalone version only */
+
+
+/*----------------------------------------------
+ * Get ALL tax_id by organism name
+ * Returns: number of organism found
+ * NOTE:
+ * 1. orgname can be a regular expression.
+ * 2. Ids consists of tax ids. Caller is responsible to free this memory
+ */
+Int4 tax1_getAllTaxIdByName(CharPtr orgname, Int4 **Ids);
+Int4 tax1_findAllTaxIdByName(CharPtr orgname, Int4 **Ids); /* standalone version only */
+
+/*----------------------------------------------
+ * Get organism by tax_id
+ * Returns: pointer to OrgRef structure if organism found
+ * NULL - if no such organism in taxonomy database
+ * NOTE:
+ * This function does not make a copy of OrgRef structure, so, caller can not use
+ * OrgRefFree function for returned pointer.
+ */
+OrgRefPtr tax1_getOrgRef(Int4 tax_id, int* is_species, CharPtr div, CharPtr embl_cde);
+
+/*---------------------------------------------
+ * Set mode for synonyms in OrgRef
+ * Returns: previous mode
+ * NOTE:
+ * Default mode: do not include synonyms in OrgRef
+ */
+Boolean tax1_setSynonyms(Boolean on_off);
+
+/*---------------------------------------------
+ * Get parent tax_id
+ */
+Int4 tax1_getParent(Int4 id_tax);
+
+/*---------------------------------------------
+ * Get taxids for all children.
+ * Returns: number of children
+ */
+int tax1_getChildren(Int4 id_tax, Int4** children_ids);
+
+/*---------------------------------------------
+ * Get genetic code name by genetic code id
+ */
+CharPtr tax1_getGCName(Int2 gc_id);
+
+/*---------------------------------------------
+ * Get the nearest common ancestor for two nodes
+ * Returns: id of this ancestor (id == 1 means that root node only is ancestor)
+ */
+Int4 tax1_join(Int4 taxid1, Int4 taxid2);
+
+/*---------------------------------------------
+ * Get all names for tax_id
+ * Returns: number of names
+ */
+
+Int2 tax1_getAllNames(Int4 tax_id, CharPtr **names, Boolean unique);
+
+/*---------------------------------------------
+ * Find organism name in the string (for PDB mostly)
+ * Returns: nimber of tax_ids found
+ * NOTE:
+ * 1. orgname is substring of search_str which matches organism name (return parameter).
+ * 2. Ids consists of tax_ids. Caller is responsible to free this memory
+ */
+Int4 tax1_getTaxId4Str(CharPtr search_str, CharPtr* orgname, Int4Ptr *Ids_out);
+
+#endif
diff --git a/network/taxon1/common/taxon1.asn b/network/taxon1/common/taxon1.asn
new file mode 100644
index 00000000..27adc12e
--- /dev/null
+++ b/network/taxon1/common/taxon1.asn
@@ -0,0 +1,85 @@
+--$Revision: 6.1 $
+--**********************************************************************
+--
+-- NCBI Taxonomy Server
+-- by James Ostell, 1995
+-- Version 1.0 - July 1995
+--
+--**********************************************************************
+
+
+
+NCBI-Taxon1 DEFINITIONS ::=
+BEGIN
+
+IMPORTS Org-ref FROM NCBI-Organism;
+
+ -- Requests to the Taxon server
+Taxon1-req ::= CHOICE {
+ init NULL, -- initialize the server
+ findname VisibleString, -- find orgnames match string
+ getdesignator VisibleString, -- find designator
+ getunique VisibleString, -- get taxid for unique name
+ getidbyorg Org-ref, -- get taxid matches orgref
+ getorgnames INTEGER, -- get all organism names
+ getcde NULL, -- get name classes
+ getranks NULL, -- get ranks
+ getdivs NULL, -- get divisions
+ getgcs NULL, -- get gencodes
+ getlineage INTEGER, -- get lineage for org
+ getchildren INTEGER, -- get children
+ getbyid INTEGER, -- get Org-ref by TaxonID
+ lookup Org-ref, -- lookup by data
+ getorgmod Taxon1-info, -- lookup for OrgMod
+ fini NULL } -- close the server
+
+Taxon1-resp ::= CHOICE {
+ error Taxon1-error, -- sent on any error
+ init NULL, -- sent by successful initiation
+ findname SET OF Taxon1-name,
+ getdesignator INTEGER,
+ getunique INTEGER,
+ getidbyorg INTEGER,
+ getorgnames SET OF Taxon1-name,
+ getcde SET OF Taxon1-info,
+ getranks SET OF Taxon1-info,
+ getdivs SET OF Taxon1-info,
+ getgcs SET OF Taxon1-info,
+ getlineage SET OF Taxon1-info,
+ getchildren SET OF Taxon1-info,
+ getbyid Taxon1-data,
+ lookup Taxon1-data,
+ getorgmod SET OF Taxon1-info,
+ fini NULL }
+
+Taxon1-info ::= SEQUENCE {
+ ival1 INTEGER,
+ ival2 INTEGER,
+ sval VisibleString OPTIONAL}
+
+Taxon1-name ::= SEQUENCE {
+ taxid INTEGER,
+ cde INTEGER,
+ oname VisibleString OPTIONAL,
+ uname VisibleString OPTIONAL }
+
+Taxon1-error ::= SEQUENCE {
+ level ENUMERATED {
+ none (0) , -- not an error, just a message
+ info (1) , -- informational error
+ warn (2) ,
+ error (3) ,
+ fatal (4) } ,
+ msg VisibleString OPTIONAL }
+
+Taxon1-data ::= SEQUENCE {
+ org Org-ref OPTIONAL, -- Org-ref with Org-name and db filled in
+ div VisibleString , -- GenBank division
+ embl-code VisibleString , -- 2 letter EMBL code
+ is-species-level BOOLEAN } -- species level or below
+
+END
+
+
+
+
diff --git a/network/taxon1/common/taxuerr.h b/network/taxon1/common/taxuerr.h
new file mode 100644
index 00000000..d8ca5714
--- /dev/null
+++ b/network/taxon1/common/taxuerr.h
@@ -0,0 +1,9 @@
+#ifndef __MODULE_taxutil__
+#define __MODULE_taxutil__
+
+#define ERR_ORGANISM 1,0
+#define ERR_ORGANISM_TaxIdNotUnique 1,1
+#define ERR_ORGANISM_TaxNameNotFound 1,2
+#define ERR_ORGANISM_TaxIdNotSpecLevel 1,3
+
+#endif
diff --git a/network/taxon1/common/taxutil.c b/network/taxon1/common/taxutil.c
new file mode 100644
index 00000000..92fbd57e
--- /dev/null
+++ b/network/taxon1/common/taxutil.c
@@ -0,0 +1,739 @@
+#include <utilpub.h>
+#include <taxutil.h>
+#include <taxuerr.h>
+#include <utilpars.h>
+
+static char *this_module ="taxutil";
+
+#ifdef THIS_MODULE
+#undef THIS_MODULE
+#endif
+#define THIS_MODULE this_module
+
+static char *this_file = "taxutil.c";
+
+#ifdef THIS_FILE
+#undef THIS_FILE
+#endif
+#define THIS_FILE this_file
+
+
+static TaxBlk cash[MAXIDLIST];
+
+static
+GeneticCodeListPtr
+GeneticCodeListNew(void)
+{
+
+ return (GeneticCodeListPtr) MemNew(sizeof(GeneticCodeList));
+
+}
+
+void tax_init(void)
+{
+ int i;
+
+ for (i = 0; i < MAXIDLIST; i++) {
+ cash[i].hits = 0;
+ }
+
+}
+
+Int4 taxname_replace(CharPtr iname, Taxon1DataPtr new)
+{
+ Int4 hitmin, imin, i;
+
+ hitmin = cash[0].hits;
+ imin = 0;
+ for (i = 1; i < MAXIDLIST; i++) {
+ if (cash[i].hits < hitmin) {
+ hitmin = cash[i].hits;
+ imin = i;
+ }
+ }
+ cash[imin].hits = 1;
+ if(cash[imin].tax != NULL)
+ Taxon1DataFree(cash[imin].tax);
+ cash[imin].tax = new;
+
+ return imin;
+
+}
+
+Int4 taxname_match(CharPtr orgname, Boolean err)
+{
+ Int4 i;
+ CharPtr taxstr = NULL;
+ Int4 tid;
+ Taxon1DataPtr new;
+
+ ErrSetOptFlags(EO_SHOW_CODES);
+ ErrSetOptFlags(EO_MSG_MSGTEXT);
+ if (orgname == NULL) {
+ return -1;
+ }
+ for (i=0; i < MAXIDLIST; i++) {
+ if (cash[i].tax != NULL) {
+ if (strcmp(orgname, cash[i].tax->org->taxname) == 0) {
+ cash[i].hits++;
+ return i;
+ }
+ }
+ }
+ tid = tax1_getTaxIdByName(orgname);
+ if (tid == 0 ) {
+ if(err)
+ ErrPostEx(SEV_WARNING, ERR_ORGANISM_TaxNameNotFound,
+ "Taxon Id not found for [%s]", orgname);
+ return -1;
+ } else if (tid < 0) {
+ if(err)
+ ErrPostEx(SEV_WARNING, ERR_ORGANISM_TaxIdNotUnique,
+ "Not an unique Taxonomic Id for %s", orgname);
+ return -1;
+ } else {
+ new = tax1_getbyid(tid);
+ if (new == NULL) {
+ if(err)
+ ErrPostEx(SEV_WARNING, ERR_ORGANISM_TaxNameNotFound,
+ "Taxon Id not found for [%s]", orgname);
+ return -1;
+ }
+ if (new->is_species_level == FALSE) {
+ if(err)
+ ErrPostEx(SEV_WARNING,ERR_ORGANISM_TaxIdNotSpecLevel,
+ "Taxarch hit is not on species level (%s)", orgname);
+ }
+ i = taxname_replace(orgname, new);
+ return i;
+ }
+}
+
+/****************************************************************************
+* get OrgRef from taxserver by name
+* doesn't use the input OrgRef for the query (see check_org_ref())
+*
+****************************************************************************/
+OrgRefPtr get_tax_org(CharPtr name)
+{
+ Int4 i;
+
+ i = taxname_match(name, FALSE);
+ if (i != -1) {
+ return cash[i].tax->org;
+ }
+ return NULL;
+}
+
+CharPtr get_lineage(CharPtr name)
+{
+ Int4 i;
+ OrgRefPtr orp;
+ OrgNamePtr onp;
+
+ i = taxname_match(name, TRUE);
+ if (i != -1) {
+ orp = cash[i].tax->org;
+ if (orp) {
+ onp = orp->orgname;
+ }
+ return Nlm_StringSave(onp->lineage);
+ }
+ return NULL;
+}
+
+GeneticCodeListPtr get_gcode(CharPtr name)
+{
+ Int4 i;
+ GeneticCodeListPtr gclp;
+ OrgRefPtr orp;
+ OrgNamePtr onp;
+
+ i = taxname_match(name, FALSE);
+ if (i != -1) {
+ orp = cash[i].tax->org;
+ if (orp) {
+ onp = orp->orgname;
+ }
+ if (onp) {
+ gclp = GeneticCodeListNew();
+ gclp->genomic = onp->gcode;
+ gclp->mitochondrial = onp->mgcode;
+ return gclp;
+ }
+ }
+ return NULL;
+}
+
+/**************************************************************************
+* CleanTail:
+* -- delete any tailing ' ', '\n', '\\', ',', ';', '~', '.', ':' characters
+****************************************************************************/
+static void CleanTail(CharPtr str)
+{
+ Int4 len;
+ CharPtr q;
+
+ if (str == NULL) {
+ return;
+ }
+ len = StringLen(str);
+
+ for (q = str + len-1; q >= str && len > 0; q--, len--) {
+ if (*q == ' ' || *q == '\n' || *q == '\\' || *q == ',' || *q == ';'
+ || *q == '~' || *q == '.' || *q == ':') {
+ *q = '\0';
+ continue;
+ }
+ break;
+ }
+
+}
+
+static ValNodePtr tie_prev(ValNodePtr head, ValNodePtr prev)
+{
+ prev->next = head;
+ return prev;
+}
+
+/*-------------------- TokenString() ---------------------*/
+/****************************************************************************
+* TokenString:
+* -- parsing string "str" by delimiter or tab key, blank
+* -- parsing stop at newline ('\n') or end of string ('\0')
+****************************************************************************/
+static ValNodePtr TokenString(CharPtr str, Char delimiter)
+{
+ CharPtr bptr, ptr;
+ Int2 len;
+ ValNodePtr curtoken, token = NULL;
+
+ /* skip first several delimiters if any existed */
+ for (ptr = str; *ptr == delimiter; ++ptr) continue;
+
+ for (; *ptr != '\0';) {
+ for (bptr = ptr, len = 0; *ptr != delimiter && *ptr != '\0';
+ ptr++, ++len) continue;
+ curtoken = ValNodeNew(NULL);
+ curtoken->data.ptrvalue = TextSave(bptr, len);
+ token = tie_prev(token, curtoken);
+ while (*ptr == delimiter || *ptr == '\t' || *ptr == ' ')
+ ++ptr;
+ }
+ return (token);
+
+}
+
+static void FreeToken(ValNodePtr token)
+{
+ ValNodePtr v, vnext;
+
+ for (v = token; v; v = vnext) {
+ vnext = v->next;
+ MemFree(v->data.ptrvalue);
+ MemFree(v);
+ }
+}
+
+GeneticCodeListPtr get_gcode_from_lineage(CharPtr lineage)
+{
+ Int4 tid;
+ GeneticCodeListPtr gclp;
+ Taxon1DataPtr tax;
+ OrgRefPtr orp;
+ OrgNamePtr onp;
+ ValNodePtr token=NULL;
+ CharPtr stoken;
+
+ for (token=TokenString(lineage, ';'); token!=NULL; token = token->next) {
+ stoken = token->data.ptrvalue;
+ CleanTail(stoken);
+ if ((tid = tax1_getTaxIdByName(stoken)) < 0)
+ tid = -tid;
+
+ tax = tax1_getbyid(tid);
+ if (tax && tax->org) {
+ orp = tax->org;
+ onp = orp->orgname;
+ if (onp) {
+ gclp = GeneticCodeListNew();
+ gclp->genomic = onp->gcode;
+ gclp->mitochondrial = onp->mgcode;
+ FreeToken(token);
+ Taxon1DataFree(tax);
+ return gclp;
+ }
+ }
+ if(tax != NULL) {
+ Taxon1DataFree(tax);
+ }
+ }
+ FreeToken(token);
+ return NULL;
+}
+
+
+/*---------------------------- check_org_ref() -------------------------*/
+/****************************************************************************
+* check_org_ref:
+* -- replace OrgRefPtr by OrgRef from server if replace is TRUE
+* -- or check OrgRef and return it back (uses cash and requires tax_init)
+****************************************************************************/
+OrgRefPtr check_org_ref(OrgRefPtr orp, Boolean replace)
+{
+ OrgRefPtr new, tmp;
+
+ if (orp == NULL) {
+ return NULL;
+ }
+ if (orp->taxname != NULL) {
+ tmp = get_tax_org(orp->taxname);
+ } else if (orp->common != NULL) {
+ tmp = get_tax_org(orp->common);
+ } else {
+ return orp;
+ }
+ if (replace && tmp != NULL) {
+ new = AsnIoMemCopy(tmp, (AsnReadFunc) OrgRefAsnRead,
+ (AsnWriteFunc) OrgRefAsnWrite);
+ OrgRefFree(orp);
+ return new;
+ }
+ return orp;
+} /* check_org_ref */
+
+/****************************************************************************
+* replace_org:
+* -- replacing OrgRefPtr by OrgRef from server
+* -- freeing the input OrgRef * if taxon id is not found return the input OrgRef
+****************************************************************************/
+OrgRefPtr replace_org_err(OrgRefPtr orp, Boolean replace)
+{
+ OrgRefPtr new;
+ Taxon1DataPtr tax;
+ CharPtr orgname;
+ Int4 tax_id;
+
+ if (orp == NULL) {
+ return NULL;
+ }
+ if (orp->taxname) {
+ orgname = orp->taxname;
+ } else if (orp->common) {
+ orgname = orp->common;
+ } else {
+ orgname = " ";
+ }
+ if ((tax_id = tax1_getTaxIdByOrgRef(orp)) < 0) {
+ ErrPostEx(SEV_WARNING, ERR_ORGANISM_TaxIdNotUnique,
+ "Not an unique Taxonomic Id for %s", orgname);
+ return orp;
+ }
+ tax = tax1_lookup(orp, 1);
+ if (tax && tax->org) {
+ if (tax->is_species_level != 1) {
+ ErrPostEx(SEV_WARNING, ERR_ORGANISM_TaxIdNotSpecLevel,
+ "Taxarch hit is not on species level (%s)", orgname);
+ }
+ if (replace) {
+ new = AsnIoMemCopy(tax->org, (AsnReadFunc) OrgRefAsnRead,
+ (AsnWriteFunc) OrgRefAsnWrite);
+ tax->org = NULL;
+ Taxon1DataFree(tax);
+ OrgRefFree(orp);
+ return new;
+ }
+ } else {
+ ErrPostEx(SEV_WARNING, ERR_ORGANISM_TaxNameNotFound,
+ "Taxon Id not found for [%s]", orgname);
+ }
+ return orp;
+} /* replace_org_err */
+
+/****************************************************************************
+* replace_org:
+* -- replacing OrgRefPtr by OrgRef from server
+* -- freeing the input OrgRef * if taxon id is not found return NULL!!
+****************************************************************************/
+OrgRefPtr replace_org(OrgRefPtr orp, Boolean replace)
+{
+ OrgRefPtr new;
+ Taxon1DataPtr tax;
+
+ if (orp == NULL) {
+ return NULL;
+ }
+ tax = tax1_lookup(orp, 1);
+ if (tax && tax->org) {
+ if (replace) {
+ new = AsnIoMemCopy(tax->org, (AsnReadFunc) OrgRefAsnRead,
+ (AsnWriteFunc) OrgRefAsnWrite);
+ tax->org = NULL;
+ Taxon1DataFree(tax);
+ OrgRefFree(orp);
+ return new;
+ }
+ }
+ return NULL;
+} /* replace_org */
+
+CharPtr get_tax_division(OrgRefPtr orp)
+{
+ Taxon1DataPtr tax;
+ CharPtr div;
+
+ if (orp == NULL) {
+ return NULL;
+ }
+ tax = tax1_lookup(orp, 0);
+ if (tax) {
+ div = StringSave(tax->div);
+ Taxon1DataFree(tax);
+ return div;
+ }
+ return NULL;
+}
+
+CharPtr get_embl_code(OrgRefPtr orp)
+{
+ Taxon1DataPtr tax;
+ CharPtr embl_code;
+
+ if (orp == NULL) {
+ return NULL;
+ }
+ tax = tax1_lookup(orp, 0);
+ if (tax) {
+ embl_code = StringSave(tax->embl_code);
+ Taxon1DataFree(tax);
+ return embl_code;
+ }
+ return NULL;
+}
+
+void GetTaxserverOrg (SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
+{
+ BioseqPtr bsp = NULL;
+ BioseqSetPtr bssp = NULL;
+ ValNodePtr descr, vnp;
+ BioSourcePtr biosp = NULL;
+ OrgRefPtr orp = NULL;
+ SeqAnnotPtr annot, sap;
+ SeqFeatPtr sfp;
+
+ if (IS_Bioseq(sep)) {
+ bsp = sep->data.ptrvalue;
+ descr = bsp->descr;
+ annot = bsp->annot;
+ } else {
+ bssp = sep->data.ptrvalue;
+ descr = bssp->descr;
+ annot = bssp->annot;
+ }
+ for (vnp = descr; vnp; vnp = vnp->next) {
+ if (vnp->choice == Seq_descr_source) {
+ biosp = vnp->data.ptrvalue;
+ if ((orp = replace_org(biosp->org, TRUE)) != NULL) {
+ biosp->org = orp;
+ }
+ }
+ }
+ for (sap = annot; sap != NULL; sap = sap->next) {
+ if (sap->type == 1) {
+ for (sfp = (SeqFeatPtr) sap->data; sfp != NULL; sfp = sfp->next) {
+ if (sfp->data.choice == SEQFEAT_BIOSRC) {
+ biosp = sfp->data.value.ptrvalue;
+ if ((orp = replace_org(biosp->org, TRUE)) != NULL) {
+ biosp->org = orp;
+ }
+ }
+ }
+ }
+ }
+}
+/* temporary simulant functions for old-new Taxon switch period */
+
+Boolean TaxArchInit (void)
+{
+ return tax1_init();
+}
+
+Boolean TaxArchFini (void)
+{
+ tax1_fini();
+
+ return TRUE;
+}
+
+/******************************************************************
+* check Taxon id in Biosource OrgrefPtr and report an error
+* if Id is not found
+********************************************************************/
+Boolean CheckTaxId(SeqEntryPtr sep)
+{
+ ValNodePtr vnp;
+ BioSourcePtr bsrp;
+ OrgRefPtr orp;
+ CharPtr orgname;
+ Taxon1DataPtr tax;
+ Boolean retval = TRUE;
+
+ ErrSetOptFlags(EO_SHOW_CODES);
+ ErrSetOptFlags(EO_MSG_MSGTEXT);
+ vnp = SeqEntryGetSeqDescr(sep, Seq_descr_source, NULL);
+ if (vnp == NULL)
+ return FALSE;
+ bsrp = (BioSourcePtr) vnp->data.ptrvalue;
+ orp = bsrp->org;
+ if (orp == NULL) {
+ return FALSE;
+ }
+ if (orp->taxname) {
+ orgname = orp->taxname;
+ } else if (orp->common) {
+ orgname = orp->common;
+ } else {
+ orgname = " ";
+ }
+ if (tax1_getTaxIdByOrgRef(orp) < 0) {
+ ErrPostEx(SEV_WARNING, ERR_ORGANISM_TaxIdNotUnique,
+ "Not an unique Taxonomic Id for %s", orgname);
+ return FALSE;
+ }
+ tax = tax1_lookup(orp, 0);
+ if (tax == NULL) {
+ ErrPostEx(SEV_WARNING, ERR_ORGANISM_TaxNameNotFound,
+ "Taxon Id not found for [%s]", orgname);
+ retval = FALSE;
+ } else if (tax->is_species_level != 1) {
+ ErrPostEx(SEV_WARNING, ERR_ORGANISM_TaxIdNotSpecLevel,
+ "Taxarch hit is not on species level (%s)", orgname);
+ }
+ if(tax != NULL)
+ Taxon1DataFree(tax);
+ return retval;
+
+}
+
+static Boolean TaxCmpOrgById(BioSourcePtr b1, BioSourcePtr b2)
+{
+ DbtagPtr d1 = NULL, d2 = NULL;
+ ValNodePtr vnp;
+
+ if (b1 == NULL || b2 == NULL) {
+ return FALSE;
+ }
+ if (b1->org == NULL || b2->org == NULL) {
+ return FALSE;
+ }
+ for (vnp = b1->org->db; vnp; vnp = vnp->next) {
+ d1 = (DbtagPtr) vnp->data.ptrvalue;
+ if (StringCmp(d1->db, "taxon") == 0) {
+ break;
+ }
+ }
+ for (vnp = b2->org->db; vnp; vnp = vnp->next) {
+ d2 = (DbtagPtr) vnp->data.ptrvalue;
+ if (StringCmp(d2->db, "taxon") == 0) {
+ break;
+ }
+ }
+ if (d1 && d2) {
+ if (d1->tag->id == d2->tag->id) {
+ return TRUE;
+ } else {
+ if (tax1_join(d1->tag->id, d2->tag->id) != 1) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+ } else if (StringICmp(b1->org->taxname, b2->org->taxname) == 0) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/****************************************************************************
+* local_tie_feat:
+* --
+* links input to list specified by head pointer 01-12-94
+****************************************************************************/
+static SeqFeatPtr local_tie_feat(SeqFeatPtr head, SeqFeatPtr next)
+{
+ SeqFeatPtr v;
+
+ if (head == NULL) {
+ return next;
+ }
+ for (v = head; v->next != NULL; v = v->next)
+ continue;
+ v->next = next;
+ return head;
+}
+
+static SubSourcePtr local_tie_next_subtype(SubSourcePtr head, SubSourcePtr next)
+{
+ SubSourcePtr v;
+
+ if (head == NULL) {
+ return next;
+ }
+ for (v = head; v->next != NULL; v = v->next)
+ continue;
+ v->next = next;
+ return head;
+}
+
+static OrgModPtr local_tie_next_OrgMod(OrgModPtr head, OrgModPtr next)
+{
+ OrgModPtr v;
+
+ if (head == NULL) {
+ return next;
+ }
+ for (v = head; v->next != NULL; v = v->next)
+ continue;
+ v->next = next;
+ return head;
+}
+
+static ValNodePtr local_remove_node(ValNodePtr head, ValNodePtr x)
+{
+ ValNodePtr v, p;
+
+ if (head == NULL) {
+ return NULL;
+ }
+ if (x == head) {
+ head = x->next;
+ x->next = NULL;
+ ValNodeFree(x);
+ return head;
+ }
+ for (v = head; v != NULL && v != x; v = v->next) {
+ p = v;
+ }
+ if (v != NULL) {
+ p->next = x->next;
+ x->next = NULL;
+ ValNodeFree(x);
+ }
+ return head;
+}
+
+static BioSourcePtr local_BioSourceMerge(BioSourcePtr host, BioSourcePtr guest)
+{
+ SubSourcePtr ssp, sp;
+ OrgModPtr omp, homp;
+ OrgNamePtr onp;
+
+ if (host == NULL && guest == NULL) {
+ return NULL;
+ }
+ if (host == NULL && guest != NULL) {
+ host = AsnIoMemCopy(guest, (AsnReadFunc) BioSourceAsnRead,
+ (AsnWriteFunc) BioSourceAsnWrite);
+ return host;
+ }
+ if (host != NULL && guest == NULL) {
+ return host;
+ }
+ if (host->genome == 0 && guest->genome != 0) {
+ host->genome = guest->genome;
+ }
+ if (host->origin == 0 && guest->origin != 0) {
+ host->origin = guest->origin;
+ }
+ for (ssp = guest->subtype; ssp; ssp = ssp->next) {
+ sp = AsnIoMemCopy(ssp, (AsnReadFunc) SubSourceAsnRead,
+ (AsnWriteFunc) SubSourceAsnWrite);
+ host->subtype = local_tie_next_subtype(host->subtype, sp);
+ }
+ if (guest->org->orgname) {
+ for (omp = guest->org->orgname->mod; omp; omp = omp->next) {
+ homp = AsnIoMemCopy(omp, (AsnReadFunc) OrgModAsnRead,
+ (AsnWriteFunc) OrgModAsnWrite);
+ if ((onp = host->org->orgname) == NULL) {
+ onp = OrgNameNew();
+ host->org->orgname = onp;
+ }
+ onp->mod = local_tie_next_OrgMod(onp->mod, homp);
+ }
+ }
+ return host;
+}
+
+/**************************************************************************
+* Compare BioSources in one bioseq->descr using Taxonomy to find
+* their join parent
+* merge if organisms are the same or create a feature if different
+*
+**************************************************************************/
+void TaxMergeBSinDescr (SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
+{
+ BioseqPtr bsp = NULL;
+ ValNodePtr vnp, v, vnext, mult;
+ SeqAnnotPtr sap = NULL;
+ SeqIdPtr sip;
+ SeqFeatPtr sfp;
+ BioSourcePtr bsrc = NULL, bs;
+
+ if (!IS_Bioseq(sep)) {
+ return;
+ }
+ mult = (ValNodePtr) data;
+ bsp = (BioseqPtr) sep->data.ptrvalue;
+ if ((bsp->repr != Seq_repr_raw) && (bsp->repr != Seq_repr_const)
+ && (bsp->repr != Seq_repr_delta))
+ return;
+
+ if (! ISA_na(bsp->mol))
+ return;
+
+ sap = bsp->annot;
+ bsp->descr = tie_next(bsp->descr, mult);
+ for (vnp = bsp->descr; vnp; vnp= vnp->next) {
+ if (vnp->choice == Seq_descr_source) {
+ bsrc = vnp->data.ptrvalue;
+ break;
+ }
+ }
+ if (bsrc == NULL || bsrc->org == NULL) {
+ return;
+ }
+ for (v = vnp->next; v; v = vnext) {
+ vnext = v->next;
+ if (v->choice != Seq_descr_source) {
+ continue;
+ }
+ bs = v->data.ptrvalue;
+ if (bs->org != NULL) {
+ if (bsrc && TaxCmpOrgById(bsrc, bs) == TRUE) {
+ bsrc = local_BioSourceMerge(bsrc, bs);
+ } else {
+ sfp = SeqFeatNew();
+ sfp->location = ValNodeNew(NULL);
+ sfp->location->choice = SEQLOC_WHOLE;
+ sip = SeqIdDup(bsp->id);
+ sfp->location->data.ptrvalue = sip ;
+ sfp->data.choice = SEQFEAT_BIOSRC;
+ sfp->data.value.ptrvalue =
+ AsnIoMemCopy(bs, (AsnReadFunc) BioSourceAsnRead,
+ (AsnWriteFunc) BioSourceAsnWrite);
+ if (sap == NULL) {
+ sap = SeqAnnotNew();
+ sap->type = 1;
+ bsp->annot = sap;
+ }
+ sap->data = local_tie_feat(sap->data, sfp);
+ }
+ } else {
+ ErrPostStr(SEV_WARNING, 0, 0, "Biosource missing Organism info");
+ }
+ BioSourceFree(bs);
+ vnp->next = local_remove_node(vnp->next, v);
+
+ }
+ return;
+}
diff --git a/network/taxon1/common/taxutil.h b/network/taxon1/common/taxutil.h
new file mode 100644
index 00000000..bc7efc78
--- /dev/null
+++ b/network/taxon1/common/taxutil.h
@@ -0,0 +1,43 @@
+
+#ifndef _TAXUTIL_H_
+#define _TAXUTIL_H_ taxutil
+
+#include <ncbi.h>
+#include <asn.h>
+#include <sequtil.h>
+#include <taxinc.h>
+
+#define MAXIDLIST 50
+
+typedef struct taxonomy_block {
+ Int4 hits;
+ Taxon1DataPtr tax;
+} TaxBlk, PNTR TaxBlkPtr;
+
+typedef struct struct_GeneticCodeList {
+ Int4 genomic;
+ Int4 mitochondrial;
+} GeneticCodeList, PNTR GeneticCodeListPtr;
+
+void tax_init PROTO((void));
+Int4 taxname_replace PROTO((CharPtr iname, Taxon1DataPtr new));
+Int4 taxname_match PROTO((CharPtr orgname, Boolean err));
+OrgRefPtr check_org_ref PROTO((OrgRefPtr orp, Boolean replace));
+OrgRefPtr get_tax_org PROTO((CharPtr name));
+CharPtr get_lineage PROTO((CharPtr name));
+GeneticCodeListPtr get_gcode PROTO((CharPtr name));
+GeneticCodeListPtr get_gcode_from_lineage PROTO((CharPtr name));
+OrgRefPtr replace_org PROTO((OrgRefPtr orp, Boolean replace));
+OrgRefPtr replace_org_err PROTO((OrgRefPtr orp, Boolean replace));
+CharPtr get_tax_division PROTO((OrgRefPtr orp));
+CharPtr get_embl_code PROTO((OrgRefPtr orp));
+OrgRefPtr check_org_ref PROTO((OrgRefPtr orp, Boolean replace));
+void GetTaxserverOrg PROTO((SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent));
+Boolean CheckTaxId PROTO((SeqEntryPtr sep));
+
+/* temporary simulant functions for old-new Taxon switch period */
+Boolean TaxArchInit PROTO((void));
+Boolean TaxArchFini PROTO((void));
+void TaxMergeBSinDescr PROTO((SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent));
+
+#endif /* _TAXUTIL_H_ */
diff --git a/network/taxon1/common/taxutil.msg b/network/taxon1/common/taxutil.msg
new file mode 100644
index 00000000..095466e5
--- /dev/null
+++ b/network/taxon1/common/taxutil.msg
@@ -0,0 +1,5 @@
+MODULE taxutil
+$$ ORGANISM, 1
+$^ TaxIdNotUnique, 1, SEV_WARNING
+$^ TaxNameNotFound, 2, SEV_WARNING
+$^ TaxIdNotSpecLevel, 3, SEV_WARNING
diff --git a/network/taxon1/server/Makefile b/network/taxon1/server/Makefile
new file mode 100644
index 00000000..318b7f7f
--- /dev/null
+++ b/network/taxon1/server/Makefile
@@ -0,0 +1,54 @@
+#
+# Makefile for taxon program
+#
+
+include $(NCBI)/ncbi.mk
+CODEGEN=asncode
+ASNTOOL=asntool
+
+PURIFY=/am/purify/purify
+CC= $(NCBI_CC) -g
+
+#
+
+INCLUDES=-I$(NCBI_INCDIR)
+
+LIBS1=-lncbitax -lncbiobj -lnetcli -lncbi $(NCBI_OTHERLIBS)
+LIBS=-lncbitax1 -lncbiobj -lnetcli -lncbi -ldl $(NCBI_OTHERLIBS)
+LIBDIRS= -L$(NCBI_ALTLIB)
+
+CFLAGS=-g $(INCLUDES)
+
+all : taxserv_fs
+
+# sources and objects for Taxonomy retrieval
+
+taxprocs.o : taxprocs.c
+ $(CC) -c $(CFLAGS) -DWARN_ON_FAILURE=1 -o taxprocs.o $(INCLUDES) taxprocs.c
+
+taxsmain.o : taxsmain.c
+ $(CC) -c $(CFLAGS) -DWARN_ON_FAILURE=1 -o taxsmain.o $(INCLUDES) taxsmain.c
+
+taxserv_fs: taxprocs.o taxsmain.o
+ $(CC) -o taxserv_fs taxsmain.o taxprocs.o $(LIBDIRS) $(LIBS)
+
+
+asntaxon.l: taxon.asn
+ rm -f asntaxon.l*
+ $(ASNTOOL) -m taxon.asn -l asntaxon.h
+ -mv asntaxon.l* asntaxon.l
+ mv asntaxon.h asntaxonstat.h
+
+asntaxon.h: taxon.asn
+ $(ASNTOOL) -m taxon.asn -o asntaxon.h
+
+clean:
+ rm -f objtaxon.c objtaxon.h asntaxon.l asntaxon.h *.o objtaxonerr objtaxonout
+
+
+
+
+
+
+
+
diff --git a/network/taxon1/server/taxprocs.c b/network/taxon1/server/taxprocs.c
new file mode 100644
index 00000000..bb12eac3
--- /dev/null
+++ b/network/taxon1/server/taxprocs.c
@@ -0,0 +1,1066 @@
+/***** taxprocs.joel.c *****/
+/*------------
+
+old name Joel name
+------------- ---------------
+tn_get_taxid get_tax_id
+ SELECT tax_id, (int)
+ name_txt, (varchar(96))
+ class_cde (int)
+ FROM #ls
+ HAVING pri = min(pri)
+
+
+
+
+ts_get_children get_children
+ SELECT DISTINCT name_txt,
+ tax_id
+ FROM #tax_get
+ WHERE tax_id != @search_tax_id
+ ORDER BY name_txt
+
+
+ts_get_parents get_parent_tax_id
+ SELECT parent_tax_id
+ FROM tax_node
+ WHERE tax_id = @search_tax_id
+
+
+tn_get_orgref get_names
+ SELECT synonym.name_txt,
+ class.class_cde,
+ class.class_txt, (varchar(30))
+ class.priority_no (int)
+ FROM synonym, class
+ WHERE synonym.tax_id = @search_tax_id AND
+ synonym.class_cde = class.class_cde
+ ORDER BY class.priority_no
+
+
+tn_get_lineage_by_taxid get_lin
+ SELECT name_txt,
+ tax_id
+ FROM #tax
+ ORDER BY tax_level_no DESC
+
+
+ts_get_gc get_tax_info ?
+tn_get_taxinfo get_tax_info
+
+ SELECT gc_id, (smallint)
+ mgc_id, (smallint)
+ gc_nm, (varchar(128))
+ mgc_nm, (varchar(128))
+ div_id,(smallint)
+ div_cde, char(3)
+ div_txt, varchar(64)
+ rank_id, smallint
+ rank_txt, (varchar(32))
+ embl_cde, char(4)
+ inherit_gc_ind, tinyint
+ inherit_mgc_ind, tinyint
+ inherit_div_ind, tinyint
+ tax_id,
+ parent_tax_id,
+ tl_ind, smallint
+ name_txt varchar(96)
+ FROM #info
+
+the new procedures are in getorg.sp
+in /export/home/plotkin/tax/stored_procs
+on peony...
+
+----------------*/
+
+#include <stdlib.h>
+#include <ncbi.h>
+#include <ncbinet.h>
+#include <accentr.h>
+#include <objfeat.h>
+#include <objtaxon.h>
+#define REALTAXsyb
+#include <tax_cmmn.h>
+
+#ifdef SYSV
+/* This is a quicky BSD -> SYSV conversion pack */
+#define bcopy(s,d,n) memmove(d,s,n)
+#define bzero(d,n) memset(d,0,n)
+#define bcmp(s1,s2,n) (memcmp(s1,s2,n) ? 1 : 0)
+#define index(s,c) strchr(s,c)
+#define rindex(s,c) strrchr(s,c)
+#endif
+
+#define MAX_ORG_LIST 10
+
+#define AssignValue( s ) ( s[0]=='\0' ? NULL : s )
+
+static _taxDBCtlPtr DBctl;
+static int IsSpeciesRank= 26;
+static Int2 SpeciesRank= 26;
+static Int2 SubspeciesRank= 27;
+static Int2 GenusRank= 22;
+static Int2 FamilyRank= 0;
+static Int2 OrderRank= 0;
+static Int2 ClassRank= 0;
+static Int2 SYNONYM= 0;
+static Int2 COMMON_NAME= 0;
+static Int2 PREF_COMMON= 0;
+
+static Int2 VRL_div= 0;
+static Int2 PHG_div= 0;
+
+static CharPtr DB_PATH= "/netopt/genbank/subtool/taxdb/";
+
+
+/**************************************************************************
+ *
+ * InitTaxDB
+ *
+ **************************************************************************/
+
+InitTaxDB()
+{
+ CharPtr tmp;
+
+ if((tmp=getenv("TAXDBPATH")) != NULL) DB_PATH= tmp;
+
+ DBctl= tax_loadTaxDB(DB_PATH, "dbctl.tax");
+ if(DBctl == NULL) return 0;
+ if(tax_loadTree(DBctl) || tax_loadNames(DBctl)) {
+ return 0;
+ }
+
+ IsSpeciesRank= tax_getRankId(DBctl, "species");
+
+ SpeciesRank= tax_getRankId(DBctl, "species");
+ SubspeciesRank= tax_getRankId(DBctl, "subspecies");
+ GenusRank= tax_getRankId(DBctl, "genus");
+ FamilyRank= tax_getRankId(DBctl, "family");
+ OrderRank= tax_getRankId(DBctl, "order");
+ ClassRank= tax_getRankId(DBctl, "class");
+
+
+ VRL_div= tax_getDivId(DBctl, "VRL", TAX_DIV_CDE);
+ PHG_div= tax_getDivId(DBctl, "PHG", TAX_DIV_CDE);
+
+ SYNONYM= tax_getClassId(DBctl, "synonym");
+ COMMON_NAME= tax_getClassId(DBctl, "common name");
+ PREF_COMMON= tax_getClassId(DBctl, "preferred common name");
+ return 1;
+}
+
+/**************************************************************************
+ *
+ * CloseTaxDB
+ *
+ **************************************************************************/
+
+CloseTaxDB()
+{
+ tax_freeNames(DBctl);
+ tax_freeTree(DBctl);
+ tax_freeGCs(DBctl);
+ tax_freeDivs(DBctl);
+ tax_freeClasses(DBctl);
+ tax_freeRanks(DBctl);
+}
+
+/***************************************************************************
+ *
+ * function: CopyString
+ *
+ ***************************************************************************/
+static
+CopyString( CharPtr new, CharPtr text )
+{
+ CharPtr p, np;
+ Char quote = '"';
+
+ for( p = text, np = new; *p; *np++ = *p++ )
+ if( *p == quote ) *np++ = *p;
+
+ *np = '\0';
+}
+
+
+/**************************************************************************
+ *
+ * FsTaxGetTaxId
+ *
+ **************************************************************************/
+TaxonIdListPtr FsTaxGetTaxId(TaxonNamePtr tnp)
+{
+ int n, i, j, f;
+ Int4 tax_id;
+ _taxNamePtr* nameList;
+ CharPtr orgname;
+ TaxonIdListPtr tilp = NULL;
+
+ orgname= tnp->data.ptrvalue;
+
+#if 0
+ if((n= tax_findByName(DBctl, orgname, TAX_NAME_SEARCH, &nameList)) == 0) {
+ /* do not find exact name */
+ if((n= tax_findByName(DBctl, orgname, TAX_RE_SEARCH, &nameList)) == 0) {
+ /* do not find again */
+ if((n= tax_findByName(DBctl, orgname, TAX_TOKEN_SEARCH, &nameList)) == 0) {
+ /* no such name */
+#ifdef WARN_ON_FAILURE
+ ErrPostEx(SEV_WARNING,1,2,"FsTaxGetTaxId: Not found: <%s>", orgname);
+#endif
+ return NULL;
+ }
+ }
+ }
+#else
+ if((n= tax_findByName(DBctl, orgname, TAX_NAME_SEARCH, &nameList)) == 0) {
+ /* no such name */
+#ifdef WARN_ON_FAILURE
+ ErrPostEx(SEV_WARNING,1,2,"FsTaxGetTaxId: Not found: <%s>", orgname);
+#endif
+ return NULL;
+ }
+#endif
+
+ tilp= TaxonIdListNew();
+ tilp->_num_ids= 0;
+ tilp->ids= MemNew(n*sizeof(Int4));
+
+ for(i= 0; i != n; i++) {
+ tax_id= nameList[i]->tax_id;
+ /* check for duplicate */
+ f= 0;
+ for(j= 0; j < tilp->_num_ids; j++) {
+ if(tilp->ids[j] == tax_id) {
+ f= 1;
+ break;
+ }
+ }
+ if(!f) {
+ tilp->ids[tilp->_num_ids++]= tax_id;
+ }
+ }
+ if(tilp->_num_ids > 1) {
+ tax_id= tax_getDesignator(orgname);
+ if(tax_id > 0) {
+ tilp->_num_ids= 1;
+ tilp->ids[0]= tax_id;
+ }
+ else {
+ tax_id= 0;
+ for(i= 0; i < tilp->_num_ids; i++) {
+ if(DBctl->tree[tilp->ids[i]].rank == SpeciesRank) {
+ if(tax_id == 0) tax_id= tilp->ids[i];
+ else if(tax_id != tilp->ids[i]) {
+ tax_id= 0;
+ break;
+ }
+ }
+ }
+ if(tax_id != 0) {
+ tilp->_num_ids= 1;
+ tilp->ids[0]= tax_id;
+ }
+ }
+ }
+
+ MemFree(nameList);
+ return tilp;
+}
+
+static Int4 getIdById(Int4 id)
+{
+ if((DBctl->tree == NULL) || (id < 0) || (id > tax_getMaxId(DBctl))) return 0;
+
+ if(DBctl->tree[id].parent < 1) {
+ /* deleted node */
+ return 0;
+ }
+
+ while(DBctl->tree[id].child == -1) {
+ id=DBctl->tree[id].parent;
+ }
+
+ return id;
+}
+
+/**************************************************************************
+ *
+ * FsTaxGetChildren
+ *
+ **************************************************************************/
+
+TaxonIdListPtr FsTaxGetChildren( int id_tax )
+{
+ TaxonIdListPtr tilp = NULL;
+ int n;
+ Int4 id;
+
+
+ if((id= getIdById(id_tax)) == 0) {
+#ifdef WARN_ON_FAILURE
+ ErrPostEx(SEV_WARNING,1,2,"FsTaxGetChildren: Not found: <%d>", id_tax);
+#endif
+ return NULL;
+ }
+
+ id_tax= id;
+
+ for(n= 0, id= tax_getChild(DBctl, id); id > 0; id= tax_getSibling(DBctl, id)) {
+ if((DBctl->tree[id].flags & TAX_HIDDEN) == 0) n++;
+ }
+
+ if(n > 0) {
+ tilp= TaxonIdListNew();
+ tilp->_num_ids= 0;
+ tilp->ids= MemNew(n*sizeof(Int4));
+ for(id= tax_getChild(DBctl, id_tax); id > 0; id= tax_getSibling(DBctl, id)) {
+ if((DBctl->tree[id].flags & TAX_HIDDEN) == 0) {
+ tilp->ids[tilp->_num_ids++]= id;
+ }
+ }
+ }
+ return tilp;
+}
+
+
+/**************************************************************************
+ *
+ * FsTaxGetParents
+ *
+ **************************************************************************/
+
+
+TaxonIdListPtr FsTaxGetParents( int id_tax )
+{
+ TaxonIdListPtr tilp = NULL;
+ Int4 id;
+ Int2 n= 1;
+
+
+ if(id_tax < 0) {
+ id_tax= -id_tax;
+ n= 0;
+ }
+
+ if((id= getIdById(id_tax)) == 0) {
+#ifdef WARN_ON_FAILURE
+ ErrPostEx(SEV_WARNING,1,2,"FsTaxGetParents: Not found: <%d>", id_tax);
+#endif
+ return NULL;
+ }
+
+ tilp= TaxonIdListNew();
+ if(n == 0) {
+ Int2 i;
+
+ for(id_tax= id; id_tax > 1; id_tax= tax_getParent(DBctl, id_tax)) n++;
+
+ if(n == 0) n= 1;
+ tilp->_num_ids= n;
+ tilp->ids= MemNew(n*sizeof(Int4));
+ for(i= 0; i < n; i++) {
+ tilp->ids[i]= id= tax_getParent(DBctl, id);
+ }
+ }
+ else {
+ tilp->_num_ids= 1;
+ tilp->ids= MemNew(sizeof(Int4));
+ tilp->ids[0]= tax_getParent(DBctl, id);
+ }
+ return tilp;
+}
+
+#define CLASS_TXT_SCI 0
+#define CLASS_TXT_COM 7
+#define CLASS_TXT_SYN 3
+#define CLASS_TXT_SYNCOM 8
+
+/**************************************************************************
+ *
+ * FsTaxGetRef
+ *
+ **************************************************************************/
+
+
+/*************************************************************************/
+/* return pointer to first non-blank character in str1 after prefix str2 */
+/* if str2 is not prefix for str1 then return str1 */
+/*************************************************************************/
+static CharPtr strTail(CharPtr str1, CharPtr str2)
+{
+ CharPtr c;
+
+ if(StringStr(str1, str2) != str1) return str1;
+
+ c= str1 + StringLen(str2);
+
+ while((*c != '\0') && IS_WHITESP(*c)) c++;
+
+ return c;
+}
+
+static OrgModPtr bldOrgMod(Int4 id, _taxNamePtr o_name)
+{
+ Int4 p_id;
+ Int2 rank;
+ _taxNamePtr parent;
+ OrgModPtr orgMdf= OrgModNew();
+ CharPtr name= o_name->name_txt;
+
+ for(p_id= DBctl->tree[id].parent; p_id > 1; p_id= DBctl->tree[p_id].parent) {
+ rank= DBctl->tree[p_id].rank;
+ if((rank == SubspeciesRank) ||
+ (rank == SpeciesRank) ||
+ (rank == GenusRank)) break;
+ }
+
+ parent= (p_id > 1)? tax_findOrgName(DBctl, p_id) : NULL;
+
+ if(parent != NULL) {
+ orgMdf->subname= StringSave(strTail(name, parent->name_txt));
+ }
+ else {
+ orgMdf->subname= StringSave(name);
+ }
+
+ rank= DBctl->tree[id].rank;
+
+ if(rank == SubspeciesRank) {
+ orgMdf->subtype= 22; /* subspecies */
+ }
+ else if(rank == tax_getRankId(DBctl, "varietas")) {
+ orgMdf->subtype= 6; /* variety */
+ }
+ else if(rank == tax_getRankId(DBctl, "forma")) {
+ orgMdf->subtype= 2; /* strain */
+ }
+ else if((parent != NULL) && (DBctl->tree[p_id].rank == SubspeciesRank)) {
+ orgMdf->subtype= 2; /* strain */
+ }
+ else {
+ orgMdf->subtype= 255; /* other */
+ }
+
+ orgMdf->attrib= NULL;
+
+ return orgMdf;
+}
+
+
+/***************************************************************/
+/* if name is binomial name build the correspondent structures */
+/* otherwise return 0 */
+/***************************************************************/
+static int binomialName(Int4 id, _taxNamePtr o_name, OrgNamePtr onp)
+{
+ int i;
+ Int4 genusId= 0;
+ Int4 speciesId= 0;
+ Int4 subspeciesId= 0;
+ Int4 p_id;
+ Int2 rank;
+ BinomialOrgNamePtr bName;
+ _taxNamePtr genus, species, subspecies;
+
+
+ for(p_id= id; p_id > 1; p_id= DBctl->tree[p_id].parent) {
+ rank= DBctl->tree[p_id].rank;
+ if(rank == SpeciesRank) speciesId= p_id;
+ else if(rank == SubspeciesRank) subspeciesId= p_id;
+ else if(rank == GenusRank) genusId= p_id;
+ }
+
+ if(genusId == 0) {
+ /* try to find subgenus if genus anavalable */
+ for(p_id= id; p_id > 1; p_id= DBctl->tree[p_id].parent) {
+ if(DBctl->tree[p_id].rank == (GenusRank + 1)) genusId= p_id;
+ }
+ }
+
+ genus= (genusId == 0)? NULL : tax_findOrgName(DBctl, genusId);
+ species= (speciesId == 0)? NULL : tax_findOrgName(DBctl, speciesId);
+ subspecies= (subspeciesId == 0)? NULL : tax_findOrgName(DBctl, subspeciesId);
+
+ if(genus == NULL) return 0; /* no genus - no binomial */
+
+ onp->choice= 1; /*binomial*/
+
+ onp->data= bName= BinomialOrgNameNew();
+
+ bName->genus= StringSave(genus->name_txt);
+
+ if(species != NULL) {
+ /* we have a species in lineage */
+ bName->species= StringSave(strTail(species->name_txt, genus->name_txt));
+ if(subspecies != NULL) {
+ /* we also have a subspecies in lineage */
+ bName->subspecies= StringSave(strTail(subspecies->name_txt, species->name_txt));
+ }
+ else {
+ bName->subspecies= NULL;
+ }
+ onp->mod= (id == speciesId)? NULL : bldOrgMod(id, o_name);
+ return 1;
+ }
+
+ /* no species in lineage */
+
+ if(subspecies != NULL) {
+ /* we have no species but we have subspecies */
+ bName->species= NULL;
+ bName->subspecies= StringSave(strTail(subspecies->name_txt, genus->name_txt));
+ onp->mod= bldOrgMod(id, o_name);
+ return 1;
+ }
+
+ /* we have no species, no subspecies but we are under species level (varietas or forma) */
+
+ bName->species= NULL;
+ bName->subspecies= NULL;
+ onp->mod= bldOrgMod(id, o_name);
+ return 1;
+}
+
+
+static void partialName(Int4 id, _taxNamePtr o_name, OrgNamePtr onp)
+{
+
+ TaxElementPtr taxElem;
+ Int2 rank_id= DBctl->tree[id].rank;
+
+ onp->choice= 5; /* partial */
+ onp->data= taxElem= TaxElementNew();
+
+ if(rank_id == FamilyRank) {
+ taxElem->fixed_level= 1; /* family */
+ taxElem->level= NULL;
+ }
+ else if(rank_id == OrderRank) {
+ taxElem->fixed_level= 2;
+ taxElem->level= NULL;
+ }
+ else if(rank_id == ClassRank) {
+ taxElem->fixed_level= 3;
+ taxElem->level= NULL;
+ }
+ else {
+ taxElem->fixed_level= 0;
+ taxElem->level= StringSave(tax_getRankById(DBctl, rank_id));
+ }
+
+ taxElem->name= StringSave(o_name->name_txt);
+ taxElem->next= NULL;
+}
+
+
+/*****************************************************************
+ * build synonyms valnodes
+ * this routine include in valnodes synonyms and common synonyms
+ */
+static ValNodePtr bldSynValNodes(Int4 id, _taxNamePtr syn)
+{
+ ValNodePtr list= NULL;
+ ValNodePtr header= NULL;
+ int i;
+ static char buff[256];
+
+ buff[0]= '~';
+ for(i= 0; syn[i].tax_id == id; i++) {
+ if((syn[i].class_cde == SYNONYM) || (syn[i].class_cde == COMMON_NAME)) {
+ list= ValNodeNew(list);
+ if(syn[i].class_cde == SYNONYM) {
+ StringCpy(&buff[1], syn[i].name_txt);
+ list->data.ptrvalue= StringSave(buff);
+ }
+ else {
+ list->data.ptrvalue= StringSave(syn[i].name_txt);
+ }
+ if(header == NULL) header= list;
+ }
+ }
+ return header;
+}
+
+
+static CharPtr bldLineage(Int4 id)
+{
+ ValNodePtr head=NULL, this=NULL;
+ int len = 2;
+ CharPtr temp, retval = NULL;
+ Int4 lineage[64];
+ int n, i;
+ _taxNamePtr orgName;
+
+ n= tax_getLin(DBctl, id, lineage);
+
+ for(i= 1; i < n; i++) {
+ if((DBctl->tree[lineage[i]].flags & GB_HIDDEN) != 0) continue;
+
+ if((DBctl->tree[lineage[i]].rank >= SpeciesRank) && head) break;
+
+ this= ValNodeNew(this);
+ if (head == NULL){
+ head = this;
+ }
+
+ orgName= tax_findOrgName(DBctl, lineage[i]);
+ this->data.ptrvalue= StringSave(orgName->name_txt);
+ len+= StringLen(orgName->name_txt) + 3;
+ }
+
+ /* all data into linked list, now format it */
+ if (len > 2){
+ temp = retval = MemNew(len);
+ for (this = head; this; this = this -> next){
+ if (this != head){
+ temp = StringMove(temp, "; " );
+ }
+ temp = StringMove(temp, this -> data.ptrvalue);
+ }
+ ValNodeFreeData(head);
+ }
+
+ if(retval == NULL) {
+ /* empty lineage */
+ if((orgName= tax_findOrgName(DBctl, id)) != NULL)
+ retval= StringSave(orgName->name_txt);
+ }
+
+ return retval;
+}
+
+
+static ValNodePtr bldDBId(Int4 id)
+{
+ ValNodePtr dbnode;
+ DbtagPtr dbtag;
+ ObjectIdPtr object_id;
+
+ /* populate tax_id */
+ dbnode= ValNodeNew(NULL);
+ dbnode->data.ptrvalue= dbtag= DbtagNew();
+ dbtag->db = StringSave("taxon");
+ dbtag->tag= object_id= ObjectIdNew();
+ object_id->str= NULL;
+ object_id->id = id;
+ return dbnode;
+}
+
+static OrgNamePtr bldOrgName(Int4 id, _taxNamePtr o_name)
+{
+ OrgNamePtr onp;
+ _taxNodePtr node;
+ Int2 rank_id= DBctl->tree[id].rank;
+ int is_species;
+ Int4 p_id, s_id;
+ CharPtr div_abbr;
+ Int2 div_id;
+ _taxNamePtr s_name;
+
+ onp= OrgNameNew();
+ node= tax_getNode(DBctl, id);
+ if(node == NULL) return NULL;
+
+ onp->gcode= node->gc;
+ onp->mgcode= node->mgc;
+ onp->div= StringSave(tax_getDivById(DBctl, node->division, TAX_DIV_CDE));
+ onp->lineage= bldLineage(id);
+
+ is_species= (rank_id >= SpeciesRank)? 1 : 0;
+ /* correct level by lineage if node has no rank */
+ if(rank_id < 0) {
+ p_id= id;
+ while(p_id > 1) {
+ p_id= DBctl->tree[p_id].parent;
+ if(DBctl->tree[p_id].rank >= SpeciesRank) {
+ is_species= 1;
+ break;
+ }
+ }
+ }
+
+ div_id= node->division;
+ tax_freeNode(node);
+
+ if(is_species) {
+ /* we are on species level or below */
+
+ /* check for viruses */
+ if((div_id == VRL_div) || (div_id == PHG_div)) {
+ /* this is a virus */
+ onp->choice= 2; /* virus */
+ if(rank_id == SpeciesRank) {
+ /* we are on species level */
+ onp->data= StringSave(o_name->name_txt);
+ onp->mod= NULL;
+ }
+ else {
+ /* we are below species */
+ /* first try to find species or min rank which below species but above us */
+ p_id= id; s_id= 0;
+ while(p_id > 1) {
+ p_id= DBctl->tree[p_id].parent;
+ if(DBctl->tree[p_id].rank == SpeciesRank) break;
+ else if(DBctl->tree[p_id].rank > SpeciesRank) s_id= p_id;
+ }
+ if(p_id <= 1) p_id= s_id;
+
+ if(p_id > 1) {
+ /* we below species but we have species above us */
+ s_name= tax_findOrgName(DBctl, p_id);
+ if(s_name != NULL) {
+ onp->data= StringSave(s_name->name_txt);
+ onp->mod= bldOrgMod(id, o_name);
+ }
+ }
+ else {
+ /* we probably below species but no species above us */
+ onp->data= StringSave(o_name->name_txt);
+ onp->mod= bldOrgMod(id, o_name);
+ }
+ }
+ }
+ else if(!binomialName(id, o_name, onp)) {
+ /* name is not binomial: set partial */
+ partialName(id, o_name, onp);
+ }
+ }
+ else {
+ /* above species */
+ partialName(id, o_name, onp);
+ }
+
+ return onp;
+}
+
+static void bldOrgRef(Int4 id, OrgRefPtr orp)
+{
+ _taxNamePtr o_name;
+ int i;
+
+ o_name= tax_findOrgName(DBctl, id);
+ if(o_name == NULL) return;
+ orp->taxname= StringSave(o_name->name_txt);
+
+ /* fill-up preferred common name */
+ orp->common= NULL;
+ for(i= 1; o_name[i].tax_id == id; i++) {
+ if(o_name[i].class_cde == PREF_COMMON) {
+ orp->common= StringSave(o_name[i].name_txt);
+ break;
+ }
+ }
+
+ /* fill-up synonyms */
+ orp->syn= bldSynValNodes(id, o_name);
+ orp->mod= NULL;
+ orp->db= bldDBId(id);
+ orp->orgname= bldOrgName(id, o_name);
+}
+
+
+static
+ValNodePtr InsertSynonymList( ValNodePtr vnp, CharPtr s )
+{
+
+ if ( vnp == NULL ) {
+ vnp = ValNodeNew(NULL);
+ }
+ else {
+ vnp->next = ValNodeNew(NULL);
+ vnp = vnp->next;
+ }
+
+ vnp->data.ptrvalue = StringSave( s );
+ return( vnp );
+}
+
+OrgRefPtr FsTaxGetRef( int id_tax )
+{
+ OrgRefPtr orp = NULL;
+ ValNodePtr vnp=NULL;
+ CharPtr p, s;
+ DbtagPtr dbtag=NULL;
+ ObjectIdPtr object_id;
+ _taxNamePtr orgName;
+ Int4 id;
+ int new_stile= 0;
+
+ if(id_tax < 0) {
+ id_tax= -id_tax;
+ new_stile= 1;
+ }
+ if(((id= getIdById(id_tax)) == 0) || ((orgName= tax_findOrgName(DBctl, id)) == NULL)) {
+#ifdef WARN_ON_FAILURE
+ ErrPostEx(SEV_WARNING,1,2,"FsTaxGetRef: Not found: <%d>", id_tax);
+#endif
+ return NULL;
+ }
+
+ orp = OrgRefNew();
+ if(new_stile) {
+ bldOrgRef(id, orp);
+ return orp;
+ }
+#if 1
+ orp->mod = NULL;
+ orp->db = ValNodeNew(NULL);
+ orp -> db -> data.ptrvalue = dbtag = DbtagNew();
+ dbtag -> db = StringSave("taxon");
+ dbtag -> tag = object_id = ObjectIdNew();
+ object_id -> str = NULL;
+ object_id -> id = id;
+ orp->taxname = NULL;
+ orp->common = NULL;
+ orp->syn = NULL;
+
+ while(orgName->tax_id == id) {
+ switch(orgName->class_cde) {
+ case CLASS_TXT_SCI :
+ orp->taxname = StringSave(orgName->name_txt);
+ break;
+
+ case CLASS_TXT_COM:
+ orp->common = StringSave(orgName->name_txt);
+ break;
+
+ default:
+ break;
+ }
+ orgName++;
+ }
+#endif
+
+ return orp;
+}
+
+/**************************************************************************
+ *
+ * FsTaxGetLineage
+ *
+ **************************************************************************/
+
+static
+CharPtr s_FsTaxGetLineage(int id_tax)
+{
+ ValNodePtr head=NULL, this=NULL;
+ int len = 2;
+ CharPtr temp, retval = NULL;
+ static Int4 lineage[128];
+ int n, i;
+ Int4 id;
+ _taxNamePtr orgName;
+
+ if((id= getIdById(id_tax)) == 0) {
+#ifdef WARN_ON_FAILURE
+ ErrPostEx(SEV_WARNING,1,2,"s_FsTaxGetLineage: Not found: <%d>", id_tax);
+#endif
+ return NULL;
+ }
+
+ n= tax_getLin(DBctl, id, lineage);
+
+ for(i= 1; i < n; i++) {
+ if((DBctl->tree[lineage[i]].flags & GB_HIDDEN) != 0) continue;
+
+ if((DBctl->tree[lineage[i]].rank >= IsSpeciesRank) && head) break;
+
+ this= ValNodeNew(this);
+ if (head == NULL){
+ head = this;
+ }
+
+ orgName= tax_findOrgName(DBctl, lineage[i]);
+ this->data.ptrvalue= StringSave(orgName->name_txt);
+ len+= StringLen(orgName->name_txt) + 3;
+ }
+
+ /* all data into linked list, now format it */
+ if (len > 2){
+ temp = retval = MemNew(len);
+ for (this = head; this; this = this -> next){
+ if (this != head){
+ temp = StringMove(temp, "; " );
+ }
+ temp = StringMove(temp, this -> data.ptrvalue);
+ }
+ ValNodeFreeData(head);
+ }
+
+ if(retval == NULL) {
+ /* empty lineage */
+ if((orgName= tax_findOrgName(DBctl, id)) != NULL)
+ retval= StringSave(orgName->name_txt);
+ }
+
+ return retval;
+}
+
+
+/**************************************************************************
+ *
+ * FsTaxGetTaxonline
+ *
+ **************************************************************************/
+
+ValNodePtr FsTaxGetTaxonline( int id_tax )
+{
+ ValNodePtr vnp = NULL;
+ char s[255];
+ CharPtr lineage = s_FsTaxGetLineage(id_tax);
+
+ if (lineage != NULL) {
+ if ( * lineage != '\0' ) {
+ vnp = ValNodeNew(NULL);
+ vnp->data.ptrvalue = lineage;
+ }else{
+ MemFree(lineage);
+ }
+ }
+
+ return( vnp );
+}
+
+
+/**************************************************************************
+ *
+ * FsTaxGetWithinDiv
+ *
+ **************************************************************************/
+
+ValNodePtr FsTaxGetWithinDiv( int id_tax )
+{
+ ValNodePtr vnp = NULL;
+ Int4 id;
+ _taxNodePtr node;
+
+ if((id= getIdById(id_tax)) == 0) {
+#ifdef WARN_ON_FAILURE
+ ErrPostEx(SEV_WARNING,1,2,"FsTaxGetWithinDiv: Not found: <%d>", id_tax);
+#endif
+ return NULL;
+ }
+
+ if((node= tax_getNode(DBctl, id)) != NULL) {
+ vnp= ValNodeNew(NULL);
+ vnp->data.ptrvalue= StringSave(tax_getDivById(DBctl, node->division, TAX_DIV_CDE));
+ }
+ return vnp;
+}
+
+/**************************************************************************
+ *
+ * FsTaxGetGeneticCode
+ *
+ **************************************************************************/
+
+GeneticCodeListPtr FsTaxGetGeneticCode( int id_tax )
+{
+ GeneticCodeListPtr gclp = NULL;
+ Int4 id;
+ _taxNodePtr node;
+
+ if((id= getIdById(id_tax)) == 0) {
+#ifdef WARN_ON_FAILURE
+ ErrPostEx(SEV_WARNING,1,2,"FsTaxGetGeneticCode: Not found: <%d>", id_tax);
+#endif
+ return NULL;
+ }
+
+ if((node= tax_getNode(DBctl, id)) != NULL) {
+ gclp= GeneticCodeListNew();
+ gclp->genomic= node->gc;
+ gclp->mitochondrial = node->mgc;
+ }
+
+ return gclp;
+
+}
+
+/**************************************************************************
+ *
+ * SybaseTaxGetComplete
+ *
+
+As Per Jim Ostell, there is a paradigm shift here.
+If a single tax_id can be found for the name, when a
+name is given, then that tax id is used for the lookup,
+else, if zero or multiple tax ids found, it fails.
+
+-Karl 12/8/94
+ **************************************************************************/
+TaxCompleteListPtr FsTaxGetComplete( TaxonIdNamePtr tinp )
+{
+ TaxCompletePtr tcp;
+ TaxCompleteListPtr tclp = NULL;
+ Char name[255];
+ TaxonNamePtr tnp = ValNodeNew(NULL) ;
+ TaxonIdListPtr tilp=NULL;
+ OrgRefPtr orp=NULL;
+ Int4 tax_id = 0;
+ _taxNodePtr node;
+
+
+ if (tinp->choice == TaxonIdName_id) {
+ tax_id= getIdById(tinp->data.intvalue);
+ }
+ else if(tinp->choice == TaxonIdName_name) {
+
+ CopyString( name, (CharPtr)tinp->data.ptrvalue );
+ tnp -> data.ptrvalue = name;
+ tilp= FsTaxGetTaxId( tnp );
+
+ if (tilp)
+ if (tilp->_num_ids == 1) {
+ tax_id= tilp->ids[0];
+ }else{
+ TaxonIdListFree(tilp);
+ return tclp;
+ }
+ TaxonIdListFree(tilp);
+ }else{
+ return tclp;
+ }
+
+ if((node= tax_getNode(DBctl, tax_id)) != NULL) {
+
+ if ( tclp == NULL ) {
+ tclp = TaxCompleteListNew();
+ tclp->num = 0;
+ tclp->info = TaxCompleteNew();
+ tcp = tclp->info;
+ }
+ tclp->num++;
+ tcp->next = NULL;
+
+ tcp->id_gc = node->gc;
+ tcp->id_mgc = node->mgc;
+ tcp->is_species_level= (DBctl->tree[tax_id].rank >= IsSpeciesRank)? 1 : 0;
+
+ tcp->gb_div= StringSave(tax_getDivById(DBctl, node->division, TAX_DIV_CDE));
+ tcp->embl_code= StringSave(node->embl_cde);
+ tcp->name_gc= StringSave(tax_getGCById(DBctl, node->gc, TAX_GC_NM));
+ tcp->name_mgc= StringSave(tax_getGCById(DBctl, node->mgc, TAX_GC_NM));
+
+ orp= FsTaxGetRef( tax_id );
+ if (orp){
+ tcp->sciname = StringSave( orp -> taxname?orp->taxname:"" );
+ tcp->comname = StringSave( orp -> common?orp->common :"");
+ OrgRefFree(orp);
+ }else{
+ }
+ tcp->synonyms = StringSave( "Call Jim Ostell if you need these synonyms" );
+
+ tcp->lineage = s_FsTaxGetLineage(tax_id);
+ }
+ else{
+#ifdef WARN_ON_FAILURE
+ ErrPostEx(SEV_WARNING,1,2,"FsTaxGetComplete: Not found: <%d>", tax_id);
+#endif
+ }
+ return( tclp );
+}
+
+
diff --git a/network/taxon1/server/taxsmain.c b/network/taxon1/server/taxsmain.c
new file mode 100644
index 00000000..c2b200b0
--- /dev/null
+++ b/network/taxon1/server/taxsmain.c
@@ -0,0 +1,320 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: taxsmain.c,v $
+* Revision 6.1 1998/02/19 20:03:04 soussov
+* -z argument added
+*
+* Revision 6.0 1997/08/25 18:42:00 madden
+* Revision changed to 6.0
+*
+* Revision 1.1 1996/05/23 16:55:55 soussov
+* Initial revision
+*
+ * Revision 1.7 1995/05/17 17:58:52 epstein
+ * add RCS log revision history
+ *
+*/
+
+#include <varargs.h>
+#include <ncbi.h>
+#include <ncbinet.h>
+#include <accentr.h>
+#include <objtaxon.h>
+#include <tax_cmmn.h>
+
+TaxonIdListPtr FsTaxGetTaxId( TaxonNamePtr tnp );
+TaxonIdListPtr FsTaxGetParents( int id_tax );
+TaxonIdListPtr FsTaxGetChildren( int id_tax );
+OrgRefPtr FsTaxGetRef( int id_tax );
+ValNodePtr FsTaxGetTaxonline( int id_tax );
+ValNodePtr FsTaxGetWithinDiv( int id_tax );
+GeneticCodeListPtr FsTaxGetGeneticCode( int id_tax );
+TaxCompleteListPtr FsTaxGetComplete( TaxonIdNamePtr tinp );
+
+
+TaxSendResp( Int2 resp_choice, Pointer ptr, AsnIoPtr asnout )
+{
+ Taxon0RespPtr taxbp;
+
+ taxbp = ValNodeNew(NULL);
+ if ( ptr == NULL )
+ {
+ taxbp->choice = Taxon0Resp_error;
+ taxbp->data.intvalue = 0;
+ }
+ else
+ {
+ taxbp->choice = resp_choice;
+ taxbp->data.ptrvalue = ptr;
+ }
+ Taxon0RespAsnWrite( taxbp, asnout, NULL );
+
+ taxbp->data.ptrvalue = NULL;
+ Taxon0RespFree( taxbp );
+}
+
+#define VBUF_SIZ 1024
+
+#ifdef DO_LOGGING
+void
+LOGIT(int va_alist)
+{
+ va_list args;
+ CharPtr message;
+ Char msgstr[VBUF_SIZ];
+ time_t now;
+ Char ctimestr[30];
+
+ MemFill(msgstr, NULL, VBUF_SIZ);
+ va_start(args);
+ message = va_arg(args, CharPtr);
+ if (message != NULL)
+ vsprintf(msgstr, message, args);
+ va_end(args);
+ time (&now);
+ StrCpy (ctimestr, ctime(&now));
+ ctimestr[StrLen(ctimestr) - 1] = '\0'; /* remove trailing newline */
+ fprintf(stderr, "%s : %s\n", ctimestr,msgstr);
+}
+#else
+void
+LOGIT(int va_alist)
+{
+ va_list args;
+ CharPtr message;
+ Char msgstr[VBUF_SIZ];
+ time_t now;
+ Char ctimestr[30];
+
+ va_start(args);
+ va_end(args);
+}
+#endif
+
+
+
+main(int argc, char *argv[])
+{
+ Taxon0ReqPtr taxrp;
+ Taxon0RespPtr taxbp;
+ Boolean debug = FALSE;
+ Boolean filter= FALSE;
+ short erract;
+ ErrDesc err;
+ int arg;
+ NI_HandPtr hp;
+ Char buf[100];
+ AsnIoPtr asnin;
+ AsnIoPtr asnout;
+ int read_timeout;
+ Boolean done = FALSE;
+
+ TaxonIdListPtr tilp;
+ OrgRefPtr orp;
+ ValNodePtr lineage;
+ ValNodePtr within_div;
+ GeneticCodeListPtr gclp;
+ TaxCompleteListPtr tclp;
+ TaxonIdNamePtr tinp;
+ TaxonNamePtr tnp;
+
+ ErrSetFatalLevel(SEV_MAX);
+
+ if (argc > 1)
+ {
+ arg = 1;
+ if (StrCmp(argv[1], "-d") == 0)
+ {
+ arg++;
+ debug = TRUE;
+ }
+ else if(StrCmp(argv[1], "-z") == 0) {
+ arg++;
+ filter= TRUE;
+ }
+ }
+
+ if (getenv("NI_LOCAL_ACCESS_DENIED") != NULL)
+ {
+ if (!debug)
+ NI_ServerNACK("Unauthorized access attempt for Taxonomy server");
+ return -1;
+ }
+
+ LOGIT("Entering InitTaxDB");
+ if (! InitTaxDB() )
+ {
+ LOGIT("InitTaxDB failed");
+
+ if (!debug)
+ NI_ServerNACK("Taxonomy service: Unable to initialize DB");
+ return( -1 );
+ }
+ LOGIT("InitTaxDB OK");
+
+
+ if (!debug) {
+ if(filter) {
+ asnin = AsnIoNew(ASNIO_BIN_IN, stdin, NULL, NULL, NULL);
+ asnout = AsnIoNew(ASNIO_BIN_OUT, stdout, NULL, NULL, NULL);
+ }
+ else {
+ NI_ServerACK();
+
+ hp = NI_OpenASNIO();
+
+ /* this read-timeout is effectively an idle timeout for */
+ /* the server process; the process will terminate upon */
+ /* read-timeout */
+ GetAppParam("NCBI", "NET_SERV", "SERV_INACT_TIMER", "10",
+ buf, sizeof buf);
+ read_timeout = atoi(buf) * 60; /* param is minutes */
+ MsgSetReadTimeout(hp, read_timeout);
+
+ asnin = hp->raip;
+ asnout = hp->waip;
+ }
+ } else {
+ asnin = AsnIoOpen("taxserv.inp", "r");
+ asnout = AsnIoOpen("taxserv.out", "w");
+ }
+
+ while (!done) {
+ /* encountering EOF on reading is a "normal" occurrence, */
+ /* and does not merit an error message */
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err); /* clear any pending error, which can be ignored */
+
+ taxrp = Taxon0ReqAsnRead(asnin, NULL);
+
+ if (ErrFetch(&err))
+ {
+ done = TRUE;
+ ErrPostEx(SEV_ERROR,1,1, "Error encountered on AsnReadId %d", err);
+ break; /* client terminated */
+ }
+ ErrSetOpts(erract, 0);
+
+ if (taxrp == NULL)
+ {
+ done = TRUE;
+ ErrPostEx(SEV_ERROR,1,1, "Null AsnReadId");
+ break; /* client terminated */
+ }
+
+ switch (taxrp->choice) {
+
+ case Taxon0Req_init:
+
+ taxbp = ValNodeNew(NULL);
+ taxbp->choice = Taxon0Resp_init;
+ taxbp->data.ptrvalue = NULL;
+ Taxon0RespAsnWrite (taxbp, asnout, NULL);
+ Taxon0RespFree (taxbp);
+ taxrp->data.ptrvalue = NULL;
+ break;
+
+ case Taxon0Req_getid:
+
+ tnp = (TaxonNamePtr) taxrp->data.ptrvalue;
+ tilp = FsTaxGetTaxId( tnp );
+
+ taxrp->data.ptrvalue = NULL;
+
+ TaxonNameFree( tnp );
+ TaxSendResp( Taxon0Resp_getid, (Pointer) tilp, asnout );
+
+ break;
+
+ case Taxon0Req_getref:
+
+ orp = FsTaxGetRef( taxrp->data.intvalue );
+
+ TaxSendResp( Taxon0Resp_getref, (Pointer) orp, asnout );
+
+ if ( orp != NULL && orp->syn != NULL )
+ orp->syn = ValNodeFree( orp->syn );
+
+ break;
+
+ case Taxon0Req_getchildren:
+
+ tilp = FsTaxGetChildren( taxrp->data.intvalue );
+
+ TaxSendResp( Taxon0Resp_gettaxon, (Pointer) tilp, asnout );
+
+ break;
+
+ case Taxon0Req_getparents:
+
+ tilp = FsTaxGetParents( taxrp->data.intvalue );
+
+ TaxSendResp( Taxon0Resp_gettaxon, (Pointer) tilp, asnout );
+
+ break;
+
+ case Taxon0Req_getgeneticcode:
+
+ gclp = FsTaxGetGeneticCode( taxrp->data.intvalue );
+
+ TaxSendResp( Taxon0Resp_getgeneticcode, (Pointer) gclp, asnout );
+
+ break;
+
+ case Taxon0Req_gettaxonline:
+
+ lineage = FsTaxGetTaxonline( taxrp->data.intvalue );
+
+ TaxSendResp( Taxon0Resp_gettaxonline,
+ (Pointer)(lineage?lineage->data.ptrvalue:""), asnout );
+
+ break;
+
+ case Taxon0Req_getdivision:
+
+ within_div = FsTaxGetWithinDiv( taxrp->data.intvalue );
+
+ TaxSendResp( Taxon0Resp_getdivision,
+ (Pointer) (within_div?within_div->data.ptrvalue:""), asnout );
+
+ break;
+
+ case Taxon0Req_getcomplete:
+
+ tinp = (TaxonIdNamePtr)taxrp->data.ptrvalue;
+ tclp = FsTaxGetComplete( tinp );
+
+ taxrp->data.ptrvalue = NULL;
+
+ TaxSendResp( Taxon0Resp_getcomplete, (Pointer) tclp, asnout );
+
+ TaxonIdNameFree( tinp );
+ TaxCompleteListFree( tclp );
+
+ break;
+
+ case Taxon0Req_fini:
+
+ done = TRUE;
+ taxbp = ValNodeNew(NULL);
+ taxbp->choice = Taxon0Resp_fini;
+ taxbp->data.ptrvalue = NULL;
+
+ Taxon0RespAsnWrite (taxbp, asnout, NULL);
+ Taxon0RespFree (taxbp);
+ taxrp->data.ptrvalue = NULL;
+ break;
+ }
+
+ AsnIoReset (asnout);
+ Taxon0ReqFree (taxrp);
+ }
+
+ CloseTaxDB();
+
+ AsnIoClose (asnin);
+ AsnIoClose (asnout);
+}
diff --git a/network/taxon1/stdalone/division.c b/network/taxon1/stdalone/division.c
new file mode 100644
index 00000000..dad3a17c
--- /dev/null
+++ b/network/taxon1/stdalone/division.c
@@ -0,0 +1,169 @@
+/****************************
+ * File: division.c
+ * Description: taxonomy division functions
+ */
+
+#include <stdlib.h>
+#include "tax_cmmn.h"
+
+/*------------------------------------------------
+ * load_bin - load divisions from binary file
+ */
+static int load_bin(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ int i;
+ _divisionPtr div;
+ int nof_divs= tax_getNofDivs(ctl);
+
+ if(nof_divs < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_DIVS, "load_bin: The number of divisions <= 1");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_DIVS_FILE), "rb")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_bin: Can't open divisions file");
+ return -1;
+ }
+
+ if((div= malloc(sizeof(_division) * nof_divs)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for divisions");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_divs; i++) {
+ div[i].div_id= fsb_getInt2(f);
+ fsb_getBytes(f, 4, div[i].div_cde);
+ div[i].div_txt= fsb_getString(f);
+ div[i].div_comments_txt= fsb_getString(f);
+ }
+
+ ctl->division= div;
+ fclose(f);
+ return 0;
+}
+
+/*---------------------------------------------------
+ * load_txt - load divisions from text file
+ */
+static int load_txt(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ int i;
+ _divisionPtr div;
+ int nof_divs= tax_getNofDivs(ctl);
+ CharPtr tmp;
+
+
+ if(nof_divs < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_RANKS, "load_txt: The number of divisions <= 1");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_DIVS_FILE), "r")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_txt: Can't open divisions file");
+ return -1;
+ }
+
+ if((div= malloc(sizeof(_division) * nof_divs)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_txt: Not enaugh memory for divisions");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_divs; i++) {
+ div[i].div_id= fs_getInt(f, tax_getMarker(ctl));
+ if((tmp= fs_getString(f, tax_getMarker(ctl))) != NULL) {
+ strncpy(div[i].div_cde, tmp, 4);
+ div[i].div_cde[3]= '\0';
+ free(tmp);
+ }
+ div[i].div_txt= fs_getString(f, tax_getMarker(ctl));
+ div[i].div_comments_txt= fs_getString(f, tax_getMarker(ctl));
+ }
+
+ ctl->division= div;
+ fclose(f);
+ return 0;
+}
+
+static int load_asn(_taxDBCtlPtr ctl)
+{
+ return -10; /* not done yet */
+}
+
+/*==============================================================
+ * tax_freeDivs - free division's memory
+ */
+void tax_freeDivs(_taxDBCtlPtr ctl)
+{
+ int nof_divs= tax_getNofDivs(ctl);
+ int i;
+ _divisionPtr div= ctl->division;
+
+ if((div == NULL) || (nof_divs < 1)) return;
+
+ for(i= 0; i != nof_divs; i++) {
+ if(div[i].div_txt != NULL) free(div[i].div_txt);
+ if(div[i].div_comments_txt != NULL) free(div[i].div_comments_txt);
+ }
+ free(div);
+ ctl->division= NULL;
+}
+
+int tax_loadDivs(_taxDBCtlPtr ctl)
+{
+
+ if(ctl->division != NULL) tax_freeDivs(ctl);
+
+ switch(tax_getDbType(ctl)) {
+ case TAX_BIN: return load_bin(ctl);
+ case TAX_TXT: return load_txt(ctl);
+ case TAX_ASN: return load_asn(ctl);
+ default: break;
+ }
+
+ tax_outMsg(TAX_ERROR, TAX_ERR_FILE_TYPE, "tax_loadDivs: Wrong file type for divisions");
+ return -1;
+}
+
+CharPtr tax_getDivById(_taxDBCtlPtr ctl, Int2 id, Int2 mode)
+{
+ int i;
+ _divisionPtr div= ctl->division;
+ int nof_divs= tax_getNofDivs(ctl);
+
+ for(i= 0; i < nof_divs; i++) {
+ if(div[i].div_id == id) {
+ switch(mode) {
+ case TAX_DIV_CDE: return div[i].div_cde;
+ case TAX_DIV_COM: return div[i].div_comments_txt;
+ default: return div[i].div_txt;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+Int2 tax_getDivId(_taxDBCtlPtr ctl, CharPtr txt, Int2 mode)
+{
+ int i;
+ _divisionPtr div= ctl->division;
+ int nof_divs= tax_getNofDivs(ctl);
+
+ for(i= 0; i < nof_divs; i++) {
+ if(mode == TAX_DIV_CDE) {
+ if(StringNICmp(div[i].div_cde, txt, 3) == 0) return div[i].div_id;
+ }
+ else {
+ if(StringICmp(div[i].div_txt, txt) == 0) return div[i].div_id;
+ }
+ }
+ return -1;
+}
+
+
+
+
diff --git a/network/taxon1/stdalone/fs1proc.c b/network/taxon1/stdalone/fs1proc.c
new file mode 100644
index 00000000..5b0b1152
--- /dev/null
+++ b/network/taxon1/stdalone/fs1proc.c
@@ -0,0 +1,1416 @@
+/*----------------*/
+
+#include <stdlib.h>
+#include <ncbi.h>
+#include "taxinc.h"
+#include "tax_cmmn.h"
+#define REALTAXsyb
+
+#define MAX_ORG_LIST 10
+
+#define BUFF_SIZE 16
+#define TAX_READ 0
+#define TAX_WRITE 1
+
+static Int2 VRL_div= 0;
+static Int2 PHG_div= 0;
+
+static _taxDBCtlPtr DBctl= NULL;
+static Int2 SpeciesRank= 26;
+static Int2 SubspeciesRank= 27;
+static Int2 GenusRank= 22;
+static Int2 FamilyRank= 0;
+static Int2 OrderRank= 0;
+static Int2 ClassRank= 0;
+static Int2 SYNONYM= 0;
+static Int2 COMMON_NAME= 0;
+static Int2 PREF_COMMON= 0;
+
+static int my_timer= 0;
+
+static char hit_name[256];
+
+static struct t_or_buff {
+ Int4 tax_id;
+ OrgRefPtr p_org_ref;
+ int timer;
+ char div[16];
+ char embl[4];
+ int is_species;
+} or_buff[BUFF_SIZE];
+
+static CharPtr DB_PATH= "/netopt/genbank/subtool/taxdb/";
+
+static Boolean we_want_synonyms= 0;
+
+Boolean tax1_setSynonyms(Boolean on_off)
+{
+ Boolean ret;
+
+ ret= we_want_synonyms;
+ we_want_synonyms= on_off;
+ return ret;
+}
+
+static void lockBuff(int mode)
+{
+ mode= mode;
+}
+
+static void unlockBuff()
+{
+}
+
+static void initBuff()
+{
+ int i;
+
+ my_timer= 0;
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ or_buff[i].tax_id= 0;
+ or_buff[i].p_org_ref= NULL;
+ }
+}
+
+static Int4 getLiveId(Int4 id)
+{
+ if((DBctl->tree == NULL) || (id < 0) || (id > tax_getMaxId(DBctl))) return 0;
+
+ if(DBctl->tree[id].parent < 1) {
+ /* deleted node */
+ return 0;
+ }
+
+ while(DBctl->tree[id].child == -1) {
+ id=DBctl->tree[id].parent;
+ }
+
+ return id;
+}
+
+static void msgCallBack(int msg_type, int msg_code, CharPtr msg_txt)
+{
+ if(msg_type == TAX_ERROR) {
+ ErrPostEx(SEV_ERROR, 100, msg_code, msg_txt);
+ }
+ else {
+ ErrPostEx(SEV_WARNING, 100, msg_code, msg_txt);
+ }
+}
+
+/**************************************************************************
+ *
+ * InitTaxDB
+ *
+ **************************************************************************/
+
+InitTaxDB()
+{
+ CharPtr tmp;
+
+ if((tmp=getenv("TAXDBPATH")) != NULL) DB_PATH= tmp;
+
+ tax_setMsgHndl(msgCallBack);
+ DBctl= tax_loadDBCtl(DB_PATH, "dbctl.tax");
+ if(DBctl == NULL) return 0;
+ if(tax_loadClasses(DBctl) || tax_loadRanks(DBctl) || tax_loadDivs(DBctl) ||
+ tax_loadGCs(DBctl) || tax_loadTree(DBctl) || tax_loadNames(DBctl)) {
+ return 0;
+ }
+
+ tax_getNode(DBctl, -1);
+
+ SpeciesRank= tax_getRankId(DBctl, "species");
+ SubspeciesRank= tax_getRankId(DBctl, "subspecies");
+ GenusRank= tax_getRankId(DBctl, "genus");
+ FamilyRank= tax_getRankId(DBctl, "family");
+ OrderRank= tax_getRankId(DBctl, "order");
+ ClassRank= tax_getRankId(DBctl, "class");
+
+
+ VRL_div= tax_getDivId(DBctl, "VRL", TAX_DIV_CDE);
+ PHG_div= tax_getDivId(DBctl, "PHG", TAX_DIV_CDE);
+
+ SYNONYM= tax_getClassId(DBctl, "synonym");
+ COMMON_NAME= tax_getClassId(DBctl, "common name");
+ PREF_COMMON= tax_getClassId(DBctl, "preferred common name");
+ initBuff();
+ return 1;
+}
+
+/**************************************************************************
+ *
+ * CloseTaxDB
+ *
+ **************************************************************************/
+
+CloseTaxDB()
+{
+ int i;
+
+ if(DBctl != NULL) {
+ tax_freeNames(DBctl);
+ tax_freeTree(DBctl);
+ tax_freeGCs(DBctl);
+ tax_freeDivs(DBctl);
+ tax_freeClasses(DBctl);
+ tax_freeRanks(DBctl);
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if(or_buff[i].p_org_ref != NULL) {
+ OrgRefFree(or_buff[i].p_org_ref);
+ }
+ }
+ }
+}
+
+
+
+/*************************************************************************/
+/* return pointer to first non-blank character in str1 after prefix str2 */
+/* if str2 is not prefix for str1 then return str1 */
+/*************************************************************************/
+static CharPtr strTail(CharPtr str1, CharPtr str2)
+{
+ CharPtr c;
+
+ if(StringStr(str1, str2) != str1) return str1;
+
+ c= str1 + StringLen(str2);
+
+ while((*c != '\0') && IS_WHITESP(*c)) c++;
+
+ return c;
+}
+
+static OrgModPtr bldOrgMod(Int4 id, _taxNamePtr o_name)
+{
+ Int4 p_id;
+ Int2 rank;
+ _taxNamePtr parent;
+ OrgModPtr orgMdf= OrgModNew();
+ CharPtr name= o_name->name_txt;
+
+ for(p_id= DBctl->tree[id].parent; p_id > 1; p_id= DBctl->tree[p_id].parent) {
+ rank= DBctl->tree[p_id].rank;
+ if((rank == SubspeciesRank) ||
+ (rank == SpeciesRank) ||
+ (rank == GenusRank)) break;
+ }
+
+ parent= (p_id > 1)? tax_findOrgName(DBctl, p_id) : NULL;
+
+ if(parent != NULL) {
+ orgMdf->subname= StringSave(strTail(name, parent->name_txt));
+ }
+ else {
+ orgMdf->subname= StringSave(name);
+ }
+
+ rank= DBctl->tree[id].rank;
+
+ if(rank == SubspeciesRank) {
+ orgMdf->subtype= 22; /* subspecies */
+ }
+ else if(rank == tax_getRankId(DBctl, "varietas")) {
+ orgMdf->subtype= 6; /* variety */
+ }
+ else if(rank == tax_getRankId(DBctl, "forma")) {
+ orgMdf->subtype= 2; /* strain */
+ }
+ else if((parent != NULL) && (DBctl->tree[p_id].rank == SubspeciesRank)) {
+ orgMdf->subtype= 2; /* strain */
+ }
+ else {
+ orgMdf->subtype= 255; /* other */
+ }
+
+ orgMdf->attrib= NULL;
+
+ return orgMdf;
+}
+
+
+/***************************************************************/
+/* if name is binomial name build the correspondent structures */
+/* otherwise return 0 */
+/***************************************************************/
+static int binomialName(Int4 id, _taxNamePtr o_name, OrgNamePtr onp)
+{
+ int i;
+ Int4 genusId= 0;
+ Int4 speciesId= 0;
+ Int4 subspeciesId= 0;
+ Int4 p_id;
+ Int2 rank;
+ BinomialOrgNamePtr bName;
+ _taxNamePtr genus, species, subspecies;
+
+
+ for(p_id= id; p_id > 1; p_id= DBctl->tree[p_id].parent) {
+ rank= DBctl->tree[p_id].rank;
+ if(rank == SpeciesRank) speciesId= p_id;
+ else if(rank == SubspeciesRank) subspeciesId= p_id;
+ else if(rank == GenusRank) genusId= p_id;
+ }
+
+ if(genusId == 0) {
+ /* try to find subgenus if genus anavalable */
+ for(p_id= id; p_id > 1; p_id= DBctl->tree[p_id].parent) {
+ if(DBctl->tree[p_id].rank == (GenusRank + 1)) genusId= p_id;
+ }
+ }
+
+ genus= (genusId == 0)? NULL : tax_findOrgName(DBctl, genusId);
+ species= (speciesId == 0)? NULL : tax_findOrgName(DBctl, speciesId);
+ subspecies= (subspeciesId == 0)? NULL : tax_findOrgName(DBctl, subspeciesId);
+
+ if(genus == NULL) return 0; /* no genus - no binomial */
+
+ onp->choice= 1; /*binomial*/
+
+ onp->data= bName= BinomialOrgNameNew();
+
+ bName->genus= StringSave(genus->name_txt);
+
+ if(species != NULL) {
+ /* we have a species in lineage */
+ bName->species= StringSave(strTail(species->name_txt, genus->name_txt));
+ if(subspecies != NULL) {
+ /* we also have a subspecies in lineage */
+ bName->subspecies= StringSave(strTail(subspecies->name_txt, species->name_txt));
+ }
+ else {
+ bName->subspecies= NULL;
+ }
+ onp->mod= (id == speciesId)? NULL : bldOrgMod(id, o_name);
+ return 1;
+ }
+
+ /* no species in lineage */
+
+ if(subspecies != NULL) {
+ /* we have no species but we have subspecies */
+ bName->species= NULL;
+ bName->subspecies= StringSave(strTail(subspecies->name_txt, genus->name_txt));
+ onp->mod= bldOrgMod(id, o_name);
+ return 1;
+ }
+
+ /* we have no species, no subspecies but we are under species level (varietas or forma) */
+
+ bName->species= NULL;
+ bName->subspecies= NULL;
+ onp->mod= bldOrgMod(id, o_name);
+ return 1;
+}
+
+
+static void partialName(Int4 id, _taxNamePtr o_name, OrgNamePtr onp)
+{
+
+ TaxElementPtr taxElem;
+ Int2 rank_id= DBctl->tree[id].rank;
+
+ onp->choice= 5; /* partial */
+ onp->data= taxElem= TaxElementNew();
+
+ if(rank_id == FamilyRank) {
+ taxElem->fixed_level= 1; /* family */
+ taxElem->level= NULL;
+ }
+ else if(rank_id == OrderRank) {
+ taxElem->fixed_level= 2;
+ taxElem->level= NULL;
+ }
+ else if(rank_id == ClassRank) {
+ taxElem->fixed_level= 3;
+ taxElem->level= NULL;
+ }
+ else {
+ taxElem->fixed_level= 0;
+ taxElem->level= StringSave(tax_getRankById(DBctl, rank_id));
+ }
+
+ taxElem->name= StringSave(o_name->name_txt);
+ taxElem->next= NULL;
+}
+
+
+/*****************************************************************
+ * build synonyms valnodes
+ * this routine include in valnodes synonyms and common synonyms
+ */
+static ValNodePtr bldSynValNodes(Int4 id, _taxNamePtr syn)
+{
+ ValNodePtr list= NULL;
+ ValNodePtr header= NULL;
+ int i;
+
+ for(i= 0; syn[i].tax_id == id; i++) {
+ if((syn[i].class_cde == SYNONYM) || (syn[i].class_cde == COMMON_NAME)) {
+ list= ValNodeNew(list);
+ list->choice= (syn[i].class_cde == SYNONYM)? 1 : 0;
+ list->data.ptrvalue= StringSave(syn[i].name_txt);
+ if(header == NULL) header= list;
+ }
+ }
+ return header;
+}
+
+
+/**************************************************************************
+ *
+ * FsTaxGetLineage
+ *
+ **************************************************************************/
+
+static CharPtr bldLineage(Int4 id)
+{
+ ValNodePtr head=NULL, this=NULL;
+ int len = 2;
+ CharPtr temp, retval = NULL;
+ Int4 lineage[64];
+ int n, i;
+ _taxNamePtr orgName;
+
+ n= tax_getLin(DBctl, id, lineage);
+
+ for(i= 1; i < n; i++) {
+ if((DBctl->tree[lineage[i]].flags & GB_HIDDEN) != 0) continue;
+
+ if((DBctl->tree[lineage[i]].rank >= SpeciesRank) && head) break;
+
+ this= ValNodeNew(this);
+ if (head == NULL){
+ head = this;
+ }
+
+ if((orgName= tax_findOrgName(DBctl, lineage[i])) != NULL) {
+ this->data.ptrvalue= StringSave(orgName->name_txt);
+ len+= StringLen(orgName->name_txt) + 3;
+ }
+ else {
+ ErrPostEx(SEV_ERROR, 100, lineage[i], "Error in taxonomy lineage");
+ }
+ }
+
+ /* all data into linked list, now format it */
+ if (len > 2){
+ temp = retval = MemNew(len);
+ for (this = head; this; this = this -> next){
+ if (this != head){
+ temp = StringMove(temp, "; " );
+ }
+ temp = StringMove(temp, this -> data.ptrvalue);
+ }
+ ValNodeFreeData(head);
+ }
+
+ if(retval == NULL) {
+ /* empty lineage */
+ if((orgName= tax_findOrgName(DBctl, id)) != NULL)
+ retval= StringSave(orgName->name_txt);
+ }
+
+ return retval;
+}
+
+
+static ValNodePtr bldDBId(Int4 id)
+{
+ ValNodePtr dbnode;
+ DbtagPtr dbtag;
+ ObjectIdPtr object_id;
+
+ /* populate tax_id */
+ dbnode= ValNodeNew(NULL);
+ dbnode->data.ptrvalue= dbtag= DbtagNew();
+ dbtag->db = StringSave("taxon");
+ dbtag->tag= object_id= ObjectIdNew();
+ object_id->str= NULL;
+ object_id->id = id;
+ return dbnode;
+}
+
+static OrgNamePtr bldOrgName(Int4 id, _taxNamePtr o_name, int* is_species_out, CharPtr div, CharPtr embl)
+{
+ OrgNamePtr onp;
+ _taxNodePtr node;
+ Int2 rank_id= DBctl->tree[id].rank;
+ int is_species;
+ Int4 p_id, s_id;
+ CharPtr div_abbr;
+ Int2 div_id;
+ _taxNamePtr s_name;
+
+ onp= OrgNameNew();
+ node= tax_getNode(DBctl, id);
+ if(node == NULL) return NULL;
+
+ onp->gcode= node->gc;
+ onp->mgcode= node->mgc;
+ onp->lineage= bldLineage(id);
+ if(embl != NULL) StringCpy(embl, ""/*node->embl_cde*/);
+
+ is_species= (rank_id >= SpeciesRank)? 1 : 0;
+ /* correct level by lineage if node has no rank */
+ if(rank_id < 0) {
+ p_id= id;
+ while(p_id > 1) {
+ p_id= DBctl->tree[p_id].parent;
+ if(DBctl->tree[p_id].rank >= SpeciesRank) {
+ is_species= 1;
+ break;
+ }
+ }
+ }
+
+ div_id= node->division;
+ tax_freeNode(node);
+ onp->div= StringSave(tax_getDivById(DBctl, div_id, TAX_DIV_CDE));
+ StringCpy(div, tax_getDivById(DBctl, div_id, TAX_DIV_CDE));
+ *is_species_out= is_species;
+
+ if(is_species) {
+ /* we are on species level or below */
+
+ /* check for viruses */
+ if((div_id == VRL_div) || (div_id == PHG_div)) {
+ /* this is a virus */
+ onp->choice= 2; /* virus */
+ if(rank_id == SpeciesRank) {
+ /* we are on species level */
+ onp->data= StringSave(o_name->name_txt);
+ onp->mod= NULL;
+ }
+ else {
+ /* we are below species */
+ /* first try to find species or min rank which below species but above us */
+ p_id= id; s_id= 0;
+ while(p_id > 1) {
+ p_id= DBctl->tree[p_id].parent;
+ if(DBctl->tree[p_id].rank == SpeciesRank) break;
+ else if(DBctl->tree[p_id].rank > SpeciesRank) s_id= p_id;
+ }
+ if(p_id <= 1) p_id= s_id;
+
+ if(p_id > 1) {
+ /* we below species but we have species above us */
+ s_name= tax_findOrgName(DBctl, p_id);
+ if(s_name != NULL) {
+ onp->data= StringSave(s_name->name_txt);
+ onp->mod= bldOrgMod(id, o_name);
+ }
+ }
+ else {
+ /* we probably below species but no species above us */
+ onp->data= StringSave(o_name->name_txt);
+ onp->mod= bldOrgMod(id, o_name);
+ }
+ }
+ }
+ else if(!binomialName(id, o_name, onp)) {
+ /* name is not binomial: set partial */
+ partialName(id, o_name, onp);
+ }
+ }
+ else {
+ /* above species */
+ partialName(id, o_name, onp);
+ }
+
+ return onp;
+}
+
+
+static void bldOrgRef(Int4 id, OrgRefPtr orp, int* is_species, CharPtr div, CharPtr embl)
+{
+ _taxNamePtr o_name;
+ int i;
+
+ *is_species= 0;
+ *div= *embl= '\0';
+ o_name= tax_findOrgName(DBctl, id);
+ if(o_name == NULL) return;
+ orp->taxname= StringSave(o_name->name_txt);
+
+ /* fill-up preferred common name */
+ orp->common= NULL;
+ for(i= 1; o_name[i].tax_id == id; i++) {
+ if(o_name[i].class_cde == PREF_COMMON) {
+ orp->common= StringSave(o_name[i].name_txt);
+ break;
+ }
+ }
+
+ /* fill-up synonyms */
+ orp->syn= bldSynValNodes(id, o_name);
+ orp->mod= NULL;
+ orp->db= bldDBId(id);
+ orp->orgname= bldOrgName(id, o_name, is_species, div, embl);
+}
+
+
+static void loadInBuff(Int4 id)
+{
+ int i, k= -1;
+ Int4 t= my_timer + 1;
+ Int4 bt;
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if(or_buff[i].tax_id == 0) {
+ k= i;
+ break;
+ }
+ if(or_buff[i].timer < t) {
+ t= or_buff[i].timer;
+ k= i;
+ }
+ }
+
+ if(k >= 0) {
+ if(or_buff[k].p_org_ref != NULL) OrgRefFree(or_buff[k].p_org_ref);
+ or_buff[k].tax_id= id;
+ or_buff[k].p_org_ref= OrgRefNew();
+ or_buff[k].timer= ++my_timer;
+ bldOrgRef(id, or_buff[k].p_org_ref, &or_buff[k].is_species, or_buff[k].div, or_buff[k].embl);
+ }
+}
+
+static OrgRefPtr getFromBuff(Int4 id, int* is_sp, CharPtr div, CharPtr embl)
+{
+ int i;
+ OrgRefPtr orp= NULL;
+
+ lockBuff(TAX_READ);
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if(or_buff[i].tax_id == id) {
+ or_buff[i].timer= ++my_timer;
+ orp= or_buff[i].p_org_ref;
+ if(is_sp != NULL) *is_sp= or_buff[i].is_species;
+ if(div != NULL) StringCpy(div, or_buff[i].div);
+ if(embl != NULL) StringCpy(embl, ""/*or_buff[i].embl*/);
+ break;
+ }
+ }
+ unlockBuff();
+ return orp;
+}
+
+OrgRefPtr tax1_getOrgRef(Int4 tax_id, int* is_species, CharPtr div, CharPtr embl_cde)
+{
+ OrgRefPtr orp;
+
+ tax_id= getLiveId(tax_id);
+ if(tax_id == 0) return NULL;
+
+ if((orp= getFromBuff(tax_id, is_species, div, embl_cde)) != NULL) {
+ /* OrgRef is already in buffer */
+ return orp;
+ }
+
+ lockBuff(TAX_WRITE);
+ loadInBuff(tax_id);
+ unlockBuff();
+
+ return getFromBuff(tax_id, is_species, div, embl_cde);
+}
+
+/***************************************************
+ * Get tax_id by organism name
+ * returns:
+ * tax_id if one node found
+ * 0 no organism found
+ * -tax_id if more than one node found
+ */
+Int4 tax1_getTaxIdByName(CharPtr orgname)
+{
+ int n, i, j, f;
+ Int4 tax_id, spec_id;
+ _taxNamePtr* nameList;
+
+#if 0
+ if((n= tax_findByName(DBctl, orgname, TAX_NAME_SEARCH, &nameList)) == 0) {
+ /* do not find exact name */
+ if((n= tax_findByName(DBctl, orgname, TAX_RE_SEARCH, &nameList)) == 0) {
+ /* do not find again */
+ if((n= tax_findByName(DBctl, orgname, TAX_TOKEN_SEARCH, &nameList)) == 0) {
+ /* no such name */
+ return 0;
+ }
+ }
+ }
+#else
+ if((n= tax_findByName(DBctl, orgname, TAX_NAME_SEARCH, &nameList)) == 0) {
+ return 0;
+ }
+#endif
+
+ tax_id= nameList[0]->tax_id;
+ for(i= 1; i < n; i++) {
+ if(tax_id != nameList[i]->tax_id) {
+ tax_id= tax_getDesignator(orgname);
+ break;
+ }
+ }
+
+ if(tax_id == 0) {
+ /* try to find species */
+ tax_id= nameList[0]->tax_id;
+ spec_id= (DBctl->tree[tax_id].rank == SpeciesRank)? tax_id : 0;
+ for(i= 1; i < n; i++) {
+ if(tax_id != nameList[i]->tax_id) {
+ tax_id= nameList[i]->tax_id;
+ if(DBctl->tree[tax_id].rank == SpeciesRank) {
+ if(spec_id == 0) spec_id= tax_id;
+ else if(spec_id != tax_id) {
+ spec_id= -spec_id;
+ break;
+ }
+ }
+ }
+ }
+ tax_id= (spec_id == 0)? -nameList[0]->tax_id : spec_id;
+ }
+
+
+ MemFree(nameList);
+ StringNCpy(hit_name, orgname, 256);
+ return tax_id;
+}
+
+
+/***************************************************
+ * Get all tax_id by organism name
+ * returns:
+ * Number of tax ids found
+ */
+Int4 tax1_getAllTaxIdByName(CharPtr orgname, Int4 **Ids_out)
+{
+ int n, i, j, f;
+ _taxNamePtr* nameList;
+ Int4 *Ids;
+
+#if 0
+ if((n= tax_findByName(DBctl, orgname, TAX_NAME_SEARCH, &nameList)) == 0) {
+ /* do not find exact name */
+ if((n= tax_findByName(DBctl, orgname, TAX_RE_SEARCH, &nameList)) == 0) {
+ /* do not find again */
+ if((n= tax_findByName(DBctl, orgname, TAX_TOKEN_SEARCH, &nameList)) == 0) {
+ /* no such name */
+ *Ids_out= NULL;
+ return 0;
+ }
+ }
+ }
+#else
+ if((n= tax_findByName(DBctl, orgname, TAX_NAME_SEARCH, &nameList)) == 0) {
+ *Ids_out= NULL;
+ return 0;
+ }
+#endif
+
+ *Ids_out= Ids= MemNew(n*sizeof(Int4));
+
+ Ids[0]= nameList[0]->tax_id;
+ j= 0;
+ for(i= 1; i < n; i++) {
+ if(Ids[j] != nameList[i]->tax_id) {
+ Ids[++j]= nameList[i]->tax_id;
+ }
+ }
+
+ MemFree(nameList);
+ return ++j;
+}
+
+/***************************************************
+ * Get tax_id by organism name
+ * returns:
+ * tax_id if one node found
+ * 0 no organism found
+ * -tax_id if more than one node found
+ */
+Int4 tax1_findTaxIdByName(CharPtr orgname)
+{
+ int n, i, j, f;
+ Int4 tax_id, spec_id;
+ _taxNamePtr* nameList;
+
+#if 1
+ if((n= tax_findByName(DBctl, orgname, TAX_ALPHANUM_SEARCH, &nameList)) == 0) {
+ CharPtr tail;
+ if((tail= StringChr(orgname, '<')) != NULL) {
+ *tail= '\0';
+ if((n= tax_findByName(DBctl, orgname, TAX_ALPHANUM_SEARCH, &nameList)) != NULL) {
+ *tail= '<';
+ for(i= 0; i < n; i++) {
+ if((nameList[i]->unique_name != NULL) &&
+ (StringICmp(nameList[i]->unique_name, orgname) == 0)) {
+ tax_id= nameList[i]->tax_id;
+ StringNCpy(hit_name, orgname, 256);
+ return tax_id;
+ }
+ }
+ }
+ *tail= '<';
+ return 0;
+ }
+ /* do not find exact name */
+ if((n= tax_findByName(DBctl, orgname, TAX_RE_SEARCH, &nameList)) == 0) {
+ /* do not find again */
+ if((n= tax_findByName(DBctl, orgname, TAX_TOKEN_SEARCH, &nameList)) == 0) {
+ /* no such name */
+ return 0;
+ }
+ }
+ }
+#else
+ if((n= tax_findByName(DBctl, orgname, TAX_NAME_SEARCH, &nameList)) == 0) {
+ return 0;
+ }
+#endif
+
+ tax_id= nameList[0]->tax_id;
+ for(i= 1; i < n; i++) {
+ if(tax_id != nameList[i]->tax_id) {
+ tax_id= tax_getDesignator(orgname);
+ break;
+ }
+ }
+
+ if(tax_id == 0) {
+ /* try to find species */
+ tax_id= nameList[0]->tax_id;
+ spec_id= (DBctl->tree[tax_id].rank == SpeciesRank)? tax_id : 0;
+ for(i= 1; i < n; i++) {
+ if(tax_id != nameList[i]->tax_id) {
+ tax_id= nameList[i]->tax_id;
+ if(DBctl->tree[tax_id].rank == SpeciesRank) {
+ if(spec_id == 0) spec_id= tax_id;
+ else if(spec_id != tax_id) {
+ spec_id= -spec_id;
+ break;
+ }
+ }
+ }
+ }
+ tax_id= (spec_id == 0)? -nameList[0]->tax_id : spec_id;
+ }
+
+
+ MemFree(nameList);
+ StringNCpy(hit_name, orgname, 256);
+ return tax_id;
+}
+
+
+/***************************************************
+ * Get all tax_id by organism name
+ * returns:
+ * Number of tax ids found
+ */
+Int4 tax1_findAllTaxIdByName(CharPtr orgname, Int4 **Ids_out)
+{
+ int n, i, j, f;
+ _taxNamePtr* nameList;
+ Int4 *Ids;
+
+#if 1
+ if((n= tax_findByName(DBctl, orgname, TAX_ALPHANUM_SEARCH, &nameList)) == 0) {
+ CharPtr tail;
+ if((tail= StringChr(orgname, '<')) != NULL) {
+ *tail= '\0';
+ if((n= tax_findByName(DBctl, orgname, TAX_ALPHANUM_SEARCH, &nameList)) != NULL) {
+ *tail= '<';
+ for(i= 0; i < n; i++) {
+ if((nameList[i]->unique_name != NULL) &&
+ (StringICmp(nameList[i]->unique_name, orgname) == 0)) {
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= nameList[i]->tax_id;
+ return 1;
+ }
+ }
+ }
+ *tail= '<';
+ *Ids_out= NULL;
+ return 0;
+ }
+ /* do not find exact name */
+ if((n= tax_findByName(DBctl, orgname, TAX_RE_SEARCH, &nameList)) == 0) {
+ /* do not find again */
+ if((n= tax_findByName(DBctl, orgname, TAX_TOKEN_SEARCH, &nameList)) == 0) {
+ /* no such name */
+ *Ids_out= NULL;
+ return 0;
+ }
+ }
+ }
+#else
+ if((n= tax_findByName(DBctl, orgname, TAX_NAME_SEARCH, &nameList)) == 0) {
+ *Ids_out= NULL;
+ return 0;
+ }
+#endif
+
+ *Ids_out= Ids= MemNew(n*sizeof(Int4));
+
+ Ids[0]= nameList[0]->tax_id;
+ j= 0;
+ for(i= 1; i < n; i++) {
+ if(Ids[j] != nameList[i]->tax_id) {
+ Ids[++j]= nameList[i]->tax_id;
+ }
+ }
+
+ MemFree(nameList);
+ return ++j;
+}
+
+static CharPtr getSearchName(OrgModPtr omp)
+{
+ while(omp != NULL) {
+ if(omp->subtype == 254) {
+ return omp->subname;
+ }
+ omp= omp->next;
+ }
+ return NULL;
+}
+
+Int4 tax1_getTaxIdByOrgRef(OrgRefPtr orgRef)
+{
+ Int4 tax_id, id;
+ ValNodePtr synonym;
+ CharPtr search_name;
+
+ tax_id= id= 0;
+ if((orgRef->orgname != NULL) && (orgRef->orgname->mod != NULL) &&
+ ((search_name= getSearchName(orgRef->orgname->mod)) != NULL)) {
+ tax_id= tax1_getTaxIdByName(search_name);
+ if(tax_id > 0) return tax_id;
+ else tax_id = 0;
+ }
+
+ if(orgRef->taxname != NULL) tax_id= tax1_getTaxIdByName(orgRef->taxname);
+ if(tax_id > 0) return tax_id;
+ if(orgRef->common != NULL) id= tax1_getTaxIdByName(orgRef->common);
+ if(id > 0) return id;
+
+ if(tax_id == 0) tax_id= id;
+
+ if(orgRef->syn != NULL) {
+ id= 0;
+
+ for(synonym= orgRef->syn; (synonym != NULL) && (id < 1); synonym= synonym->next) {
+ id= tax1_getTaxIdByName(synonym->data.ptrvalue);
+ }
+ }
+
+ return (id > 0)? id : tax_id;
+
+}
+
+static void cleanOrgName(OrgNamePtr onp)
+{
+ if(onp->lineage != NULL) MemFree(onp->lineage);
+ if(onp->div != NULL) MemFree(onp->div);
+#if 0
+ /* #if 0 means that we will trust to initial modifier */
+ if(onp->mod != NULL) OrgModSetFree(onp->mod);
+#endif
+ if(onp->next != NULL) OrgNameSetFree(onp->next);
+ if(onp->data != NULL) {
+ switch(onp->choice) {
+ case 1: /* binomial name */
+ BinomialOrgNameFree(onp->data);
+ break;
+ case 2: /* virus name */
+ MemFree(onp->data);
+ break;
+ case 5: /* partial name */
+ TaxElementSetFree(onp->data);
+ break;
+ }
+ }
+}
+
+
+static BinomialOrgNamePtr copyBinomial(BinomialOrgNamePtr src)
+{
+ BinomialOrgNamePtr dst;
+
+ if(src == NULL) return NULL;
+
+ dst= BinomialOrgNameNew();
+ dst->genus= (src->genus != NULL)? StringSave(src->genus) : NULL;
+ dst->species= (src->species != NULL)? StringSave(src->species) : NULL;
+ dst->subspecies= (src->subspecies != NULL)? StringSave(src->subspecies) : NULL;
+
+ return dst;
+}
+
+static TaxElementPtr copyPartial(TaxElementPtr src)
+{
+ TaxElementPtr dst;
+
+ if(src == NULL) return NULL;
+
+ dst= TaxElementNew();
+ dst->fixed_level= src->fixed_level;
+ dst->level= (src->level != NULL)? StringSave(src->level) : NULL;
+ dst->name= (src->name != NULL)? StringSave(src->name) : NULL;
+ dst->next= (src->next != NULL)? copyPartial(src->next) : NULL;
+ return dst;
+}
+
+static OrgModPtr copyOrgMod(OrgModPtr src)
+{
+#if 0
+ OrgModPtr dst;
+
+ if(src == NULL) return NULL;
+
+ dst= OrgModNew();
+ dst->subtype= src->subtype;
+ dst->subname= (src->subname != NULL)? StringSave(src->subname) : NULL;
+ dst->attrib= (src->attrib != NULL)? StringSave(src->attrib) : NULL;
+ dst->next= (src->next != NULL)? copyOrgMod(src->next) : NULL;
+
+ return dst;
+#endif
+ return NULL;
+}
+
+static ValNodePtr removeDbtag(ValNodePtr vnp)
+{
+ ValNodePtr vnn, vnf, vnl= NULL;
+ DbtagPtr dbtag;
+
+ for(vnf= vnp; vnp != NULL; vnp= vnn) {
+ dbtag= vnp->data.ptrvalue;
+ vnn= vnp->next;
+ if(dbtag == NULL) return NULL;
+ if(StringCmp(dbtag->db, "taxon") == 0) {
+ /* taxon tag, remove it */
+ if(vnl == NULL) {
+ vnf= vnn;
+ }
+ else {
+ vnl->next= vnn;
+ }
+ DbtagFree(dbtag);
+ MemFree(vnp);
+ }
+ else {
+ vnl= vnp;
+ }
+ }
+ return vnf;
+}
+
+
+static void bldOrgRefOut(OrgRefPtr dst, OrgRefPtr src, Int4 tax_id)
+{
+ ValNodePtr vnp, vnl;
+ DbtagPtr dbtag;
+ ObjectIdPtr object_id;
+ OrgNamePtr onp;
+
+ dst->taxname= StringSave(src->taxname);
+ dst->common= (src->common != NULL)? StringSave(src->common) : NULL;
+
+ /* populate tax_id */
+ vnp= ValNodeNew(NULL);
+ if (dst->db != NULL) {
+ dst->db= removeDbtag(dst->db);
+ }
+ vnp->next= dst->db;
+ dst->db= vnp;
+ vnp->data.ptrvalue= dbtag= DbtagNew();
+ dbtag->db = StringSave("taxon");
+ dbtag->tag= object_id= ObjectIdNew();
+ object_id->str= NULL;
+ object_id->id = getLiveId(tax_id);
+
+ /* copy the synonym list */
+ dst->syn= NULL; vnl= NULL;
+ if(we_want_synonyms) {
+ for(vnp= src->syn; vnp != NULL; vnp= vnp->next) {
+ vnl= ValNodeNew(vnl);
+ vnl->choice= vnp->choice;
+ vnl->data.ptrvalue= StringSave(vnp->data.ptrvalue);
+ if(dst->syn == NULL) dst->syn= vnl;
+ }
+ }
+
+ /* copy orgname */
+ if(dst->orgname == NULL) dst->orgname= onp= OrgNameNew();
+ else onp= dst->orgname;
+
+ onp->choice= src->orgname->choice;
+
+ switch(src->orgname->choice) {
+ case 1: /*binomial*/
+ onp->data= copyBinomial(src->orgname->data);
+ break;
+ case 2: /* virus */
+ onp->data= (src->orgname->data != NULL)? StringSave(src->orgname->data) : NULL;
+ break;
+ case 5: /* partial */
+ onp->data= copyPartial(src->orgname->data);
+ break;
+ default: /* can't handle */
+ onp->data= NULL;
+ }
+
+ if(onp->mod == NULL) onp->mod= copyOrgMod(src->orgname->mod);
+ onp->lineage= (src->orgname->lineage != NULL)? StringSave(src->orgname->lineage) : NULL;
+ onp->gcode= src->orgname->gcode;
+ onp->mgcode= src->orgname->mgcode;
+ onp->div= StringSave(src->orgname->div);
+}
+
+static void populateReplaced(OrgRefPtr orp, CharPtr oldName)
+{
+ OrgNamePtr onp;
+ OrgModPtr omp;
+
+ if((orp->taxname != NULL) && (StringICmp(orp->taxname, oldName) == 0)) return;
+ if((orp->common != NULL) && (StringICmp(orp->common, oldName) == 0)) return;
+
+ /* organism name was changed */
+ onp= orp->orgname;
+ if((onp != NULL) && (getSearchName(onp->mod) == NULL)) {
+ omp= OrgModNew();
+ omp->next= onp->mod;
+ omp->subtype= 254;
+ omp->subname= StringSave(oldName);
+ onp->mod= omp;
+ }
+}
+
+Taxon1DataPtr tax1_lookup(OrgRefPtr inp_orgRef, int merge)
+{
+ Taxon1DataPtr res;
+ Int4 tax_id;
+ OrgRefPtr db_orgRef;
+ int is_species;
+
+ tax_id= tax1_getTaxIdByOrgRef(inp_orgRef);
+ if(tax_id <= 0) return NULL;
+ res= Taxon1DataNew();
+ res->div= MemNew(16);
+ res->embl_code= MemNew(4);
+ db_orgRef= tax1_getOrgRef(tax_id, &is_species, res->div, NULL /*res->embl_code*/);
+ res->embl_code[0]= '\0';
+ if(db_orgRef == NULL) {
+ Taxon1DataFree(res);
+ return NULL;
+ }
+
+ res->is_species_level= is_species;
+ if(merge) {
+ /* we have to merge old orgref with new one */
+ res->org= inp_orgRef;
+ /* clean-up old information */
+ if(inp_orgRef->taxname != NULL) MemFree(inp_orgRef->taxname);
+ if(inp_orgRef->common != NULL) MemFree(inp_orgRef->common);
+ if(inp_orgRef->syn != NULL) ValNodeFreeData(inp_orgRef->syn);
+ if(inp_orgRef->orgname != NULL) cleanOrgName(inp_orgRef->orgname);
+ }
+ else {
+ /* make new orgref */
+ res->org= OrgRefNew();
+ res->org->db= NULL;
+ res->org->orgname= NULL;
+ }
+ /* fill-up orgref based on db_orgRef */
+ bldOrgRefOut(res->org, db_orgRef, tax_id);
+ populateReplaced(res->org, hit_name);
+ return res;
+}
+
+
+Taxon1DataPtr tax1_getbyid(Int4 tax_id)
+{
+ Taxon1DataPtr res;
+ OrgRefPtr db_orgRef;
+ int is_species;
+
+ if(tax_id <= 0) return NULL;
+ res= Taxon1DataNew();
+ res->div= MemNew(16);
+ res->embl_code= MemNew(4);
+ db_orgRef= tax1_getOrgRef(tax_id, &is_species, res->div, NULL/*res->embl_code*/);
+ res->embl_code[0]= '\0';
+ if(db_orgRef == NULL) {
+ Taxon1DataFree(res);
+ return NULL;
+ }
+
+ /* make new orgref */
+ res->org= OrgRefNew();
+ res->org->db= NULL;
+ res->org->orgname= NULL;
+ res->is_species_level= is_species;
+
+ /* fill-up orgref based on db_orgRef */
+ bldOrgRefOut(res->org, db_orgRef, getLiveId(tax_id));
+ return res;
+}
+
+Boolean tax1_init()
+{
+ return InitTaxDB();
+}
+
+void tax1_fini()
+{
+ CloseTaxDB();
+}
+
+Int4 tax1_getParent(Int4 id_tax)
+{
+ return (id_tax == 1)? 0 : tax_getParent(DBctl, id_tax);
+}
+
+int tax1_getChildren(Int4 id_tax, Int4** ids_out)
+{
+ int n, i;
+ Int4* ids;
+ Int4 id;
+
+ for(n= 0, id= tax_getChild(DBctl, id_tax); id > 0; id= tax_getSibling(DBctl, id)) {
+ n++;
+ }
+
+ if(n > 0) {
+ ids= MemNew(n*sizeof(Int4));
+ for(i= 0, id= tax_getChild(DBctl, id_tax); id > 0; id= tax_getSibling(DBctl, id)) {
+ ids[i++]= id;
+ }
+ *ids_out= ids;
+ }
+ return n;
+}
+
+CharPtr tax1_getGCName(Int2 gc_id)
+{
+ return tax_getGCById(DBctl, gc_id, TAX_GC_NM);
+}
+
+/* find last common ancestor for two nodes */
+Int4 tax1_join(Int4 taxid1, Int4 taxid2)
+{
+ Int4 lin1[64];
+ Int2 i= 1, j;
+
+ lin1[0]= taxid1;
+ if(taxid1 > 1) {
+ for(i= 1; i < 64; i++) {
+ lin1[i]= tax_getParent(DBctl, lin1[i-1]);
+ if(lin1[i] <= 1) break;
+ if(lin1[i] == taxid2) return taxid2;
+ }
+ }
+
+ while(taxid2 > 1) {
+ for(j= 0; j < i; j++) {
+ if(taxid2 == lin1[j]) return taxid2;
+ }
+ taxid2= tax_getParent(DBctl, taxid2);
+ }
+
+ return 1;
+}
+
+Int2 tax1_getAllNames(Int4 tax_id, CharPtr **out_names, Boolean unique)
+{
+ CharPtr* names;
+ _taxNamePtr org_n;
+ Int2 k, i;
+
+ *out_names= NULL;
+
+ org_n= tax_findOrgName(DBctl, tax_id);
+ if(org_n == NULL) return 0;
+
+ for(k= 0; (k <= tax_getNofNames(DBctl)) && (org_n[k].tax_id == tax_id); k++);
+
+ *out_names= names= MemNew(k*sizeof(CharPtr));
+
+ for(i= 0; i < k; i++) {
+ if(unique) {
+ names[i]= StringSave((org_n[i].unique_name == NULL)?
+ org_n[i].name_txt : org_n[i].unique_name);
+ }
+ else {
+ names[i]= StringSave(org_n[i].name_txt);
+ }
+ }
+
+ return k;
+}
+
+Int4 tax1_getTaxId4Str(CharPtr str, CharPtr* substring, Int4Ptr *Ids_out)
+{
+ CharPtr b, e;
+ Int4 n, tax_id;
+ Int4Ptr Ids;
+ int k;
+ char c;
+
+ *substring= NULL;
+ tax_id= tax1_getTaxIdByName(str);
+
+ if(tax_id > 1) {
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ *substring= StringSave(str);
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(str);
+ return tax1_getAllTaxIdByName(str, Ids_out);
+ }
+
+ /* whole string matches nothing */
+ /* try the whole string inside first set of parenthesis */
+ for(b= str; *b != '\0'; b++) {
+ if(*b == '(') {
+ k= 0;
+ for(e= b+1; *e != '\0'; e++) {
+ if(*e == '(') {
+ k++;
+ continue;
+ }
+ if(*e == ')') {
+ if(k > 0) {
+ k--;
+ continue;
+ }
+
+ *e= '\0';
+ tax_id= tax1_getTaxIdByName(b+1);
+
+ if(tax_id > 1) {
+ *substring= StringSave(b+1);
+ *e= ')';
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(b+1);
+ *e= ')';
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+
+ /* whole string won't help lets try truncate it at first comma*/
+ *e= ')';
+ for(e= b+1; *e != '\0'; e++) {
+ if(*e == ',') {
+ *e= '\0';
+ tax_id= tax1_getTaxIdByName(b+1);
+
+ if(tax_id > 1) {
+ *substring= StringSave(b+1);
+ *e= ',';
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(b+1);
+ *e= ',';
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+ *e= ',';
+ break;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ /* we still have got nothing */
+ /* try the substring before first '(' */
+
+ if(*b == '(') {
+ /* we are staying on the first '(' */
+ *b= '\0';
+
+ tax_id= tax1_getTaxIdByName(str);
+
+ if(tax_id > 1) {
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ *substring= StringSave(str);
+ *b= '(';
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(str);
+ *b= '(';
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+ *b= '(';
+ }
+
+ b= StringStr(str, "Organism");
+ if(b == NULL) b= StringStr(str, "organism");
+ if(b == NULL) b= StringStr(str, "ORGANISM");
+
+ if(b != NULL) {
+ e= StringChr(b, ':');
+ if(e != NULL) {
+ b= e+1;
+ tax_id= tax1_getTaxIdByName(b);
+
+ if(tax_id > 1) {
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ *substring= StringSave(b);
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(b);
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+
+ /* if multiple lines or ; , ( */
+ for(++e; *e != '\0'; e++) {
+ if((*e == '\n') || (*e == ';') || (*e == ',') || (*e == '(')) {
+ c= *e;
+ *e= '\0';
+ tax_id= tax1_getTaxIdByName(b);
+
+ if(tax_id > 1) {
+ *substring= StringSave(b);
+ *e= c;
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(b);
+ *e= c;
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+ *e= c;
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+
diff --git a/network/taxon1/stdalone/fsutils.c b/network/taxon1/stdalone/fsutils.c
new file mode 100644
index 00000000..0bc2fa3b
--- /dev/null
+++ b/network/taxon1/stdalone/fsutils.c
@@ -0,0 +1,211 @@
+/****************************
+ * File: fsutils.c
+ * Description: utility functions
+ */
+
+#include "fsutils.h"
+
+CharPtr fs_getString(FILE* f, CharPtr marker)
+{
+ CharPtr buff;
+ int i, buffSize= 16;
+ int l;
+
+ l= strlen(marker);
+
+ if((buff= MemNew(buffSize + 2)) == NULL) {
+ return NULL;
+ }
+
+ for(buff[i= 0]= fgetc(f); feof(f) == 0; buff[++i]= fgetc(f)) {
+ if(i == buffSize) {
+ buffSize+= buffSize/2;
+ if((buff= MemMore(buff, buffSize + 2)) == NULL) return NULL;
+ }
+
+ /* check for marker*/
+ if(i >= (l-1)) {
+ switch (l) {
+ case 0:
+ continue;
+ case 1:
+ if(buff[i] == *marker) {
+ buff[i]= '\0';
+ break;
+ }
+ continue;
+ case 2:
+ if((buff[i-1] == marker[0]) && (buff[i] == marker[1])) {
+ buff[i-1]= '\0';
+ break;
+ }
+ continue;
+ case 3:
+ if((buff[i-2] == marker[0]) && (buff[i-1] == marker[1]) && (buff[i] == marker[2])) {
+ buff[i-2]= '\0';
+ break;
+ }
+ continue;
+ default:
+ if((buff[i-l+1] == *marker) && (strncmp(&buff[i-l+1], marker, l) == 0)) {
+ buff[i-l+1]= '\0';
+ break;
+ }
+ continue;
+ }
+ /* match marker */
+ buff= MemMore(buff, strlen(buff)+1);
+ return buff;
+ }
+ }
+ /* eof matched */
+ buff[i]= '\0';
+ buff= MemMore(buff, i+1);
+ return buff;
+}
+
+Int2 fs_getInt(FILE* f, CharPtr marker)
+{
+ CharPtr buff;
+ int res;
+
+ if((buff= fs_getString(f, marker)) == NULL) return 0;
+
+ if(buff[0] == '\0') {
+ res= 0;
+ }
+ else {
+ res= atoi(buff);
+ }
+
+ MemFree(buff);
+ return (Int2)res;
+}
+
+Int4 fs_getLong(FILE* f, CharPtr marker)
+{
+ CharPtr buff;
+ long res;
+
+ if((buff= fs_getString(f, marker)) == NULL) return 0;
+
+ if(buff[0] == '\0') {
+ res= 0;
+ }
+ else {
+ res= atol(buff);
+ }
+
+ MemFree(buff);
+ return (Int4) res;
+}
+
+Int4 fs_putString(FILE* f, CharPtr str, CharPtr marker)
+{
+ Int4 l1= 0, l2= 0;
+
+ if((str != NULL) && ((l1= strlen(str)) > 0)) {
+ if(FilePuts(str, f) == EOF) return -1;
+ }
+ if((marker != NULL) && ((l2= strlen(marker)) > 0)) {
+ if(FilePuts(marker, f)) return -1;
+ }
+ return l1+l2;
+}
+
+Int4 fs_putInt2(FILE* f, Int2 val, CharPtr marker)
+{
+ char buff[32];
+
+ sprintf(buff, "%d", val);
+ return fs_putString(f, buff, marker);
+}
+
+Int4 fs_putInt4(FILE* f, Int4 val, CharPtr marker)
+{
+ char buff[32];
+
+ sprintf(buff, "%ld", val);
+ return fs_putString(f, buff, marker);
+}
+
+Int2 fsb_getInt2(FILE* f)
+{
+ Int2 res;
+
+ if(fread(&res, 2, 1, f) > 0) return res;
+ else return 0;
+}
+
+Int4 fsb_getInt4(FILE* f)
+{
+ Int4 res;
+
+ if(fread(&res, 4, 1, f) > 0) return res;
+ else return 0;
+}
+
+CharPtr fsb_getString(FILE* f)
+{
+ Int2 len;
+ CharPtr buff;
+
+ if((len= fsb_getInt2(f)) > 0) {
+ if((buff= MemNew(len)) != NULL) {
+ fread(buff, 1, len, f);
+ return buff;
+ }
+ }
+
+ return NULL;
+}
+
+Int4 fsb_putInt2(FILE* f, Int2 v)
+{
+ return fwrite(&v, 2, 1, f)*2;
+}
+
+Int4 fsb_putInt4(FILE* f, Int4 v)
+{
+ return fwrite(&v, 4, 1, f)*4;
+}
+
+Int4 fsb_putString(FILE* f, CharPtr str)
+{
+ Int4 len, res;
+ Int2 l;
+
+ len= strlen(str)+1;
+ if(len > (32*1024 - 1)) l= 32*1024 - 1;
+ else l= (Int2) len;
+
+ if(l == 1) l= 0;
+
+ len= l;
+
+ res= fwrite(&l, 2, 1, f)*2;
+
+ return res + ((len > 0)? (fwrite(str, len, 1, f)*len) : 0);
+}
+
+static char nameBuff[1024];
+
+CharPtr fs_fileName(CharPtr path, CharPtr name)
+{
+ int n;
+#define PATH_SEPARATOR '/'
+
+ if((path == NULL) || (path[0] == '\0')) return name;
+
+ n= StringLen(path);
+
+ StringCpy(nameBuff, path);
+ if(path[n-1] != PATH_SEPARATOR) {
+ nameBuff[n]= PATH_SEPARATOR;
+ nameBuff[n+1]= '\0';
+ }
+
+ StringCat(nameBuff, name);
+
+ return nameBuff;
+}
diff --git a/network/taxon1/stdalone/fsutils.h b/network/taxon1/stdalone/fsutils.h
new file mode 100644
index 00000000..cfc17cd4
--- /dev/null
+++ b/network/taxon1/stdalone/fsutils.h
@@ -0,0 +1,44 @@
+/***************************
+ * File: fsutils.h
+ * Description: header for fsutils.c
+ */
+
+#ifndef FSUTILS_H_DONE
+#define FSUTILS_H_DONE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ncbi.h>
+
+CharPtr fs_getString(FILE* f, CharPtr marker);
+Int2 fs_getInt2(FILE* f, CharPtr marker);
+Int4 fs_getInt4(FILE* f, CharPtr marker);
+Int4 fs_putString(FILE* f, CharPtr str, CharPtr marker);
+Int4 fs_putInt2(FILE* f, Int2 val, CharPtr marker);
+Int4 fs_putInt4(FILE* f, Int4 val, CharPtr marker);
+
+#define fs_getInt(f, m) fs_getInt2(f, m)
+#define fs_getLong(f, m) fs_getInt4(f, m)
+#define fs_putInt(f, v, m) fs_putInt2(f, v, m)
+#define fs_putLong(f, v, m) fs_putInt4(f, v, m)
+
+#define fsb_getBytes(f, n, b) fread(b, n, 1, f)
+#define fsb_getInt1(f) getc(f)
+
+Int2 fsb_getInt2(FILE* f);
+Int4 fsb_getInt4(FILE* f);
+CharPtr fsb_getString(FILE* f);
+
+#define fsb_putBytes(f, n, b) (fwrite(b, n, 1, f)*(n))
+#define fsb_putInt1(f, v) ((putc(v, f) != EOF) ? 1 : 0)
+
+Int4 fsb_putInt2(FILE* f, Int2 v);
+Int4 fsb_putInt4(FILE* f, Int4 v);
+Int4 fsb_putString(FILE* f, CharPtr str);
+
+#define fsb_getInt(f) fsb_getInt2(f)
+#define fsb_getLong(f) fsb_getInt4(f);
+
+CharPtr fs_fileName(CharPtr path, CharPtr name);
+
+#endif
diff --git a/network/taxon1/stdalone/gc.c b/network/taxon1/stdalone/gc.c
new file mode 100644
index 00000000..6f3143bb
--- /dev/null
+++ b/network/taxon1/stdalone/gc.c
@@ -0,0 +1,173 @@
+/****************************
+ * File: gc.c
+ * Description: taxonomy GC functions
+ */
+
+#include <stdlib.h>
+#include "tax_cmmn.h"
+
+/*------------------------------------------------
+ * load_bin - load GCs from binary file
+ */
+static int load_bin(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ int i;
+ _gencodePtr GC;
+ int nof_GCs= tax_getNofGCs(ctl);
+
+ if(nof_GCs < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_GC, "load_bin: The number of GCs <= 1");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_GC_FILE), "rb")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_bin: Can't open GC file");
+ return -1;
+ }
+
+ if((GC= malloc(sizeof(_gencode) * nof_GCs)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for GCs");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_GCs; i++) {
+ GC[i].gc_id= fsb_getInt2(f);
+ fsb_getBytes(f, 6, GC[i].gc_abbrev);
+ GC[i].gc_nm= fsb_getString(f);
+ GC[i].gc_cde= fsb_getString(f);
+ GC[i].gc_starts= fsb_getString(f);
+ }
+
+ ctl->gc= GC;
+ fclose(f);
+ return 0;
+}
+
+/*---------------------------------------------------
+ * load_txt - load GC from text file
+ */
+static int load_txt(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ int i;
+ _gencodePtr GC;
+ int nof_GCs= tax_getNofGCs(ctl);
+ CharPtr tmp;
+
+
+ if(nof_GCs < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_RANKS, "load_txt: The number of GCs <= 1");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_GC_FILE), "r")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_txt: Can't open GC file");
+ return -1;
+ }
+
+ if((GC= malloc(sizeof(_gencode) * nof_GCs)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_txt: Not enaugh memory for GCs");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_GCs; i++) {
+ GC[i].gc_id= fs_getInt(f, tax_getMarker(ctl));
+ if((tmp= fs_getString(f, tax_getMarker(ctl))) != NULL) {
+ strncpy(GC[i].gc_abbrev, tmp, 6);
+ GC[i].gc_abbrev[5]= '\0';
+ free(tmp);
+ }
+ GC[i].gc_nm= fs_getString(f, tax_getMarker(ctl));
+ GC[i].gc_cde= fs_getString(f, tax_getMarker(ctl));
+ GC[i].gc_starts= fs_getString(f, tax_getMarker(ctl));
+ }
+
+ ctl->gc= GC;
+ fclose(f);
+ return 0;
+}
+
+static int load_asn(_taxDBCtlPtr ctl)
+{
+ return -10; /* not done yet */
+}
+
+/*==============================================================
+ * tax_freeDivs - free division's memory
+ */
+void tax_freeGCs(_taxDBCtlPtr ctl)
+{
+ int nof_GCs= tax_getNofGCs(ctl);
+ int i;
+ _gencodePtr GC= ctl->gc;
+
+ if((GC == NULL) || (nof_GCs < 1)) return;
+
+ for(i= 0; i != nof_GCs; i++) {
+ if(GC[i].gc_nm != NULL) free(GC[i].gc_nm);
+ if(GC[i].gc_cde != NULL) free(GC[i].gc_cde);
+ if(GC[i].gc_starts != NULL) free(GC[i].gc_starts);
+ }
+ free(GC);
+ ctl->gc= NULL;
+}
+
+int tax_loadGCs(_taxDBCtlPtr ctl)
+{
+
+ if(ctl->gc != NULL) tax_freeGCs(ctl);
+
+ switch(tax_getDbType(ctl)) {
+ case TAX_BIN: return load_bin(ctl);
+ case TAX_TXT: return load_txt(ctl);
+ case TAX_ASN: return load_asn(ctl);
+ default: break;
+ }
+
+ tax_outMsg(TAX_ERROR, TAX_ERR_FILE_TYPE, "tax_loadDivs: Wrong file type for GCs");
+ return -1;
+}
+
+CharPtr tax_getGCById(_taxDBCtlPtr ctl, Int2 id, Int2 mode)
+{
+ int i;
+ _gencodePtr GC= ctl->gc;
+ int nof_GCs= tax_getNofGCs(ctl);
+
+ for(i= 0; i < nof_GCs; i++) {
+ if(GC[i].gc_id == id) {
+ switch(mode) {
+ case TAX_GC_CDE: return GC[i].gc_cde;
+ case TAX_GC_ABBREV: return GC[i].gc_abbrev;
+ case TAX_GC_STARTS: return GC[i].gc_starts;
+ default: return GC[i].gc_nm;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+Int2 tax_getGCId(_taxDBCtlPtr ctl, CharPtr txt, Int2 mode)
+{
+ int i;
+ _gencodePtr GC= ctl->gc;
+ int nof_GCs= tax_getNofGCs(ctl);
+
+ for(i= 0; i < nof_GCs; i++) {
+ if(mode == TAX_GC_ABBREV) {
+ if(StringNICmp(GC[i].gc_abbrev, txt, 6) == 0) return GC[i].gc_id;
+ }
+ else {
+ if(StringICmp(GC[i].gc_nm, txt) == 0) return GC[i].gc_id;
+ }
+ }
+ return -1;
+}
+
+
+
+
diff --git a/network/taxon1/stdalone/nmclass.c b/network/taxon1/stdalone/nmclass.c
new file mode 100644
index 00000000..3483aa2c
--- /dev/null
+++ b/network/taxon1/stdalone/nmclass.c
@@ -0,0 +1,151 @@
+/****************************
+ * File: nmclass.c
+ * Description: taxonomy name class functions
+ */
+
+#include <stdlib.h>
+#include "tax_cmmn.h"
+
+/*------------------------------------------------
+ * load_bin - load name classes from binary file
+ */
+static int load_bin(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ int i;
+ Int2 t;
+ _nmclassPtr nmc;
+ int nof_nmcs= tax_getNofClasses(ctl);
+
+ if(nof_nmcs < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_CLASSES, "load_bin: The number of name classes <= 1");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_CLASS_FILE), "rb")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_bin: Can't open name classes file");
+ return -1;
+ }
+
+ if((nmc= malloc(sizeof(_nmclass) * nof_nmcs)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for name classes");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_nmcs; i++) {
+ nmc[i].class_cde= fsb_getInt2(f);
+ nmc[i].class_txt= fsb_getString(f);
+ }
+
+ ctl->nmclass= nmc;
+ fclose(f);
+ return 0;
+}
+
+/*---------------------------------------------------
+ * load_txt - load name classes from text file
+ */
+static int load_txt(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ int i;
+ _nmclassPtr nmc;
+ int nof_nmcs= tax_getNofClasses(ctl);
+
+
+ if(nof_nmcs < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_CLASSES, "load_txt: The number of name classes <= 1");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_CLASS_FILE), "r")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_txt: Can't open name classes file");
+ return -1;
+ }
+
+ if((nmc= malloc(sizeof(_nmclass) * nof_nmcs)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_txt: Not enaugh memory for name classes");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_nmcs; i++) {
+ nmc[i].class_cde= fs_getInt(f, tax_getMarker(ctl));
+ nmc[i].class_txt= fs_getString(f, tax_getMarker(ctl));
+ }
+
+ ctl->nmclass= nmc;
+ fclose(f);
+ return 0;
+}
+
+static int load_asn(_taxDBCtlPtr ctl)
+{
+ return -10; /* not done yet */
+}
+
+/*==============================================================
+ * tax_freeClasses - free memory
+ */
+void tax_freeClasses(_taxDBCtlPtr ctl)
+{
+ int nof_nmcs= tax_getNofClasses(ctl);
+ int i;
+ _nmclassPtr r= ctl->nmclass;
+
+ if((r == NULL) || (nof_nmcs < 1)) return;
+
+ for(i= 0; i != nof_nmcs; i++) {
+ if(r[i].class_txt != NULL) free(r[i].class_txt);
+ }
+ free(r);
+ ctl->nmclass= NULL;
+}
+
+int tax_loadClasses(_taxDBCtlPtr ctl)
+{
+
+ if(ctl->nmclass != NULL) tax_freeClasses(ctl);
+
+ switch(tax_getDbType(ctl)) {
+ case TAX_BIN: return load_bin(ctl);
+ case TAX_TXT: return load_txt(ctl);
+ case TAX_ASN: return load_asn(ctl);
+ default: break;
+ }
+
+ tax_outMsg(TAX_ERROR, TAX_ERR_FILE_TYPE, "tax_loadClasses: Wrong file type for name classes");
+ return -1;
+}
+
+char* tax_getClassById(_taxDBCtlPtr ctl, Int2 id)
+{
+ int i;
+ _nmclassPtr r= ctl->nmclass;
+ int nof_nmcs= tax_getNofClasses(ctl);
+
+ for(i= 0; i < nof_nmcs; i++) {
+ if(r[i].class_cde == id) return r[i].class_txt;
+ }
+
+ return NULL;
+}
+
+Int2 tax_getClassId(_taxDBCtlPtr ctl, CharPtr class_name)
+{
+ int i;
+ _nmclassPtr r= ctl->nmclass;
+ int nof_nmcs= tax_getNofClasses(ctl);
+
+ for(i= 0; i < nof_nmcs; i++) {
+ if(strcmp(r[i].class_txt, class_name) == 0) {
+ return r[i].class_cde;
+ }
+ }
+ return 99;
+}
+
+
+
+
diff --git a/network/taxon1/stdalone/objtax0.c b/network/taxon1/stdalone/objtax0.c
new file mode 100644
index 00000000..cd041bb5
--- /dev/null
+++ b/network/taxon1/stdalone/objtax0.c
@@ -0,0 +1,1464 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: objtax0.c,v $
+* Revision 6.0 1997/08/25 18:42:20 madden
+* Revision changed to 6.0
+*
+* Revision 1.1 1996/02/05 14:51:02 soussov
+* Initial revision
+*
+*/
+
+#include <asn.h>
+#include <ncbi.h>
+#include <objfeat.h>
+
+#ifdef NLM_OBJ_INCL
+#include NLM_OBJ_INCL
+#endif
+#include "objtax0.h"
+
+static Boolean loaded = FALSE;
+
+#include "asntaxon.h"
+
+#ifndef NLM_EXTERN_LOADS
+#define NLM_EXTERN_LOADS {}
+#endif
+
+static Boolean _AsnLoad(void)
+{
+
+ if ( ! loaded) {
+ NLM_EXTERN_LOADS
+
+ if ( ! AsnLoad ())
+ return FALSE;
+ loaded = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/**************************************************
+*
+* Generated object loaders for Module NCBI-Taxon0
+*
+**************************************************/
+
+
+/**************************************************
+*
+* Taxon0ReqFree()
+*
+**************************************************/
+Taxon0ReqPtr LIBCALL Taxon0ReqFree ( Taxon0ReqPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ {Pointer pt = ptr -> data.ptrvalue;
+ switch (ptr -> choice){
+ case Taxon0Req_getid :
+ TaxonNameFree(pt);
+ break;
+ case Taxon0Req_getcomplete :
+ TaxonIdNameFree(pt);
+ break;
+ }}
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonNameFree()
+*
+**************************************************/
+TaxonNamePtr LIBCALL TaxonNameFree ( TaxonNamePtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ {Pointer pt = ptr -> data.ptrvalue;
+ switch (ptr -> choice){
+ case TaxonName_taxname :
+ case TaxonName_common :
+ case TaxonName_tax_synonym :
+ case TaxonName_com_synonym :
+ MemFree(pt);
+ break;
+ }}
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonIdNameFree()
+*
+**************************************************/
+TaxonIdNamePtr LIBCALL TaxonIdNameFree ( TaxonIdNamePtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ {Pointer pt = ptr -> data.ptrvalue;
+ switch (ptr -> choice){
+ case TaxonIdName_name :
+ MemFree(pt);
+ break;
+ }}
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* Taxon0RespFree()
+*
+**************************************************/
+Taxon0RespPtr LIBCALL Taxon0RespFree ( Taxon0RespPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ {Pointer pt = ptr -> data.ptrvalue;
+ switch (ptr -> choice){
+ case Taxon0Resp_getid :
+ TaxonIdListFree(pt);
+ break;
+ case Taxon0Resp_getref :
+ OrgRefFree(pt);
+ break;
+ case Taxon0Resp_gettaxon :
+ TaxonIdListFree(pt);
+ break;
+ case Taxon0Resp_getgeneticcode :
+ GeneticCodeListFree(pt);
+ break;
+ case Taxon0Resp_gettaxonline :
+ case Taxon0Resp_getdivision :
+ MemFree(pt);
+ break;
+ case Taxon0Resp_getcomplete :
+ TaxCompleteListFree(pt);
+ break;
+ }}
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonIdListFree()
+*
+**************************************************/
+TaxonIdListPtr LIBCALL TaxonIdListFree ( TaxonIdListPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ MemFree(ptr -> ids);
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* GeneticCodeListFree()
+*
+**************************************************/
+GeneticCodeListPtr LIBCALL GeneticCodeListFree ( GeneticCodeListPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxCompleteListFree()
+*
+**************************************************/
+TaxCompleteListPtr LIBCALL TaxCompleteListFree ( TaxCompleteListPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ TaxCompleteFree( ptr -> info);
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonIdFree()
+*
+**************************************************/
+TaxonIdPtr LIBCALL TaxonIdFree ( TaxonIdPtr ptr)
+{
+ if (ptr == NULL) return NULL;
+
+ MemFree(ptr);
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxCompleteFree()
+*
+**************************************************/
+TaxCompletePtr LIBCALL TaxCompleteFree ( TaxCompletePtr head_ptr)
+{
+ TaxCompletePtr ptr, hold_ptr;
+
+ if (head_ptr == NULL) return NULL;
+
+ for (ptr = head_ptr; ptr; ptr = hold_ptr){
+ hold_ptr = ptr -> next;
+ MemFree(ptr -> sciname);
+ MemFree(ptr -> comname);
+ MemFree(ptr -> synonyms);
+ MemFree(ptr -> name_gc);
+ MemFree(ptr -> name_mgc);
+ MemFree(ptr -> gb_div);
+ MemFree(ptr -> embl_code);
+ MemFree(ptr -> lineage);
+ MemFree(ptr);
+ }
+ return NULL;
+}
+
+
+/**************************************************
+*
+* TaxonIdListNew()
+*
+**************************************************/
+
+TaxonIdListPtr LIBCALL
+TaxonIdListNew()
+{
+
+ return (TaxonIdListPtr) MemNew(sizeof(TaxonIdList));
+
+}
+
+
+
+/**************************************************
+*
+* GeneticCodeListNew()
+*
+**************************************************/
+
+GeneticCodeListPtr LIBCALL
+GeneticCodeListNew()
+{
+
+ return (GeneticCodeListPtr) MemNew(sizeof(GeneticCodeList));
+
+}
+
+
+
+/**************************************************
+*
+* TaxCompleteListNew()
+*
+**************************************************/
+
+TaxCompleteListPtr LIBCALL
+TaxCompleteListNew()
+{
+
+ return (TaxCompleteListPtr) MemNew(sizeof(TaxCompleteList));
+
+}
+
+
+
+/**************************************************
+*
+* TaxonIdNew()
+*
+**************************************************/
+
+TaxonIdPtr LIBCALL
+TaxonIdNew()
+{
+
+ return (TaxonIdPtr) MemNew(sizeof(TaxonId));
+
+}
+
+
+
+/**************************************************
+*
+* TaxCompleteNew()
+*
+**************************************************/
+
+TaxCompletePtr LIBCALL
+TaxCompleteNew()
+{
+
+ return (TaxCompletePtr) MemNew(sizeof(TaxComplete));
+
+}
+
+
+
+/**************************************************
+*
+* Taxon0ReqAsnRead()
+*
+**************************************************/
+Taxon0ReqPtr LIBCALL Taxon0ReqAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr vnp;
+ Uint1 choice ;
+ AsnReadFunc func;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON0_REQ);
+ else
+ atp = AsnLinkType(orig, TAXON0_REQ);
+ if(atp == NULL) return NULL;
+
+ vnp = ValNodeNew(NULL);
+ if (vnp == NULL) goto erret;
+ if ( AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ if ( (atp = AsnReadId(aip, amp, atp)) == NULL) goto erret;
+ func = NULL;
+ if (atp == TAXON0_REQ_init){
+ choice = Taxon0Req_init;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getid){
+ choice = Taxon0Req_getid;
+ func = (AsnReadFunc) TaxonNameAsnRead;
+ }
+ else
+ if (atp == TAXON0_REQ_getref){
+ choice = Taxon0Req_getref;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getchildren){
+ choice = Taxon0Req_getchildren;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getparents){
+ choice = Taxon0Req_getparents;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getgeneticcode){
+ choice = Taxon0Req_getgeneticcode;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_gettaxonline){
+ choice = Taxon0Req_gettaxonline;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getdivision){
+ choice = Taxon0Req_getdivision;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_REQ_getcomplete){
+ choice = Taxon0Req_getcomplete;
+ func = (AsnReadFunc) TaxonIdNameAsnRead;
+ }
+ else
+ if (atp == TAXON0_REQ_fini){
+ choice = Taxon0Req_fini;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ goto erret;
+ vnp -> choice = choice;
+ if (func != NULL)
+ vnp -> data.ptrvalue = (*func) (aip,atp);
+ret:
+ AsnUnlinkType(orig);
+ return vnp;
+erret:
+ vnp=Taxon0ReqFree(vnp);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonNameAsnRead()
+*
+**************************************************/
+TaxonNamePtr LIBCALL TaxonNameAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr vnp;
+ Uint1 choice ;
+ AsnReadFunc func;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON_NAME);
+ else
+ atp = AsnLinkType(orig, TAXON_NAME);
+ if(atp == NULL) return NULL;
+
+ vnp = ValNodeNew(NULL);
+ if (vnp == NULL) goto erret;
+ if ( AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ if ( (atp = AsnReadId(aip, amp, atp)) == NULL) goto erret;
+ func = NULL;
+ if (atp == TAXON_NAME_taxname){
+ choice = TaxonName_taxname;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON_NAME_common){
+ choice = TaxonName_common;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON_NAME_tax_synonym){
+ choice = TaxonName_tax_synonym;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON_NAME_com_synonym){
+ choice = TaxonName_com_synonym;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ goto erret;
+ vnp -> choice = choice;
+ if (func != NULL)
+ vnp -> data.ptrvalue = (*func) (aip,atp);
+ret:
+ AsnUnlinkType(orig);
+ return vnp;
+erret:
+ vnp=TaxonNameFree(vnp);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdNameAsnRead()
+*
+**************************************************/
+TaxonIdNamePtr LIBCALL TaxonIdNameAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr vnp;
+ Uint1 choice ;
+ AsnReadFunc func;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON_ID_NAME);
+ else
+ atp = AsnLinkType(orig, TAXON_ID_NAME);
+ if(atp == NULL) return NULL;
+
+ vnp = ValNodeNew(NULL);
+ if (vnp == NULL) goto erret;
+ if ( AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ if ( (atp = AsnReadId(aip, amp, atp)) == NULL) goto erret;
+ func = NULL;
+ if (atp == TAXON_ID_NAME_id){
+ choice = TaxonIdName_id;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON_ID_NAME_name){
+ choice = TaxonIdName_name;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ goto erret;
+ vnp -> choice = choice;
+ if (func != NULL)
+ vnp -> data.ptrvalue = (*func) (aip,atp);
+ret:
+ AsnUnlinkType(orig);
+ return vnp;
+erret:
+ vnp=TaxonIdNameFree(vnp);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Taxon0RespAsnRead()
+*
+**************************************************/
+Taxon0RespPtr LIBCALL Taxon0RespAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ ValNodePtr vnp;
+ Uint1 choice ;
+ AsnReadFunc func;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON0_RESP);
+ else
+ atp = AsnLinkType(orig, TAXON0_RESP);
+ if(atp == NULL) return NULL;
+
+ vnp = ValNodeNew(NULL);
+ if (vnp == NULL) goto erret;
+ if ( AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ if ( (atp = AsnReadId(aip, amp, atp)) == NULL) goto erret;
+ func = NULL;
+ if (atp == TAXON0_RESP_error){
+ choice = Taxon0Resp_error;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_RESP_init){
+ choice = Taxon0Resp_init;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_RESP_getid){
+ choice = Taxon0Resp_getid;
+ func = (AsnReadFunc) TaxonIdListAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_getref){
+ choice = Taxon0Resp_getref;
+ func = (AsnReadFunc) OrgRefAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_gettaxon){
+ choice = Taxon0Resp_gettaxon;
+ func = (AsnReadFunc) TaxonIdListAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_getgeneticcode){
+ choice = Taxon0Resp_getgeneticcode;
+ func = (AsnReadFunc) GeneticCodeListAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_gettaxonline){
+ choice = Taxon0Resp_gettaxonline;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_RESP_getdivision){
+ choice = Taxon0Resp_getdivision;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ if (atp == TAXON0_RESP_getcomplete){
+ choice = Taxon0Resp_getcomplete;
+ func = (AsnReadFunc) TaxCompleteListAsnRead;
+ }
+ else
+ if (atp == TAXON0_RESP_fini){
+ choice = Taxon0Resp_fini;
+ AsnReadVal(aip,atp,&av);
+ vnp -> data.ptrvalue = av.ptrvalue;
+ }
+ else
+ goto erret;
+ vnp -> choice = choice;
+ if (func != NULL)
+ vnp -> data.ptrvalue = (*func) (aip,atp);
+ret:
+ AsnUnlinkType(orig);
+ return vnp;
+erret:
+ vnp=Taxon0RespFree(vnp);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdListAsnRead()
+*
+**************************************************/
+TaxonIdListPtr LIBCALL TaxonIdListAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ TaxonIdListPtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON_ID_LIST);
+ else
+ atp = AsnLinkType(orig, TAXON_ID_LIST);
+ if(atp == NULL) return NULL;
+
+ ptr = TaxonIdListNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == TAXON_ID_LIST_ids)
+ {
+ AsnTypePtr now_atp;
+ ValNodePtr current;
+ ValNodePtr head = NULL;
+ ValNodePtr prev = NULL;
+ Int4 _num_ = 0;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* START_STUCT */
+ goto erret;
+
+ now_atp = atp;
+
+ while ((now_atp = AsnReadId(aip, amp, now_atp)) != atp){
+ if (now_atp == NULL) goto erret;
+
+ current = ValNodeNew(prev);
+ AsnReadVal(aip, now_atp, & current -> data);
+ _num_ ++;
+ if (current == NULL) goto erret;
+
+ if (head == NULL)
+ head = current;
+ else
+ prev -> next = current;
+ prev=current;
+ }
+ if (AsnReadVal(aip, atp, &av) <=0) /* END_STRUCT */ goto erret;
+ ptr -> _num_ids = _num_;
+ ptr -> ids = MemNew( _num_ * sizeof (Pointer) );
+ for (_num_ = 0, current = head; current; current = current -> next, _num_ ++){
+ (ptr -> ids) [_num_] = current -> data.intvalue;
+ }
+ ValNodeFree(head);
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=TaxonIdListFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* GeneticCodeListAsnRead()
+*
+**************************************************/
+GeneticCodeListPtr LIBCALL GeneticCodeListAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ GeneticCodeListPtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, GENETICCODELIST);
+ else
+ atp = AsnLinkType(orig, GENETICCODELIST);
+ if(atp == NULL) return NULL;
+
+ ptr = GeneticCodeListNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == GENETICCODELIST_genomic){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->genomic = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == GENETICCODELIST_mitochondrial){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->mitochondrial = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=GeneticCodeListFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxCompleteListAsnRead()
+*
+**************************************************/
+TaxCompleteListPtr LIBCALL TaxCompleteListAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ TaxCompleteListPtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAX_COMPLETE_LIST);
+ else
+ atp = AsnLinkType(orig, TAX_COMPLETE_LIST);
+ if(atp == NULL) return NULL;
+
+ ptr = TaxCompleteListNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == TAX_COMPLETE_LIST_num){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->num = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_LIST_info)
+ {
+ AsnTypePtr now_atp;
+ TaxCompletePtr current;
+ TaxCompletePtr head = NULL;
+ TaxCompletePtr prev = NULL;
+ if (AsnReadVal(aip, atp, &av) <= 0) /* START_STUCT */
+ goto erret;
+
+ now_atp = atp;
+
+ while ((now_atp = AsnReadId(aip, amp, now_atp)) != atp){
+ if (now_atp == NULL) goto erret;
+
+ current= TaxCompleteAsnRead(aip, now_atp);
+ if (current == NULL) goto erret;
+
+ if (head == NULL)
+ head = current;
+ else
+ prev -> next = current;
+ prev=current;
+ }
+ if (AsnReadVal(aip, atp, &av) <=0) /* END_STRUCT */ goto erret;
+ ptr -> info = head;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=TaxCompleteListFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdAsnRead()
+*
+**************************************************/
+TaxonIdPtr LIBCALL TaxonIdAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ TaxonIdPtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAXON_ID);
+ else
+ atp = AsnLinkType(orig, TAXON_ID);
+ if(atp == NULL) return NULL;
+
+ ptr = TaxonIdNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == TAXON_ID_id){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->id = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=TaxonIdFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxCompleteAsnRead()
+*
+**************************************************/
+TaxCompletePtr LIBCALL TaxCompleteAsnRead ( AsnIoPtr aip, AsnTypePtr orig)
+{
+ DataVal av;
+ AsnTypePtr atp;
+ TaxCompletePtr ptr;
+
+ if (aip == NULL) return NULL;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ loaded = TRUE;
+ }
+ if (orig == NULL)
+ atp = AsnReadId(aip, amp, TAX_COMPLETE);
+ else
+ atp = AsnLinkType(orig, TAX_COMPLETE);
+ if(atp == NULL) return NULL;
+
+ ptr = TaxCompleteNew();
+ if (ptr == NULL) goto erret;
+
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+
+ atp = AsnReadId(aip,amp, atp);
+ if (atp == TAX_COMPLETE_sciname){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->sciname = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_comname){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->comname = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_synonyms){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->synonyms = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_id_gc){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->id_gc = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_name_gc){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->name_gc = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_id_mgc){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->id_mgc = av.intvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_name_mgc){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->name_mgc = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_gb_div){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->gb_div = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_embl_code){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->embl_code = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_lineage){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->lineage = (CharPtr)av.ptrvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (atp == TAX_COMPLETE_is_species_level){
+ if (AsnReadVal(aip, atp, &av) <= 0)
+ goto erret;
+ ptr->is_species_level = (Uint1)av.boolvalue;
+ atp = AsnReadId(aip,amp, atp);
+ }
+ if (AsnReadVal(aip, atp, &av) <= 0) goto erret;
+ret:
+ AsnUnlinkType(orig);
+ return ptr;
+erret:
+ ptr=TaxCompleteFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Taxon0ReqAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL Taxon0ReqAsnWrite (Taxon0ReqPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+ AsnWriteFunc func;
+ AsnTypePtr writetype = NULL;
+ Pointer pnt;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON0_REQ);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ av.ptrvalue = (Pointer) ptr;
+ if (! AsnWriteChoice(aip, atp, ptr -> choice, & av)) goto erret;
+ pnt = ptr -> data.ptrvalue;
+ av.intvalue = ptr -> data.intvalue;
+ switch (ptr -> choice){
+ case Taxon0Req_init :
+ retval = AsnWrite(aip, TAXON0_REQ_init, &av); break;
+ case Taxon0Req_getid :
+ writetype = TAXON0_REQ_getid;
+ func = (AsnWriteFunc) TaxonNameAsnWrite;
+ break;
+ case Taxon0Req_getref :
+ retval = AsnWrite(aip, TAXON0_REQ_getref, &av); break;
+ case Taxon0Req_getchildren :
+ retval = AsnWrite(aip, TAXON0_REQ_getchildren, &av); break;
+ case Taxon0Req_getparents :
+ retval = AsnWrite(aip, TAXON0_REQ_getparents, &av); break;
+ case Taxon0Req_getgeneticcode :
+ retval = AsnWrite(aip, TAXON0_REQ_getgeneticcode, &av); break;
+ case Taxon0Req_gettaxonline :
+ retval = AsnWrite(aip, TAXON0_REQ_gettaxonline, &av); break;
+ case Taxon0Req_getdivision :
+ retval = AsnWrite(aip, TAXON0_REQ_getdivision, &av); break;
+ case Taxon0Req_getcomplete :
+ writetype = TAXON0_REQ_getcomplete;
+ func = (AsnWriteFunc) TaxonIdNameAsnWrite;
+ break;
+ case Taxon0Req_fini :
+ retval = AsnWrite(aip, TAXON0_REQ_fini, &av); break;
+ }
+ if (writetype != NULL)
+ retval = (*func) (pnt, aip,writetype);
+ret:
+ AsnUnlinkType(orig);
+ return retval;
+erret:
+ ptr=Taxon0ReqFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonNameAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxonNameAsnWrite (TaxonNamePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+ AsnWriteFunc func;
+ AsnTypePtr writetype = NULL;
+ Pointer pnt;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON_NAME);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ av.ptrvalue = (Pointer) ptr;
+ if (! AsnWriteChoice(aip, atp, ptr -> choice, & av)) goto erret;
+ pnt = ptr -> data.ptrvalue;
+ av.intvalue = ptr -> data.intvalue;
+ switch (ptr -> choice){
+ case TaxonName_taxname :
+ retval = AsnWrite(aip, TAXON_NAME_taxname, &av); break;
+ case TaxonName_common :
+ retval = AsnWrite(aip, TAXON_NAME_common, &av); break;
+ case TaxonName_tax_synonym :
+ retval = AsnWrite(aip, TAXON_NAME_tax_synonym, &av); break;
+ case TaxonName_com_synonym :
+ retval = AsnWrite(aip, TAXON_NAME_com_synonym, &av); break;
+ }
+ if (writetype != NULL)
+ retval = (*func) (pnt, aip,writetype);
+ret:
+ AsnUnlinkType(orig);
+ return retval;
+erret:
+ ptr=TaxonNameFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdNameAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxonIdNameAsnWrite (TaxonIdNamePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+ AsnWriteFunc func;
+ AsnTypePtr writetype = NULL;
+ Pointer pnt;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON_ID_NAME);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ av.ptrvalue = (Pointer) ptr;
+ if (! AsnWriteChoice(aip, atp, ptr -> choice, & av)) goto erret;
+ pnt = ptr -> data.ptrvalue;
+ av.intvalue = ptr -> data.intvalue;
+ switch (ptr -> choice){
+ case TaxonIdName_id :
+ retval = AsnWrite(aip, TAXON_ID_NAME_id, &av); break;
+ case TaxonIdName_name :
+ retval = AsnWrite(aip, TAXON_ID_NAME_name, &av); break;
+ }
+ if (writetype != NULL)
+ retval = (*func) (pnt, aip,writetype);
+ret:
+ AsnUnlinkType(orig);
+ return retval;
+erret:
+ ptr=TaxonIdNameFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* Taxon0RespAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL Taxon0RespAsnWrite (Taxon0RespPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+ AsnWriteFunc func;
+ AsnTypePtr writetype = NULL;
+ Pointer pnt;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON0_RESP);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ av.ptrvalue = (Pointer) ptr;
+ if (! AsnWriteChoice(aip, atp, ptr -> choice, & av)) goto erret;
+ pnt = ptr -> data.ptrvalue;
+ av.intvalue = ptr -> data.intvalue;
+ switch (ptr -> choice){
+ case Taxon0Resp_error :
+ retval = AsnWrite(aip, TAXON0_RESP_error, &av); break;
+ case Taxon0Resp_init :
+ retval = AsnWrite(aip, TAXON0_RESP_init, &av); break;
+ case Taxon0Resp_getid :
+ writetype = TAXON0_RESP_getid;
+ func = (AsnWriteFunc) TaxonIdListAsnWrite;
+ break;
+ case Taxon0Resp_getref :
+ writetype = TAXON0_RESP_getref;
+ func = (AsnWriteFunc) OrgRefAsnWrite;
+ break;
+ case Taxon0Resp_gettaxon :
+ writetype = TAXON0_RESP_gettaxon;
+ func = (AsnWriteFunc) TaxonIdListAsnWrite;
+ break;
+ case Taxon0Resp_getgeneticcode :
+ writetype = TAXON0_RESP_getgeneticcode;
+ func = (AsnWriteFunc) GeneticCodeListAsnWrite;
+ break;
+ case Taxon0Resp_gettaxonline :
+ retval = AsnWrite(aip, TAXON0_RESP_gettaxonline, &av); break;
+ case Taxon0Resp_getdivision :
+ retval = AsnWrite(aip, TAXON0_RESP_getdivision, &av); break;
+ case Taxon0Resp_getcomplete :
+ writetype = TAXON0_RESP_getcomplete;
+ func = (AsnWriteFunc) TaxCompleteListAsnWrite;
+ break;
+ case Taxon0Resp_fini :
+ retval = AsnWrite(aip, TAXON0_RESP_fini, &av); break;
+ }
+ if (writetype != NULL)
+ retval = (*func) (pnt, aip,writetype);
+ret:
+ AsnUnlinkType(orig);
+ return retval;
+erret:
+ ptr=Taxon0RespFree(ptr);
+ goto ret;
+}
+
+
+/**************************************************
+*
+* TaxonIdListAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxonIdListAsnWrite (TaxonIdListPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON_ID_LIST);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ if (ptr -> ids != NULL){
+ if (! AsnOpenStruct (aip, TAXON_ID_LIST_ids, (Pointer) ptr -> ids))
+ goto erret;
+
+ {Int4 _num_ ;
+ for( _num_ = 0; _num_ < ptr -> _num_ids; _num_ ++){
+ av.intvalue = (ptr -> ids) [_num_];
+ if ( ! AsnWrite(aip, TAXON_ID_LIST_ids_E, & av)) goto erret;
+ }}
+
+ if (! AsnCloseStruct (aip, TAXON_ID_LIST_ids, (Pointer) ptr -> ids))
+ goto erret;
+ }
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
+
+
+/**************************************************
+*
+* GeneticCodeListAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL GeneticCodeListAsnWrite (GeneticCodeListPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, GENETICCODELIST);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ av.intvalue = (int) ptr -> genomic;
+ if ( ! AsnWrite(aip,GENETICCODELIST_genomic, &av)) goto erret;
+ av.intvalue = (int) ptr -> mitochondrial;
+ if ( ! AsnWrite(aip,GENETICCODELIST_mitochondrial, &av)) goto erret;
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
+
+
+/**************************************************
+*
+* TaxCompleteListAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxCompleteListAsnWrite (TaxCompleteListPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAX_COMPLETE_LIST);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ av.intvalue = (int) ptr -> num;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_LIST_num, &av)) goto erret;
+ if (ptr -> info != NULL){
+ if (! AsnOpenStruct (aip, TAX_COMPLETE_LIST_info, (Pointer) ptr -> info))
+ goto erret;
+
+ {TaxCompletePtr current;
+ for(current=ptr -> info; current; current = current -> next){
+ if ( ! TaxCompleteAsnWrite(current,aip,TAX_COMPLETE_LIST_info_E)) goto erret;
+ }}
+
+ if (! AsnCloseStruct (aip, TAX_COMPLETE_LIST_info, (Pointer) ptr -> info))
+ goto erret;
+ }
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
+
+
+/**************************************************
+*
+* TaxonIdAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxonIdAsnWrite (TaxonIdPtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAXON_ID);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ av.intvalue = (int) ptr -> id;
+ if ( ! AsnWrite(aip,TAXON_ID_id, &av)) goto erret;
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
+
+
+/**************************************************
+*
+* TaxCompleteAsnWrite()
+*
+**************************************************/
+Boolean LIBCALL TaxCompleteAsnWrite (TaxCompletePtr ptr, AsnIoPtr aip, AsnTypePtr orig)
+{
+ Boolean retval = FALSE;
+ DataVal av;
+ AsnTypePtr atp;
+
+ if (aip == NULL) return FALSE;
+
+
+ if ( ! loaded){
+ if ( ! _AsnLoad ())
+ goto erret;
+ amp = AsnAllModPtr();
+ loaded = TRUE;
+ }
+ atp = AsnLinkType(orig, TAX_COMPLETE);
+ if(atp == NULL) {AsnNullValueMsg(aip,atp); goto erret;}
+ if (! AsnOpenStruct (aip, atp, (Pointer) ptr)) goto erret;
+
+ if (ptr -> sciname != NULL){
+ av.ptrvalue = (Pointer) ptr -> sciname;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_sciname, &av)) goto erret;
+ }
+ if (ptr -> comname != NULL){
+ av.ptrvalue = (Pointer) ptr -> comname;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_comname, &av)) goto erret;
+ }
+ if (ptr -> synonyms != NULL){
+ av.ptrvalue = (Pointer) ptr -> synonyms;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_synonyms, &av)) goto erret;
+ }
+ av.intvalue = (int) ptr -> id_gc;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_id_gc, &av)) goto erret;
+ if (ptr -> name_gc != NULL){
+ av.ptrvalue = (Pointer) ptr -> name_gc;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_name_gc, &av)) goto erret;
+ }
+ av.intvalue = (int) ptr -> id_mgc;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_id_mgc, &av)) goto erret;
+ if (ptr -> name_mgc != NULL){
+ av.ptrvalue = (Pointer) ptr -> name_mgc;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_name_mgc, &av)) goto erret;
+ }
+ if (ptr -> gb_div != NULL){
+ av.ptrvalue = (Pointer) ptr -> gb_div;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_gb_div, &av)) goto erret;
+ }
+ if (ptr -> embl_code != NULL){
+ av.ptrvalue = (Pointer) ptr -> embl_code;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_embl_code, &av)) goto erret;
+ }
+ if (ptr -> lineage != NULL){
+ av.ptrvalue = (Pointer) ptr -> lineage;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_lineage, &av)) goto erret;
+ }
+ av.boolvalue = (int) ptr -> is_species_level;
+ if ( ! AsnWrite(aip,TAX_COMPLETE_is_species_level, &av)) goto erret;
+ if (! AsnCloseStruct (aip, atp, (Pointer) ptr)) goto erret;
+ retval = TRUE;
+erret:AsnUnlinkType(orig);
+ return retval;
+}
diff --git a/network/taxon1/stdalone/objtax0.h b/network/taxon1/stdalone/objtax0.h
new file mode 100644
index 00000000..393e6329
--- /dev/null
+++ b/network/taxon1/stdalone/objtax0.h
@@ -0,0 +1,204 @@
+/*
+*
+*
+* RCS Modification History:
+* $Log: objtax0.h,v $
+* Revision 6.0 1997/08/25 18:42:23 madden
+* Revision changed to 6.0
+*
+* Revision 1.1 1996/02/05 14:51:02 soussov
+* Initial revision
+*
+*/
+
+
+
+/**************************************************
+*
+* Generated objects for Module NCBI-Taxon0
+*
+**************************************************/
+
+
+/**************************************************
+*
+* Taxon0Req
+*
+**************************************************/
+typedef ValNode Taxon0Req;
+typedef ValNodePtr Taxon0ReqPtr;
+#define Taxon0Req_init 1 /* NULL */
+#define Taxon0Req_getid 2 /* Taxon-name */
+#define Taxon0Req_getref 3 /* INTEGER */
+#define Taxon0Req_getchildren 4 /* INTEGER */
+#define Taxon0Req_getparents 5 /* INTEGER */
+#define Taxon0Req_getgeneticcode 6 /* INTEGER */
+#define Taxon0Req_gettaxonline 7 /* INTEGER */
+#define Taxon0Req_getdivision 8 /* INTEGER */
+#define Taxon0Req_getcomplete 9 /* Taxon-id-name */
+#define Taxon0Req_fini 10 /* NULL */
+
+
+Taxon0ReqPtr LIBCALL Taxon0ReqFree PROTO ((Taxon0ReqPtr ));
+Taxon0ReqPtr LIBCALL Taxon0ReqAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL Taxon0ReqAsnWrite PROTO (( Taxon0ReqPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxonName
+*
+**************************************************/
+typedef ValNode TaxonName;
+typedef ValNodePtr TaxonNamePtr;
+#define TaxonName_taxname 1 /* VisibleString */
+#define TaxonName_common 2 /* VisibleString */
+#define TaxonName_tax_synonym 3 /* VisibleString */
+#define TaxonName_com_synonym 4 /* VisibleString */
+
+
+TaxonNamePtr LIBCALL TaxonNameFree PROTO ((TaxonNamePtr ));
+TaxonNamePtr LIBCALL TaxonNameAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxonNameAsnWrite PROTO (( TaxonNamePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxonIdName
+*
+**************************************************/
+typedef ValNode TaxonIdName;
+typedef ValNodePtr TaxonIdNamePtr;
+#define TaxonIdName_id 1 /* INTEGER */
+#define TaxonIdName_name 2 /* VisibleString */
+
+
+TaxonIdNamePtr LIBCALL TaxonIdNameFree PROTO ((TaxonIdNamePtr ));
+TaxonIdNamePtr LIBCALL TaxonIdNameAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxonIdNameAsnWrite PROTO (( TaxonIdNamePtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* Taxon0Resp
+*
+**************************************************/
+typedef ValNode Taxon0Resp;
+typedef ValNodePtr Taxon0RespPtr;
+#define Taxon0Resp_error 1 /* INTEGER */
+#define Taxon0Resp_init 2 /* NULL */
+#define Taxon0Resp_getid 3 /* Taxon-id-list */
+#define Taxon0Resp_getref 4 /* Org-ref */
+#define Taxon0Resp_gettaxon 5 /* Taxon-id-list */
+#define Taxon0Resp_getgeneticcode 6 /* GeneticCodeList */
+#define Taxon0Resp_gettaxonline 7 /* VisibleString */
+#define Taxon0Resp_getdivision 8 /* VisibleString */
+#define Taxon0Resp_getcomplete 9 /* Tax-complete-list */
+#define Taxon0Resp_fini 10 /* NULL */
+
+
+Taxon0RespPtr LIBCALL Taxon0RespFree PROTO ((Taxon0RespPtr ));
+Taxon0RespPtr LIBCALL Taxon0RespAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL Taxon0RespAsnWrite PROTO (( Taxon0RespPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxonIdList
+*
+**************************************************/
+typedef struct struct_Taxon_id_list {
+ Int4 _num_ids;
+ Int4 PNTR ids;
+} TaxonIdList, PNTR TaxonIdListPtr;
+
+
+TaxonIdListPtr LIBCALL TaxonIdListFree PROTO ((TaxonIdListPtr ));
+TaxonIdListPtr LIBCALL TaxonIdListNew PROTO (( void ));
+TaxonIdListPtr LIBCALL TaxonIdListAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxonIdListAsnWrite PROTO (( TaxonIdListPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* GeneticCodeList
+*
+**************************************************/
+typedef struct struct_GeneticCodeList {
+ Int4 genomic;
+ Int4 mitochondrial;
+} GeneticCodeList, PNTR GeneticCodeListPtr;
+
+
+GeneticCodeListPtr LIBCALL GeneticCodeListFree PROTO ((GeneticCodeListPtr ));
+GeneticCodeListPtr LIBCALL GeneticCodeListNew PROTO (( void ));
+GeneticCodeListPtr LIBCALL GeneticCodeListAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL GeneticCodeListAsnWrite PROTO (( GeneticCodeListPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxonId
+*
+**************************************************/
+typedef struct struct_Taxon_id {
+ Int4 id;
+} TaxonId, PNTR TaxonIdPtr;
+
+
+TaxonIdPtr LIBCALL TaxonIdFree PROTO ((TaxonIdPtr ));
+TaxonIdPtr LIBCALL TaxonIdNew PROTO (( void ));
+TaxonIdPtr LIBCALL TaxonIdAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxonIdAsnWrite PROTO (( TaxonIdPtr , AsnIoPtr, AsnTypePtr));
+
+
+
+/**************************************************
+*
+* TaxComplete
+*
+**************************************************/
+typedef struct struct_Tax_complete {
+ struct struct_Tax_complete PNTR next;
+ CharPtr sciname;
+ CharPtr comname;
+ CharPtr synonyms;
+ Int4 id_gc;
+ CharPtr name_gc;
+ Int4 id_mgc;
+ CharPtr name_mgc;
+ CharPtr gb_div;
+ CharPtr embl_code;
+ CharPtr lineage;
+ Uint1 is_species_level;
+} TaxComplete, PNTR TaxCompletePtr;
+
+
+TaxCompletePtr LIBCALL TaxCompleteFree PROTO ((TaxCompletePtr ));
+TaxCompletePtr LIBCALL TaxCompleteNew PROTO (( void ));
+TaxCompletePtr LIBCALL TaxCompleteAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxCompleteAsnWrite PROTO (( TaxCompletePtr , AsnIoPtr, AsnTypePtr));
+
+
+/**************************************************
+*
+* TaxCompleteList
+*
+**************************************************/
+typedef struct struct_Tax_complete_list {
+ Int4 num;
+ TaxCompletePtr info;
+} TaxCompleteList, PNTR TaxCompleteListPtr;
+
+
+TaxCompleteListPtr LIBCALL TaxCompleteListFree PROTO ((TaxCompleteListPtr ));
+TaxCompleteListPtr LIBCALL TaxCompleteListNew PROTO (( void ));
+TaxCompleteListPtr LIBCALL TaxCompleteListAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
+Boolean LIBCALL TaxCompleteListAsnWrite PROTO (( TaxCompleteListPtr , AsnIoPtr, AsnTypePtr));
+
diff --git a/network/taxon1/stdalone/rank.c b/network/taxon1/stdalone/rank.c
new file mode 100644
index 00000000..e18d5d0b
--- /dev/null
+++ b/network/taxon1/stdalone/rank.c
@@ -0,0 +1,151 @@
+/****************************
+ * File: rank.c
+ * Description: taxonomy rank functions
+ */
+
+#include <stdlib.h>
+#include "tax_cmmn.h"
+
+/*------------------------------------------------
+ * load_bin - load ranks from binary file
+ */
+static int load_bin(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ int i;
+ Int2 t;
+ _rankPtr rank;
+ int nof_ranks= tax_getNofRanks(ctl);
+
+ if(nof_ranks < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_RANKS, "load_bin: The number of ranks <= 1");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_RANK_FILE), "rb")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_bin: Can't open rank file");
+ return -1;
+ }
+
+ if((rank= malloc(sizeof(_rank) * nof_ranks)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for ranks");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_ranks; i++) {
+ rank[i].rank_id= fsb_getInt2(f);
+ rank[i].rank_txt= fsb_getString(f);
+ }
+
+ ctl->rank= rank;
+ fclose(f);
+ return 0;
+}
+
+/*---------------------------------------------------
+ * load_txt - load ranks from text file
+ */
+static int load_txt(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ int i;
+ _rankPtr rank;
+ int nof_ranks= tax_getNofRanks(ctl);
+
+
+ if(nof_ranks < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_RANKS, "load_txt: The number of ranks <= 1");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_RANK_FILE), "r")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_txt: Can't open rank file");
+ return -1;
+ }
+
+ if((rank= malloc(sizeof(_rank) * nof_ranks)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_txt: Not enaugh memory for ranks");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_ranks; i++) {
+ rank[i].rank_id= fs_getInt(f, tax_getMarker(ctl));
+ rank[i].rank_txt= fs_getString(f, tax_getMarker(ctl));
+ }
+
+ ctl->rank= rank;
+ fclose(f);
+ return 0;
+}
+
+static int load_asn(_taxDBCtlPtr ctl)
+{
+ return -10; /* not done yet */
+}
+
+/*==============================================================
+ * tax_freeRanks - free rank's memory
+ */
+void tax_freeRanks(_taxDBCtlPtr ctl)
+{
+ int nof_ranks= tax_getNofRanks(ctl);
+ int i;
+ _rankPtr r= ctl->rank;
+
+ if((r == NULL) || (nof_ranks < 1)) return;
+
+ for(i= 0; i != nof_ranks; i++) {
+ if(r[i].rank_txt != NULL) free(r[i].rank_txt);
+ }
+ free(r);
+ ctl->rank= NULL;
+}
+
+int tax_loadRanks(_taxDBCtlPtr ctl)
+{
+
+ if(ctl->rank != NULL) tax_freeRanks(ctl);
+
+ switch(tax_getDbType(ctl)) {
+ case TAX_BIN: return load_bin(ctl);
+ case TAX_TXT: return load_txt(ctl);
+ case TAX_ASN: return load_asn(ctl);
+ default: break;
+ }
+
+ tax_outMsg(TAX_ERROR, TAX_ERR_FILE_TYPE, "tax_loadRanks: Wrong file type for rank");
+ return -1;
+}
+
+char* tax_getRankById(_taxDBCtlPtr ctl, Int2 id)
+{
+ int i;
+ _rankPtr r= ctl->rank;
+ int nof_ranks= tax_getNofRanks(ctl);
+
+ for(i= 0; i < nof_ranks; i++) {
+ if(r[i].rank_id == id) return r[i].rank_txt;
+ }
+
+ return NULL;
+}
+
+Int2 tax_getRankId(_taxDBCtlPtr ctl, CharPtr rank_name)
+{
+ int i;
+ _rankPtr r= ctl->rank;
+ int nof_ranks= tax_getNofRanks(ctl);
+
+ for(i= 0; i < nof_ranks; i++) {
+ if(strcmp(r[i].rank_txt, rank_name) == 0) {
+ return r[i].rank_id;
+ }
+ }
+ return -1;
+}
+
+
+
+
diff --git a/network/taxon1/stdalone/rex_util.c b/network/taxon1/stdalone/rex_util.c
new file mode 100644
index 00000000..c362bd82
--- /dev/null
+++ b/network/taxon1/stdalone/rex_util.c
@@ -0,0 +1,89 @@
+/*******************************************
+ * File: rex_util.c
+ * Description: regular expression searcher
+ */
+
+#include "rex_util.h"
+#include <string.h>
+#include <stdlib.h>
+
+rex_handler rex_setExpr(char* re_in, int mode)
+{
+ struct re_pattern_buffer *buf;
+ int i;
+ char* trn;
+ char* re;
+
+
+ /* replace "*" with ".*" , "+" with ".+" and "?" with ".?" */
+ if((re= malloc(strlen(re_in)*2 + 1)) == NULL) return NULL;
+
+ for(i= 0; *re_in != '\0'; i++, re_in++) {
+ if((*re_in == '*') || (*re_in == '+') || (*re_in == '?')) {
+ if((i == 0) || (re[i-1] != '\\')) {
+ re[i++]= '.';
+ }
+ }
+ re[i]= *re_in;
+ }
+ re[i]= '\0';
+
+ if((buf= malloc(sizeof(struct re_pattern_buffer))) == NULL) return NULL;
+
+ memset(buf, 0, sizeof(struct re_pattern_buffer));
+
+ /* prepare re_syntax_options */
+#if 1
+ re_syntax_options= RE_BACKSLASH_ESCAPE_IN_LISTS |
+ RE_CONTEXT_INDEP_ANCHORS |
+ RE_CONTEXT_INDEP_OPS |
+ RE_INTERVALS |
+ RE_NO_BK_BRACES |
+ RE_NO_BK_VBAR;
+#else
+ re_syntax_options= RE_SYNTAX_AWK;
+#endif
+
+ /* initialize some fields in pattern buffer */
+ buf->buffer= NULL;
+ buf->allocated= 0;
+ buf->fastmap= NULL;
+ if(mode == 0) {
+ buf->translate= NULL;
+ }
+ else {
+ if((trn= malloc(256)) != NULL) {
+ for(i= 0; i != 256; i++) trn[i]= i;
+ if((mode & REX_NO_CASE) != 0) {
+ for(i= 1; i != 256; i++) trn[i]= toupper(i);
+ }
+ if((mode & REX_NO_SPACE) != 0) {
+ for(i= 1; i != 256; i++) {
+ if(isspace(i)) trn[i]= ' ';
+ }
+ }
+ }
+ buf->translate= trn;
+ }
+
+ /* compile the regular expression */
+ if((trn= (char *) re_compile_pattern(re, strlen(re), buf)) != NULL) {
+ fprintf(stderr,"Error in regular expression: %s\n", trn);
+ free(buf);
+ free(re);
+ return NULL;
+ }
+
+ free(re);
+ return buf;
+}
+
+int rex_cmp(rex_handler re, char* str)
+{
+ int res;
+
+ res= re_match(re, str, strlen(str), 0, NULL);
+ return (res < 0)? 0 : 1;
+}
+
+
diff --git a/network/taxon1/stdalone/rex_util.h b/network/taxon1/stdalone/rex_util.h
new file mode 100644
index 00000000..b670a968
--- /dev/null
+++ b/network/taxon1/stdalone/rex_util.h
@@ -0,0 +1,21 @@
+/*******************************************
+ * File: rex_util.h
+ * Description: regular expression searcher
+ */
+
+#ifndef REX_UTIL_H_DONE
+#define REX_UTIL_H_DONE
+
+#include <string.h>
+#include <stdio.h>
+#include <regex.h>
+
+typedef struct re_pattern_buffer * rex_handler;
+
+#define REX_NO_CASE 0x1
+#define REX_NO_SPACE 0x2
+
+rex_handler rex_setExpr(char* expr, int mode);
+int rex_cmp(rex_handler re, char* str);
+
+#endif
diff --git a/network/taxon1/stdalone/tax1proc.c b/network/taxon1/stdalone/tax1proc.c
new file mode 100644
index 00000000..f1be40b2
--- /dev/null
+++ b/network/taxon1/stdalone/tax1proc.c
@@ -0,0 +1,159 @@
+/*************************
+ * File: tax1proc.c
+ * Description: old stile client functions
+ */
+
+#include <taxinc.h>
+#include <objsset.h>
+#include <taxarch.h>
+
+#if 0
+Boolean TaxArchInit(void)
+{
+ return tax1_init();
+}
+
+Boolean TaxArchFini(void)
+{
+ tax1_fini();
+ return TRUE;
+}
+#endif
+
+TaxonIdListPtr TaxArchGetTaxId(TaxonNamePtr tnp)
+{
+ TaxonIdListPtr res= TaxonIdListNew();
+
+ res->_num_ids= tax1_getAllTaxIdByName(tnp->data.ptrvalue, &res->ids);
+ return res;
+}
+
+TaxonIdListPtr TaxArchGetChildren(Int4 id_tax)
+{
+ TaxonIdListPtr res= TaxonIdListNew();
+
+ res->_num_ids= tax1_getChildren(id_tax, &res->ids);
+ return res;
+}
+
+TaxonIdListPtr TaxArchGetParents(Int4 id_tax)
+{
+ TaxonIdListPtr res= TaxonIdListNew();
+ Int4 pid;
+
+ pid= tax1_getParent(id_tax);
+ if(pid > 0) {
+ res->_num_ids= 1;
+ res->ids= MemNew(sizeof(Int4));
+ *(res->ids)= pid;
+ }
+ else {
+ res->_num_ids= 0;
+ res->ids= NULL;
+ }
+ return res;
+}
+
+OrgRefPtr TaxArchGetRef(Int4 id_tax)
+{
+ Taxon1DataPtr res;
+ OrgRefPtr orp;
+
+ res= tax1_getbyid(id_tax);
+ if(res == NULL) return NULL;
+ orp= res->org;
+ res->org= NULL;
+ Taxon1DataFree(res);
+ return orp;
+}
+
+CharPtr TaxArchGetTaxonLine(Int4 id_tax)
+{
+ OrgRefPtr orp;
+ CharPtr lin;
+
+ orp= tax1_getOrgRef(id_tax, NULL, NULL, NULL);
+ if((orp == NULL) || (orp->orgname == NULL)) {
+ return NULL;
+ }
+ lin= StringSave(orp->orgname->lineage);
+ return lin;
+}
+
+CharPtr TaxArchGetWithinDiv(Int4 id_tax)
+{
+ CharPtr division= MemNew(8);
+ OrgRefPtr orp= tax1_getOrgRef(id_tax, NULL, division, NULL);
+
+ if(orp == NULL) {
+ MemFree(division);
+ return NULL;
+ }
+
+ return division;
+}
+
+GeneticCodeListPtr TaxArchGetGeneticCode(Int4 id_tax)
+{
+ OrgRefPtr orp;
+ GeneticCodeListPtr gclp;
+
+ orp= tax1_getOrgRef(id_tax, NULL, NULL, NULL);
+ if((orp == NULL) || (orp->orgname == NULL)) {
+ return NULL;
+ }
+ gclp= GeneticCodeListNew();
+ gclp->genomic= orp->orgname->gcode;
+ gclp->mitochondrial= orp->orgname->mgcode;
+ return gclp;
+}
+
+TaxCompleteListPtr TaxArchGetComplete(TaxonIdNamePtr tinp)
+{
+ OrgRefPtr orp;
+ TaxCompleteListPtr tclp;
+ TaxCompletePtr tcp;
+ Int4 id_tax;
+ char embl[8], divis[8];
+ int is_spec;
+
+ if(tinp->choice == TaxonIdName_id) {
+ id_tax= tinp->data.intvalue;
+ }
+ else if(tinp->choice == TaxonIdName_name) {
+ id_tax= tax1_getTaxIdByName(tinp->data.ptrvalue);
+ }
+ else {
+ id_tax= -1;
+ }
+
+ if(id_tax <= 0) return NULL;
+
+ *embl= *divis= '\0';
+ orp= tax1_getOrgRef(id_tax, &is_spec, divis, embl);
+ if(orp == NULL) return NULL;
+
+ tclp= TaxCompleteListNew();
+ tclp->num= 1;
+ tclp->info= tcp= TaxCompleteNew();
+
+ tcp->next= NULL;
+ tcp->sciname= (orp->taxname == NULL)? NULL : StringSave(orp->taxname);
+ tcp->comname= (orp->common == NULL)? NULL : StringSave(orp->common);
+ tcp->synonyms= NULL;
+ tcp->gb_div= (*divis == '\0')? NULL : StringSave(divis);
+ tcp->embl_code= (*embl == '\0')? NULL : StringSave(embl);
+ tcp->is_species_level= is_spec;
+ if(orp->orgname != NULL) {
+ tcp->id_gc= orp->orgname->gcode;
+ tcp->id_mgc= orp->orgname->mgcode;
+ tcp->lineage= (orp->orgname->lineage == NULL)? NULL : StringSave(orp->orgname->lineage);
+ }
+ tcp->name_gc= tax1_getGCName(tcp->id_gc);
+ tcp->name_mgc= tax1_getGCName(tcp->id_mgc);
+
+ return tclp;
+}
+
+
+
diff --git a/network/taxon1/stdalone/tax_cmmn.h b/network/taxon1/stdalone/tax_cmmn.h
new file mode 100644
index 00000000..b1098e7f
--- /dev/null
+++ b/network/taxon1/stdalone/tax_cmmn.h
@@ -0,0 +1,232 @@
+/**************************
+ * File: tax_cmmn.h
+ * Description: common types, constants and variables
+ */
+
+#ifndef TAX_CMMN_H_DONE
+#define TAX_CMMN_H_DONE
+
+#include <ncbi.h>
+#include "taxobj.h"
+#include "fsutils.h"
+
+#define NOF_FILES 7
+
+/*----------------------------------
+ * File types
+ */
+
+#define TAX_BIN 'b'
+#define TAX_TXT 't'
+#define TAX_ASN '1'
+
+/*----------------------------------
+ * message types
+ */
+#define TAX_MSG 0
+#define TAX_WARN 1
+#define TAX_ERROR -1
+
+/*----------------------------------
+ * message codes
+ */
+/* warnings */
+#define TAX_WARN_NO_RANKS 100
+#define TAX_WARN_NO_CLASSES 101
+#define TAX_WARN_NO_DIVS 102
+#define TAX_WARN_NO_GC 103
+#define TAX_WARN_EMPTY_TREE 104
+#define TAX_WARN_NO_NAMES 105
+
+/* errors */
+#define TAX_ERR_NO_MEMORY 1000
+#define TAX_ERR_NO_FILE 1001
+#define TAX_ERR_FILE_TYPE 1002
+#define TAX_ERR_WRONG_FILE 1003
+
+/*----------------------------------
+ * file indexes
+ */
+#define TAX_TREE_FILE 0
+#define TAX_NAME_FILE 1
+#define TAX_NODE_FILE 2
+#define TAX_GC_FILE 3
+#define TAX_RANK_FILE 4
+#define TAX_CLASS_FILE 5
+#define TAX_DIVS_FILE 6
+/*----------------------------------
+ * various constants
+ */
+#define CTL_FILE_MARKER "\n"
+
+#define TAX_DIV_TXT 0
+#define TAX_DIV_CDE 1
+#define TAX_DIV_COM 2
+
+#define TAX_GC_NM 0
+#define TAX_GC_ABBREV 1
+#define TAX_GC_CDE 2
+#define TAX_GC_STARTS 3
+
+#define TAX_NAME_SEARCH 0
+#define TAX_RE_SEARCH 1
+#define TAX_TOKEN_SEARCH 2
+#define TAX_ALPHANUM_SEARCH 3
+
+/*---------------------------------
+ * private types
+ */
+
+typedef struct t_rank {
+ Int2 rank_id;
+ CharPtr rank_txt;
+} _rank, PNTR _rankPtr;
+
+typedef struct t_nmclass {
+ Int2 class_cde;
+ CharPtr class_txt;
+} _nmclass, PNTR _nmclassPtr;
+
+typedef struct t_division {
+ Int2 div_id;
+ char div_cde[4];
+ CharPtr div_txt;
+ CharPtr div_comments_txt;
+} _division, PNTR _divisionPtr;
+
+typedef struct t_gencode {
+ Int2 gc_id;
+ char gc_abbrev[6];
+ CharPtr gc_nm;
+ CharPtr gc_cde;
+ CharPtr gc_starts;
+} _gencode, PNTR _gencodePtr;
+
+typedef struct t_hashItem {
+ _taxNamePtr tax_name;
+ struct t_hashItem* next;
+} _hashItem, PNTR _hashItemPtr;
+
+#if 0
+typedef struct t_taxName {
+ int tax_id;
+ _TINY class_cde;
+ CharPtr name_txt;
+} _taxName, PNTR _taxNamePtr;
+#endif
+
+typedef _taxCtlNodePtr _treePtr;
+typedef _taxCtlNode _tree;
+
+/*=================================
+ * public types
+ */
+
+typedef struct t_taxDBCtl {
+ _taxCtlNodePtr tree;
+ _hashItemPtr hashTbl;
+ _taxNamePtr names;
+ _rankPtr rank;
+ _nmclassPtr nmclass;
+ _divisionPtr division;
+ _gencodePtr gc;
+ FILE* nodefile;
+ Int4 MaxId;
+ Int4 NofNodes;
+ Int4 NofNames;
+ Int2 NofRanks;
+ Int2 NofDivs;
+ Int2 NofClasses;
+ Int2 NofGCs;
+ CharPtr path;
+ CharPtr FileName[NOF_FILES];
+ char DbType;
+ char DbFieldMarker[7];
+} _taxDBCtl;
+
+typedef _taxDBCtl PNTR _taxDBCtlPtr;
+
+/*===================================
+ * prototypes and macros
+ */
+
+typedef void (*tax_MessageHandler)(int, int, CharPtr);
+
+#define tax_getNodeRank(c, i) ((c)->tree[i].rank)
+#define tax_nodeGBHide(c, i) ((c)->tree[i].flags & GB_HIDDEN)
+
+_taxDBCtlPtr tax_loadDBCtl(CharPtr DBPath, CharPtr ctlFileName);
+_taxDBCtlPtr tax_loadTaxDB(CharPtr DBPath, CharPtr ctlFileName);
+Int4 tax_getMaxId(_taxDBCtlPtr ctl);
+Int4 tax_getNofNodes(_taxDBCtlPtr ctl);
+Int4 tax_getNofNames(_taxDBCtlPtr ctl);
+Int2 tax_getNofRanks(_taxDBCtlPtr ctl);
+Int2 tax_getNofDivs(_taxDBCtlPtr ctl);
+Int2 tax_getNofClasses(_taxDBCtlPtr ctl);
+Int2 tax_getNofGCs(_taxDBCtlPtr ctl);
+void tax_closeDbCtl(_taxDBCtlPtr ctl);
+void tax_outMsg(int msg_type, int msg_code, CharPtr msg_txt);
+void tax_setMsgHndl(tax_MessageHandler f);
+
+#define tax_getDbType(x) ((x)->DbType)
+#define tax_getMarker(x) ((x)->DbFieldMarker)
+#define tax_getFileName(x, n) fs_fileName((x)->path, (x)->FileName[n])
+
+/*-------------------------------------
+ * rank.c
+ */
+void tax_freeRanks(_taxDBCtlPtr ctl);
+int tax_loadRanks(_taxDBCtlPtr ctl);
+CharPtr tax_getRankById(_taxDBCtlPtr ctl, Int2 id);
+Int2 tax_getRankId(_taxDBCtlPtr ctl, CharPtr rank_name);
+
+/*-------------------------------------
+ * nmclass.c
+ */
+void tax_freeClasses(_taxDBCtlPtr ctl);
+int tax_loadClasses(_taxDBCtlPtr ctl);
+CharPtr tax_getClassById(_taxDBCtlPtr ctl, Int2 id);
+Int2 tax_getClassId(_taxDBCtlPtr ctl, CharPtr class_name);
+
+
+/*-------------------------------------
+ * division.c
+ */
+void tax_freeDivs(_taxDBCtlPtr ctl);
+int tax_loadDivs(_taxDBCtlPtr ctl);
+CharPtr tax_getDivById(_taxDBCtlPtr ctl, Int2 id, Int2 mode);
+Int2 tax_getDivId(_taxDBCtlPtr ctl, CharPtr txt, Int2 mode);
+
+/*-------------------------------------
+ * gc.c
+ */
+void tax_freeGCs(_taxDBCtlPtr ctl);
+int tax_loadGCs(_taxDBCtlPtr ctl);
+CharPtr tax_getGCById(_taxDBCtlPtr ctl, Int2 id, Int2 mode);
+Int2 tax_getGCId(_taxDBCtlPtr ctl, CharPtr txt, Int2 mode);
+
+/*-------------------------------------
+ * tree.c
+ */
+void tax_freeTree(_taxDBCtlPtr ctl);
+int tax_loadTree(_taxDBCtlPtr ctl);
+void tax_freeNode(_taxNodePtr node);
+_taxNodePtr tax_getNode(_taxDBCtlPtr ctl, Int4 id);
+Int2 tax_getLin(_taxDBCtlPtr ctl, Int4 id, Int4Ptr lin);
+#define tax_getParent(c, i) ((c)->tree[i].parent)
+#define tax_getChild(c, i) ((c)->tree[i].child)
+#define tax_getSibling(c, i) ((c)->tree[i].sibling)
+#define tax_getNodeKey(c, i) ((c)->tree[i].dataKey)
+#define tax_getNamesKey(c, i) ((c)->tree[i].namesKey)
+
+
+/*-------------------------------------
+ * taxname.c
+ */
+void tax_freeNames(_taxDBCtlPtr ctl);
+int tax_loadNames(_taxDBCtlPtr ctl);
+int tax_findByName(_taxDBCtlPtr ctl, CharPtr sname, int mode, _taxNamePtr** nameList);
+_taxNamePtr tax_findOrgName(_taxDBCtlPtr ctl, Int4 id);
+Int4 tax_getDesignator(CharPtr name);
+
+#endif
diff --git a/network/taxon1/stdalone/taxctl.c b/network/taxon1/stdalone/taxctl.c
new file mode 100644
index 00000000..614258e8
--- /dev/null
+++ b/network/taxon1/stdalone/taxctl.c
@@ -0,0 +1,349 @@
+/**************************
+ * File: taxctl.c
+ * Description: catalog file utility
+ */
+
+#include "tax_cmmn.h"
+#include "fsutils.h"
+
+#define DEFAULT_MARKER "\t|\n"
+
+static tax_MessageHandler msg_hndl= NULL;
+
+void tax_setMsgHndl(tax_MessageHandler f)
+{
+ msg_hndl= f;
+}
+
+void tax_outMsg(int msg_type, int msg_code, CharPtr msg_txt)
+{
+ if(msg_hndl != NULL) {
+ (*msg_hndl)(msg_type, msg_code, msg_txt);
+ }
+ else {
+ char* et;
+
+ et= (msg_type == TAX_MSG)? "NOTE" : ((msg_type == TAX_WARN)? "WARNING" : "ERROR");
+
+ fprintf(stderr, "%s: File based taxonomy: %s\n", et, msg_txt);
+ if(msg_type == TAX_ERROR) {
+ fprintf(stderr, "The taxonomy files are corrupted\n");
+ exit(1);
+ }
+ }
+}
+
+static char default_DB[]= "dbctl.tax";
+
+_taxDBCtlPtr tax_loadDBCtl(CharPtr DBPath, CharPtr ctlFileName)
+{
+ FILE* f;
+ _taxDBCtlPtr pctl;
+ CharPtr resp;
+ int i;
+
+ if(ctlFileName == NULL) ctlFileName= default_DB;
+
+ if((f= fopen(fs_fileName(DBPath, ctlFileName), "r")) == NULL) return NULL;
+
+ if((pctl= malloc(sizeof(_taxDBCtl))) == NULL) return NULL;
+ memset(pctl, 0, sizeof(_taxDBCtl));
+
+ pctl->path= StringSave(DBPath);
+
+ /* Get DB type (bin, txt or ASN */
+ resp= fs_getString(f, CTL_FILE_MARKER);
+ if(resp == NULL) {
+ free(pctl);
+ return NULL;
+ }
+
+ pctl->DbType= resp[0];
+ free(resp);
+ if(pctl->DbType != TAX_ASN) {
+ /* not ASN.1 database */
+ pctl->MaxId= fs_getLong(f, CTL_FILE_MARKER);
+ pctl->NofNodes= fs_getLong(f, CTL_FILE_MARKER);
+ pctl->NofNames= fs_getLong(f, CTL_FILE_MARKER);
+ pctl->NofRanks= fs_getInt(f, CTL_FILE_MARKER);
+ pctl->NofDivs= fs_getInt(f, CTL_FILE_MARKER);
+ pctl->NofClasses= fs_getInt(f, CTL_FILE_MARKER);
+ pctl->NofGCs= fs_getInt(f, CTL_FILE_MARKER);
+
+ for(i= 0; i != NOF_FILES; i++) {
+ pctl->FileName[i]= fs_getString(f, CTL_FILE_MARKER);
+ }
+
+ resp= fs_getString(f, CTL_FILE_MARKER);
+ if((resp != NULL) && (resp[0] != '\0')) {
+ strncpy(pctl->DbFieldMarker, resp, 6);
+ pctl->DbFieldMarker[6]= '\0';
+ }
+ else {
+ strcpy(pctl->DbFieldMarker, DEFAULT_MARKER);
+ }
+
+ if(resp != NULL) free(resp);
+ }
+ else {
+ /* ASN.1 files */
+ /* ... */
+ }
+ pctl->nodefile= NULL;
+
+ return pctl;
+}
+
+Int4 tax_getMaxId(_taxDBCtlPtr ctl)
+{
+ if(ctl->MaxId > 0) return ctl->MaxId;
+
+ return (ctl->DbType == TAX_ASN)? (-1) : 0;
+}
+
+Int4 tax_getNofNodes(_taxDBCtlPtr ctl)
+{
+ if(ctl->NofNodes > 0) return ctl->NofNodes;
+
+ return (ctl->DbType == TAX_ASN)? (-1) : 0;
+}
+
+Int4 tax_getNofNames(_taxDBCtlPtr ctl)
+{
+ if(ctl->NofNames > 0) return ctl->NofNames;
+
+ return (ctl->DbType == TAX_ASN)? (-1) : 0;
+}
+
+Int2 tax_getNofRanks(_taxDBCtlPtr ctl)
+{
+ if(ctl->NofRanks > 0) return ctl->NofRanks;
+
+ return (ctl->DbType == TAX_ASN)? (-1) : 0;
+}
+
+Int2 tax_getNofDivs(_taxDBCtlPtr ctl)
+{
+ if(ctl->NofDivs > 0) return ctl->NofDivs;
+
+ return (ctl->DbType == TAX_ASN)? (-1) : 0;
+}
+
+Int2 tax_getNofClasses(_taxDBCtlPtr ctl)
+{
+ if(ctl->NofClasses > 0) return ctl->NofClasses;
+
+ return (ctl->DbType == TAX_ASN)? (-1) : 0;
+}
+
+Int2 tax_getNofGCs(_taxDBCtlPtr ctl)
+{
+ if(ctl->NofGCs > 0) return ctl->NofGCs;
+
+ return (ctl->DbType == TAX_ASN)? (-1) : 0;
+}
+
+void tax_closeDbCtl(_taxDBCtlPtr ctl)
+{
+ int i;
+
+ for(i= 0; i != NOF_FILES; i++) {
+ if(ctl->FileName[i] != NULL) free(ctl->FileName[i]);
+ }
+
+ free(ctl);
+}
+
+/*------------------------------------------------
+ * load_div - load divisions from binary file
+ */
+static int load_div(_taxDBCtlPtr ctl, FILE* f)
+{
+ int i;
+ _divisionPtr div;
+ int nof_divs= tax_getNofDivs(ctl);
+
+ if(nof_divs < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_DIVS, "load_bin: The number of divisions <= 1");
+ return 1;
+ }
+
+ if((div= malloc(sizeof(_division) * nof_divs)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for divisions");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_divs; i++) {
+ div[i].div_id= fsb_getInt2(f);
+ fsb_getBytes(f, 4, div[i].div_cde);
+ div[i].div_txt= fsb_getString(f);
+ div[i].div_comments_txt= fsb_getString(f);
+ }
+
+ ctl->division= div;
+ return 0;
+}
+
+/*------------------------------------------------
+ * load_gc - load GCs from binary file
+ */
+static int load_gc(_taxDBCtlPtr ctl, FILE* f)
+{
+ int i;
+ _gencodePtr GC;
+ int nof_GCs= tax_getNofGCs(ctl);
+
+ if(nof_GCs < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_GC, "load_bin: The number of GCs <= 1");
+ return 1;
+ }
+
+ if((GC= malloc(sizeof(_gencode) * nof_GCs)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for GCs");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_GCs; i++) {
+ GC[i].gc_id= fsb_getInt2(f);
+ fsb_getBytes(f, 6, GC[i].gc_abbrev);
+ GC[i].gc_nm= fsb_getString(f);
+ GC[i].gc_cde= fsb_getString(f);
+ GC[i].gc_starts= fsb_getString(f);
+ }
+
+ ctl->gc= GC;
+ return 0;
+}
+
+/*------------------------------------------------
+ * load_classes - load name classes from binary file
+ */
+static int load_classes(_taxDBCtlPtr ctl, FILE* f)
+{
+ int i;
+ Int2 t;
+ _nmclassPtr nmc;
+ int nof_nmcs= tax_getNofClasses(ctl);
+
+ if(nof_nmcs < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_CLASSES, "load_bin: The number of name classes <= 1");
+ return 1;
+ }
+
+ if((nmc= malloc(sizeof(_nmclass) * nof_nmcs)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for name classes");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_nmcs; i++) {
+ nmc[i].class_cde= fsb_getInt2(f);
+ nmc[i].class_txt= fsb_getString(f);
+ }
+
+ ctl->nmclass= nmc;
+ return 0;
+}
+
+/*------------------------------------------------
+ * load_rank - load ranks from binary file
+ */
+static int load_rank(_taxDBCtlPtr ctl, FILE* f)
+{
+ int i;
+ Int2 t;
+ _rankPtr rank;
+ int nof_ranks= tax_getNofRanks(ctl);
+
+ if(nof_ranks < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_RANKS, "load_bin: The number of ranks <= 1");
+ return 1;
+ }
+
+ if((rank= malloc(sizeof(_rank) * nof_ranks)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for ranks");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_ranks; i++) {
+ rank[i].rank_id= fsb_getInt2(f);
+ rank[i].rank_txt= fsb_getString(f);
+ }
+
+ ctl->rank= rank;
+ return 0;
+}
+
+
+static char data_file[]= "dbdata.dat";
+
+_taxDBCtlPtr tax_loadTaxDB(CharPtr DBPath, CharPtr ctlFileName)
+{
+ FILE* f;
+ _taxDBCtlPtr pctl;
+ CharPtr resp;
+ int i;
+ FILE* df;
+
+ if(ctlFileName == NULL) ctlFileName= default_DB;
+
+ if((f= fopen(fs_fileName(DBPath, ctlFileName), "r")) == NULL) return NULL;
+
+ if((pctl= malloc(sizeof(_taxDBCtl))) == NULL) return NULL;
+ memset(pctl, 0, sizeof(_taxDBCtl));
+
+ pctl->path= StringSave(DBPath);
+
+ /* Get DB type (bin, txt or ASN */
+ resp= fs_getString(f, CTL_FILE_MARKER);
+ if(resp == NULL) {
+ free(pctl);
+ return NULL;
+ }
+
+ pctl->DbType= resp[0];
+ free(resp);
+ if(pctl->DbType != TAX_ASN) {
+ /* not ASN.1 database */
+ pctl->MaxId= fs_getLong(f, CTL_FILE_MARKER);
+ pctl->NofNodes= fs_getLong(f, CTL_FILE_MARKER);
+ pctl->NofNames= fs_getLong(f, CTL_FILE_MARKER);
+ pctl->NofRanks= fs_getInt(f, CTL_FILE_MARKER);
+ pctl->NofDivs= fs_getInt(f, CTL_FILE_MARKER);
+ pctl->NofClasses= fs_getInt(f, CTL_FILE_MARKER);
+ pctl->NofGCs= fs_getInt(f, CTL_FILE_MARKER);
+
+ for(i= 0; i != NOF_FILES; i++) {
+ pctl->FileName[i]= fs_getString(f, CTL_FILE_MARKER);
+ }
+
+ resp= fs_getString(f, CTL_FILE_MARKER);
+ if((resp != NULL) && (resp[0] != '\0')) {
+ strncpy(pctl->DbFieldMarker, resp, 6);
+ pctl->DbFieldMarker[6]= '\0';
+ }
+ else {
+ strcpy(pctl->DbFieldMarker, DEFAULT_MARKER);
+ }
+
+ if(resp != NULL) free(resp);
+ }
+ else {
+ /* ASN.1 files */
+ /* ... */
+ }
+ pctl->nodefile= NULL;
+
+ if((df= fopen(fs_fileName(DBPath, data_file), "rb")) != NULL) {
+ load_div(pctl, df);
+ load_gc(pctl, df);
+ load_classes(pctl, df);
+ load_rank(pctl, df);
+ fclose(df);
+ }
+
+ return pctl;
+}
diff --git a/network/taxon1/stdalone/taxinc.h b/network/taxon1/stdalone/taxinc.h
new file mode 100644
index 00000000..6720c5d5
--- /dev/null
+++ b/network/taxon1/stdalone/taxinc.h
@@ -0,0 +1,130 @@
+/*****************************************
+ * File: taxinc.h
+ * Description: taxon1 API
+ */
+
+#ifndef TAXINC_H_DONE
+#define TAXINC_H_DONE
+
+#include <ncbi.h>
+#include <objfeat.h>
+
+#define struct_Org_ref orgref
+
+#include "objtax1.h"
+
+/* API functions prototypes */
+
+/*---------------------------------------------
+ * Taxon1 server init
+ * Returns: TRUE - OK
+ * FALSE - Can't open taxonomy database
+ */
+Boolean tax1_init();
+
+/*---------------------------------------------
+ * Taxon1 server fini (frees memory)
+ */
+
+void tax1_fini();
+
+/*---------------------------------------------
+ * Get organism by tax_id
+ * Returns: pointer to Taxon1Data if organism exists
+ * NULL - if tax_id wrong
+ *
+ * typedef struct struct_Taxon1_data {
+ * OrgRefPtr org;
+ * CharPtr div; genbank division ("MAM", "VIR", "PHG", ...)
+ * CharPtr embl_code; in common case first letters from genus-species pair
+ * Uint1 is_species_level; 1 if node on species level or below
+ * } Taxon1Data, PNTR Taxon1DataPtr;
+ *
+ * NOTE:
+ * Caller gets his own copy of OrgRef structure.
+ */
+
+Taxon1DataPtr tax1_getbyid(Int4 tax_id);
+
+/*----------------------------------------------
+ * Get organism by OrgRef
+ * Returns: pointer to Taxon1Data if organism exists
+ * NULL - if no such organism in taxonomy database
+ *
+ * NOTE:
+ * 1. This functions uses the following data from inp_orgRef to find organism
+ * in taxonomy database. It uses taxname first. If no organism was found (or multiple nodes found)
+ * then it tryes to find organism using common name. If nothing found, then it tryes to find
+ * organism using synonyms. tax1_lookup never uses tax_id to find organism.
+ * 2. If merge == 0 this function makes the new copy of OrgRef structure and puts into it data
+ * from taxonomy database.
+ * If merge != 0 this function updates inp_orgRef structure.
+ */
+Taxon1DataPtr tax1_lookup(OrgRefPtr inp_orgRef, int merge);
+
+/*-----------------------------------------------
+ * Get tax_id by OrgRef
+ * Returns: tax_id - if organism found
+ * 0 - no organism found
+ * -tax_id - if multiple nodes found (where tax_id is id of one of the nodes)
+ * NOTE:
+ * This function uses the same information from inp_orgRef as a tax1_lookup
+ */
+Int4 tax1_getTaxIdByOrgRef(OrgRefPtr inp_orgRef);
+
+/*----------------------------------------------
+ * Get tax_id by organism name
+ * Returns: tax_id - if organism found
+ * 0 - no organism found
+ * -tax_id - if multiple nodes found (where tax_id is id of one of the nodes)
+ * NOTE:
+ * orgname can be a regular expression.
+ */
+Int4 tax1_getTaxIdByName(CharPtr orgname);
+
+
+/*----------------------------------------------
+ * Get ALL tax_id by organism name
+ * Returns: number of organism found
+ * NOTE:
+ * 1. orgname can be a regular expression.
+ * 2. Ids consists of tax ids. Caller is responsible to free this memory
+ */
+Int4 tax1_getAllTaxIdByName(CharPtr orgname, Int4 **Ids);
+
+/*----------------------------------------------
+ * Get organism by tax_id
+ * Returns: pointer to OrgRef structure if organism found
+ * NULL - if no such organism in taxonomy database
+ * NOTE:
+ * This function does not make a copy of OrgRef structure, so, caller can not use
+ * OrgRefFree function for returned pointer.
+ */
+OrgRefPtr tax1_getOrgRef(Int4 tax_id, int* is_species, CharPtr div, CharPtr embl_cde);
+
+/*---------------------------------------------
+ * Set mode for synonyms in OrgRef
+ * Returns: previous mode
+ * NOTE:
+ * Default mode: do not include synonyms in OrgRef
+ */
+Boolean tax1_setSynonyms(Boolean on_off);
+
+/*---------------------------------------------
+ * Get parent tax_id
+ */
+Int4 tax1_getParent(Int4 id_tax);
+
+/*---------------------------------------------
+ * Get taxids for all children.
+ * Returns: number of children
+ */
+int tax1_getChildren(Int4 id_tax, Int4** children_ids);
+
+/*---------------------------------------------
+ * Get genetic code name by genetic code id
+ */
+CharPtr tax1_getGCName(Int2 gc_id);
+
+
+#endif
diff --git a/network/taxon1/stdalone/taxname.c b/network/taxon1/stdalone/taxname.c
new file mode 100644
index 00000000..7325f3b6
--- /dev/null
+++ b/network/taxon1/stdalone/taxname.c
@@ -0,0 +1,734 @@
+/****************************
+ * File: taxname.c
+ * Description: taxonomy name/search functions
+ */
+
+#include <stdlib.h>
+#include <rex_util.h>
+#include "tax_cmmn.h"
+
+static Int4 nof_des= 0;
+
+typedef struct t_NameDesign{
+ Int4 tax_id;
+ CharPtr name_txt;
+} _NameDesign;
+
+static _NameDesign* design= NULL;
+
+static int get_hashValue(CharPtr str)
+{
+ int i;
+ int v;
+
+ if(str == NULL) return 0;
+
+ for(v= 0,i= 0; *str != '\0'; str++, i++) {
+ if(isalnum(*str)) {
+ v+= toupper(*str) - 0x20;
+ v&= 0xFFF;
+ }
+ }
+ return v;
+}
+
+static void insert_name(_hashItemPtr hTbl, _taxNamePtr name)
+{
+ _hashItemPtr item;
+
+ item= &hTbl[get_hashValue(name->name_txt)];
+ if(item->tax_name == NULL) {
+ /* this hash value still free */
+ item->next= NULL;
+ item->tax_name= name;
+ }
+ else {
+ /* already occupied */
+ _hashItemPtr new_item= MemNew(sizeof(_hashItem));
+
+ if(new_item != NULL) {
+ new_item->next= item->next;
+ item->next= new_item;
+ new_item->tax_name= name;
+ }
+ }
+}
+
+/* Compare strings ignore non alphanum symbols and case */
+static int strWCmp(CharPtr s1, CharPtr s2)
+{
+ int i;
+
+ while((*s1 != '\0') && (*s2 != '\0')) {
+ if(!isalnum(*s1)) {
+ ++s1;
+ continue;
+ }
+ if(!isalnum(*s2)) {
+ ++s2;
+ continue;
+ }
+
+ i= toupper(*s1) - toupper(*s2);
+ if(i != 0) return i;
+
+ ++s1; ++s2;
+ }
+
+ while(*s1 != '\0') {
+ if(isalnum(*s1)) return 1;
+ ++s1;
+ }
+
+ while(*s2 != '\0') {
+ if(isalnum(*s2)) return -1;
+ ++s2;
+ }
+
+ return 0;
+}
+
+
+static int find_exactName(_hashItemPtr hashTbl, CharPtr sname, _taxNamePtr** nameList)
+{
+ _hashItemPtr item;
+ _taxNamePtr* list= NULL;
+ _hashItemPtr tmp;
+ int n= 0;
+
+ item= &hashTbl[get_hashValue(sname)];
+
+ if(item->tax_name == NULL) return 0; /* no name found */
+
+ /* on the first pass we'll search for exact hit */
+
+ for(tmp= item; tmp != NULL; tmp= tmp->next) {
+ if(strcmp(tmp->tax_name->name_txt, sname) == 0) {
+ /* we've found it! */
+ if(list == NULL) {
+ list= MemNew(sizeof(_taxNamePtr));
+ if(list != NULL) {
+ *list= tmp->tax_name;
+ n= 1;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ else {
+ ++n;
+ list= MemMore(list, n*sizeof(_taxNamePtr));
+ if(list != NULL) {
+ list[n-1]= tmp->tax_name;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ }
+ }
+
+ if(n > 0) {
+ /* we've found something */
+ *nameList= list;
+ return n;
+ }
+
+ /* First pass was unsuccessfull, let's try the case ignore search */
+
+ for(tmp= item; tmp != NULL; tmp= tmp->next) {
+ if(StringICmp(tmp->tax_name->name_txt, sname) == 0) {
+ /* we've found it! */
+ if(list == NULL) {
+ list= MemNew(sizeof(_taxNamePtr));
+ if(list != NULL) {
+ *list= tmp->tax_name;
+ n= 1;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ else {
+ ++n;
+ list= MemMore(list, n*sizeof(_taxNamePtr));
+ if(list != NULL) {
+ list[n-1]= tmp->tax_name;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ }
+ }
+
+ if(n > 0) {
+ /* we've found something */
+ *nameList= list;
+ }
+
+ return n;
+}
+
+
+static int find_alphanumName(_hashItemPtr hashTbl, CharPtr sname, _taxNamePtr** nameList)
+{
+ _hashItemPtr item;
+ _taxNamePtr* list= NULL;
+ _hashItemPtr tmp;
+ int n= 0;
+
+ item= &hashTbl[get_hashValue(sname)];
+
+ if(item->tax_name == NULL) return 0; /* no name found */
+
+ /* on the first pass we'll search for exact hit */
+
+ for(tmp= item; tmp != NULL; tmp= tmp->next) {
+ if(strcmp(tmp->tax_name->name_txt, sname) == 0) {
+ /* we've found it! */
+ if(list == NULL) {
+ list= MemNew(sizeof(_taxNamePtr));
+ if(list != NULL) {
+ *list= tmp->tax_name;
+ n= 1;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ else {
+ ++n;
+ list= MemMore(list, n*sizeof(_taxNamePtr));
+ if(list != NULL) {
+ list[n-1]= tmp->tax_name;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ }
+ }
+
+ if(n > 0) {
+ /* we've found something */
+ *nameList= list;
+ return n;
+ }
+
+ /* First pass was unsuccessfull, let's try the case ignore search */
+
+ for(tmp= item; tmp != NULL; tmp= tmp->next) {
+ if(StringICmp(tmp->tax_name->name_txt, sname) == 0) {
+ /* we've found it! */
+ if(list == NULL) {
+ list= MemNew(sizeof(_taxNamePtr));
+ if(list != NULL) {
+ *list= tmp->tax_name;
+ n= 1;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ else {
+ ++n;
+ list= MemMore(list, n*sizeof(_taxNamePtr));
+ if(list != NULL) {
+ list[n-1]= tmp->tax_name;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ }
+ }
+
+ if(n > 0) {
+ /* we've found something */
+ *nameList= list;
+ return n;
+ }
+
+ /* Nothing found on second pass too, let's try to exclude all non alphanum symbols
+ and go through again
+ */
+
+ for(tmp= item; tmp != NULL; tmp= tmp->next) {
+ if(strWCmp(tmp->tax_name->name_txt, sname) == 0) {
+ /* we've found it! */
+ if(list == NULL) {
+ list= MemNew(sizeof(_taxNamePtr));
+ if(list != NULL) {
+ *list= tmp->tax_name;
+ n= 1;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ else {
+ ++n;
+ list= MemMore(list, n*sizeof(_taxNamePtr));
+ if(list != NULL) {
+ list[n-1]= tmp->tax_name;
+ }
+ else {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "find_exactName: not enaugh memory");
+ return -1;
+ }
+ }
+ }
+ }
+
+ if(n > 0) {
+ /* we've found something */
+ *nameList= list;
+ }
+
+ return n;
+}
+
+static void freeHashTbl(_taxDBCtlPtr ctl)
+{
+ _hashItemPtr item;
+ int i;
+ _hashItemPtr nxt;
+
+ if(ctl->hashTbl == NULL) return;
+
+ /* free all chain in hash structure */
+ for(i= 0; i <= 0xFFF; i++) {
+ for(item= ctl->hashTbl[i].next; item != NULL; item= nxt) {
+ nxt= item->next;
+ MemFree(item);
+ }
+ }
+
+
+ /* free table itself */
+ MemFree(ctl->hashTbl);
+ ctl->hashTbl= NULL;
+}
+
+
+static int iniHashTbl(_taxDBCtlPtr ctl)
+{
+ _hashItemPtr tbl;
+ int i;
+
+ if(ctl->hashTbl != NULL) freeHashTbl(ctl);
+
+ if((tbl= MemNew(sizeof(_hashItem) * (0xFFF + 1))) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "iniHashTbl: not enaugh memory");
+ return -1;
+ }
+
+ for(i= 0; i <= 0xFFF; i++) {
+ tbl[i].tax_name= NULL;
+ tbl[i].next= NULL;
+ }
+
+ ctl->hashTbl= tbl;
+ return 0;
+}
+
+
+/*------------------------------------------------
+ * load_bin - load tree from binary file
+ */
+static int load_bin(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ _taxNamePtr nTbl;
+ Int4 i;
+ Int4 nof_names= tax_getNofNames(ctl);
+
+ if(nof_names < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_NAMES, "load_bin: no names in taxonomy");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_NAME_FILE), "rb")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_bin: Can't open taxonomy names file");
+ return -1;
+ }
+
+ if((nTbl= malloc(sizeof(_taxName) * nof_names)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for taxonomy names");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_names; i++) {
+ nTbl[i].tax_id= fsb_getInt4(f);
+ nTbl[i].class_cde= fsb_getInt1(f);
+ nTbl[i].name_txt= fsb_getString(f);
+ nTbl[i].unique_name= fsb_getString(f);
+ insert_name(ctl->hashTbl, &nTbl[i]); /* insert name into hash table */
+ }
+
+ ctl->names= nTbl;
+
+ nof_des= fsb_getInt4(f);
+ if(nof_des > 0) {
+ design= MemNew(nof_des*sizeof(_NameDesign));
+ for(i= 0; i < nof_des; i++) {
+ design[i].tax_id= fsb_getInt4(f);
+ design[i].name_txt= fsb_getString(f);
+ }
+ }
+ fclose(f);
+ return 0;
+}
+
+/*---------------------------------------------------
+ * load_txt - load taxonomy tree from text file
+ */
+static int load_txt(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ Int4 i;
+ _taxNamePtr nTbl;
+ Int4 nof_names= tax_getNofNames(ctl);
+
+
+ if(nof_names < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_NO_NAMES, "load_txt: no taxonomy names");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_NAME_FILE), "r")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_txt: Can't open taxonomy names file");
+ return -1;
+ }
+
+ if((nTbl= malloc(sizeof(_taxName) * nof_names)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_txt: Not enaugh memory for taxonomy names");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_names; i++) {
+ nTbl[i].tax_id= fs_getInt4(f, tax_getMarker(ctl));
+ nTbl[i].class_cde= fs_getInt2(f, tax_getMarker(ctl));
+ nTbl[i].name_txt= fs_getString(f, tax_getMarker(ctl));
+ nTbl[i].unique_name= fs_getString(f, tax_getMarker(ctl));
+ insert_name(ctl->hashTbl, &nTbl[i]); /* insert name into hash table */
+ }
+
+ ctl->names= nTbl;
+ fclose(f);
+ return 0;
+}
+
+static int load_asn(_taxDBCtlPtr ctl)
+{
+ return -10; /* not done yet */
+}
+
+/*==============================================================
+ * tax_freeNames - free memory
+ */
+void tax_freeNames(_taxDBCtlPtr ctl)
+{
+ _taxNamePtr nTbl= ctl->names;
+ Int4 nof_names= tax_getNofNames(ctl);
+ Int4 i;
+
+ if((nof_names > 0) && (nTbl != NULL)) {
+ for(i= 0; i != nof_names; i++) {
+ if(nTbl[i].name_txt != NULL) MemFree(nTbl[i].name_txt);
+ if(nTbl[i].unique_name != NULL) MemFree(nTbl[i].unique_name);
+ }
+ MemFree(nTbl);
+ }
+
+ freeHashTbl(ctl);
+ ctl->names= NULL;
+ if(design != NULL) {
+ for(i= 0; i < nof_des; i++) {
+ if(design[i].name_txt != NULL) MemFree(design[i].name_txt);
+ }
+ MemFree(design);
+ design= NULL;
+ nof_des= 0;
+ }
+}
+
+int tax_loadNames(_taxDBCtlPtr ctl)
+{
+
+ if(ctl->names != NULL) tax_freeNames(ctl);
+
+ if(iniHashTbl(ctl)) return -1;
+
+ switch(tax_getDbType(ctl)) {
+ case TAX_BIN: return load_bin(ctl);
+ case TAX_TXT: return load_txt(ctl);
+ case TAX_ASN: return load_asn(ctl);
+ default: break;
+ }
+
+ tax_outMsg(TAX_ERROR, TAX_ERR_FILE_TYPE, "tax_loadNames: Wrong file type for taxonomy names");
+ return -1;
+}
+
+static int rex_search(_taxDBCtlPtr ctl, CharPtr sname, _taxNamePtr** nameList)
+{
+ char nBuff[256];
+ Int4 nof_names= tax_getNofNames(ctl);
+ _taxNamePtr nTbl= ctl->names;
+ _taxNamePtr* list= NULL;
+ Int4 i, k, n= 0;
+ rex_handler rh;
+ CharPtr tmp;
+
+ strncpy(&nBuff[1], sname, 250);
+ nBuff[0]= '@';
+ k= strlen(nBuff);
+ nBuff[k]= '@';
+ nBuff[k+1]= '\0';
+ rh= rex_setExpr(nBuff, REX_NO_CASE | REX_NO_SPACE);
+ if(rh == NULL) return 0;
+
+ nBuff[0]= '@';
+ for(i= 0; i < nof_names; i++) {
+ tmp= nTbl[i].name_txt;
+ for(k= 0; (k < 250) && (tmp[k] != '\0'); k++) {
+ nBuff[k+1]= toupper(tmp[k]);
+ }
+ k++;
+ nBuff[k]= '@';
+ nBuff[k+1]= '\0';
+
+ if(rex_cmp(rh, nBuff)) {
+ /* name found */
+ if(list == NULL) {
+ if((list= MemNew(sizeof(_taxNamePtr))) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "rex_search: not enaugh memory for name list");
+ return 0;
+ }
+ *list= &nTbl[i];
+ n= 1;
+ }
+ else {
+ ++n;
+ if((list= MemMore(list, sizeof(_taxNamePtr)*n)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "rex_search: not enaugh memory for name list");
+ return 0;
+ }
+ list[n-1]= &nTbl[i];
+ }
+ }
+ }
+
+ if(n > 0) *nameList= list;
+ free(rh);
+ return n;
+}
+
+static CharPtr get_token(CharPtr str, CharPtr token)
+{
+ int i;
+
+ token[2]= '\0';
+
+ while(IS_WHITESP(*str)) {
+ if(*str == '\0') return NULL;
+ ++str;
+ }
+
+ if(*str == '\0') return NULL;
+
+ for(i= 1; i < 250; i++) {
+ if(IS_WHITESP(*str)) {
+ token[i]= ' ';
+ token[i+1]= '\0';
+ return str;
+ }
+
+ if(*str == '\0') {
+ token[i]= ' ';
+ token[i+1]= '\0';
+ return NULL;
+ }
+
+ token[i]= TO_UPPER(*str);
+ str++;
+ }
+
+ token[i]= ' ';
+ token[i+1]= '*';
+ token[i+2]= '\0';
+ return str;
+}
+
+static int token_search(_taxDBCtlPtr ctl, CharPtr sname, _taxNamePtr** nameList)
+{
+ char nBuff[256];
+ Int4 nof_names= tax_getNofNames(ctl);
+ _taxNamePtr nTbl= ctl->names;
+ _taxNamePtr* list= NULL;
+ Int4 i, k, n= 0;
+ rex_handler rh[16];
+ Int2 nof_rh, j, res;
+ CharPtr tail= sname;
+
+ nBuff[0]= '*';
+ nBuff[1]= ' ';
+ for(nof_rh= 0; (nof_rh != 16) && (tail != NULL); nof_rh++) {
+ tail= get_token(tail, nBuff);
+ rh[nof_rh]= rex_setExpr(nBuff, REX_NO_CASE | REX_NO_SPACE);
+ if(rh[nof_rh] == NULL) nof_rh--;
+ }
+ if(nof_rh < 1) return 0;
+
+ nBuff[0]= ' ';
+ for(i= 0; i < nof_names; i++) {
+ tail= nTbl[i].name_txt;
+ for(k= 0; (k < 250) && (tail[k] != '\0'); k++) {
+ nBuff[k+1]= toupper(tail[k]);
+ }
+ k++;
+ nBuff[k]= ' ';
+ nBuff[k+1]= '\0';
+
+ for(res= 1, j= 0; (j < nof_rh) && (res > 0); j++) {
+ res= rex_cmp(rh[j], nBuff);
+ }
+
+ if(res) {
+ /* name found */
+ if(list == NULL) {
+ if((list= MemNew(sizeof(_taxNamePtr))) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "rex_search: not enaugh memory for name list");
+ return 0;
+ }
+ *list= &nTbl[i];
+ n= 1;
+ }
+ else {
+ ++n;
+ if((list= MemMore(list, sizeof(_taxNamePtr)*n)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "rex_search: not enaugh memory for name list");
+ return 0;
+ }
+ list[n-1]= &nTbl[i];
+ }
+ }
+ }
+
+ if(n > 0) *nameList= list;
+ for(j= 0; j < nof_rh; j++) {
+ free(rh[j]);
+ }
+ return n;
+}
+
+int tax_findByName(_taxDBCtlPtr ctl, CharPtr inp_sname, int mode, _taxNamePtr** nameList)
+{
+ char sname[128];
+ int i, k;
+
+ for(i= 0; inp_sname[i] != '\0'; i++) {
+ if(!isspace(inp_sname[i])) break;
+ }
+
+ sname[0]= inp_sname[i++];
+
+ for(k= 0; k < 120; i++) {
+ if(inp_sname[i] == '\0') {
+ break;
+ }
+ if(isspace(inp_sname[i])) {
+ if(isspace(sname[k])) continue;
+ else {
+ sname[++k]= ' ';
+ }
+ }
+ else {
+ sname[++k]= inp_sname[i];
+ }
+ }
+
+ if(sname[k] != ' ') k++;
+
+ sname[k]= '\0';
+
+ switch(mode) {
+ case TAX_RE_SEARCH: return rex_search(ctl, sname, nameList);
+ case TAX_TOKEN_SEARCH: return token_search(ctl, sname, nameList);
+ case TAX_ALPHANUM_SEARCH: return find_alphanumName(ctl->hashTbl, sname, nameList);
+ default: return find_exactName(ctl->hashTbl, sname, nameList);
+
+ }
+}
+
+_taxNamePtr tax_findOrgName(_taxDBCtlPtr ctl, Int4 id)
+{
+ _taxNamePtr nameList;
+ Int4 m, l= 0, r= ctl->NofNames - 1;
+
+
+ nameList= ctl->names;
+ if(nameList == NULL) return NULL;
+
+ /* binary search */
+ while((r - l) > 1) {
+ m= (r + l)/2;
+ if(nameList[m].tax_id >= id) r= m;
+ else l= m;
+ }
+
+ if((nameList[r].tax_id < id) || (nameList[l].tax_id > id)) return NULL;
+
+ if(nameList[l].tax_id == id) {
+ while(l > 0) {
+ if(nameList[l-1].tax_id == id) l--;
+ else break;
+ }
+ return &nameList[l];
+ }
+
+ if(nameList[r].tax_id == id) return &nameList[r];
+
+ return NULL;
+}
+
+Int4 tax_getDesignator(CharPtr name)
+{
+ Int4 i;
+
+ for(i= 0; i < nof_des; i++) {
+ if(strcmp(name, design[i].name_txt) == 0) {
+ return design[i].tax_id;
+ }
+ }
+
+ /* try to find ignore case */
+ for(i= 0; i < nof_des; i++) {
+ if(StringICmp(name, design[i].name_txt) == 0) {
+ return design[i].tax_id;
+ }
+ }
+
+ /* try to find ignore case and non alphanum */
+ for(i= 0; i < nof_des; i++) {
+ if(strWCmp(name, design[i].name_txt) == 0) {
+ return design[i].tax_id;
+ }
+ }
+ return 0;
+}
+
+
diff --git a/network/taxon1/stdalone/taxobj.h b/network/taxon1/stdalone/taxobj.h
new file mode 100644
index 00000000..f4ca6551
--- /dev/null
+++ b/network/taxon1/stdalone/taxobj.h
@@ -0,0 +1,61 @@
+/****************************
+ * File: taxobj.h
+ * Description: header file for taxonomy objects
+ */
+
+
+#ifndef TAXOBJ_H_DONE
+#define TAXOBJ_H_DONE
+
+#include <stdio.h>
+#include <ncbi.h>
+
+typedef unsigned char _TINY;
+typedef Int4 _DBKEY;
+
+#define INHERIT_DIV 0x1
+#define INHERIT_GC 0x2
+#define INHERIT_MGC 0x4
+#define GB_HIDDEN 0x8
+#define TAX_HIDDEN 0x10
+
+
+typedef struct t_taxCursor {
+ FILE* f;
+ _DBKEY position;
+} _taxCursor;
+
+_taxCursor* tq_openCursor(char* fileName);
+void tq_closeCursor(_taxCursor* cursor);
+int tq_setCursor(_taxCursor* cursor, _DBKEY pos);
+
+typedef struct t_taxCtlNode {
+ Int4 parent, child, sibling;
+ _DBKEY dataKey;
+ Int2 rank;
+ Int2 flags;
+} _taxCtlNode, PNTR _taxCtlNodePtr;
+
+typedef struct t_taxName {
+ int tax_id;
+ _TINY class_cde;
+ CharPtr name_txt;
+ CharPtr unique_name;
+} _taxName, PNTR _taxNamePtr;
+
+typedef struct t_taxNode {
+ int tax_id;
+ char* comment;
+ char embl_cde[4];
+ _TINY division;
+ _TINY gc;
+ _TINY mgc;
+ _TINY comment_size; /* number of 32 bytes pices in comment */
+} _taxNode, PNTR _taxNodePtr;
+
+
+int tq_loadNode(_taxCursor* cursor, _taxNode* node);
+int tq_loadNodeNames(_taxCursor* cursor, _taxName* name);
+
+
+#endif
diff --git a/network/taxon1/stdalone/taxtree.c b/network/taxon1/stdalone/taxtree.c
new file mode 100644
index 00000000..6ea7fea1
--- /dev/null
+++ b/network/taxon1/stdalone/taxtree.c
@@ -0,0 +1,395 @@
+/****************************
+ * File: tree.c
+ * Description: taxonomy tree functions
+ */
+
+#include <stdlib.h>
+#include "tax_cmmn.h"
+
+static _taxNodePtr nodeSet= NULL;
+
+/*------------------------------------------------
+ * load_bin - load tree from binary file
+ */
+static int load_bin(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ _treePtr node;
+ long nof_ids= tax_getMaxId(ctl);
+
+ if(nof_ids < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_EMPTY_TREE, "load_bin: taxonomy tree is empty");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_TREE_FILE), "rb")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_bin: Can't open taxonomy tree file");
+ return -1;
+ }
+
+ if((node= malloc(sizeof(_tree) * (nof_ids+1))) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_bin: Not enaugh memory for taxonomy tree");
+ return -1;
+ }
+ memset(node, 0, sizeof(_tree) * (nof_ids+1));
+
+ /* read file and fill-up array */
+ if(fread(node, sizeof(_tree), nof_ids, f) < nof_ids) {
+ free(node);
+ tax_outMsg(TAX_ERROR, TAX_ERR_WRONG_FILE, "load_bin: taxonomy tree currupted");
+ return -1;
+ }
+
+ ctl->tree= node;
+ fclose(f);
+ return 0;
+}
+
+/*---------------------------------------------------
+ * load_txt - load taxonomy tree from text file
+ */
+static int load_txt(_taxDBCtlPtr ctl)
+{
+ FILE* f;
+ long i;
+ _treePtr nmc;
+ long nof_ids= tax_getMaxId(ctl);
+ _treePtr node;
+
+
+ if(nof_ids < 1) {
+ tax_outMsg(TAX_WARN, TAX_WARN_EMPTY_TREE, "load_txt: taxonomy tree is empty");
+ return 1;
+ }
+
+ if((f= fopen(tax_getFileName(ctl, TAX_TREE_FILE), "r")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "load_txt: Can't open taxonomy tree file");
+ return -1;
+ }
+
+ if((node= malloc(sizeof(_tree) * nof_ids)) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "load_txt: Not enaugh memory for taxonomy tree");
+ return -1;
+ }
+
+ /* read file and fill-up array */
+ for(i= 0; i < nof_ids; i++) {
+ node[i].parent= fs_getLong(f, tax_getMarker(ctl));
+ node[i].child= fs_getLong(f, tax_getMarker(ctl));
+ node[i].sibling= fs_getLong(f, tax_getMarker(ctl));
+ node[i].dataKey= fs_getLong(f, tax_getMarker(ctl));
+ node[i].rank= fs_getInt2(f, tax_getMarker(ctl));
+ node[i].flags= fs_getInt2(f, tax_getMarker(ctl));
+ }
+
+ ctl->tree= node;
+ fclose(f);
+ return 0;
+}
+
+static int load_asn(_taxDBCtlPtr ctl)
+{
+ return -10; /* not done yet */
+}
+
+/*==============================================================
+ * tax_freeClasses - free memory
+ */
+void tax_freeTree(_taxDBCtlPtr ctl)
+{
+ Int4 i;
+
+ if(nodeSet != NULL) {
+ for(i= 0; i < tax_getNofNodes(ctl); i++) {
+ if(nodeSet[i].comment != NULL) MemFree(nodeSet[i].comment);
+ }
+ MemFree(nodeSet);
+ nodeSet= NULL;
+ }
+
+ if((tax_getMaxId(ctl) > 0) && (ctl->tree != NULL)) {
+ free(ctl->tree);
+ }
+ ctl->tree= NULL;
+}
+
+int tax_loadTree(_taxDBCtlPtr ctl)
+{
+
+ if(ctl->tree != NULL) tax_freeTree(ctl);
+
+ switch(tax_getDbType(ctl)) {
+ case TAX_BIN: return load_bin(ctl);
+ case TAX_TXT: return load_txt(ctl);
+ case TAX_ASN: return load_asn(ctl);
+ default: break;
+ }
+
+ tax_outMsg(TAX_ERROR, TAX_ERR_FILE_TYPE, "tax_loadTree: Wrong file type for taxonomy tree");
+ return -1;
+}
+
+static CharPtr emblcode(CharPtr name)
+{
+ static char embl[4];
+ int i;
+
+ embl[0]= embl[1]= embl[2]= embl[3]= '\0';
+ for(i= 0; name[i] != '\0'; i++) {
+ if(IS_ALPHA(name[i])) {
+ embl[0]= TO_UPPER(name[i]);
+ break;
+ }
+ }
+
+ if(name[i] != '\0') {
+ for(;name[i] != '\0'; i++) {
+ if(IS_WHITESP(name[i])) break;
+ }
+ while(name[i++] != '\0') {
+ if(IS_ALPHANUM(name[i])) {
+ embl[1]= TO_UPPER(name[i]);
+ break;
+ }
+ }
+ }
+
+ if(embl[0] == '\0') {
+ embl[0]=embl[1]= 'X';
+ }
+ else if(embl[1] == '\0') {
+ embl[1]= 'X';
+ }
+
+ return embl;
+}
+
+
+static int loadNodesBin(_taxDBCtlPtr ctl)
+{
+ _taxNodePtr node;
+ Int4 nofNodes= tax_getNofNodes(ctl);
+ Int4 i;
+
+ if(ctl->nodefile == NULL) {
+ /* open node file */
+ if((ctl->nodefile= fopen(tax_getFileName(ctl, TAX_NODE_FILE), "rb")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "loadNodesBin: Can't open node file");
+ return NULL;
+ }
+ }
+ else {
+ fseek(ctl->nodefile, 0L, SEEK_SET);
+ }
+
+
+ nodeSet= MemNew(sizeof(_taxNode)*nofNodes);
+ if(nodeSet == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "loadNodesBin: Not enaugh memory");
+ return -1;
+ }
+
+ for(i= 0; i < nofNodes; i++) {
+ if(fread(&nodeSet[i], sizeof(_taxNode), 1, ctl->nodefile) != 1) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_WRONG_FILE, "loadNodesBin: File currapted");
+ return -2;
+ }
+ if(nodeSet[i].comment_size > 0) nodeSet[i].comment= fsb_getString(ctl->nodefile);
+ else nodeSet[i].comment= NULL;
+ }
+ fclose(ctl->nodefile);
+ ctl->nodefile= NULL;
+ return 0;
+}
+
+
+static _taxNodePtr getNodeMem(_taxDBCtlPtr ctl, Int4 id)
+{
+ Int4 l, u, m;
+ _taxNodePtr node;
+ _taxNamePtr orgName;
+
+ l= 0;
+ u= tax_getNofNodes(ctl);
+
+ while((u-l) > 1) {
+ m= (u + l)/2;
+ if(nodeSet[m].tax_id > id) u= m;
+ else l= m;
+ }
+
+ if(nodeSet[l].tax_id == id) m= l;
+ else m= u;
+
+ if((node= MemNew(sizeof(_taxNode))) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "getNodeMem: Not enaugh memory for tax node");
+ return NULL;
+ }
+
+ *node= nodeSet[m];
+ if(node->comment_size > 0) node->comment= StringSave(nodeSet[m].comment);
+ if((node->embl_cde[0] == '\0') && (ctl->tree[id].rank > 25)) {
+ /* we need to calculate the default EMBL code */
+ if(ctl->names == NULL) tax_loadNames(ctl);
+ orgName= tax_findOrgName(ctl, id);
+ strcpy(node->embl_cde, emblcode(orgName->name_txt));
+ }
+ return node;
+}
+
+
+static _taxNodePtr getNodeBin(_taxDBCtlPtr ctl, Int4 id)
+{
+ _taxNodePtr node;
+ _taxNamePtr orgName;
+
+ if(ctl->nodefile == NULL) {
+ /* open node file */
+ if((ctl->nodefile= fopen(tax_getFileName(ctl, TAX_NODE_FILE), "rb")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "getNodeBin: Can't open node file");
+ return NULL;
+ }
+ }
+
+ if((node= MemNew(sizeof(_taxNode))) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "getNodeBin: Not enaugh memory for tax node");
+ return NULL;
+ }
+
+ fseek(ctl->nodefile, ctl->tree[id].dataKey, SEEK_SET);
+ fread(node, sizeof(_taxNode), 1, ctl->nodefile);
+ if(node->comment_size > 0) node->comment= fsb_getString(ctl->nodefile);
+ if((node->embl_cde[0] == '\0') && (ctl->tree[id].rank > 25)) {
+ /* we need to calculate the default EMBL code */
+ if(ctl->names == NULL) tax_loadNames(ctl);
+ orgName= tax_findOrgName(ctl, id);
+ strcpy(node->embl_cde, emblcode(orgName->name_txt));
+ }
+ return node;
+}
+
+
+
+static _taxNodePtr getNodeTxt(_taxDBCtlPtr ctl, Int4 id)
+{
+ _taxNodePtr node;
+ FILE* f;
+ CharPtr marker;
+ CharPtr t;
+ _taxNamePtr orgName;
+
+ if(ctl->nodefile == NULL) {
+ /* open node file */
+ if((ctl->nodefile= fopen(tax_getFileName(ctl, TAX_NODE_FILE), "r")) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_FILE, "getNodeTxt: Can't open node file");
+ return NULL;
+ }
+ }
+
+ if((node= MemNew(sizeof(_taxNode))) == NULL) {
+ tax_outMsg(TAX_ERROR, TAX_ERR_NO_MEMORY, "getNodeTxt: Not enaugh memory for tax node");
+ return NULL;
+ }
+
+ f= ctl->nodefile;
+ marker= tax_getMarker(ctl);
+
+ fseek(f, ctl->tree[id].dataKey, SEEK_SET);
+ node->tax_id= fs_getInt4(f, marker);
+ t= fs_getString(f, marker);
+ strncpy(node->embl_cde, t, 4);
+ MemFree(t);
+ if((node->embl_cde[0] == '\0') && (ctl->tree[id].rank > 25)) {
+ /* we need to calculate the default EMBL code */
+ if(ctl->names == NULL) tax_loadNames(ctl);
+ orgName= tax_findOrgName(ctl, id);
+ strcpy(node->embl_cde, emblcode(orgName->name_txt));
+ }
+
+ node->division= fs_getInt2(f, marker);
+ node->gc= fs_getInt2(f, marker);
+ node->mgc= fs_getInt2(f, marker);
+ node->comment_size= fs_getInt2(f, marker);
+ if(node->comment_size > 0) node->comment= fs_getString(f, marker);
+ return node;
+}
+
+static _taxNodePtr getNodeAsn(_taxDBCtlPtr ctl, Int4 id)
+{
+ return NULL;
+}
+
+void tax_freeNode(_taxNodePtr node)
+{
+ if(node != NULL) {
+ if(node->comment_size > 0) MemFree(node->comment);
+ MemFree(node);
+ }
+}
+
+
+_taxNodePtr tax_getNode(_taxDBCtlPtr ctl, Int4 id)
+{
+
+ if((id < 0) && (nodeSet == NULL)) {
+ loadNodesBin(ctl);
+ return NULL;
+ }
+
+ if((ctl->tree == NULL) || (id < 0) || (id > tax_getMaxId(ctl))) return NULL;
+
+ if(ctl->tree[id].parent < 1) {
+ /* deleted node */
+ return NULL;
+ }
+
+ while(ctl->tree[id].child == -1) {
+ id=ctl->tree[id].parent;
+ }
+
+ if(nodeSet != NULL) return getNodeMem(ctl, id);
+
+ switch(tax_getDbType(ctl)) {
+ case TAX_BIN: return getNodeBin(ctl, id);
+ case TAX_TXT: return getNodeTxt(ctl, id);
+ case TAX_ASN: return getNodeAsn(ctl, id);
+ default: break;
+ }
+
+ tax_outMsg(TAX_ERROR, TAX_ERR_FILE_TYPE, "tax_getNode: Wrong file type for taxonomy node");
+ return NULL;
+}
+
+Int2 tax_getLin(_taxDBCtlPtr ctl, Int4 id, Int4Ptr lin)
+{
+ int n, k;
+ Int4 i;
+
+ if((ctl->tree == NULL) || (id < 0) || (id > tax_getMaxId(ctl))) return 0;
+
+ if(ctl->tree[id].parent < 1) {
+ /* deleted node */
+ return 0;
+ }
+
+ while(ctl->tree[id].child == -1) {
+ id=ctl->tree[id].parent;
+ }
+
+ i= ctl->tree[id].parent;
+ if(i == id) return 0; /* No lineage */
+
+ /* calculate the number of nodes in lineage */
+
+ for(k= 1; i != ctl->tree[i].parent; i= ctl->tree[i].parent) {
+ k++;
+ }
+
+ n= k;
+
+ for(i= ctl->tree[id].parent; k-- > 0; i= ctl->tree[i].parent) {
+ lin[k]= i;
+ }
+
+ return n;
+}
diff --git a/network/taxon1/taxon2/parttree.c b/network/taxon1/taxon2/parttree.c
new file mode 100644
index 00000000..e9957e01
--- /dev/null
+++ b/network/taxon1/taxon2/parttree.c
@@ -0,0 +1,297 @@
+/* parttree.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: parttree.c
+*
+* Author: Vladimir Soussov
+*
+* File Description: taxonomy partial tree functions
+*
+*
+* $Log: parttree.c,v $
+* Revision 1.4 1998/07/23 18:24:30 soussov
+* Added function for attaching subtrees
+*
+* Revision 1.3 1998/06/11 20:43:56 soussov
+* kill some warnings
+*
+* Revision 1.2 1998/04/01 17:34:08 soussov
+* changed tp include <>
+*
+* Revision 1.1 1998/02/10 20:11:57 soussov
+* taxon2 related soft
+*
+ * Revision 1.1.1.1 1997/04/30 21:29:47 soussov
+ * initial tree for taxon2
+ *
+*
+*/
+
+#include <txclient.h>
+
+static VoidPtr ptree_getNode(TreeCursorPtr cursor, Uint4 format, Uint2Ptr size)
+{
+ Uint2 s;
+ TXC_TreeNodePtr tnp;
+
+ *size= 4;
+ if(format == TREE_NODE_FMT_DISTANCE) return (VoidPtr)1;
+ if(format == TREE_NODE_FMT_ICON) return (VoidPtr)-1;
+
+ tnp= tree_getNodeData(cursor, &s);
+ switch(format) {
+ case TREE_NODE_FMT_LABEL:
+ *size= strlen(tnp->node_label);
+ return tnp->node_label;
+ case TREE_NODE_FMT_DEFAULT:
+ *size= s;
+ return tnp;
+ default:
+ return &tnp->tax_id;
+ }
+}
+
+
+TreePtr tax_ptree_new(void)
+{
+ TreePtr ptree= tree_new();
+ TreeCursorPtr cursor= tree_openCursor(ptree, NULL, NULL);
+ TXC_TreeNodePtr tnp= MemNew(20);
+
+ tnp->tax_id= 1;
+ tnp->flags= 0;
+ StringCpy(tnp->node_label, "root");
+
+ tree_updateNodeData(cursor, tnp, 20);
+
+ tree_setGetNodeFunc(ptree, ptree_getNode);
+
+ MemFree(tnp);
+ tree_closeCursor(cursor);
+ return ptree;
+}
+
+/********************************************
+ * Find id among children of current node and make this node current
+ */
+static Boolean known_id(TreeCursorPtr cursor, Int4 id)
+{
+ TXC_TreeNodePtr tnp;
+ Uint2 s;
+
+ if(tree_child(cursor)) {
+ do {
+ tnp= tree_getNodeData(cursor, &s);
+ if(tnp->tax_id == id) return TRUE;
+ }
+ while(tree_sibling(cursor));
+ tree_parent(cursor);
+ }
+ return FALSE;
+}
+
+
+Boolean tax_ptree_addNode(TreePtr ptree, Int4 tax_id)
+{
+ Int4 lin_size, i;
+ Uint2 s;
+ TXC_TreeNodePtr* lineage;
+ TreeCursorPtr cursor;
+ TreeNodeId nid;
+
+ lineage= txc_getLineage(tax_id, &lin_size);
+
+ if((lineage == NULL) || (lin_size < 1)) return FALSE;
+
+ cursor= tree_openCursor(ptree, NULL, NULL);
+ if(cursor == NULL) return FALSE;
+
+ for(i= lin_size; i--; ) {
+ if(!known_id(cursor, lineage[i]->tax_id)) break;
+ MemFree(lineage[i]);
+ }
+
+ if(i >= 0) {
+
+ /* add nodes begining with this point */
+ do {
+ s= 9 + StringLen(lineage[i]->node_label);
+ nid= tree_addChild(cursor, lineage[i], s);
+ tree_toNode(cursor, nid);
+ MemFree(lineage[i]);
+ }
+ while(i--);
+ }
+
+ tree_closeCursor(cursor);
+ MemFree(lineage);
+ return TRUE;
+}
+
+static Boolean ptree_toTaxId(TreeCursorPtr cursor, Int4 id)
+{
+ TXC_TreeNodePtr tnp;
+ Uint2 s;
+
+ tnp= tree_getNodeData(cursor, &s);
+ if(tnp->tax_id == id) return TRUE;
+
+ if(tree_child(cursor)) {
+ do {
+ if(ptree_toTaxId(cursor, id)) return TRUE;
+ }
+ while(tree_sibling(cursor));
+
+ tree_parent(cursor);
+ }
+ return FALSE;
+}
+
+Boolean tax_ptree_toTaxId(TreeCursorPtr cursor, Int4 tax_id, Boolean search_in_subtree)
+{
+ TreeNodeId id= tree_getId(cursor);
+
+ if(!search_in_subtree) {
+ tree_root(cursor);
+ }
+
+ if(ptree_toTaxId(cursor, tax_id)) return TRUE;
+ else {
+ tree_toNode(cursor, id);
+ return FALSE;
+ }
+}
+
+Boolean tax_ptree_addChildren(TreeCursorPtr cursor)
+{
+ Int4 nof_children, i;
+ Uint2 s;
+ TXC_TreeNodePtr* child;
+ TXC_TreeNodePtr my_node= tree_getNodeData(cursor, &s);
+ TreeNodeId nid= tree_getId(cursor);
+ Boolean need_remove= FALSE;
+
+ if(my_node == NULL) return FALSE;
+
+ child= txc_getChildren(my_node->tax_id, &nof_children);
+
+ if((child == NULL) || (nof_children < 1)) return FALSE;
+
+ if(tree_child(cursor)) {
+ /* update all children which already exist in the tree */
+ do {
+ my_node= tree_getNodeData(cursor, &s);
+ if(my_node != NULL) {
+ for(i= 0; i < nof_children; i++) {
+ if((child[i] != NULL) && (child[i]->tax_id == my_node->tax_id)) {
+ s= 9 + StringLen(child[i]->node_label);
+ tree_updateNodeData(cursor, child[i], s);
+ child[i]= MemFree(child[i]);
+ break;
+ }
+ }
+ if(i >= nof_children) {
+ /* this node does not exists any more --> mark it for removing */
+ my_node->tax_id= 0;
+ need_remove= TRUE;
+ }
+ }
+ }
+ while(tree_sibling(cursor));
+
+ tree_parent(cursor);
+
+ while(need_remove) {
+ /* remove all marked nodes */
+ need_remove= FALSE;
+ if(tree_child(cursor)) {
+
+ do {
+ my_node= tree_getNodeData(cursor, &s);
+ if((my_node != NULL) && (my_node->tax_id == 0)) {
+ need_remove= TRUE;
+ tree_delSubtree(cursor);
+ break;
+ }
+ }
+ while (tree_sibling(cursor));
+ }
+ }
+ }
+
+ /* add new children */
+ tree_toNode(cursor, nid);
+
+ for(i= 0; i < nof_children; i++) {
+ if(child[i] != NULL) {
+ s= 9 + StringLen(child[i]->node_label);
+ tree_addChild(cursor, child[i], s);
+ child[i]= MemFree(child[i]);
+ }
+ }
+
+ MemFree(child);
+ return TRUE;
+}
+
+Boolean tax_ptree_addSubtree(TreeCursorPtr cursor)
+{
+ Int4 nof_children, i;
+ Uint2 s;
+ TXC_TreeNodePtr* child;
+ TXC_TreeNodePtr my_node= tree_getNodeData(cursor, &s);
+ TreeNodeId nid= tree_getId(cursor);
+ Boolean need_remove= FALSE;
+
+ if(my_node == NULL) return FALSE;
+
+ child= txc_getChildren(-(my_node->tax_id), &nof_children);
+
+ if((child == NULL) || (nof_children < 1)) return FALSE;
+
+ while(tree_child(cursor)) {
+ tree_delSubtree(cursor);
+ }
+
+ /* add new children */
+ tree_toNode(cursor, nid);
+
+ for(i= 0; i < nof_children; i++) {
+ if(child[i] != NULL) {
+ if((child[i]->flags & TXC_SUFFIX) != 0) {
+ tree_root(cursor);
+ ptree_toTaxId(cursor, child[i]->tax_id);
+ }
+ else {
+ s= 9 + StringLen(child[i]->node_label);
+ tree_addChild(cursor, child[i], s);
+ }
+ child[i]= MemFree(child[i]);
+ }
+ }
+
+ MemFree(child);
+ return TRUE;
+}
diff --git a/network/taxon1/taxon2/taxcs.c b/network/taxon1/taxon2/taxcs.c
new file mode 100644
index 00000000..40052bdf
--- /dev/null
+++ b/network/taxon1/taxon2/taxcs.c
@@ -0,0 +1,534 @@
+/* taxcs.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: taxcs.c
+*
+* Author: Vladimir Soussov
+*
+* File Description: taxonomy server/client common utilities
+*
+*
+* $Log: taxcs.c,v $
+* Revision 1.3 1998/09/01 15:41:39 soussov
+* removing warnings
+*
+* Revision 1.2 1998/04/01 17:34:06 soussov
+* changed tp include <>
+*
+* Revision 1.1 1998/02/10 20:11:59 soussov
+* taxon2 related soft
+*
+* Revision 1.2 1997/05/12 18:32:33 soussov
+* 05/12/97
+*
+ * Revision 1.1.1.1 1997/04/30 21:29:41 soussov
+ * initial tree for taxon2
+ *
+*
+*/
+
+#include <time.h>
+#include <stdlib.h>
+#include <txcommon.h>
+
+/*
+typedef struct t_nameClass {
+ Int2 priority;
+ char class_txt[34];
+} TaxNameClass, PNTR TaxNameClassPtr;
+ */
+static Int2 class_alloced= 16;
+static TaxNameClassPtr name_class= NULL;
+
+Int4 tax_getBaseTime(void)
+{
+ static Int4 basetime= 0;
+ static Boolean baseTime_set= FALSE;
+
+ if(!baseTime_set) {
+ Int4 yy, vv, dd= 0;
+ time_t t= 0;
+
+ vv= gmtime(&t)->tm_year;
+
+ if(vv > 0) {
+ for(yy= 1900; yy < (1900 + vv); yy++) {
+ if(yy%4 == 0) dd+= 366;
+ else dd+= 365;
+ }
+
+ dd--;
+
+ basetime= (dd*24)*60;
+ }
+ baseTime_set= TRUE;
+
+ }
+
+ return basetime;
+}
+
+CharPtr tax_prntTime(Int4 t)
+{
+ time_t ttt= (t - tax_getBaseTime())* 60;
+
+ return asctime(localtime(&ttt));
+}
+
+Int4 tax_getTime(void)
+{
+ time_t ttt= time(NULL);
+ Int4 t= ttt/60 + tax_getBaseTime();
+ return t;
+}
+
+Boolean tax_addNameClass(Int4 class_cde, CharPtr class_txt, Int4 priority)
+{
+ Int2 i;
+
+ if(name_class == NULL) {
+ name_class= MemNew(sizeof(TaxNameClass)*class_alloced);
+ if(name_class == NULL) return FALSE;
+
+ for(i= 0; i < class_alloced; i++) {
+ name_class[i].priority= 1000;
+ name_class[i].class_txt[0]= name_class[i].class_txt[33]= '\0';
+ }
+ }
+
+ if(class_cde < 0) return FALSE;
+
+ if(class_cde >= class_alloced) {
+ TaxNameClassPtr tmp= MemMore(name_class, sizeof(TaxNameClass)*(class_cde + 8));
+
+ if(tmp == NULL) return FALSE;
+
+ name_class= tmp;
+ for(i= class_alloced; i < class_cde + 8; i++) {
+ name_class[i].priority= 1000;
+ name_class[i].class_txt[0]= name_class[i].class_txt[33]= '\0';
+ }
+ class_alloced= class_cde + 8;
+ }
+
+ name_class[class_cde].priority= priority;
+ StringNCpy(name_class[class_cde].class_txt, class_txt, 33);
+
+ return TRUE;
+}
+
+CharPtr tax_getNameClass(Int4 class_cde, Int4Ptr priority)
+{
+ if((class_cde < 0) || (class_cde >= class_alloced)) {
+ if(priority != NULL) *priority= 1000;
+ return "";
+ }
+
+ if(priority != NULL) *priority= name_class[class_cde].priority;
+ return name_class[class_cde].class_txt;
+}
+
+Int4 tax_getClass_cde(CharPtr class_txt)
+{
+ Int2 i;
+
+ if(class_txt == NULL) return -1;
+
+ for(i= 0; i < class_alloced; i++) {
+ if(StringICmp(name_class[i].class_txt, class_txt) == 0) return (Int4)i;
+ }
+
+ return -1;
+}
+
+Boolean tax_dumpNameClasses(void (*dmpFunc)(VoidPtr, Int2, Int2, CharPtr), VoidPtr usrData)
+{
+ Int2 i;
+
+ if((name_class == NULL) || (dmpFunc == NULL)) return FALSE;
+
+ for(i= 0; i < class_alloced; i++) {
+ if(name_class[i].class_txt[0] != '\0') {
+ (*dmpFunc)(usrData, i, name_class[i].priority, name_class[i].class_txt);
+ }
+ }
+ return TRUE;
+}
+
+/*
+typedef struct t_rank {
+ char rank_txt[64];
+} TaxRank, PNTR TaxRankPtr;
+ */
+
+static Int2 rank_alloced= 48, d_rank= 1;
+static TaxRankPtr tax_rank= NULL;
+
+Boolean tax_addRank(Int2 rank_id, CharPtr rank_txt)
+{
+ Int2 i;
+
+ rank_id+= d_rank;
+
+ if(tax_rank == NULL) {
+ tax_rank= MemNew(sizeof(TaxRank)*rank_alloced);
+ if(tax_rank == NULL) return FALSE;
+
+ for(i= 0; i < rank_alloced; i++) {
+ tax_rank[i].rank_txt[0]= tax_rank[i].rank_txt[63]= '\0';
+ }
+ }
+
+ if(rank_id < 0) return FALSE;
+
+ if(rank_id >= rank_alloced) {
+ TaxRankPtr tmp= MemMore(tax_rank, sizeof(TaxRank)*(rank_id + 8));
+
+ if(tmp == NULL) return FALSE;
+
+ tax_rank= tmp;
+ for(i= rank_alloced; i < rank_id + 8; i++) {
+ tax_rank[i].rank_txt[0]= tax_rank[i].rank_txt[63]= '\0';
+ }
+ rank_alloced= rank_id + 8;
+ }
+
+ StringNCpy(tax_rank[rank_id].rank_txt, rank_txt, 63);
+
+ return TRUE;
+}
+
+CharPtr tax_getRank(Int2 rank_id)
+{
+ rank_id+= d_rank;
+
+ if((rank_id < 0) || (rank_id >= rank_alloced)) return "";
+
+ return tax_rank[rank_id].rank_txt;
+}
+
+Int2 tax_getRankId(CharPtr rank_txt)
+{
+ Int2 i;
+
+ if(rank_txt == NULL) return -d_rank;
+
+ for(i= 0; i < rank_alloced; i++) {
+ if(StringICmp(tax_rank[i].rank_txt, rank_txt) == 0) return i - d_rank;
+ }
+
+ return -d_rank;
+}
+
+
+Boolean tax_dumpRanks(void (*dmpFunc)(VoidPtr, Int2, CharPtr), VoidPtr usrData)
+{
+ Int2 i;
+
+ if((tax_rank == NULL) || (dmpFunc == NULL)) return FALSE;
+
+ for(i= 0; i < rank_alloced; i++) {
+ if(tax_rank[i].rank_txt[0] != '\0') {
+ (*dmpFunc)(usrData, i - d_rank, tax_rank[i].rank_txt);
+ }
+ }
+ return TRUE;
+}
+
+/*
+typedef struct t_division {
+ char div_cde[4];
+ char div_txt[64];
+} TaxDivision, PNTR TaxDivisionPtr;
+ */
+
+static Int2 div_alloced= 16;
+static TaxDivisionPtr tax_div= NULL;
+
+Boolean tax_addDivision(Int4 div_id, CharPtr div_cde, CharPtr div_txt)
+{
+ Int2 i;
+
+ if(tax_div == NULL) {
+ tax_div= MemNew(sizeof(TaxDivision)*div_alloced);
+ if(tax_div == NULL) return FALSE;
+
+ for(i= 0; i < div_alloced; i++) {
+ tax_div[i].div_cde[0]= tax_div[i].div_cde[3]=
+ tax_div[i].div_txt[0]= tax_div[i].div_txt[63]= '\0';
+ }
+ }
+
+ if(div_id < 0) return FALSE;
+
+ if(div_id >= div_alloced) {
+ TaxDivisionPtr tmp= MemMore(tax_div, sizeof(TaxDivision)*(div_id + 8));
+
+ if(tmp == NULL) return FALSE;
+
+ tax_div= tmp;
+ for(i= div_alloced; i < div_id + 8; i++) {
+ tax_div[i].div_cde[0]= tax_div[i].div_cde[3]=
+ tax_div[i].div_txt[0]= tax_div[i].div_txt[63]= '\0';
+ }
+ div_alloced= div_id + 8;
+ }
+
+ StringNCpy(tax_div[div_id].div_cde, div_cde, 3);
+ StringNCpy(tax_div[div_id].div_txt, div_txt, 63);
+
+ return TRUE;
+}
+
+Boolean tax_getDivision(Int2 div_id, CharPtr* div_cde, CharPtr* div_txt)
+{
+ if((div_id < 0) || (div_id >= div_alloced)) return FALSE;
+
+ if(div_cde != NULL) *div_cde= tax_div[div_id].div_cde;
+ if(div_txt != NULL) *div_txt= tax_div[div_id].div_txt;
+ return TRUE;
+}
+
+Int2 tax_getDivisionId(CharPtr div_cde, CharPtr div_txt)
+{
+ Int2 i;
+
+ if(div_cde != NULL) {
+ for(i= 0; i < div_alloced; i++) {
+ if(StringICmp(tax_div[i].div_cde, div_cde) == 0) return i;
+ }
+ }
+
+ if(div_txt != NULL) {
+ for(i= 0; i < div_alloced; i++) {
+ if(StringICmp(tax_div[i].div_txt, div_txt) == 0) return i;
+ }
+ }
+
+ return -1;
+}
+
+Boolean tax_dumpDivisions(void (*dmpFunc)(VoidPtr, Int2, CharPtr, CharPtr), VoidPtr usrData)
+{
+ Int2 i;
+
+ if((tax_div == NULL) || (dmpFunc == NULL)) return FALSE;
+
+ for(i= 0; i < div_alloced; i++) {
+ if(tax_div[i].div_txt[0] != '\0') {
+ (*dmpFunc)(usrData, i, tax_div[i].div_cde, tax_div[i].div_txt);
+ }
+ }
+ return TRUE;
+}
+
+/*
+typedef struct t_genCode {
+ char gc_name[128];
+} TaxGenCode, PNTR TaxGenCodePtr;
+ */
+static Int2 gc_alloced= 20;
+static TaxGenCodePtr tax_gc= NULL;
+
+Boolean tax_addGC(Int2 gc_id, CharPtr gc_txt)
+{
+ Int2 i;
+
+ if(tax_gc == NULL) {
+ tax_gc= MemNew(sizeof(TaxGenCode)*gc_alloced);
+ if(tax_gc == NULL) return FALSE;
+
+ for(i= 0; i < gc_alloced; i++) {
+ tax_gc[i].gc_name[0]= tax_gc[i].gc_name[127]= '\0';
+ }
+ }
+
+ if(gc_id < 0) return FALSE;
+
+ if(gc_id >= gc_alloced) {
+ TaxGenCodePtr tmp= MemMore(tax_gc, sizeof(TaxGenCode)*(gc_id + 8));
+
+ if(tmp == NULL) return FALSE;
+
+ tax_gc= tmp;
+ for(i= gc_alloced; i < gc_id + 8; i++) {
+ tax_gc[i].gc_name[0]= tax_gc[i].gc_name[127]= '\0';
+ }
+ gc_alloced= gc_id + 8;
+ }
+
+ StringNCpy(tax_gc[gc_id].gc_name, gc_txt, 127);
+
+ return TRUE;
+}
+
+CharPtr tax_getGCName(Int2 gc_id)
+{
+
+ if((gc_id < 0) || (gc_id >= gc_alloced)) return "";
+
+ return tax_gc[gc_id].gc_name;
+}
+
+Int2 tax_getGCId(CharPtr gc_txt)
+{
+ Int2 i;
+
+ if(gc_txt == NULL) return -1;
+
+ for(i= 0; i < gc_alloced; i++) {
+ if(StringICmp(tax_gc[i].gc_name, gc_txt) == 0) return i;
+ }
+
+ return -1;
+}
+
+Boolean tax_dumpGCs(void (*dmpFunc)(VoidPtr, Int2, CharPtr), VoidPtr usrData)
+{
+ Int2 i;
+
+ if((tax_gc == NULL) || (dmpFunc == NULL)) return FALSE;
+
+ for(i= 0; i < gc_alloced; i++) {
+ if(tax_gc[i].gc_name[0] != '\0') {
+ (*dmpFunc)(usrData, i, tax_gc[i].gc_name);
+ }
+ }
+ return TRUE;
+}
+
+
+#ifdef TAX_LOG
+
+#include <rex_util.h>
+
+static CharPtr get_token(CharPtr str, CharPtr token)
+{
+ int i;
+
+ token[2]= '\0';
+
+ while(IS_WHITESP(*str)) {
+ if(*str == '\0') return NULL;
+ ++str;
+ }
+
+ if(*str == '\0') return NULL;
+
+ for(i= 1; i < 250; i++) {
+ if(IS_WHITESP(*str)) {
+ token[i]= ' ';
+ token[i+1]= '\0';
+ return str;
+ }
+
+ if(*str == '\0') {
+ token[i]= ' ';
+ token[i+1]= '\0';
+ return NULL;
+ }
+
+ token[i]= TO_UPPER(*str);
+ str++;
+ }
+
+ token[i]= ' ';
+ token[i+1]= '*';
+ token[i+2]= '\0';
+ return str;
+}
+
+Boolean tax_matchName(CharPtr orgName, CharPtr str, Int4 mode)
+{
+ if(StringICmp(orgName, str) == 0) return TRUE;
+
+ if(mode == TAX_RE_SEARCH) {
+ /* regular expression search */
+ char nBuff[256];
+ Int4 k;
+ rex_handler rh;
+ Boolean res;
+
+ strncpy(&nBuff[1], str, 250);
+ nBuff[0]= '@';
+ k= strlen(nBuff);
+ nBuff[k]= '@';
+ nBuff[k+1]= '\0';
+ rh= rex_setExpr(nBuff, REX_NO_CASE | REX_NO_SPACE);
+ if(rh == NULL) return 0;
+
+ nBuff[0]= '@';
+ for(k= 0; (k < 250) && (orgName[k] != '\0'); k++) {
+ nBuff[k+1]= toupper(orgName[k]);
+ }
+ k++;
+ nBuff[k]= '@';
+ nBuff[k+1]= '\0';
+
+ res= rex_cmp(rh, nBuff);
+
+ free(rh);
+ return res;
+ }
+
+ if(mode == TAX_TOKEN_SEARCH) {
+ char nBuff[256];
+ Int4 k;
+ rex_handler rh[16];
+ Int2 nof_rh, j, res;
+ CharPtr tail= str;
+
+ nBuff[0]= '*';
+ nBuff[1]= ' ';
+ for(nof_rh= 0; (nof_rh != 16) && (tail != NULL); nof_rh++) {
+ tail= get_token(tail, nBuff);
+ rh[nof_rh]= rex_setExpr(nBuff, REX_NO_CASE | REX_NO_SPACE);
+ if(rh[nof_rh] == NULL) nof_rh--;
+ }
+ if(nof_rh < 1) return FALSE;
+
+ nBuff[0]= ' ';
+
+ tail= orgName;
+ for(k= 0; (k < 250) && (tail[k] != '\0'); k++) {
+ nBuff[k+1]= toupper(tail[k]);
+ }
+ k++;
+ nBuff[k]= ' ';
+ nBuff[k+1]= '\0';
+
+ for(res= 1, j= 0; (j < nof_rh) && (res > 0); j++) {
+ res= rex_cmp(rh[j], nBuff);
+ }
+
+ for(j= 0; j < nof_rh; j++) {
+ free(rh[j]);
+ }
+ return (res != 0)? TRUE : FALSE;
+ }
+
+ return FALSE;
+}
+#endif
diff --git a/network/taxon1/taxon2/taxext.h b/network/taxon1/taxon2/taxext.h
new file mode 100644
index 00000000..42737e5b
--- /dev/null
+++ b/network/taxon1/taxon2/taxext.h
@@ -0,0 +1,88 @@
+/* taxext.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: taxext.h
+*
+* Author: Vladimir Soussov
+*
+* File Description: Header file for extendent taxonomy API
+*
+*
+* $Log: taxext.h,v $
+* Revision 1.1 1998/02/10 20:12:00 soussov
+* taxon2 related soft
+*
+*
+*/
+
+#ifndef TAXEXT_H_DONE
+#define TAXEXT_H_DONE
+
+#include <ncbi.h>
+#include <taxinc.h>
+#include <treemgr.h>
+
+/*-------------------------------------
+Get pointer to partial taxonomy tree
+You can call this function after tax1_init()
+The partial taxonomy tree will exists until you call tax1_fini()
+*/
+TreePtr tax1e_getTaxTreePtr();
+
+/*-------------------------------------
+Invoke the taxonomy node from the database and add it to
+taxonomy partial tree. This function invokes the whole path
+from the root to given node and merges this path with existing
+partial tree.
+Returns TRUE if node was added to the tree
+*/
+Boolean tax1e_invokeNode(Int4 tax_id);
+
+/*-------------------------------------
+Invoke the children of given node and add all of them to
+taxonomy partial tree. (It works like tax1e_invokeNode for
+all children but more efficient
+*/
+Boolean tax1e_invokeChildren(Int4 tax_id);
+
+/*-------------------------------------
+Move cursor to taxonomy node
+*/
+Boolean tax1e_toNode(TreeCursorPtr cursor, Int4 tax_id);
+
+/*-------------------------------------
+Get tax_id
+*/
+Int4 tax1e_getTaxId(TreeCursorPtr cursor);
+
+/*-------------------------------------
+Get taxname (scientific name)
+This function makes a copy of tax_name, you have to free this memory
+*/
+CharPtr tax1e_getTaxName(TreeCursorPtr cursor);
+
+
+
+#endif
diff --git a/network/taxon1/taxon2/tc2proc.c b/network/taxon1/taxon2/tc2proc.c
new file mode 100644
index 00000000..63e1f4c9
--- /dev/null
+++ b/network/taxon1/taxon2/tc2proc.c
@@ -0,0 +1,1644 @@
+/*----------------*/
+
+#include <stdlib.h>
+#include <ncbi.h>
+#include <taxinc.h>
+#include <txclient.h>
+#define REALTAXsyb
+
+#define MAX_ORG_LIST 10
+
+#define BUFF_SIZE 16
+#define TAX_READ 0
+#define TAX_WRITE 1
+
+
+static TreePtr tax_tree= NULL;
+
+static Int2 VRL_div= 0;
+static Int2 PHG_div= 0;
+
+static Int2 SpeciesRank= 26;
+static Int2 SubspeciesRank= 27;
+static Int2 GenusRank= 22;
+static Int2 FamilyRank= 0;
+static Int2 OrderRank= 0;
+static Int2 ClassRank= 0;
+static Int2 SYNONYM= 0;
+static Int2 COMMON_NAME= 0;
+static Int2 PREF_COMMON= 0;
+
+static int my_timer= 0;
+
+static struct t_or_buff {
+ Int4 tax_id;
+ OrgRefPtr p_org_ref;
+ int timer;
+ char div[16];
+ char embl[4];
+ int is_species;
+} or_buff[BUFF_SIZE];
+
+static CharPtr DB_PATH= "TAXCLIENT_OS";
+
+static Boolean we_want_synonyms= 0;
+
+static OrgRefPtr getFromBuff(Int4 id, int* is_sp, CharPtr div, CharPtr embl);
+static void loadInBuff(Int4 id);
+static void bldOrgRefOut(OrgRefPtr dst, OrgRefPtr src, Int4 tax_id);
+
+Boolean tax1_setSynonyms(Boolean on_off)
+{
+ Boolean ret;
+
+ ret= we_want_synonyms;
+ we_want_synonyms= on_off;
+ return ret;
+}
+
+
+static Boolean tc2_toNode(TreeCursorPtr cursor, Int4 tax_id)
+{
+ if(!tax_ptree_toTaxId(cursor, tax_id, FALSE)) {
+ /* this node is not in our tree */
+ return (tax_ptree_addNode(tax_tree, tax_id)) ?
+ tax_ptree_toTaxId(cursor, tax_id, FALSE) : FALSE;
+ }
+ return TRUE;
+}
+
+static void lockBuff(int mode)
+{
+ mode= mode;
+}
+
+static void unlockBuff(void)
+{
+}
+
+static void initBuff(void)
+{
+ int i;
+
+ my_timer= 0;
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ or_buff[i].tax_id= 0;
+ or_buff[i].p_org_ref= NULL;
+ }
+}
+
+static Int4 getLiveId(Int4 id)
+{
+ TreeCursorPtr cursor= tree_openCursor(tax_tree, NULL, NULL);
+ Uint2 s;
+ TXC_TreeNodePtr tnp;
+
+ if((cursor == NULL) || (!tc2_toNode(cursor, id))) return 0;
+
+ tnp= tree_getNodeData(cursor, &s);
+ tree_closeCursor(cursor);
+ return (tnp != NULL)? tnp->tax_id : 0;
+}
+
+
+/**************************************************************************
+ *
+ * InitTaxDB
+ *
+ **************************************************************************/
+
+int InitTaxDB(void)
+{
+ CharPtr tmp;
+
+ if((tmp=getenv("TAXDBPATH")) != NULL) DB_PATH= tmp;
+
+ if(!txc_connect2Server(DB_PATH, "soussov", "vladimir", "tax2cl")) {
+
+ return 0;
+ }
+
+ if((!txc_loadNameClasses()) || (!txc_loadRanks()) ||
+ (!txc_loadDivisions()) || (!txc_loadGCs())) {
+
+ return 0;
+ }
+
+
+ SpeciesRank= tax_getRankId("species");
+ SubspeciesRank= tax_getRankId("subspecies");
+ GenusRank= tax_getRankId("genus");
+ FamilyRank= tax_getRankId("family");
+ OrderRank= tax_getRankId("order");
+ ClassRank= tax_getRankId("class");
+
+
+ VRL_div= tax_getDivisionId("VRL", NULL);
+ PHG_div= tax_getDivisionId("PHG", NULL);
+
+ SYNONYM= tax_getClass_cde("synonym");
+ COMMON_NAME= tax_getClass_cde("common name");
+ PREF_COMMON= tax_getClass_cde("preferred common name");
+
+ initBuff();
+ tax_tree= tax_ptree_new();
+
+ return (tax_tree == NULL)? 0 : 1;
+}
+
+/**************************************************************************
+ *
+ * CloseTaxDB
+ *
+ **************************************************************************/
+
+int CloseTaxDB(void)
+{
+ int i;
+
+ if(tax_tree != NULL) {
+ tree_delete(tax_tree);
+
+ txc_close();
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if(or_buff[i].p_org_ref != NULL) {
+ OrgRefFree(or_buff[i].p_org_ref);
+ }
+ }
+ }
+ return 1;
+}
+
+Int4 tax1_getParent(Int4 id_tax)
+{
+ TreeCursorPtr cursor;
+ Int4 ret_id= -1;
+
+ if(tax_tree == NULL) return -1;
+
+ if(id_tax == 1) return 0;
+
+ cursor= tree_openCursor(tax_tree, NULL, NULL);
+ if(cursor == NULL) return -1;
+
+ if(tc2_toNode(cursor, id_tax)) {
+ TXC_TreeNodePtr tnp;
+ Uint2 s;
+
+ tree_parent(cursor);
+ tnp= tree_getNodeData(cursor, &s);
+ if(tnp != NULL) ret_id= tnp->tax_id;
+ }
+
+ tree_closeCursor(cursor);
+ return ret_id;
+}
+
+int tax1_getChildren(Int4 id_tax, Int4** ids_out)
+{
+ int n= 0;
+ Int4* ids;
+ TreeCursorPtr cursor= tree_openCursor(tax_tree, NULL, NULL);
+
+ *ids_out= NULL;
+
+ if(cursor == NULL) return 0;
+
+ if(tc2_toNode(cursor, id_tax)) {
+ if(tax_ptree_addChildren(cursor) && tree_child(cursor)) {
+ TXC_TreeNodePtr tnp;
+ Uint2 s;
+
+ do {
+ n++;
+ }
+ while(tree_sibling(cursor));
+
+ *ids_out= ids= MemNew(n*sizeof(Int4));
+
+ tree_parent(cursor);
+ tree_child(cursor);
+ n= 0;
+ do {
+ tnp= tree_getNodeData(cursor, &s);
+ if(tnp != NULL) ids[n++]= tnp->tax_id;
+ }
+ while(tree_sibling(cursor));
+ }
+ }
+
+ tree_closeCursor(cursor);
+ return n;
+}
+
+
+/* find last common ancestor for two nodes */
+Int4 tax1_join(Int4 taxid1, Int4 taxid2)
+{
+ TreeNodeId nid;
+ Int4 aid= 0;
+ TreeCursorPtr cursor1= tree_openCursor(tax_tree, NULL, NULL);
+ TreeCursorPtr cursor2= tree_openCursor(tax_tree, NULL, NULL);
+
+ if((cursor1 == NULL) || (cursor2 == NULL) ||
+ (!tc2_toNode(cursor1, taxid1)) || (!tc2_toNode(cursor2, taxid2))) {
+ if(cursor1 != NULL) tree_closeCursor(cursor1);
+ if(cursor2 != NULL) tree_closeCursor(cursor2);
+ return -1;
+ }
+
+ nid= tree_getAncestor(cursor1, cursor2);
+
+ if(tree_toNode(cursor1, nid)) {
+ TXC_TreeNodePtr tnp;
+ Uint2 s;
+
+ tnp= tree_getNodeData(cursor1, &s);
+ if(tnp != NULL) aid= tnp->tax_id;
+ }
+
+ tree_closeCursor(cursor1);
+ tree_closeCursor(cursor2);
+ return aid;
+}
+
+
+/***************************************************
+ * Get tax_id by organism name
+ * returns:
+ * tax_id if one node found
+ * 0 no organism found
+ * -tax_id if more than one node found
+ */
+Int4 tax1_getTaxIdByName(CharPtr orgname)
+{
+ return tax_getIdByName(orgname, NULL, 0);
+}
+
+/***************************************************
+ * Get all tax_id by organism name
+ * returns:
+ * Number of tax ids found
+ */
+Int4 tax1_getAllTaxIdByName(CharPtr orgname, Int4 **Ids_out)
+{
+ int i;
+ TaxNamePtr nameList;
+ Int4 *Ids;
+ int n= tax_findByName(orgname, TAX_NAME_SEARCH, &nameList);
+
+ if(n < 1) return 0;
+
+ *Ids_out= Ids= MemNew(n*sizeof(Int4));
+ if(Ids != NULL) {
+ for(i= 0; i < n; i++) {
+ Ids[i]= nameList[i].tax_id;
+ if(nameList[i].name_txt != NULL) MemFree(nameList[i].name_txt);
+ if(nameList[i].unique_name != NULL) MemFree(nameList[i].unique_name);
+ }
+ }
+ else {
+ for(i= 0; i < n; i++) {
+ if(nameList[i].name_txt != NULL) MemFree(nameList[i].name_txt);
+ if(nameList[i].unique_name != NULL) MemFree(nameList[i].unique_name);
+ }
+ n= 0;
+ }
+ MemFree(nameList);
+ return n;
+}
+
+static Boolean goodOrgMode(Uint1 t)
+{
+ return (t != 254) && (t != 20);
+}
+
+static Int4 getIdByOrgRef(CharPtr sname, OrgNamePtr orNm)
+{
+ if(orNm != NULL) {
+ OrgModPtr o_mod= orNm->mod;
+ Boolean om_flag= FALSE;
+ Int4 tax_id, id;
+ CharPtr altname= NULL;
+ int nof_mods= 0;
+ _subspecPtr ss;
+ _subspec src;
+
+ /* first try to search using search name */
+ for(;o_mod != NULL; o_mod= o_mod->next) {
+ if(o_mod->subtype == 254) {
+ /* search name */
+ altname= o_mod->subname;
+ }
+ else if(o_mod->subtype != 20) nof_mods++;
+ }
+
+ if(nof_mods == 0) {
+ /* we have no modifiers */
+ if(altname != NULL) {
+ if((tax_id= tax_getIdByName(altname, NULL, 0)) > 0) return tax_id;
+ return tax_getIdByName(sname, altname, 254);
+ }
+ return tax_getIdByName(sname, NULL, 0);
+ }
+
+ if(nof_mods == 1) {
+ /* we have one valuable modifier */
+ for(o_mod= orNm->mod; o_mod != NULL; o_mod= o_mod->next) {
+ if(goodOrgMode(o_mod->subtype)) {
+ if(altname != NULL) {
+ if((tax_id= tax_getIdByName(altname, o_mod->subname, o_mod->subtype)) > 0)
+ return tax_id; /* find by old name and modifier */
+ if((tax_id= tax_getIdByName(sname, o_mod->subname, o_mod->subtype)) > 0)
+ return tax_id; /* find by new name and modifier */
+ return tax_getIdByName(sname, altname, 254); /* find by new name and old name */
+ }
+ return tax_getIdByName(sname, o_mod->subname, o_mod->subtype);
+ }
+ }
+ return 0;
+ }
+
+ /* we have more than one modifier */
+ /* first try to find organism using just names */
+ if(altname != NULL) {
+ if((tax_id= tax_getIdByName(altname, NULL, 0)) == 0) {
+ tax_id= tax_getIdByName(sname, altname, 254);
+ }
+ }
+ else {
+ tax_id= tax_getIdByName(sname, NULL, 0);
+ }
+
+ if(tax_id == 0) return 0; /* we have no such names */
+ if(tax_id > 0) {
+ /* we have found just one node, check it against modifiers */
+ id= 0;
+ for(o_mod= orNm->mod; o_mod != NULL; o_mod= o_mod->next) {
+ if(o_mod->subtype != 20) {
+ src.stype= o_mod->subtype;
+ src.sname= o_mod->subname;
+ src.rname= NULL;
+ if((ss= tax_SSget(tax_id, &src)) != NULL) {
+ if(ss->rname != NULL) MemFree(ss->rname);
+ if((ss->r_id != 0) && (ss->r_id != tax_id)) {
+ if(id == 0) id= ss->r_id;
+ else if(id != ss->r_id) {
+ id= -id; /* conflict in mapping */
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(id == 0) return tax_id;
+ if(id < 0) return -tax_id; /* we have a mapping conflict */
+
+ /* we have a mapping without conflict, we try to make the best assumption */
+ return id;
+ }
+
+ if(tax_id < 0) {
+ /* more than one tax_id was found */
+ Int4Ptr ids;
+ Int4 n;
+
+ if(altname != NULL) {
+ n= tax1_getAllTaxIdByName(altname, &ids);
+ if(n < 1) n= tax1_getAllTaxIdByName(sname, &ids);
+ }
+ else n= tax1_getAllTaxIdByName(sname, &ids);
+
+ id= 0;
+ while(n-- > 0) {
+ for(o_mod= orNm->mod; o_mod != NULL; o_mod= o_mod->next) {
+ if(goodOrgMode(o_mod->subtype)) {
+ src.stype= o_mod->subtype;
+ src.sname= o_mod->subname;
+ src.rname= NULL;
+ if((ss= tax_SSget(ids[n], &src)) != NULL) {
+ if(ss->rname != NULL) MemFree(ss->rname);
+ if(ss->r_id != 0) {
+ if(id == 0) id= ss->r_id;
+ else if(id != ss->r_id) id= -id;
+ }
+ }
+ }
+ }
+ }
+ if(ids != NULL) MemFree(ids);
+ if(id > 0) return id;
+ }
+ return tax_id;
+ }
+ else {
+ /* we have no modifiers */
+ return tax_getIdByName(sname, NULL, 0);
+ }
+
+}
+
+Int4 tax1_getTaxIdByOrgRef(OrgRefPtr orgRef)
+{
+#ifdef TAXSERVICE
+ return txc_getTaxIdByOrgRef(orgRef);
+#else
+ Int4 tax_id, id;
+
+ if(orgRef == NULL) return 0;
+
+ tax_id= 0;
+
+ if((orgRef->taxname != NULL) &&
+ ((tax_id= getIdByOrgRef(orgRef->taxname, orgRef->orgname)) > 0)) return tax_id;
+
+ if((orgRef->common != NULL) &&
+ ((tax_id= getIdByOrgRef(orgRef->common, orgRef->orgname)) > 0)) return tax_id;
+
+ if(orgRef->syn != NULL) {
+ ValNodePtr synonym;
+
+ id= 0;
+
+ for(synonym= orgRef->syn; (synonym != NULL) && (id < 1); synonym= synonym->next) {
+ id= getIdByOrgRef(synonym->data.ptrvalue, orgRef->orgname);
+ }
+ }
+
+ return (id > 0)? id : tax_id;
+#endif
+}
+
+/*******************************************************************
+ * Get tax_id by organism name (it could be "unique" variant of name)
+ * returns:
+ * tax_id if one node found
+ * 0 no organism found
+ * -tax_id if more than one node found
+ */
+Int4 tax1_findTaxIdByName(CharPtr orgname)
+{
+ Int4 id= tax_getIdByName(orgname, NULL, 0);
+
+ if(id < 1) {
+ Int4 idu= tax_uniqueName(orgname, 0);
+
+ if(idu > 0) id= idu;
+ }
+ return id;
+}
+
+
+/*************************************************************************
+ * Get all tax_id by organism name (it could be "unique" variant of name)
+ * returns:
+ * Number of tax ids found
+ */
+Int4 tax1_findAllTaxIdByName(CharPtr orgname, Int4 **Ids_out)
+{
+ Int4 id= tax1_findTaxIdByName(orgname);
+
+ if(id > 0) {
+ *Ids_out= MemNew(sizeof(Int4));
+ if(*Ids_out != NULL) {
+ **Ids_out= id;
+ return 1;
+ }
+ else return 0;
+ }
+
+ if(id < 0) {
+ return tax1_getAllTaxIdByName(orgname, Ids_out);
+ }
+
+ return 0;
+}
+
+Int2 tax1_getAllNames(Int4 tax_id, CharPtr **out_names, Boolean unique)
+{
+ TaxNamePtr nameList;
+ Int2 n= tax_getOrgNames(tax_id, &nameList);
+ Int2 i;
+ CharPtr* names;
+
+ if(n < 1) return 0;
+
+ *out_names= names= MemNew(n*sizeof(CharPtr));
+ if(names != NULL) {
+ for(i= 0; i < n; i++) {
+ if(unique && (nameList[i].unique_name != NULL)) {
+ names[i]= nameList[i].unique_name;
+ nameList[i].unique_name= NULL;
+ }
+ else {
+ names[i]= nameList[i].name_txt;
+ nameList[i].name_txt= NULL;
+ }
+ }
+ }
+
+ for(i= 0; i < n; i++) {
+ if(nameList[i].name_txt != NULL) MemFree(nameList[i].name_txt);
+ if(nameList[i].unique_name != NULL) MemFree(nameList[i].unique_name);
+ }
+
+ MemFree(nameList);
+ return n;
+}
+
+
+CharPtr tax1_getGCName(Int2 gc_id)
+{
+ return tax_getGCName(gc_id);
+}
+
+OrgRefPtr tax1_getOrgRef(Int4 tax_id, int* is_species, CharPtr div, CharPtr embl_cde)
+{
+ OrgRefPtr orp;
+
+ tax_id= getLiveId(tax_id);
+ if(tax_id == 0) return NULL;
+
+ if((orp= getFromBuff(tax_id, is_species, div, embl_cde)) != NULL) {
+ /* OrgRef is already in buffer */
+ return orp;
+ }
+
+ lockBuff(TAX_WRITE);
+ loadInBuff(tax_id);
+ unlockBuff();
+
+ return getFromBuff(tax_id, is_species, div, embl_cde);
+}
+
+Taxon1DataPtr tax1_getbyid(Int4 tax_id)
+{
+ Taxon1DataPtr res;
+ OrgRefPtr db_orgRef;
+ int is_species;
+
+ if(tax_id <= 0) return NULL;
+ res= Taxon1DataNew();
+ res->div= MemNew(16);
+ res->embl_code= MemNew(4);
+ db_orgRef= tax1_getOrgRef(tax_id, &is_species, res->div, NULL/*res->embl_code*/);
+ res->embl_code[0]= '\0';
+ if(db_orgRef == NULL) {
+ Taxon1DataFree(res);
+ return NULL;
+ }
+
+ /* make new orgref */
+ res->org= OrgRefNew();
+ res->org->db= NULL;
+ res->org->orgname= NULL;
+ res->is_species_level= is_species;
+
+ /* fill-up orgref based on db_orgRef */
+ bldOrgRefOut(res->org, db_orgRef, getLiveId(tax_id));
+ return res;
+}
+
+/*************************************************************************/
+/* return pointer to first non-blank character in str1 after prefix str2 */
+/* if str2 is not prefix for str1 then return str1 */
+/*************************************************************************/
+static CharPtr strTail(CharPtr str1, CharPtr str2)
+{
+ CharPtr c;
+
+ if(StringStr(str1, str2) != str1) return str1;
+
+ c= str1 + StringLen(str2);
+
+ while((*c != '\0') && IS_WHITESP(*c)) c++;
+
+ return c;
+}
+
+
+
+static OrgModPtr bldOrgMod(TreeCursorPtr cursor)
+{
+ TXC_TreeNodePtr parent= NULL;
+ Uint2 s;
+ TXC_TreeNodePtr me= tree_getNodeData(cursor, &s);
+ TXC_TreeNodePtr tnp;
+ TreeNodeId nid= tree_getId(cursor);
+ Int2 rank, prank;
+ OrgModPtr orgMdf= OrgModNew();
+
+ while(tree_parent(cursor)) {
+ if((tnp= tree_getNodeData(cursor, &s)) == NULL) continue;
+ prank= tnp->flags & 0xFF;
+ --prank;
+ if((prank == SubspeciesRank) ||
+ (prank == SpeciesRank) ||
+ (prank == GenusRank)) {
+ parent= tnp;
+ break;
+ }
+ }
+ tree_toNode(cursor, nid);
+
+ if(parent != NULL) {
+ orgMdf->subname= StringSave(strTail(me->node_label, parent->node_label));
+ }
+ else {
+ orgMdf->subname= StringSave(me->node_label);
+ }
+
+ rank= me->flags & 0xFF;
+
+ if(--rank == SubspeciesRank) {
+ orgMdf->subtype= 22; /* subspecies */
+ }
+ else if(rank == tax_getRankId("varietas")) {
+ orgMdf->subtype= 6; /* variety */
+ }
+ else if(rank == tax_getRankId("forma")) {
+ orgMdf->subtype= 2; /* strain */
+ }
+ else if((parent != NULL) && (prank == SubspeciesRank)) {
+ orgMdf->subtype= 2; /* strain */
+ }
+ else {
+ orgMdf->subtype= 255; /* other */
+ }
+
+ orgMdf->attrib= NULL;
+
+ return orgMdf;
+}
+
+
+/***************************************************************/
+/* if name is binomial name build the correspondent structures */
+/* otherwise return 0 */
+/***************************************************************/
+static int binomialName(TreeCursorPtr cursor, OrgNamePtr onp)
+{
+ TXC_TreeNodePtr spec= NULL;
+ TXC_TreeNodePtr subspec= NULL;
+ TXC_TreeNodePtr genus= NULL;
+ TXC_TreeNodePtr tnp;
+ Uint2 s;
+ TreeNodeId nid= tree_getId(cursor);
+ Int2 rank;
+ BinomialOrgNamePtr bName;
+
+ do {
+ tnp= tree_getNodeData(cursor, &s);
+ if(tnp == NULL) continue;
+ rank= tnp->flags & 0xFF;
+ if(--rank == SubspeciesRank) subspec= tnp;
+ else if(rank == SpeciesRank) spec= tnp;
+ else if(rank == GenusRank) {
+ genus= tnp;
+ break;
+ }
+ }
+ while(tree_parent(cursor));
+
+ tree_toNode(cursor, nid);
+
+ if(genus == NULL) {
+ /* try to find subgenus */
+ do {
+ tnp= tree_getNodeData(cursor, &s);
+ if(tnp == NULL) continue;
+ rank= tnp->flags & 0xFF;
+ if(--rank == (GenusRank + 1)) {
+ genus= tnp;
+ break;
+ }
+ }
+ while(tree_parent(cursor));
+ tree_toNode(cursor, nid);
+ }
+
+ if(genus == NULL) return 0; /* no genus - no binomial */
+
+ onp->choice= 1; /*binomial*/
+
+ onp->data= bName= BinomialOrgNameNew();
+
+ bName->genus= StringSave(genus->node_label);
+
+
+ if(spec != NULL) {
+ /* we have a species in lineage */
+ bName->species= StringSave(strTail(spec->node_label, genus->node_label));
+
+ if(subspec != NULL) {
+ /* we also have a subspecies in lineage */
+ bName->subspecies= StringSave(strTail(subspec->node_label, spec->node_label));
+ }
+ else {
+ bName->subspecies= NULL;
+ }
+ tnp= tree_getNodeData(cursor, &s);
+
+ onp->mod= (tnp == spec)? NULL : bldOrgMod(cursor);
+ return 1;
+ }
+
+ /* no species in lineage */
+
+ if(subspec != NULL) {
+ /* we have no species but we have subspecies */
+ bName->species= NULL;
+ bName->subspecies= StringSave(strTail(subspec->node_label, genus->node_label));
+ onp->mod= bldOrgMod(cursor);
+ return 1;
+ }
+
+ /* we have no species, no subspecies but we are under species level (varietas or forma) */
+
+ bName->species= NULL;
+ bName->subspecies= NULL;
+ onp->mod= bldOrgMod(cursor);
+ return 1;
+}
+
+
+static void partialName(TreeCursorPtr cursor, OrgNamePtr onp)
+{
+ TaxElementPtr taxElem;
+ Uint2 s;
+ TXC_TreeNodePtr tnp= tree_getNodeData(cursor, &s);
+ Int2 rank_id= tnp->flags & 0xFF;
+
+ onp->choice= 5; /* partial */
+ onp->data= taxElem= TaxElementNew();
+
+ if(--rank_id == FamilyRank) {
+ taxElem->fixed_level= 1; /* family */
+ taxElem->level= NULL;
+ }
+ else if(rank_id == OrderRank) {
+ taxElem->fixed_level= 2;
+ taxElem->level= NULL;
+ }
+ else if(rank_id == ClassRank) {
+ taxElem->fixed_level= 3;
+ taxElem->level= NULL;
+ }
+ else {
+ taxElem->fixed_level= 0;
+ taxElem->level= StringSave(tax_getRank(rank_id));
+ }
+
+ taxElem->name= StringSave(tnp->node_label);
+ taxElem->next= NULL;
+}
+
+
+/*****************************************************************
+ * build synonyms valnodes
+ * this routine include in valnodes synonyms and common synonyms
+ */
+static ValNodePtr bldSynValNodes(TaxNamePtr syn, Int2 n)
+{
+ ValNodePtr list= NULL;
+ ValNodePtr header= NULL;
+ Int2 i;
+
+ for(i= 1; i < n; i++) {
+ if((syn[i].class_cde == SYNONYM) || (syn[i].class_cde == COMMON_NAME)) {
+ list= ValNodeNew(list);
+ list->choice= (syn[i].class_cde == SYNONYM)? 1 : 0;
+ list->data.ptrvalue= syn[i].name_txt;
+ syn[i].name_txt= NULL;
+ if(header == NULL) header= list;
+ }
+ }
+ return header;
+}
+
+
+/**************************************************************************
+ *
+ * FsTaxGetLineage
+ *
+ **************************************************************************/
+
+static CharPtr bldLineage(TreeCursorPtr cursor)
+{
+ TXC_TreeNodePtr tnp;
+ Uint2 s;
+ TreeNodeId nid= tree_getId(cursor);
+ CharPtr lineage= NULL;
+ CharPtr tmp, t;
+ Int2 rank;
+
+
+ while(tree_parent(cursor)) {
+ if((tnp= tree_getNodeData(cursor, &s)) != NULL) {
+ rank= tnp->flags & 0xFF;
+ if(rank > SpeciesRank) {
+ if(lineage != NULL) MemFree(lineage);
+ continue;
+ }
+ if(tnp->tax_id < 2) break;
+
+ if((tnp->flags & TXC_GBHIDE) == 0) {
+ s= StringLen(tnp->node_label);
+ if(lineage != NULL) {
+ s+= StringLen(lineage) + 2;
+ }
+
+ tmp= MemNew(s+2);
+ if(tmp == NULL) continue;
+ t= StringMove(tmp, tnp->node_label);
+ if(lineage != NULL) {
+ t= StringMove(t, "; ");
+ t= StringMove(t, lineage);
+ MemFree(lineage);
+ }
+ lineage= tmp;
+ }
+ }
+ }
+
+ tree_toNode(cursor, nid);
+
+ return lineage;
+}
+
+static ValNodePtr bldDBId(Int4 id)
+{
+ ValNodePtr dbnode;
+ DbtagPtr dbtag;
+ ObjectIdPtr object_id;
+
+ /* populate tax_id */
+ dbnode= ValNodeNew(NULL);
+ dbnode->data.ptrvalue= dbtag= DbtagNew();
+ dbtag->db = StringSave("taxon");
+ dbtag->tag= object_id= ObjectIdNew();
+ object_id->str= NULL;
+ object_id->id = id;
+ return dbnode;
+}
+
+static OrgNamePtr bldOrgName(TreeCursorPtr cursor, int* is_species_out, CharPtr div, CharPtr embl)
+{
+ OrgNamePtr onp;
+ Uint2 s;
+ TXC_TreeNodePtr tnp= tree_getNodeData(cursor, &s);
+ CharPtr div_abbr;
+ Int2 rank_id;
+ int is_species;
+ Int2 div_id;
+ TreeNodeId nid= tree_getId(cursor);
+ Int2 rank;
+
+ /*Int4 p_id, s_id;*/
+
+ if(tnp == NULL) return NULL;
+
+ onp= OrgNameNew();
+
+ rank_id= tnp->flags & 0xFF;
+ rank_id--;
+
+ div_id= (tnp->flags >> 8) & 0x3F;
+ onp->gcode= (tnp->flags >> (8+6)) & 0x3F;
+ onp->mgcode= (tnp->flags >> (8+6+6)) & 0x3F;
+ onp->lineage= bldLineage(cursor);
+ if(embl != NULL) *embl= '\0';
+
+ is_species= (rank_id >= SpeciesRank)? 1 : 0;
+ /* correct level by lineage if node has no rank */
+ if(rank_id < 0) {
+
+ while(tree_parent(cursor)) {
+ tnp= tree_getNodeData(cursor, &s);
+ if(tnp != NULL) {
+ rank= tnp->flags & 0xFF;
+ if(rank != 0) {
+ is_species= (rank >= SpeciesRank) ? 1 : 0;
+ break;
+ }
+ }
+ }
+ tree_toNode(cursor, nid);
+ tnp= tree_getNodeData(cursor, &s);
+ }
+
+ if(tax_getDivision(div_id, &div_abbr, NULL)) {
+ onp->div= StringSave(div_abbr);
+ StringCpy(div, div_abbr);
+ }
+ *is_species_out= is_species;
+
+ if(is_species) {
+ /* we are on species level or below */
+
+ /* check for viruses */
+ if((div_id == VRL_div) || (div_id == PHG_div)) {
+ /* this is a virus */
+ onp->choice= 2; /* virus */
+ if(rank_id == SpeciesRank) {
+ /* we are on species level */
+ onp->data= StringSave(tnp->node_label);
+ onp->mod= NULL;
+ }
+ else {
+ /* we are below species */
+ /* first try to find species or min rank which below species but above us */
+ TreeNodeId s_id;
+
+ s_id.idi= 0;
+ while(tree_parent(cursor)) {
+ tnp= tree_getNodeData(cursor, &s);
+ if(tnp != NULL) {
+ rank= tnp->flags & 0xFF;
+ if(--rank >= SpeciesRank) {
+ s_id= tree_getId(cursor);
+ if(rank == SpeciesRank) break;
+ }
+ else if(rank >= 0) break;
+ }
+ }
+ if(s_id.idi != 0) {
+ /* we have species or something above us */
+ tree_toNode(cursor, s_id);
+ }
+ else {
+ /* no species above */
+ tree_toNode(cursor, nid);
+ }
+
+ tnp= tree_getNodeData(cursor, &s);
+ onp->data= StringSave(tnp->node_label);
+ if(s_id.idi != 0) {
+ tree_toNode(cursor, nid);
+ }
+
+ onp->mod= bldOrgMod(cursor);
+ }
+ }
+ else if(!binomialName(cursor, onp)) {
+ /* name is not binomial: set partial */
+ partialName(cursor, onp);
+ }
+ }
+ else {
+ /* above species */
+ partialName(cursor, onp);
+ }
+
+ return onp;
+}
+
+
+static Boolean bldOrgRef(Int4 id, OrgRefPtr orp, int* is_species, CharPtr div, CharPtr embl)
+{
+ TreeCursorPtr cursor= tree_openCursor(tax_tree, NULL, NULL);
+ TaxNamePtr nameList;
+ Int2 n, i;
+
+ if((cursor == NULL) || (!tc2_toNode(cursor, id))) return FALSE;
+
+ *is_species= 0;
+ *div= *embl= '\0';
+
+ n= tax_getOrgNames(id, &nameList);
+
+ if(n < 1) {
+ tree_closeCursor(cursor);
+ return FALSE;
+ }
+
+ orp->taxname= nameList[0].name_txt;
+ nameList[0].name_txt= NULL;
+
+
+ /* fill-up preferred common name */
+ orp->common= NULL;
+ for(i= 1; i < n; i++) {
+ if(nameList[i].class_cde == PREF_COMMON) {
+ orp->common= nameList[i].name_txt;
+ nameList[i].name_txt= NULL;
+ break;
+ }
+ }
+
+ /* fill-up synonyms */
+ orp->syn= bldSynValNodes(nameList, n);
+ for(i= 0; i < n; i++) {
+ if(nameList[i].name_txt != NULL) MemFree(nameList[i].name_txt);
+ if(nameList[i].unique_name != NULL) MemFree(nameList[i].unique_name);
+ }
+
+ MemFree(nameList);
+
+ orp->mod= NULL;
+ orp->db= bldDBId(id);
+ orp->orgname= bldOrgName(cursor, is_species, div, embl);
+
+
+ tree_closeCursor(cursor);
+ return TRUE;
+}
+
+
+static void loadInBuff(Int4 id)
+{
+ int i, k= -1;
+ Int4 t= my_timer + 1;
+ /*Int4 bt;*/
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if(or_buff[i].tax_id == 0) {
+ k= i;
+ break;
+ }
+ if(or_buff[i].timer < t) {
+ t= or_buff[i].timer;
+ k= i;
+ }
+ }
+
+ if(k >= 0) {
+ if(or_buff[k].p_org_ref != NULL) OrgRefFree(or_buff[k].p_org_ref);
+ or_buff[k].tax_id= id;
+ or_buff[k].p_org_ref= OrgRefNew();
+ or_buff[k].timer= ++my_timer;
+ if(!bldOrgRef(id, or_buff[k].p_org_ref, &or_buff[k].is_species, or_buff[k].div, or_buff[k].embl)) {
+ OrgRefFree(or_buff[k].p_org_ref);
+ or_buff[k].tax_id= 0;
+ }
+ }
+}
+
+static OrgRefPtr getFromBuff(Int4 id, int* is_sp, CharPtr div, CharPtr embl)
+{
+ int i;
+ OrgRefPtr orp= NULL;
+
+ lockBuff(TAX_READ);
+
+ for(i= 0; i < BUFF_SIZE; i++) {
+ if(or_buff[i].tax_id == id) {
+ or_buff[i].timer= ++my_timer;
+ orp= or_buff[i].p_org_ref;
+ if(is_sp != NULL) *is_sp= or_buff[i].is_species;
+ if(div != NULL) StringCpy(div, or_buff[i].div);
+ if(embl != NULL) StringCpy(embl, ""/*or_buff[i].embl*/);
+ break;
+ }
+ }
+ unlockBuff();
+ return orp;
+}
+
+static OrgModPtr fixModifier(Int4 tax_id, OrgModPtr omp)
+{
+ _subspec src_ss;
+ _subspecPtr ss= NULL;
+
+ if((omp->subname != NULL) && (omp->subtype != 0)) {
+ src_ss.stype= omp->subtype;
+ src_ss.sname= omp->subname;
+ src_ss.rname= NULL;
+
+ ss= tax_SSget(tax_id, &src_ss);
+ }
+
+ if((ss != NULL) && (ss->r_id == tax_id) && (ss->stype == 0)) {
+ /* remove it */
+ if(ss->rname != NULL) MemFree(ss->rname);
+ omp->next= NULL;
+ OrgModFree(omp);
+ return NULL;
+ }
+
+ if((ss != NULL) && (ss->r_id == tax_id) && (ss->stype != 0)) {
+ MemFree(omp->subname);
+ omp->subname= src_ss.rname;
+ omp->subtype= src_ss.rtype;
+ return omp;
+ }
+
+ if(src_ss.rname != NULL) MemFree(src_ss.rname);
+ return omp;
+}
+
+static void CleanOrgMod(Int4 tax_id, OrgNamePtr onp)
+{
+ OrgModPtr omp, omp_p, omp_n;
+
+ for(omp_p= NULL, omp= onp->mod; omp != NULL; omp= omp_n) {
+ omp_n= omp->next;
+ if((omp= fixModifier(tax_id, omp)) == NULL) {
+ /* exclude this modifier */
+ if(omp_p == NULL) {
+ onp->mod= omp_n;
+ }
+ else omp_p->next= omp_n;
+ }
+ else omp_p= omp;
+ }
+}
+
+static void cleanOrgName(Int4 tax_id, OrgNamePtr onp)
+{
+ if(onp->lineage != NULL) MemFree(onp->lineage);
+ if(onp->div != NULL) MemFree(onp->div);
+#if 1
+ /* #if 0 means that we will trust to initial modifier */
+ if(onp->mod != NULL) CleanOrgMod(tax_id, onp);
+#endif
+ if(onp->next != NULL) OrgNameSetFree(onp->next);
+ if(onp->data != NULL) {
+ switch(onp->choice) {
+ case 1 : /* binomial name */
+ BinomialOrgNameFree(onp->data);
+ break;
+ case 2 : /* virus name */
+ MemFree(onp->data);
+ break;
+ case 5 : /* partial name */
+ TaxElementSetFree(onp->data);
+ break;
+ }
+ }
+}
+
+
+static BinomialOrgNamePtr copyBinomial(BinomialOrgNamePtr src)
+{
+ BinomialOrgNamePtr dst;
+
+ if(src == NULL) return NULL;
+
+ dst= BinomialOrgNameNew();
+ dst->genus= (src->genus != NULL)? StringSave(src->genus) : NULL;
+ dst->species= (src->species != NULL)? StringSave(src->species) : NULL;
+ dst->subspecies= (src->subspecies != NULL)? StringSave(src->subspecies) : NULL;
+
+ return dst;
+}
+
+static TaxElementPtr copyPartial(TaxElementPtr src)
+{
+ TaxElementPtr dst;
+
+ if(src == NULL) return NULL;
+
+ dst= TaxElementNew();
+ dst->fixed_level= src->fixed_level;
+ dst->level= (src->level != NULL)? StringSave(src->level) : NULL;
+ dst->name= (src->name != NULL)? StringSave(src->name) : NULL;
+ dst->next= (src->next != NULL)? copyPartial(src->next) : NULL;
+ return dst;
+}
+
+static OrgModPtr copyOrgMod(OrgModPtr src)
+{
+#if 0
+ OrgModPtr dst;
+
+ if(src == NULL) return NULL;
+
+ dst= OrgModNew();
+ dst->subtype= src->subtype;
+ dst->subname= (src->subname != NULL)? StringSave(src->subname) : NULL;
+ dst->attrib= (src->attrib != NULL)? StringSave(src->attrib) : NULL;
+ dst->next= (src->next != NULL)? copyOrgMod(src->next) : NULL;
+
+ return dst;
+#endif
+ return NULL;
+}
+
+static ValNodePtr removeDbtag(ValNodePtr vnp)
+{
+ ValNodePtr vnn, vnf, vnl= NULL;
+ DbtagPtr dbtag;
+
+ for(vnf= vnp; vnp != NULL; vnp= vnn) {
+ dbtag= vnp->data.ptrvalue;
+ vnn= vnp->next;
+ if(dbtag == NULL) return NULL;
+ if(StringCmp(dbtag->db, "taxon") == 0) {
+ /* taxon tag, remove it */
+ if(vnl == NULL) {
+ vnf= vnn;
+ }
+ else {
+ vnl->next= vnn;
+ }
+ DbtagFree(dbtag);
+ MemFree(vnp);
+ }
+ else {
+ vnl= vnp;
+ }
+ }
+ return vnf;
+}
+
+
+static void bldOrgRefOut(OrgRefPtr dst, OrgRefPtr src, Int4 tax_id)
+{
+ ValNodePtr vnp, vnl;
+ DbtagPtr dbtag;
+ ObjectIdPtr object_id;
+ OrgNamePtr onp;
+
+ dst->taxname= StringSave(src->taxname);
+ dst->common= (src->common != NULL)? StringSave(src->common) : NULL;
+
+ /* populate tax_id */
+ vnp= ValNodeNew(NULL);
+ if (dst->db != NULL) {
+ dst->db= removeDbtag(dst->db);
+ }
+ vnp->next= dst->db;
+ dst->db= vnp;
+ vnp->data.ptrvalue= dbtag= DbtagNew();
+ dbtag->db = StringSave("taxon");
+ dbtag->tag= object_id= ObjectIdNew();
+ object_id->str= NULL;
+ object_id->id = getLiveId(tax_id);
+
+ /* copy the synonym list */
+ dst->syn= NULL; vnl= NULL;
+ if(we_want_synonyms) {
+ for(vnp= src->syn; vnp != NULL; vnp= vnp->next) {
+ vnl= ValNodeNew(vnl);
+ vnl->choice= vnp->choice;
+ vnl->data.ptrvalue= StringSave(vnp->data.ptrvalue);
+ if(dst->syn == NULL) dst->syn= vnl;
+ }
+ }
+
+ /* copy orgname */
+ if(dst->orgname == NULL) dst->orgname= onp= OrgNameNew();
+ else onp= dst->orgname;
+
+ onp->choice= src->orgname->choice;
+
+ switch(src->orgname->choice) {
+ case 1 : /*binomial*/
+ onp->data= copyBinomial(src->orgname->data);
+ break;
+ case 2 : /* virus */
+ onp->data= (src->orgname->data != NULL)? StringSave(src->orgname->data) : NULL;
+ break;
+ case 5 : /* partial */
+ onp->data= copyPartial(src->orgname->data);
+ break;
+ default : /* can't handle */
+ onp->data= NULL;
+ }
+
+ if(onp->mod == NULL) onp->mod= copyOrgMod(src->orgname->mod);
+ onp->lineage= (src->orgname->lineage != NULL)? StringSave(src->orgname->lineage) : NULL;
+ onp->gcode= src->orgname->gcode;
+ onp->mgcode= src->orgname->mgcode;
+ onp->div= StringSave(src->orgname->div);
+}
+
+static void populateReplaced(OrgRefPtr orp, CharPtr oldName)
+{
+ OrgNamePtr onp;
+ OrgModPtr omp;
+
+ if((orp->taxname != NULL) && (StringICmp(orp->taxname, oldName) == 0)) {
+ MemFree(oldName);
+ return;
+ }
+
+ if((orp->common != NULL) && (StringICmp(orp->common, oldName) == 0)) {
+ MemFree(oldName);
+ return;
+ }
+
+ /* organism name was changed */
+ onp= orp->orgname;
+ if(onp != NULL) {
+ omp= OrgModNew();
+ omp->next= onp->mod;
+ omp->subtype= 254;
+ omp->subname= oldName;
+ onp->mod= omp;
+ }
+ else {
+ MemFree(oldName);
+ }
+}
+
+Taxon1DataPtr tax1_lookup(OrgRefPtr inp_orgRef, int merge)
+{
+ Taxon1DataPtr res;
+ Int4 tax_id;
+ OrgRefPtr db_orgRef;
+ int is_species;
+ Boolean need_search_name= TRUE;
+ CharPtr hit_name;
+
+ tax_id= tax1_getTaxIdByOrgRef(inp_orgRef);
+ if(tax_id <= 0) return NULL;
+ res= Taxon1DataNew();
+ res->div= MemNew(16);
+ res->embl_code= MemNew(4);
+ db_orgRef= tax1_getOrgRef(tax_id, &is_species, res->div, NULL /*res->embl_code*/);
+ res->embl_code[0]= '\0';
+ if(db_orgRef == NULL) {
+ Taxon1DataFree(res);
+ return NULL;
+ }
+
+ res->is_species_level= is_species;
+
+ /* populate search name if necessary */
+ if(inp_orgRef->taxname != NULL) {
+ if((db_orgRef->taxname != NULL) && (StringICmp(inp_orgRef->taxname, db_orgRef->taxname) == 0)) {
+ need_search_name= FALSE;
+ }
+ else if((db_orgRef->common != NULL) && (StringICmp(inp_orgRef->taxname, db_orgRef->common) == 0)) {
+ need_search_name= FALSE;
+ }
+ }
+
+ if(need_search_name && (inp_orgRef->common != NULL)) {
+ if((db_orgRef->taxname != NULL) && (StringICmp(inp_orgRef->common, db_orgRef->taxname) == 0)) {
+ need_search_name= FALSE;
+ }
+ else if((db_orgRef->common != NULL) && (StringICmp(inp_orgRef->common, db_orgRef->common) == 0)) {
+ need_search_name= FALSE;
+ }
+ }
+
+ if(need_search_name && (inp_orgRef->orgname != NULL)) {
+ /* check if search name already exists */
+ OrgModPtr omp;
+
+ for(omp= inp_orgRef->orgname->mod; omp != NULL; omp= omp->next) {
+ if(omp->subtype == 254) {
+ need_search_name= FALSE;
+ break;
+ }
+ }
+ }
+
+ hit_name= NULL;
+ if(need_search_name) {
+ if((inp_orgRef->taxname != NULL) && (inp_orgRef->taxname[0] != '\0')) {
+ hit_name= StringSave(inp_orgRef->taxname);
+ }
+ else if((inp_orgRef->common != NULL) && (inp_orgRef->common[0] != '\0')) {
+ hit_name= StringSave(inp_orgRef->common);
+ }
+ }
+
+ if(merge) {
+ /* we have to merge old orgref with the new one */
+ res->org= inp_orgRef;
+ /* clean-up old information */
+ if(inp_orgRef->taxname != NULL) MemFree(inp_orgRef->taxname);
+ if(inp_orgRef->common != NULL) MemFree(inp_orgRef->common);
+ if(inp_orgRef->syn != NULL) ValNodeFreeData(inp_orgRef->syn);
+ if(inp_orgRef->orgname != NULL) cleanOrgName(tax_id, inp_orgRef->orgname);
+ }
+ else {
+ /* make new orgref */
+ res->org= OrgRefNew();
+ res->org->db= NULL;
+ res->org->orgname= NULL;
+ }
+ /* fill-up orgref based on db_orgRef */
+ bldOrgRefOut(res->org, db_orgRef, tax_id);
+ if(need_search_name && (hit_name != NULL)) populateReplaced(res->org, hit_name);
+ return res;
+}
+
+
+Boolean tax1_init(void)
+{
+ return InitTaxDB();
+}
+
+void tax1_fini(void)
+{
+ CloseTaxDB();
+}
+
+TreePtr tax1e_getTaxTreePtr(void)
+{
+ return tax_tree;
+}
+
+Boolean tax1e_invokeNode(Int4 tax_id)
+{
+ return tax_ptree_addNode(tax_tree, tax_id);
+}
+
+Boolean tax1e_invokeChildren(Int4 tax_id)
+{
+ Boolean res= FALSE;
+
+ TreeCursorPtr cursor= tree_openCursor(tax_tree, NULL, NULL);
+ if(tax_id < 0) {
+ res= TRUE;
+ tax_id= -tax_id;
+ }
+
+ if((cursor == NULL) || (!tc2_toNode(cursor, tax_id))) return FALSE;
+
+ res= res? tax_ptree_addSubtree(cursor) : tax_ptree_addChildren(cursor);
+
+ tree_closeCursor(cursor);
+ return res;
+}
+
+Boolean tax1e_toNode(TreeCursorPtr cursor, Int4 tax_id)
+{
+ return tc2_toNode(cursor, tax_id);
+}
+
+Int4 tax1e_getTaxId(TreeCursorPtr cursor)
+{
+ Uint2 s;
+ TXC_TreeNodePtr tnp;
+
+ tnp= tree_getNodeData(cursor, &s);
+
+ return (tnp != NULL)? tnp->tax_id : 0;
+}
+
+CharPtr tax1e_getTaxName(TreeCursorPtr cursor)
+{
+ Uint2 s;
+ TXC_TreeNodePtr tnp;
+
+ tnp= tree_getNodeData(cursor, &s);
+
+ return (tnp != NULL)? StringSave(tnp->node_label) : NULL;
+}
+
+Int4 tax1_getTaxId4Str(CharPtr str, CharPtr* substring, Int4Ptr *Ids_out)
+{
+ CharPtr b, e;
+ Int4 tax_id;
+ /*Int4Ptr Ids;*/
+ int k;
+ char c;
+
+ *substring= NULL;
+ tax_id= tax1_getTaxIdByName(str);
+
+ if(tax_id > 1) {
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ *substring= StringSave(str);
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(str);
+ return tax1_getAllTaxIdByName(str, Ids_out);
+ }
+
+ /* whole string matches nothing */
+ /* try the whole string inside first set of parenthesis */
+ for(b= str; *b != '\0'; b++) {
+ if(*b == '(') {
+ k= 0;
+ for(e= b+1; *e != '\0'; e++) {
+ if(*e == '(') {
+ k++;
+ continue;
+ }
+ if(*e == ')') {
+ if(k > 0) {
+ k--;
+ continue;
+ }
+
+ *e= '\0';
+ tax_id= tax1_getTaxIdByName(b+1);
+
+ if(tax_id > 1) {
+ *substring= StringSave(b+1);
+ *e= ')';
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(b+1);
+ *e= ')';
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+
+ /* whole string won't help lets try truncate it at first comma*/
+ *e= ')';
+ for(e= b+1; *e != '\0'; e++) {
+ if(*e == ',') {
+ *e= '\0';
+ tax_id= tax1_getTaxIdByName(b+1);
+
+ if(tax_id > 1) {
+ *substring= StringSave(b+1);
+ *e= ',';
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(b+1);
+ *e= ',';
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+ *e= ',';
+ break;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ /* we still have got nothing */
+ /* try the substring before first '(' */
+
+ if(*b == '(') {
+ /* we are staying on the first '(' */
+ *b= '\0';
+
+ tax_id= tax1_getTaxIdByName(str);
+
+ if(tax_id > 1) {
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ *substring= StringSave(str);
+ *b= '(';
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(str);
+ *b= '(';
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+ *b= '(';
+ }
+
+ b= StringStr(str, "Organism");
+ if(b == NULL) b= StringStr(str, "organism");
+ if(b == NULL) b= StringStr(str, "ORGANISM");
+
+ if(b != NULL) {
+ e= StringChr(b, ':');
+ if(e != NULL) {
+ b= e+1;
+ tax_id= tax1_getTaxIdByName(b);
+
+ if(tax_id > 1) {
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ *substring= StringSave(b);
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(b);
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+
+ /* if multiple lines or ; , ( */
+ for(++e; *e != '\0'; e++) {
+ if((*e == '\n') || (*e == ';') || (*e == ',') || (*e == '(')) {
+ c= *e;
+ *e= '\0';
+ tax_id= tax1_getTaxIdByName(b);
+
+ if(tax_id > 1) {
+ *substring= StringSave(b);
+ *e= c;
+ *Ids_out= MemNew(sizeof(Int4));
+ **Ids_out= tax_id;
+ return 1;
+ }
+ else if(tax_id < 0) {
+ *substring= StringSave(b);
+ *e= c;
+ return tax1_getAllTaxIdByName(*substring, Ids_out);
+ }
+ *e= c;
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+
diff --git a/network/taxon1/taxon2/txcdproc.c b/network/taxon1/taxon2/txcdproc.c
new file mode 100644
index 00000000..2af8b252
--- /dev/null
+++ b/network/taxon1/taxon2/txcdproc.c
@@ -0,0 +1,1244 @@
+/* txcdproc.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: txcdproc.c
+*
+* Author: Vladimir Soussov
+*
+* Version Creation Date: 07/15/97
+*
+* $Revision: 1.5 $
+*
+* File Description:
+* API for Taxonomy service
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+* ==========================================================================
+*
+*
+* RCS Modification History:
+* $Log: txcdproc.c,v $
+* Revision 1.5 1998/07/27 16:54:04 soussov
+* bug in txc_getChildren fixed
+*
+* Revision 1.4 1998/06/11 20:42:11 soussov
+* kill some warnings
+*
+* Revision 1.3 1998/04/01 17:34:02 soussov
+* changed tp include <>
+*
+* Revision 1.2 1998/03/31 22:54:42 kans
+* codewarrior can tell null from 0, and unsigned charptr needed cast to CharPtr
+*
+* Revision 1.1 1998/02/10 20:12:02 soussov
+* taxon2 related soft
+*
+ *
+*/
+
+/** for ErrPostEx() ****/
+
+static char *this_module = "txcdproc";
+
+#ifdef THIS_MODULE
+#undef THIS_MODULE
+#endif
+
+#define THIS_MODULE this_module
+static char *this_file = __FILE__;
+#define THIS_FILE this_file
+
+#include <ncbinet.h>
+#include <objall.h>
+#include <objfeat.h>
+#include <objtax1.h>
+#include <txclient.h>
+#include <taxinc.h>
+
+#define TAXARCH_SERV_RETRIES 4
+
+static Taxon1RespPtr NetTaxArchReadAsn PROTO((void));
+static Boolean ReestablishNetTaxArch PROTO((void));
+static Boolean NetInit PROTO((void));
+static Boolean ForceNetInit PROTO((void));
+static Boolean NetFini PROTO((void));
+static Boolean GenericReestablishNet PROTO((CharPtr svcName, Boolean showErrs));
+static Boolean TaxServFini (void);
+
+static NI_HandPtr svcp = NULL;
+static AsnIoPtr asnin = NULL;
+static AsnIoPtr asnout = NULL;
+static Boolean num_attached = 0;
+static Boolean reallyFinal = TRUE;
+static NI_DispatcherPtr dispatcher;
+static Boolean (*myNetInit) PROTO((void));
+
+/*****************************************************************************
+*
+* NetTaxArchReadAsn ()
+*
+*****************************************************************************/
+
+static Taxon1RespPtr NetTaxArchReadAsn(void)
+{
+ Taxon1RespPtr taxbp;
+ short erract;
+ ErrDesc err;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_CONTINUE, 0);
+ ErrFetch(&err); /* clear any pending error */
+
+ taxbp = Taxon1RespAsnRead(asnin, NULL);
+
+ if (ErrFetch(&err))
+ {
+ ErrPost (CTX_UNKNOWN, 1, "Null message read from server");
+ }
+ ErrSetOpts(erract, 0);
+
+ return taxbp;
+}
+
+/*****************************************************************************
+*
+* txc_connect2server()
+*
+* all arguments are optional just to keep os interface
+*****************************************************************************/
+
+static Boolean TaxServInit(void)
+{
+ DataVal av;
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+
+ myNetInit = TaxServInit;
+
+ if (!NetInit()) return FALSE;
+
+ svcp= NI_GenericGetService(dispatcher, NULL, "TAXONOMY", "TaxService", TRUE);
+
+ if (svcp == NULL) {
+ ErrPostEx(SEV_ERROR, 0, 0, "NI_ServiceGet [%s] (%s)", ni_errlist[ni_errno], ni_errtext);
+ TaxServFini();
+ return FALSE;
+ }
+
+ asnin= svcp->raip;
+ asnout= svcp->waip;
+
+ /**********************************************************/
+
+ taxrp= ValNodeNew(NULL);
+ taxrp->choice = Taxon1Req_init;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon1ReqFree (taxrp);
+
+ if((taxbp = NetTaxArchReadAsn()) == NULL) {
+ return FALSE;
+ }
+ else {
+ taxbp->data.ptrvalue = NULL;
+ Taxon1RespFree (taxbp);
+ return TRUE;
+ }
+}
+
+Boolean txc_connect2Server(CharPtr server, CharPtr user, CharPtr passwd, CharPtr module)
+{
+ return TaxServInit();
+}
+
+
+/*****************************************************************************
+*
+* Tax0Fini ()
+*
+*****************************************************************************/
+
+static Boolean s_TaxArchFini(void)
+{
+ Boolean retval = TRUE;
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+
+
+ if (asnout != NULL && asnin != NULL) {
+ taxrp = ValNodeNew(NULL);
+ taxrp->choice = Taxon1Req_fini;
+ Taxon1ReqAsnWrite (taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon1ReqFree (taxrp);
+
+ if ((taxbp = NetTaxArchReadAsn()) == NULL) {
+ retval = FALSE;
+ }
+ else {
+ taxbp->data.ptrvalue = NULL;
+ Taxon1RespFree (taxbp);
+ }
+ }
+
+ NetFini();
+
+ return retval;
+}
+
+/* the only thing done here is to suppress errors */
+
+static Boolean TaxServFini (void)
+{
+ short erract;
+ ErrDesc err;
+ Boolean retval;
+
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ retval = s_TaxArchFini();
+
+ ErrSetOpts(erract, 0);
+ ErrFetch(&err);
+
+ return retval;
+}
+
+void txc_close(void)
+{
+ TaxServFini();
+}
+
+
+static Taxon1NamePtr s_findname(CharPtr sname)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Taxon1NamePtr tnp;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return NULL;
+ taxrp->choice= Taxon1Req_findname;
+ taxrp->data.ptrvalue= sname;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ taxrp->data.ptrvalue= NULL;
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return NULL;
+
+ if(taxbp->choice != Taxon1Resp_findname) {
+ Taxon1RespFree(taxbp);
+ return NULL;
+ }
+
+ tnp= taxbp->data.ptrvalue;
+ taxbp->data.ptrvalue= NULL;
+ Taxon1RespFree(taxbp);
+
+ return tnp;
+}
+
+static Taxon1NamePtr findname(CharPtr sname)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Taxon1NamePtr tnp = NULL;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tnp = s_findname(sname);
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return(tnp);
+}
+
+Int4 tax_findByName(CharPtr sname, int mode, TaxNamePtr* res_name)
+{
+ TaxNamePtr o_name;
+ Int4 i, n= 0;
+ Taxon1NamePtr tnp, tnp_list= ((sname == NULL) || (*sname == '\0'))? NULL : findname(sname);
+
+
+ if((res_name == NULL) || (tnp_list == NULL)) return 0;
+ for(tnp= tnp_list; tnp != NULL; tnp= tnp->next) n++;
+
+ *res_name= o_name= MemNew(n*sizeof(TaxName));
+ if(o_name == NULL) {
+ for(i= 0; i < n; i++) {
+ tnp= tnp_list->next;
+ Taxon1NameFree(tnp_list);
+ tnp_list= tnp;
+ }
+ return 0;
+ }
+
+ for(i= 0; i < n; i++) {
+ tnp= tnp_list->next;
+ o_name[i].tax_id= tnp_list->taxid;
+ o_name[i].class_cde= tnp_list->cde;
+ o_name[i].name_txt= tnp_list->oname;
+ o_name[i].unique_name= tnp_list->uname;
+ MemFree(tnp_list);
+ tnp_list= tnp;
+ }
+
+ return n;
+}
+
+static Taxon1NamePtr s_getorgnames(Int4 tax_id)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Taxon1NamePtr tnp;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return NULL;
+ taxrp->choice= Taxon1Req_getorgnames;
+ taxrp->data.intvalue= tax_id;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return NULL;
+
+ if(taxbp->choice != Taxon1Resp_getorgnames) {
+ Taxon1RespFree(taxbp);
+ return NULL;
+ }
+
+ tnp= taxbp->data.ptrvalue;
+ taxbp->data.ptrvalue= NULL;
+ Taxon1RespFree(taxbp);
+
+ return tnp;
+}
+
+
+static Taxon1NamePtr getorgnames(Int4 tax_id)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Taxon1NamePtr tnp = NULL;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tnp = s_getorgnames(tax_id);
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return(tnp);
+}
+
+Int4 tax_getOrgNames(Int4 tax_id, TaxNamePtr* res_name)
+{
+ TaxNamePtr o_name;
+ Int4 i, n= 0;
+ Taxon1NamePtr tnp, tnp_list= (tax_id > 0)? getorgnames(tax_id) : NULL;
+
+
+ if((res_name == NULL) || (tnp_list == NULL)) return 0;
+ for(tnp= tnp_list; tnp != NULL; tnp= tnp->next) n++;
+
+ *res_name= o_name= MemNew(n*sizeof(TaxName));
+ if(o_name == NULL) {
+ for(i= 0; i < n; i++) {
+ tnp= tnp_list->next;
+ Taxon1NameFree(tnp_list);
+ tnp_list= tnp;
+ }
+ return 0;
+ }
+
+ for(i= 0; i < n; i++) {
+ tnp= tnp_list->next;
+ o_name[i].tax_id= tnp_list->taxid;
+ o_name[i].class_cde= tnp_list->cde;
+ o_name[i].name_txt= tnp_list->oname;
+ o_name[i].unique_name= tnp_list->uname;
+ MemFree(tnp_list);
+ tnp_list= tnp;
+ }
+
+ return n;
+}
+
+static Int4 s_getdesignator(CharPtr sname)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Int4 tax_id;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return 0;
+ taxrp->choice= Taxon1Req_getdesignator;
+ taxrp->data.ptrvalue= sname;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ taxrp->data.ptrvalue= NULL;
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return 0;
+
+ if(taxbp->choice != Taxon1Resp_getdesignator) {
+ Taxon1RespFree(taxbp);
+ return 0;
+ }
+
+ tax_id= taxbp->data.intvalue;
+ Taxon1RespFree(taxbp);
+
+ return tax_id;
+}
+
+static Int4 getdesignator(CharPtr sname)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Int4 tax_id= 0;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tax_id = s_getdesignator(sname);
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return tax_id;
+}
+
+Int4 tax_getDesignator(char* sname)
+{
+ return getdesignator(sname);
+}
+
+static Int4 s_getunique(CharPtr sname)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Int4 tax_id;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return 0;
+ taxrp->choice= Taxon1Req_getunique;
+ taxrp->data.ptrvalue= sname;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ taxrp->data.ptrvalue= NULL;
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return 0;
+
+ if(taxbp->choice != Taxon1Resp_getunique) {
+ Taxon1RespFree(taxbp);
+ return 0;
+ }
+
+ tax_id= taxbp->data.intvalue;
+ Taxon1RespFree(taxbp);
+
+ return tax_id;
+}
+
+static Int4 getunique(CharPtr sname)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Int4 tax_id= 0;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tax_id = s_getunique(sname);
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return tax_id;
+}
+
+Int4 tax_uniqueName(CharPtr sname, Int4 id)
+{
+ Int4 tax_id= getunique(sname);
+ return (tax_id == id)? 0 : tax_id;
+}
+
+static Int4 s_getidbyorg(OrgRefPtr orgRef)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Int4 tax_id;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return 0;
+ taxrp->choice= Taxon1Req_getidbyorg;
+ taxrp->data.ptrvalue= orgRef;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ taxrp->data.ptrvalue= NULL;
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return 0;
+
+ if(taxbp->choice != Taxon1Resp_getidbyorg) {
+ Taxon1RespFree(taxbp);
+ return 0;
+ }
+
+ tax_id= taxbp->data.intvalue;
+ Taxon1RespFree(taxbp);
+
+ return tax_id;
+}
+
+static Int4 getidbyorg(OrgRefPtr orgRef)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Int4 tax_id= 0;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tax_id = s_getidbyorg(orgRef);
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return tax_id;
+}
+
+Int4 txc_getTaxIdByOrgRef(OrgRefPtr orgRef)
+{
+ return getidbyorg(orgRef);
+}
+
+Int4 tax_getIdByName(char* sname, char* qualif, Int1 id)
+{
+ OrgRefPtr orgRef= OrgRefNew();
+ Int4 tax_id;
+
+ orgRef->taxname= sname;
+ if(qualif != NULL) {
+ orgRef->orgname= OrgNameNew();
+ orgRef->orgname->mod= OrgModNew();
+ orgRef->orgname->mod->subtype= id;
+ orgRef->orgname->mod->subname= qualif;
+ }
+
+ tax_id= getidbyorg(orgRef);
+ orgRef->taxname= NULL;
+ if(qualif != NULL) {
+ orgRef->orgname->mod->subname=NULL;
+ }
+ OrgRefFree(orgRef);
+ return tax_id;
+}
+
+static Taxon1InfoPtr s_getlineage(Int4 tax_id)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Taxon1InfoPtr tnp;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return NULL;
+ taxrp->choice= Taxon1Req_getlineage;
+ taxrp->data.intvalue= tax_id;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return NULL;
+
+ if(taxbp->choice != Taxon1Resp_getlineage) {
+ Taxon1RespFree(taxbp);
+ return NULL;
+ }
+
+ tnp= taxbp->data.ptrvalue;
+ taxbp->data.ptrvalue= NULL;
+ Taxon1RespFree(taxbp);
+
+ return tnp;
+}
+
+
+static Taxon1InfoPtr getlineage(Int4 tax_id)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Taxon1InfoPtr tnp = NULL;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tnp = s_getlineage(tax_id);
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return(tnp);
+}
+
+TXC_TreeNodePtr* txc_getLineage(Int4 lin_id, Int4Ptr lin_len)
+{
+ TXC_TreeNodePtr* lin;
+ Int4 n= 0, i, k;
+ Taxon1InfoPtr tnp, tnp_list= (lin_id > 0)? getlineage(lin_id) : NULL;
+
+ if(lin_len != NULL) *lin_len= 0;
+
+ if(tnp_list == NULL) return NULL;
+
+ for(tnp= tnp_list; tnp != NULL; tnp= tnp->next) n++;
+
+ if((lin= MemNew(n*sizeof(TXC_TreeNodePtr))) == NULL) {
+ /* no memory, just free tnp_list */
+ for(i= 0; i < n; i++) {
+ tnp= tnp_list->next;
+ Taxon1InfoFree(tnp_list);
+ tnp_list= tnp;
+ }
+ return NULL;
+ }
+
+ for(i= 0; i < n; i++) {
+ tnp= tnp_list->next;
+ k= StringLen(tnp_list->sval);
+ if((lin[i]= MemNew(k+10)) != NULL) {
+ lin[i]->tax_id= tnp_list->ival1;
+ lin[i]->flags= tnp_list->ival2;
+ StringCpy(lin[i]->node_label, tnp_list->sval);
+ }
+ Taxon1InfoFree(tnp_list);
+ tnp_list= tnp;
+ }
+
+ if(lin_len != NULL) *lin_len= n;
+ return lin;
+}
+
+static Taxon1InfoPtr s_getchildren(Int4 tax_id)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Taxon1InfoPtr tnp;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return NULL;
+ taxrp->choice= Taxon1Req_getchildren;
+ taxrp->data.intvalue= tax_id;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return NULL;
+
+ if(taxbp->choice != Taxon1Resp_getchildren) {
+ Taxon1RespFree(taxbp);
+ return NULL;
+ }
+
+ tnp= taxbp->data.ptrvalue;
+ taxbp->data.ptrvalue= NULL;
+ Taxon1RespFree(taxbp);
+
+ return tnp;
+}
+
+
+static Taxon1InfoPtr getchildren(Int4 tax_id)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Taxon1InfoPtr tnp = NULL;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tnp = s_getchildren(tax_id);
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return(tnp);
+}
+
+TXC_TreeNodePtr* txc_getChildren(Int4 node_id, Int4Ptr nof_children)
+{
+ TXC_TreeNodePtr* lin;
+ Int4 n= 0, i, k;
+ Taxon1InfoPtr tnp, tnp_list= getchildren(node_id);
+
+ if(nof_children != NULL) *nof_children= 0;
+
+ if(tnp_list == NULL) return NULL;
+
+ for(tnp= tnp_list; tnp != NULL; tnp= tnp->next) n++;
+
+ if((lin= MemNew(n*sizeof(TXC_TreeNodePtr))) == NULL) {
+ /* no memory, just free tnp_list */
+ for(i= 0; i < n; i++) {
+ tnp= tnp_list->next;
+ Taxon1InfoFree(tnp_list);
+ tnp_list= tnp;
+ }
+ return NULL;
+ }
+
+ for(i= 0; i < n; i++) {
+ tnp= tnp_list->next;
+ k= ((tnp_list->ival2 & TXC_SUFFIX) != 0)? 0 : StringLen(tnp_list->sval);
+ if((lin[i]= MemNew(k+10)) != NULL) {
+ lin[i]->tax_id= tnp_list->ival1;
+ lin[i]->flags= tnp_list->ival2;
+ if(k > 0) StringCpy(lin[i]->node_label, tnp_list->sval);
+ }
+ Taxon1InfoFree(tnp_list);
+ tnp_list= tnp;
+ }
+
+ if(nof_children != NULL) *nof_children= n;
+ return lin;
+}
+
+static Taxon1InfoPtr s_getcde(void)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Taxon1InfoPtr tnp;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return NULL;
+ taxrp->choice= Taxon1Req_getcde;
+ taxrp->data.ptrvalue= NULL;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return NULL;
+
+ if(taxbp->choice != Taxon1Resp_getcde) {
+ Taxon1RespFree(taxbp);
+ return NULL;
+ }
+
+ tnp= taxbp->data.ptrvalue;
+ taxbp->data.ptrvalue= NULL;
+ Taxon1RespFree(taxbp);
+
+ return tnp;
+}
+
+
+static Taxon1InfoPtr getcde(void)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Taxon1InfoPtr tnp = NULL;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tnp = s_getcde();
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return(tnp);
+}
+
+Boolean txc_loadNameClasses(void)
+{
+ Taxon1InfoPtr tnp, tnp_list= getcde();
+
+ if(tnp_list == NULL) return FALSE;
+
+ while(tnp_list != NULL) {
+ tax_addNameClass(tnp_list->ival1, tnp_list->sval, tnp_list->ival2);
+ tnp= tnp_list->next;
+ Taxon1InfoFree(tnp_list);
+ tnp_list= tnp;
+ }
+ return TRUE;
+}
+
+
+static Taxon1InfoPtr s_getranks(void)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Taxon1InfoPtr tnp;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return NULL;
+ taxrp->choice= Taxon1Req_getranks;
+ taxrp->data.ptrvalue= NULL;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return NULL;
+
+ if(taxbp->choice != Taxon1Resp_getranks) {
+ Taxon1RespFree(taxbp);
+ return NULL;
+ }
+
+ tnp= taxbp->data.ptrvalue;
+ taxbp->data.ptrvalue= NULL;
+ Taxon1RespFree(taxbp);
+
+ return tnp;
+}
+
+
+static Taxon1InfoPtr getranks(void)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Taxon1InfoPtr tnp = NULL;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tnp = s_getranks();
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return(tnp);
+}
+
+Boolean txc_loadRanks(void)
+{
+ Taxon1InfoPtr tnp, tnp_list= getranks();
+
+ if(tnp_list == NULL) return FALSE;
+
+ while(tnp_list != NULL) {
+ tax_addRank(tnp_list->ival1, tnp_list->sval);
+ tnp= tnp_list->next;
+ Taxon1InfoFree(tnp_list);
+ tnp_list= tnp;
+ }
+ return TRUE;
+}
+
+static Taxon1InfoPtr s_getdivs(void)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Taxon1InfoPtr tnp;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return NULL;
+ taxrp->choice= Taxon1Req_getdivs;
+ taxrp->data.ptrvalue= NULL;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return NULL;
+
+ if(taxbp->choice != Taxon1Resp_getdivs) {
+ Taxon1RespFree(taxbp);
+ return NULL;
+ }
+
+ tnp= taxbp->data.ptrvalue;
+ taxbp->data.ptrvalue= NULL;
+ Taxon1RespFree(taxbp);
+
+ return tnp;
+}
+
+
+static Taxon1InfoPtr getdivs(void)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Taxon1InfoPtr tnp = NULL;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tnp = s_getdivs();
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return(tnp);
+}
+
+Boolean txc_loadDivisions(void)
+{
+ Taxon1InfoPtr tnp, tnp_list= getdivs();
+ Uint4 w;
+ int i;
+ unsigned char buff[8];
+
+ if(tnp_list == NULL) return FALSE;
+
+ while(tnp_list != NULL) {
+ w= tnp_list->ival2;
+ for(i= 0; i < 3; i++) {
+ buff[i]= (w >> (8*(3-i))) & 0xFF;
+ }
+ buff[3]= w & 0xFF;
+ buff[4]= '\0';
+ tax_addDivision(tnp_list->ival1, (CharPtr) buff, tnp_list->sval);
+ tnp= tnp_list->next;
+ Taxon1InfoFree(tnp_list);
+ tnp_list= tnp;
+ }
+ return TRUE;
+}
+
+static Taxon1InfoPtr s_getgcs(void)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Taxon1InfoPtr tnp;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return NULL;
+ taxrp->choice= Taxon1Req_getgcs;
+ taxrp->data.ptrvalue= NULL;
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return NULL;
+
+ if(taxbp->choice != Taxon1Resp_getgcs) {
+ Taxon1RespFree(taxbp);
+ return NULL;
+ }
+
+ tnp= taxbp->data.ptrvalue;
+ taxbp->data.ptrvalue= NULL;
+ Taxon1RespFree(taxbp);
+
+ return tnp;
+}
+
+
+static Taxon1InfoPtr getgcs(void)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ Taxon1InfoPtr tnp = NULL;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ tnp = s_getgcs();
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return(tnp);
+}
+
+Boolean txc_loadGCs(void)
+{
+ Taxon1InfoPtr tnp, tnp_list= getgcs();
+
+ if(tnp_list == NULL) return FALSE;
+
+ while(tnp_list != NULL) {
+ tax_addGC(tnp_list->ival1, tnp_list->sval);
+ tnp= tnp_list->next;
+ Taxon1InfoFree(tnp_list);
+ tnp_list= tnp;
+ }
+ return TRUE;
+}
+
+
+/*****************************************************************************
+*
+* ReestablishNetTaxArch ()
+*
+*****************************************************************************/
+
+static Boolean ReestablishNetTaxArch(void)
+{
+ return GenericReestablishNet("Taxon2", TRUE);
+}
+
+/*****************************************************************************
+*
+* GenericReestablishNet ()
+*
+*****************************************************************************/
+
+static Boolean GenericReestablishNet(CharPtr svcName, Boolean showErrs)
+{
+ MonitorPtr mon = NULL;
+ Boolean retval;
+ CharPtr buf;
+
+ buf = MemNew(2 * StrLen(svcName) + 60);
+
+ if (showErrs) {
+ sprintf (buf, "Re-establishing %s Service", svcName);
+ mon = MonitorStrNew(buf, 40);
+ sprintf (buf, "Requesting %s service", svcName);
+ MonitorStrValue(mon, buf);
+ }
+ NetFini();
+ retval = TRUE;
+
+ if (!myNetInit())
+ {
+ sprintf (buf, "%s get failed; re-contacting dispatcher", svcName);
+ MonitorStrValue(mon, buf);
+ retval = FALSE;
+ if (ForceNetInit())
+ { /* successfully established contact w/dispatcher */
+ sprintf (buf, "%s get failed; re-requesting %s service",
+ svcName, svcName);
+ MonitorStrValue(mon, buf);
+ retval = myNetInit();
+ }
+ else {
+ ErrPost(CTX_UNKNOWN, 1, "Unable to re-contact dispatcher");
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+ }
+
+ MonitorFree(mon);
+
+ if (! retval )
+ {
+ sprintf (buf, "Unable to re-establish %s service", svcName);
+ ErrPost(CTX_UNKNOWN, 1, buf);
+ if (showErrs) {
+ ErrShow();
+ }
+ }
+
+ MemFree(buf);
+ return retval;
+}
+
+/*****************************************************************************
+*
+* NetInit ()
+*
+*****************************************************************************/
+
+static Boolean NetInit(void)
+{
+ if (num_attached++ > 0)
+ return TRUE;
+
+ return ((dispatcher = NI_GenericInit(NULL, NULL, TRUE, NULL, 0)) != NULL);
+}
+
+
+/*****************************************************************************
+*
+* ForceNetInit ()
+*
+*****************************************************************************/
+
+static Boolean ForceNetInit(void)
+{
+ Boolean retval;
+
+ reallyFinal = FALSE;
+ num_attached = 0; /* force re-attempt to contact dispatcher */
+ retval = NetInit();
+ reallyFinal = TRUE;
+
+ return retval;
+}
+
+/*****************************************************************************
+*
+* NetFini ()
+*
+*****************************************************************************/
+
+static Boolean NetFini(void)
+{
+ if (num_attached > 0)
+ num_attached--;
+
+ if (num_attached == 0)
+ {
+ NI_ServiceDisconnect(svcp);
+ svcp = NULL;
+ NI_EndServices (dispatcher);
+ dispatcher = NULL;
+ }
+
+ return TRUE;
+}
+
+
+static _subspecPtr s_SSget(Int4 tax_id, _subspecPtr ss)
+{
+ Taxon1ReqPtr taxrp;
+ Taxon1RespPtr taxbp;
+ Taxon1InfoPtr tax_info;
+
+ if((taxrp= ValNodeNew(NULL)) == NULL) return NULL;
+ taxrp->choice= Taxon1Req_getorgmod;
+ taxrp->data.ptrvalue= tax_info= Taxon1InfoNew();
+ if(tax_info == NULL) {
+ MemFree(taxrp);
+ return NULL;
+ }
+ tax_info->ival1= tax_id;
+ if(ss != NULL) {
+ tax_info->ival2= ss->stype;
+ tax_info->sval= ss->sname;
+ }
+ Taxon1ReqAsnWrite(taxrp, asnout, NULL);
+ AsnIoReset(asnout);
+ tax_info->sval= NULL;
+ Taxon1ReqFree(taxrp);
+
+ if((taxbp= NetTaxArchReadAsn()) == NULL) return NULL;
+
+ if(taxbp->choice != Taxon1Resp_getorgmod) {
+ Taxon1RespFree(taxbp);
+ return NULL;
+ }
+
+ if(ss != NULL) {
+ tax_info= taxbp->data.ptrvalue;
+ if(tax_info != NULL) {
+ ss->r_id= tax_info->ival1;
+ ss->rtype= tax_info->ival2;
+ ss->rname= tax_info->sval;
+ tax_info->sval= NULL;
+ }
+ else ss= NULL;
+ Taxon1RespFree(taxbp);
+ return ss;
+ }
+
+ Taxon1RespFree(taxbp);
+
+ return NULL;
+}
+
+_subspecPtr tax_SSget(Int4 tax_id, _subspecPtr ss)
+{
+ Int4 i;
+ short erract;
+ ErrDesc err;
+ _subspecPtr res= NULL;
+
+ for (i= TAXARCH_SERV_RETRIES; i >= 0; --i) {
+ ErrGetOpts(&erract, NULL);
+ ErrSetOpts(ERR_IGNORE, 0);
+ ErrFetch(&err);
+
+ res= s_SSget(tax_id, ss);
+
+ ErrSetOpts(erract, 0);
+ if (!ErrFetch(&err)) break; /* success */
+
+ if(!ReestablishNetTaxArch()) break;
+ }
+
+ return res;
+}
diff --git a/network/taxon1/taxon2/txclient.h b/network/taxon1/taxon2/txclient.h
new file mode 100644
index 00000000..711614c9
--- /dev/null
+++ b/network/taxon1/taxon2/txclient.h
@@ -0,0 +1,178 @@
+/* txclient.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: txclient.h
+*
+* Author: Vladimir Soussov
+*
+* File Description: Data types for taxonomy client
+*
+*
+* $Log: txclient.h,v $
+* Revision 1.6 1998/07/23 18:27:01 soussov
+* one prototype added
+*
+* Revision 1.5 1998/06/12 15:14:26 soussov
+* kill some warnings
+*
+* Revision 1.4 1998/04/01 17:34:00 soussov
+* changed tp include <>
+*
+* Revision 1.3 1998/03/31 23:12:57 kans
+* minor changes needed for code warrior
+*
+* Revision 1.2 1998/02/11 15:52:31 soussov
+* ctpublic.h has been removed
+*
+* Revision 1.1 1998/02/10 20:12:04 soussov
+* taxon2 related soft
+*
+* Revision 1.2 1997/05/12 18:31:31 soussov
+* 05/12/97
+*
+ * Revision 1.1.1.1 1997/04/30 21:29:42 soussov
+ * initial tree for taxon2
+ *
+*
+*/
+
+#ifndef TXCLIENT_H_DONE
+#define TXCLIENT_H_DONE
+
+#include <ncbi.h>
+#include <txcommon.h>
+#include <treemgr.h>
+#ifdef TAXSERVICE
+#include <objfeat.h>
+#endif
+
+typedef struct t_TXC_Name {
+ Int4 tax_id;
+ Uint1 class_cde;
+ Uint1 designator;
+ Uint1 name_length;
+ Uint1 flags;
+ char name_txt[2];
+} TXC_Name, PNTR TXC_NamePtr;
+
+/* to map tax_id to node_id use tax_node_id map index */
+
+typedef struct t_TXC_CitList {
+ Int4 cit_id;
+ CharPtr cit_key;
+} TXC_CitList, PNTR TXC_CitListPtr;
+
+typedef struct t_citation {
+ Int4 id;
+ CharPtr key;
+ Int4 flags;
+ Int4 mu_id;
+ Int4 pm_id;
+ CharPtr url;
+ CharPtr txt;
+} _citation;
+
+typedef struct t_OrgMod {
+ struct t_OrgMod* next;
+ CharPtr subname;
+ Uint1 subtype;
+} tax_OrgMod, PNTR tax_OrgModPtr;
+
+typedef struct t_subspec {
+ struct t_subspec* next;
+ Int4 r_id;
+ CharPtr sname;
+ CharPtr rname;
+ Uint1 stype, rtype;
+
+} _subspec, PNTR _subspecPtr;
+
+/* client connection library prototypes */
+#if 0
+Boolean txc_setSubtree(Int4 tax_id);
+Int4 txc_findByName(CharPtr sname, Uint1 mode, TaxNamePtr* found_names);
+Int4 txc_getOrgNames(Int4 tax_id, TaxNamePtr* found_names);
+Int4 txc_getDesignator(CharPtr name);
+Int4 txc_uniqueName(CharPtr s_name);
+Boolean txc_setDesignator(CharPtr name, Int4 tax_id);
+Boolean txc_addName(Int4 tax_id, CharPtr name, CharPtr uname, Int2 class, Boolean designat);
+Boolean txc_delName(Int4 tax_id, CharPtr dname);
+
+TaxNodeDataPtr txc_getNodeRecord(Int4 tax_id);
+Boolean txc_delNode(Int4 tax_id);
+Boolean txc_delSubtree(Int4 tax_id);
+Boolean txc_moveNode(Int4 new_parent, Int4 tax_id);
+Boolean txc_moveChildren(Int4 new_parent, Int4 tax_id);
+Boolean txc_mergeNodes(Int4 tax_id1, Int4 tax_id2);
+Int4 txc_splitNode(Int4 tax_id);
+Int4 txc_addNode(Int4 parent_id, CharPtr name, TaxNodeDataPtr node_data);
+Boolean txc_updateNode(Int4 tax_id, TaxNodeDataPtr node_data);
+Boolean txc_save(void);
+#endif
+
+Boolean txc_connect2Server(CharPtr srv_name, CharPtr usr, CharPtr passwd, CharPtr applic);
+
+Boolean txc_load(Int4 root, Int2 levels);
+TreeNodeId tax_getNodeId(Int4 tax_id);
+Boolean txc_loadNameClasses(void);
+Boolean txc_loadRanks(void);
+Boolean txc_loadDivisions(void);
+Boolean txc_loadGCs(void);
+TXC_NodeDataPtr txc_getOrgData(Int4 tax_id);
+TXC_TreeNodePtr* txc_getLineage(Int4 lin_id, Int4Ptr lin_len);
+TXC_TreeNodePtr* txc_getChildren(Int4 node_id, Int4Ptr nof_children);
+
+
+TreePtr tax_ptree_new(void);
+Boolean tax_ptree_addNode(TreePtr ptree, Int4 tax_id);
+Boolean tax_ptree_toTaxId(TreeCursorPtr cursor, Int4 tax_id, Boolean search_in_subtree);
+Boolean tax_ptree_addChildren(TreeCursorPtr cursor);
+Boolean tax_ptree_addSubtree(TreeCursorPtr cursor);
+
+
+TXC_CitListPtr txc_citGet4Node(Int4 tax_id, Int4Ptr nof_cit);
+CharPtr txc_citGetKey(Int4 cit_id);
+TXC_CitListPtr txc_citFind(CharPtr key_str, Int4Ptr nof_cit);
+_citation* txc_citGetByKey(CharPtr key_str);
+Boolean txc_citUpdate(_citation* cit);
+Int4 txc_citInsert(_citation* cit);
+void txc_close(void);
+
+Boolean wwwtax_getByName(CharPtr sname, int mode_in, int levels_in,
+ void (*callBack)(int, int, CharPtr));
+Boolean wwwtax_getById(Int4 tax_id, int mode_in, int levels_in,
+ void (*callBack)(int, int, CharPtr));
+Boolean te_saveEditWindows(void);
+
+#ifdef TAXSERVICE
+Int4 txc_getTaxIdByOrgRef(OrgRefPtr orgRef);
+#endif
+
+_subspecPtr tax_SSgetAll(Int4 tax_id);
+_subspecPtr tax_SSget(Int4 tax_id, _subspecPtr ssrec);
+tax_OrgModPtr tax_SSgetLegal(Int4 tax_id);
+Int4 tax_SSgetNodes(Uint1 stype, CharPtr sname, Uint1 mode, Int4Ptr* ids);
+
+#endif
diff --git a/network/taxon1/taxon2/txcommon.h b/network/taxon1/taxon2/txcommon.h
new file mode 100644
index 00000000..41f0c0f7
--- /dev/null
+++ b/network/taxon1/taxon2/txcommon.h
@@ -0,0 +1,225 @@
+/* txcommon.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: txcommon.h
+*
+* Author: Vladimir Soussov
+*
+* File Description: Common data types & prototypes for taxonomy server/client
+*
+*
+* $Log: txcommon.h,v $
+* Revision 1.2 1998/06/12 15:16:07 soussov
+* kill some warnings
+*
+* Revision 1.1 1998/02/10 20:12:05 soussov
+* taxon2 related soft
+*
+* Revision 1.2 1997/05/12 18:31:44 soussov
+* 05/12/97
+*
+ * Revision 1.1.1.1 1997/04/30 21:29:57 soussov
+ * initial tree for taxon2
+ *
+*
+*/
+
+#ifndef TXCOMMON_H_DONE
+#define TXCOMMON_H_DONE
+
+#include <ncbi.h>
+
+#define TAX_DIV_TXT 0
+#define TAX_DIV_CDE 1
+#define TAX_DIV_COM 2
+
+#define TAX_GC_NM 0
+#define TAX_GC_ABBREV 1
+#define TAX_GC_CDE 2
+#define TAX_GC_STARTS 3
+
+#define TAX_NAME_SEARCH 0
+#define TAX_RE_SEARCH 1
+#define TAX_TOKEN_SEARCH 2
+
+#define INHERIT_DIV 0x1
+#define INHERIT_GC 0x2
+#define INHERIT_MGC 0x4
+#define GB_HIDDEN 0x8
+#define TAX_HIDDEN 0x10
+#define TAX_REFERENCED 0x20
+
+#define TXC_INH_DIV 0x4000000
+#define TXC_INH_GC 0x8000000
+#define TXC_INH_MGC 0x10000000
+/* the following two flags is the same (it is not bug) */
+#define TXC_SUFFIX 0x20000000
+#define TXC_UPDATED 0x20000000
+
+#define TXC_GBHIDE 0x40000000
+#define TXC_STHIDE 0x80000000
+
+#define TXCL_DEL_NAME 1
+#define TXCL_ADD_NAME 2
+#define TXCL_ADD_NODE 3
+#define TXCL_UPD_NODE 4
+#define TXCL_DEL_NODE 5
+#define TXCL_DEL_SUBTREE 6
+#define TXCL_MOVE_SUBTREE 7
+#define TXCL_MERGE_NODES 8
+#define TXCL_MOVE_CHILDREN 9
+#define TXCL_CIT_LINK 10
+#define TXCL_CIT_UNLINK 11
+#define TXCL_CIT_DELETE 12
+#define TXCL_SS_ADD 13
+#define TXCL_SS_CHECK 14
+#define TXCL_SS_DELETE 15
+
+#define WWW_NAME_NOT_FOUND -100
+#define WWW_NODE_NOT_FOUND -110
+#define WWW_MULT_NODES_BEGIN -200
+#define WWW_MULT_NODES_END -210
+#define WWW_TREE_BEGIN -300
+#define WWW_LEVEL_BEGIN -320
+#define WWW_LEVEL_END -330
+#define WWW_TREE_END -390
+#define WWW_LIN_BEGIN -400
+#define WWW_LIN_END -490
+#define WWW_INFO_BEGIN -500
+#define WWW_INFO_END -590
+#define WWW_NAMES_BEGIN -600
+#define WWW_NAMES_END -690
+#define WWW_DIVISION -1000
+#define WWW_RANK -1010
+#define WWW_GC -1020
+#define WWW_MGC -1030
+#define WWW_NUCLEOTIDE -1040
+#define WWW_PROTEIN -1050
+#define WWW_NO_SEQUENCES -2000
+
+#define WWWTAX_NAME_SEARCH 0x1
+#define WWWTAX_REXP_SEARCH 0x2
+#define WWWTAX_TOKEN_SEARCH 0x4
+#define WWW_SHOW_ALL 0x8
+#define WWW_SHOW_NUCLEOTIDE 0x10
+#define WWW_SHOW_PROTEIN 0x20
+#define WWW_SHOW_SEQ 0x30
+
+typedef struct t_TaxNamePublic {
+ Int4 tax_id;
+ CharPtr name_txt;
+ CharPtr unique_name;
+ Uint1 class_cde;
+ Uint1 designator;
+} TaxName, PNTR TaxNamePtr;
+
+/* taxonomy node */
+
+typedef struct t_TXC_NodeData {
+ Int4 tax_id;
+ Uint4 crt_date;
+ Uint4 upd_date;
+ Uint4 nucleotides, proteins;
+ Int1 rank_id;
+ Int1 gc_id;
+ Int1 mgc_id;
+ Int1 div_id;
+ Char embl_cde[4];
+ Uint2 hist;
+ Uint2 flags;
+} TXC_NodeData, PNTR TXC_NodeDataPtr;
+
+typedef struct t_TXC_TreeNode {
+ Int4 tax_id;
+ Uint4 flags;
+ char node_label[2];
+} PNTR TXC_TreeNodePtr;
+
+typedef struct t_nameClass {
+ Int2 priority;
+ char class_txt[34];
+} TaxNameClass, PNTR TaxNameClassPtr;
+
+typedef struct t_rank {
+ char rank_txt[64];
+} TaxRank, PNTR TaxRankPtr;
+
+typedef struct t_division {
+ char div_cde[4];
+ char div_txt[64];
+} TaxDivision, PNTR TaxDivisionPtr;
+
+typedef struct t_genCode {
+ char gc_name[128];
+} TaxGenCode, PNTR TaxGenCodePtr;
+
+typedef struct t_ssRec {
+ Int4 r_id;
+ char sname[120];
+ char rname[120];
+ Uint1 stype, rtype;
+} TaxSSRec, PNTR TaxSSRecPtr;
+
+CharPtr tax_prntTime(Int4 t);
+Int4 tax_getBaseTime(void);
+Int4 tax_getTime(void);
+
+Int4 tax_findByName(CharPtr sname, int mode, TaxNamePtr* res_name);
+Int4 tax_getIdByName(CharPtr org_name, CharPtr qualif, Int1 q_type);
+Int4 tax_getDesignator(CharPtr name);
+Int4 tax_uniqueName(CharPtr s_name, Int4 tax_id);
+Boolean tax_setDesignator(CharPtr name, Int4 tax_id);
+
+Int4 tax_issueTaxId(void);
+
+Boolean tax_addName(Int4 tax_id, CharPtr name, CharPtr uname, Int2 class, Boolean designat);
+Int4 tax_getOrgNames(Int4 tax_id, TaxNamePtr* org_names);
+CharPtr tax_getTaxName(Int4 tax_id, CharPtr* unique_name);
+Boolean tax_delName(Int4 tax_id, CharPtr dname);
+Boolean tax_delAllNodeNames(Int4 tax_id);
+
+Boolean tax_addNameClass(Int4 class_cde, CharPtr class_txt, Int4 priority);
+CharPtr tax_getNameClass(Int4 class_cde, Int4Ptr priority);
+Int4 tax_getClass_cde(CharPtr class_txt);
+Boolean tax_dumpNameClasses(void (*dmpFunc)(VoidPtr, Int2, Int2, CharPtr), VoidPtr usrData);
+
+Boolean tax_addRank(Int2 rank_id, CharPtr rank_txt);
+CharPtr tax_getRank(Int2 rank_id);
+Int2 tax_getRankId(CharPtr rank_txt);
+Boolean tax_dumpRanks(void (*dmpFunc)(VoidPtr, Int2, CharPtr), VoidPtr usrData);
+
+Boolean tax_addDivision(Int4 div_id, CharPtr div_cde, CharPtr div_txt);
+Boolean tax_getDivision(Int2 div_id, CharPtr* div_cde, CharPtr* div_txt);
+Int2 tax_getDivisionId(CharPtr div_cde, CharPtr div_txt);
+Boolean tax_dumpDivisions(void (*dmpFunc)(VoidPtr, Int2, CharPtr, CharPtr), VoidPtr usrData);
+
+Boolean tax_addGC(Int2 gc_id, CharPtr gc_name);
+CharPtr tax_getGCName(Int2 gc_id);
+Int2 tax_getGCId(CharPtr gc_txt);
+Boolean tax_dumpGCs(void (*dmpFunc)(VoidPtr, Int2, CharPtr), VoidPtr usrData);
+
+Boolean tax_matchName(CharPtr orgName, CharPtr str, Int4 mode);
+
+#endif
diff --git a/network/taxon1/taxon2/txcproc.c b/network/taxon1/taxon2/txcproc.c
new file mode 100644
index 00000000..2bcc833b
--- /dev/null
+++ b/network/taxon1/taxon2/txcproc.c
@@ -0,0 +1,2499 @@
+/* txcproc.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government have not placed any restriction on its use or reproduction.
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* Please cite the author in any work or product based on this material.
+*
+* ===========================================================================
+*
+* File Name: txcproc.c
+*
+* Author: Vladimir Soussov
+*
+* File Description: taxonomy client communication procedures
+*
+*
+* $Log: txcproc.c,v $
+* Revision 1.5 1998/07/27 16:55:08 soussov
+* Subtree version
+*
+* Revision 1.4 1998/04/01 17:33:57 soussov
+* changed tp include <>
+*
+* Revision 1.3 1998/03/13 19:18:54 soussov
+* add CS_CANCELED case for ct_results
+*
+* Revision 1.2 1998/02/11 15:53:13 soussov
+* ctpublic.h was added
+*
+* Revision 1.1 1998/02/10 20:12:06 soussov
+* taxon2 related soft
+*
+*
+*/
+
+#include <ctpublic.h>
+#include <txclient.h>
+
+static CS_CONTEXT* te_context;
+static CS_CONNECTION* te_link;
+static CS_INT my_last_update= 0;
+
+CS_RETCODE c_msg_proc(CS_CONTEXT* cp, CS_CONNECTION* chp, CS_CLIENTMSG* emsgp)
+{
+ char buff[512];
+
+ if(emsgp->msgstringlen > 0) {
+ sprintf(buff, "! ct error: %s\n", emsgp->msgstring);
+ ErrPostEx(SEV_ERROR, 100, 1, buff);
+ }
+ if((emsgp->osnumber != 0) && (emsgp->osstringlen > 0)) {
+ sprintf(buff, "! os error: %s\n", emsgp->osstring);
+ ErrPostEx(SEV_ERROR, 100, 2, buff);
+ }
+ if((emsgp->sqlstatelen > 0) && (strcmp(emsgp->sqlstate, "ZZZZZ") != 0)) {
+ sprintf(buff, "! sql statement: %s\n", emsgp->sqlstate);
+ ErrPostEx(SEV_ERROR, 100, 3, buff);
+ }
+
+ return CS_SUCCEED;
+}
+
+CS_RETCODE s_msg_proc(CS_CONTEXT* cp, CS_CONNECTION* chp, CS_SERVERMSG* msg)
+{
+ char buff[512];
+
+ if((msg->textlen > 0) && (msg->severity > 0)) {
+ sprintf(buff, "! server message: %s\t %s\t %s\t %s\n", msg->svrname, msg->proc, msg->text, msg->sqlstate);
+ ErrPostEx(SEV_ERROR, 100, 4, buff);
+ }
+ return CS_SUCCEED;
+}
+
+Boolean txc_connect2Server(CharPtr srv_name, CharPtr usr, CharPtr passwd, CharPtr applic)
+{
+ CS_BOOL val= CS_TRUE;
+ CS_INT t_out= 40;
+
+ cs_ctx_alloc(CS_VERSION_110, &te_context);
+ ct_init(te_context, CS_VERSION_110);
+ ct_config(te_context, CS_SET, CS_TIMEOUT, &t_out, CS_UNUSED, NULL);
+
+ ct_callback(te_context, NULL, CS_SET, CS_CLIENTMSG_CB, c_msg_proc);
+ ct_callback(te_context, NULL, CS_SET, CS_SERVERMSG_CB, s_msg_proc);
+
+ ct_con_alloc(te_context, &te_link);
+ ct_con_props(te_link, CS_SET, CS_USERNAME, usr, CS_NULLTERM, NULL);
+ ct_con_props(te_link, CS_SET, CS_PASSWORD, passwd, CS_NULLTERM, NULL);
+ ct_con_props(te_link, CS_SET, CS_APPNAME, applic, CS_NULLTERM, NULL);
+ if(ct_connect(te_link, srv_name, CS_NULLTERM) != CS_SUCCEED) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+Int4 tax_findByName(CharPtr sname, int mode, TaxNamePtr* res_name)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_TINYINT smode;
+ CS_INT res_type, rows_read, tax_id;
+ char nbuff[256], ubuff[256];
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ CS_SMALLINT has_unique;
+ CS_TINYINT class_cde, designator;
+ Int4 n= 0, alloc_room= 0;
+ TaxNamePtr fnd_name= NULL;
+ int nnn= 64;
+
+ if(sname == NULL) return 0;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+
+ /* build command: tax_findByName @name_txt, @mode */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_findByName", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@name_txt");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.maxlength= strlen(sname);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, sname, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ strcpy(parfmt.name, "@mode");
+ parfmt.datatype= CS_TINYINT_TYPE;
+ parfmt.maxlength= 1;
+ parfmt.locale= NULL;
+ smode= mode;
+ if(ct_param(cmd, &parfmt, &smode, 1, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return 0;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if(ct_bind(cmd, 1, &parfmt, &tax_id, NULL, NULL) != CS_SUCCEED) break;
+
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 255;
+ if((ct_bind(cmd, 2, &parfmt, nbuff, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 3, &parfmt, ubuff, NULL, &has_unique) != CS_SUCCEED)) break;
+
+ parfmt.datatype= CS_TINYINT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 1;
+ if((ct_bind(cmd, 4, &parfmt, &class_cde, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 5, &parfmt, &designator, NULL, NULL) != CS_SUCCEED)) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(n == 0) {
+ *res_name= fnd_name= malloc(sizeof(TaxName));
+ alloc_room= 1;
+ }
+ else if(n >= alloc_room) {
+
+ alloc_room+= (8 > (alloc_room/4))? 8 : (alloc_room/4);
+ *res_name= realloc(fnd_name, alloc_room*sizeof(TaxName));
+ if(*res_name == NULL) {
+ alloc_room= n--;
+ *res_name= fnd_name;
+ }
+ else fnd_name= *res_name;
+ }
+
+ fnd_name[n].tax_id= tax_id;
+ fnd_name[n].class_cde= class_cde;
+ fnd_name[n].designator= designator;
+ fnd_name[n].name_txt= StringSave(nbuff);
+ fnd_name[n].unique_name= (has_unique < 0)? NULL : StringSave(ubuff);
+ n++;
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is a error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return n;
+}
+
+Int4 tax_getDesignator(char* sname)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read, tax_id= 0;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ int nnn= 64;
+
+ if((sname == NULL) || (*sname == '\0')) return 0;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+ /* build command: tax_getDesignator @name_txt */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_getDesignator", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@name_txt");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.maxlength= strlen(sname);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, sname, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return 0;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_STATUS_RESULT) {
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ if(ct_bind(cmd, 1, &parfmt, &tax_id, NULL, NULL) != CS_SUCCEED) break;
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is a error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return tax_id;
+}
+
+
+Int4 tax_uniqueName(char* sname, Int4 id)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read, tax_id= 0;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ int nnn= 64;
+
+ if((sname == NULL) || (*sname == '\0')) return 0;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+ /* build command: tax_checkUnique @name_txt, @tax_id */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_checkUnique", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@name_txt");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.maxlength= strlen(sname);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, sname, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ strcpy(parfmt.name, "@tax_id");
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.maxlength= sizeof(CS_INT);
+ if(ct_param(cmd, &parfmt, &id, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return 0;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_STATUS_RESULT) {
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ if(ct_bind(cmd, 1, &parfmt, &tax_id, NULL, NULL) != CS_SUCCEED) break;
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is a error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return tax_id;
+}
+
+
+Int4 tax_getIdByName(char* sname, char* qualif, Int1 id)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read, tax_id= 0;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char s_sname[100];
+ char s_qualif[120];
+
+ if((sname == NULL) || (*sname == '\0')) return 0;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+ /* build command: tax_getIdByName(@org_name, @qualif, @q_type) */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_getIdByName", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@org_name");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_CHAR_TYPE;
+ strncpy(s_sname, sname, 96);
+ s_sname[96]= '\0';
+ parfmt.maxlength= strlen(s_sname);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, s_sname, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+ strcpy(parfmt.name, "@qualif");
+ if(qualif == NULL) {
+ s_qualif[0]= s_qualif[1]= '\0';
+ parfmt.maxlength= 1;
+ }
+ else {
+ strncpy(s_qualif, qualif, 116);
+ s_qualif[116]= '\0';
+ parfmt.maxlength= strlen(s_qualif);
+ }
+
+ if(ct_param(cmd, &parfmt, s_qualif, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ strcpy(parfmt.name, "@q_type");
+ parfmt.datatype= CS_TINYINT_TYPE;
+ parfmt.maxlength= sizeof(CS_TINYINT);
+ if(ct_param(cmd, &parfmt, &id, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return 0;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_STATUS_RESULT) {
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ if(ct_bind(cmd, 1, &parfmt, &tax_id, NULL, NULL) != CS_SUCCEED) break;
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is a error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return tax_id;
+}
+
+
+Int4 tax_getOrgNames(Int4 tax_id, TaxNamePtr* res_name)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_TINYINT smode;
+ CS_INT res_type, rows_read;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char nbuff[256], ubuff[256];
+ CS_SMALLINT has_unique;
+ CS_TINYINT class_cde, designator;
+ Int4 n= 0, alloc_room= 0;
+ TaxNamePtr fnd_name= NULL;
+ int nnn= 64;
+
+ if(tax_id <= 0) return 0;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+
+ /* build command: tax_getOrgNames @tax_id */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_getOrgNames", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@tax_id");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.maxlength= sizeof(Int4);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, &tax_id, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return 0;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if(ct_bind(cmd, 1, &parfmt, &tax_id, NULL, NULL) != CS_SUCCEED) break;
+
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 255;
+ if((ct_bind(cmd, 2, &parfmt, nbuff, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 3, &parfmt, ubuff, NULL, &has_unique) != CS_SUCCEED)) break;
+
+ parfmt.datatype= CS_TINYINT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 1;
+ if((ct_bind(cmd, 4, &parfmt, &class_cde, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 5, &parfmt, &designator, NULL, NULL) != CS_SUCCEED)) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(n == 0) {
+ *res_name= fnd_name= malloc(sizeof(TaxName));
+ alloc_room= 1;
+ }
+ else if(n >= alloc_room) {
+
+ alloc_room+= (8 > (alloc_room/4))? 8 : (alloc_room/4);
+ *res_name= realloc(fnd_name, alloc_room*sizeof(TaxName));
+ if(*res_name == NULL) {
+ alloc_room= n--;
+ *res_name= fnd_name;
+ }
+ else fnd_name= *res_name;
+ }
+
+ fnd_name[n].tax_id= tax_id;
+ fnd_name[n].class_cde= class_cde;
+ fnd_name[n].designator= designator;
+ fnd_name[n].name_txt= StringSave(nbuff);
+ fnd_name[n].unique_name= (has_unique < 0)? NULL : StringSave(ubuff);
+ n++;
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return n;
+}
+
+
+TXC_NodeDataPtr txc_getOrgData(Int4 tax_id)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read;
+ CS_SMALLINT rank_id, gc_id, mgc_id, div_id;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ TXC_NodeDataPtr node_data= NULL;
+ int nnn= 64;
+ char embl_buff[8];
+
+ if(tax_id <= 0) return 0;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+
+ /* build command: tax_getOrgData @tax_id */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_getOrgData", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@tax_id");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.maxlength= sizeof(Int4);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, &tax_id, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return NULL;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ if(node_data == NULL) {
+ if((node_data= MemNew(sizeof(TXC_NodeData))) == NULL) {
+ ct_cancel(NULL, cmd, CS_CANCEL_ALL);
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+ node_data->tax_id= tax_id;
+ }
+
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if((ct_bind(cmd, 1, &parfmt, &node_data->crt_date, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 2, &parfmt, &node_data->upd_date, NULL, NULL) != CS_SUCCEED)) break;
+
+ parfmt.datatype= CS_SMALLINT_TYPE;
+ parfmt.maxlength= 2;
+ if((ct_bind(cmd, 3, &parfmt, &rank_id, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 4, &parfmt, &gc_id, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 5, &parfmt, &mgc_id, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 6, &parfmt, &div_id, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 7, &parfmt, &node_data->flags, NULL, NULL) != CS_SUCCEED)) break;
+
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 8;
+ if(ct_bind(cmd, 8, &parfmt, embl_buff, NULL, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &rows_read)) {
+ case CS_SUCCEED :
+ node_data->rank_id= rank_id;
+ node_data->gc_id= gc_id;
+ node_data->mgc_id= mgc_id;
+ node_data->div_id= div_id;
+ StringNCpy(node_data->embl_cde, embl_buff, 4);
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return node_data;
+}
+
+
+Boolean txc_loadNameClasses()
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT datafmt;
+ CS_SMALLINT class_cde, priority;
+ CS_INT res_type, rows_read;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char class_txt[128];
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+
+ /* build command: tax_dumpClasses() */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_dumpClasses", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+
+ memset(&datafmt, 0, sizeof(CS_DATAFMT));
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return FALSE;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ datafmt.datatype= CS_SMALLINT_TYPE;
+ datafmt.format= CS_FMT_UNUSED;
+ datafmt.maxlength= sizeof(CS_SMALLINT);
+ datafmt.scale= CS_SRC_VALUE;
+ datafmt.precision= CS_SRC_VALUE;
+ datafmt.count= 1;
+ datafmt.locale= NULL;
+ if((ct_bind(cmd, 1, &datafmt, &class_cde, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 2, &datafmt, &priority, NULL, NULL) != CS_SUCCEED)) break;
+
+ datafmt.datatype= CS_CHAR_TYPE;
+ datafmt.format= CS_FMT_NULLTERM;
+ datafmt.maxlength= 128;
+ if(ct_bind(cmd, 3, &datafmt, class_txt, NULL, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &rows_read)) {
+ case CS_SUCCEED :
+ tax_addNameClass(class_cde, class_txt, priority);
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return TRUE;
+}
+
+
+Boolean txc_loadRanks()
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT datafmt;
+ CS_SMALLINT rank_id;
+ CS_INT res_type, rows_read;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char rank_txt[128];
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+
+ /* build command: tax_dumpRanks() */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_dumpRanks", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+
+ memset(&datafmt, 0, sizeof(CS_DATAFMT));
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return FALSE;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ datafmt.datatype= CS_SMALLINT_TYPE;
+ datafmt.format= CS_FMT_UNUSED;
+ datafmt.maxlength= sizeof(CS_SMALLINT);
+ datafmt.scale= CS_SRC_VALUE;
+ datafmt.precision= CS_SRC_VALUE;
+ datafmt.count= 1;
+ datafmt.locale= NULL;
+ if(ct_bind(cmd, 1, &datafmt, &rank_id, NULL, NULL) != CS_SUCCEED) break;
+
+ datafmt.datatype= CS_CHAR_TYPE;
+ datafmt.format= CS_FMT_NULLTERM;
+ datafmt.maxlength= 128;
+ if(ct_bind(cmd, 2, &datafmt, rank_txt, NULL, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &rows_read)) {
+ case CS_SUCCEED :
+ tax_addRank(rank_id, rank_txt);
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return TRUE;
+}
+
+
+Boolean txc_loadDivisions()
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT datafmt;
+ CS_SMALLINT div_id;
+ CS_INT res_type, rows_read;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char div_cde[8], div_txt[128];
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+
+ /* build command: tax_dumpDivisions() */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_dumpDivisions", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+
+ memset(&datafmt, 0, sizeof(CS_DATAFMT));
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return FALSE;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ datafmt.datatype= CS_SMALLINT_TYPE;
+ datafmt.format= CS_FMT_UNUSED;
+ datafmt.maxlength= sizeof(CS_SMALLINT);
+ datafmt.scale= CS_SRC_VALUE;
+ datafmt.precision= CS_SRC_VALUE;
+ datafmt.count= 1;
+ datafmt.locale= NULL;
+ if(ct_bind(cmd, 1, &datafmt, &div_id, NULL, NULL) != CS_SUCCEED) break;
+
+ datafmt.datatype= CS_CHAR_TYPE;
+ datafmt.format= CS_FMT_NULLTERM;
+ datafmt.maxlength= 8;
+ if(ct_bind(cmd, 2, &datafmt, div_cde, NULL, NULL) != CS_SUCCEED) break;
+
+ datafmt.maxlength= 128;
+ if(ct_bind(cmd, 3, &datafmt, div_txt, NULL, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &rows_read)) {
+ case CS_SUCCEED :
+ tax_addDivision(div_id, div_cde, div_txt);
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return TRUE;
+}
+
+Boolean txc_loadGCs()
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT datafmt;
+ CS_SMALLINT gc_id;
+ CS_INT res_type, rows_read;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char gc_name[128];
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+
+ /* build command: tax_dumpGCs() */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_dumpGCs", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+
+ memset(&datafmt, 0, sizeof(CS_DATAFMT));
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return FALSE;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ datafmt.datatype= CS_SMALLINT_TYPE;
+ datafmt.format= CS_FMT_UNUSED;
+ datafmt.maxlength= sizeof(CS_SMALLINT);
+ datafmt.scale= CS_SRC_VALUE;
+ datafmt.precision= CS_SRC_VALUE;
+ datafmt.count= 1;
+ datafmt.locale= NULL;
+ if(ct_bind(cmd, 1, &datafmt, &gc_id, NULL, NULL) != CS_SUCCEED) break;
+
+ datafmt.datatype= CS_CHAR_TYPE;
+ datafmt.format= CS_FMT_NULLTERM;
+ datafmt.maxlength= 128;
+ if(ct_bind(cmd, 2, &datafmt, gc_name, NULL, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &rows_read)) {
+ case CS_SUCCEED :
+ tax_addGC(gc_id, gc_name);
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return FALSE;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ return TRUE;
+}
+
+
+TXC_TreeNodePtr* txc_getLineage(Int4 lin_id, Int4Ptr lin_len)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read, tax_id, flags;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ Int4 n, l, alloc_room= 48;
+ char label[512];
+ TXC_TreeNodePtr* lineage= NULL;
+ CharPtr c;
+
+ *lin_len= 0;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return FALSE;
+
+
+ /* build command: tax_getLineage @tax_id=lin_id */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_getLineage", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@tax_id");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.maxlength= CS_UNUSED;
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, &lin_id, 4, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return NULL;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if((ct_bind(cmd, 1, &parfmt, &tax_id, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 2, &parfmt, &flags, NULL, NULL) != CS_SUCCEED)) {
+ break;
+ }
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 255;
+ if(ct_bind(cmd, 3, &parfmt, label, NULL, NULL) != CS_SUCCEED) break;
+
+ if(lineage == NULL) {
+ lineage= MemNew(alloc_room*sizeof(TXC_TreeNodePtr));
+ if(lineage == NULL) {
+ ct_cancel(NULL, cmd, CS_CANCEL_ALL);
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+ n= 0;
+ }
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(n >= alloc_room) {
+ /* need more memory */
+ TXC_TreeNodePtr* tmp= MemMore(lineage, (alloc_room + 8)*sizeof(TXC_TreeNodePtr));
+
+ if(tmp == NULL) continue;
+ lineage= tmp;
+ alloc_room+= 8;
+ }
+ l= StringLen(label) + 1;
+ if((lineage[n]= MemNew(l + 8)) != NULL) {
+ lineage[n]->tax_id= tax_id;
+ lineage[n]->flags= flags;
+ StringCpy(lineage[n]->node_label, label);
+ if((flags & TXC_SUFFIX) != 0) {
+ c= StringChr(lineage[n]->node_label, '~');
+ if(c != NULL) *c= '\0';
+ lineage[n]->flags^= TXC_SUFFIX; /* clear this flag */
+ }
+ n++;
+ }
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is a error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ *lin_len= n;
+ return lineage;
+}
+
+
+TXC_TreeNodePtr* txc_getChildren(Int4 node_id, Int4Ptr nof_children)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read, tax_id, parent_id, flags, last_parent= -1;
+ CS_SMALLINT levels= 1;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ Int4 n, l, alloc_room= 16;
+ char label[512];
+ TXC_TreeNodePtr* child= NULL;
+ CharPtr c;
+
+ if(node_id < 0) {
+ node_id= -node_id;
+ levels= 64;
+ alloc_room= 64*1024;
+ }
+
+ *nof_children= 0;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return NULL;
+
+
+ /* build command: tax_getSubtree @root_id=root, @levels= levels */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_getSubtree", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@root_id");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.maxlength= CS_UNUSED;
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, &node_id, 4, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ strcpy(parfmt.name, "@levels");
+ parfmt.datatype= CS_SMALLINT_TYPE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, &levels, 2, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return NULL;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_STATUS_RESULT) {
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ if(ct_bind(cmd, 1, &parfmt, &tax_id, NULL, NULL) != CS_SUCCEED) break;
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is a error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+ }
+ }
+ else if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if((ct_bind(cmd, 1, &parfmt, &parent_id, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 2, &parfmt, &tax_id, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 3, &parfmt, &flags, NULL, NULL) != CS_SUCCEED)) {
+ break;
+ }
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 255;
+ if(ct_bind(cmd, 4, &parfmt, label, NULL, NULL) != CS_SUCCEED) break;
+
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(((levels == 1) && (parent_id != node_id)) || (tax_id == node_id)) continue;
+
+ if(child == NULL) {
+ child= MemNew(alloc_room*sizeof(TXC_TreeNodePtr));
+ if(child == NULL) {
+ ct_cancel(NULL, cmd, CS_CANCEL_ALL);
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+ n= 0;
+ }
+ else if(n >= alloc_room-1) {
+ /* need more memory */
+ TXC_TreeNodePtr* tmp=
+ MemMore(child, (alloc_room + 8*levels)*sizeof(TXC_TreeNodePtr));
+
+ if(tmp == NULL) continue;
+ child= tmp;
+ alloc_room+= 8*levels;
+ }
+ if((levels > 1) && (parent_id != last_parent)) {
+ last_parent= parent_id;
+ child[n]= MemNew(8);
+ child[n]->tax_id= parent_id;
+ child[n++]->flags= TXC_SUFFIX;
+ }
+ l= StringLen(label) + 1;
+ if((child[n]= MemNew(l + 8)) != NULL) {
+ child[n]->tax_id= tax_id;
+ child[n]->flags= flags;
+ StringCpy(child[n]->node_label, label);
+ if((flags & TXC_SUFFIX) != 0) {
+ c= StringChr(child[n]->node_label, '~');
+ if(c != NULL) *c= '\0';
+ child[n]->flags^= TXC_SUFFIX; /* clear this flag */
+ }
+ n++;
+ }
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+ default :
+ /* this is a error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+ *nof_children= n;
+ if(n == 0) {
+ MemFree(child);
+ child= NULL;
+ }
+ return child;
+}
+
+
+TXC_CitListPtr txc_citGet4Node(Int4 tax_id, Int4Ptr nof_cit)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char cit_key[132];
+ CS_INT cit_id;
+ Int4 n= 0, alloc_room= 0;
+ TXC_CitListPtr refer= NULL, tmp;
+
+ if(tax_id <= 0) return NULL;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return NULL;
+
+
+ /* build command: tax_citGet4Node @tax_id */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_getCit4Node", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@tax_id");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.maxlength= sizeof(Int4);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, &tax_id, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return NULL;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if(ct_bind(cmd, 1, &parfmt, &cit_id, NULL, NULL) != CS_SUCCEED) break;
+
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 128;
+ if(ct_bind(cmd, 2, &parfmt, cit_key, NULL, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(n == 0) {
+ refer= malloc(sizeof(TXC_CitList));
+ alloc_room= 1;
+ }
+ else if(n >= alloc_room) {
+
+ alloc_room+= 2;
+ tmp= realloc(refer, alloc_room*sizeof(TXC_CitList));
+ if(tmp == NULL) {
+ alloc_room= n--;
+ }
+ else refer= tmp;
+ }
+
+ refer[n].cit_id= cit_id;
+ refer[n].cit_key= StringSave(cit_key);
+ n++;
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return refer;
+ }
+ }
+ }
+ continue;
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+
+ *nof_cit= n;
+ return refer;
+}
+
+
+CharPtr txc_citGetKey(Int4 cit_id)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char cit_key[132];
+
+ if(cit_id <= 0) return NULL;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return NULL;
+
+
+ /* build command: tax_citGet4Node @tax_id */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_getCitKey", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@cit_id");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.maxlength= sizeof(Int4);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, &cit_id, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return NULL;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+
+ more_fetch= TRUE;
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 128;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if(ct_bind(cmd, 1, &parfmt, cit_key, NULL, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ cit_key[131]= '\0';
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return StringSave(cit_key);
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+
+ return StringSave(cit_key);
+}
+
+TXC_CitListPtr txc_citFind(CharPtr key_str, Int4Ptr nof_cit)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char cit_key[132];
+ CS_INT cit_id;
+ Int4 n= 0, alloc_room= 0;
+ TXC_CitListPtr refer= NULL, tmp;
+
+ if((key_str == NULL) || (*key_str == '\0')) return NULL;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return NULL;
+
+
+ /* build command: tax_citGet4Node @tax_id */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_findCit", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@cit_key");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.maxlength= strlen(key_str);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, key_str, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ /* send this command to the server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return NULL;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if(ct_bind(cmd, 1, &parfmt, &cit_id, NULL, NULL) != CS_SUCCEED) break;
+
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 128;
+ if(ct_bind(cmd, 2, &parfmt, cit_key, NULL, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(n == 0) {
+ refer= malloc(sizeof(TXC_CitList));
+ alloc_room= 1;
+ }
+ else if(n >= alloc_room) {
+
+ alloc_room+= 2;
+ tmp= realloc(refer, alloc_room*sizeof(TXC_CitList));
+ if(tmp == NULL) {
+ alloc_room= n--;
+ }
+ else refer= tmp;
+ }
+
+ refer[n].cit_id= cit_id;
+ refer[n].cit_key= StringSave(cit_key);
+ n++;
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return refer;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+
+ *nof_cit= n;
+ return refer;
+}
+
+_citation* txc_citGetByKey(CharPtr key_str)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char cit_key[132], url[132], txt[6*256];
+ CS_INT cit_key_ln, url_ln, txt_ln[6];
+ CS_SMALLINT url_ind, txt_ind[6];
+ CS_INT cit_id, flags, medline_id, pubmed_id;
+ Int4 n, i;
+ _citation* cit= NULL;
+
+ if((key_str == NULL) || (*key_str == '\0')) return NULL;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return NULL;
+
+
+ /* build command: tax_citGet4Node @tax_id */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_citGetByKey", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@cit_key");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.maxlength= strlen(key_str);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, key_str, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ /* send this command to the server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return NULL;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if((ct_bind(cmd, 1, &parfmt, &cit_id, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 3, &parfmt, &flags, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 4, &parfmt, &medline_id, NULL, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 5, &parfmt, &pubmed_id, NULL, NULL) != CS_SUCCEED)) break;
+
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 128;
+ if((ct_bind(cmd, 2, &parfmt, cit_key, &cit_key_ln, NULL) != CS_SUCCEED) ||
+ (ct_bind(cmd, 6, &parfmt, url, &url_ln, &url_ind) != CS_SUCCEED)) break;
+
+ parfmt.maxlength= 256;
+ for(n= 0; n < 6; n++) {
+ if(ct_bind(cmd, 7+n, &parfmt, txt + 256*n, &txt_ln[n], &txt_ind[n]) != CS_SUCCEED)
+ break;
+ }
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(cit == NULL) {
+ cit= malloc(sizeof(_citation));
+ }
+ cit->id= cit_id;
+ cit->key= StringSave(cit_key);
+ cit->flags= flags;
+ cit->mu_id= medline_id;
+ cit->pm_id= pubmed_id;
+ cit->url= ((url_ind == -1) || (url_ln < 1) || (url[0] == '\0'))? NULL :
+ StringSave(url);
+
+ for(i= n= 0; i < 6; i++) {
+ n+= ((txt_ind[i] == -1) || (txt_ln[i] < 1) || (txt[256*i] == '\0'))? 0 :
+ (txt_ln[i] + 1);
+ }
+ if(n == 0) {
+ cit->txt= NULL;
+ }
+ else {
+ cit->txt= MemNew(n);
+ cit->txt[0]= '\0';
+ for(i= 0; i < 6; i++) {
+ if((txt_ind[i] != -1) && (txt_ln[i] > 0) && (txt[256*i] != '\0')) {
+ strcat(cit->txt, &txt[256*i]);
+ }
+ }
+ }
+ continue;
+
+ case CS_ROW_FAIL :
+ break;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return cit;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+
+ return cit;
+}
+
+void txc_close()
+{
+ int i= 0;
+ CS_RETCODE rc;
+
+ while((rc= ct_close(te_link, CS_UNUSED)) == CS_FAIL) {
+ ++i;
+ if(ct_cancel(te_link, NULL, CS_CANCEL_ALL) != CS_SUCCEED) break;
+ if(i > 2) break;
+ }
+ if(rc == CS_FAIL) ct_close(te_link, CS_FORCE_CLOSE);
+
+ if(ct_exit(te_context, CS_UNUSED) != CS_FAIL) {
+ ct_exit(te_context, CS_FORCE_EXIT);
+ }
+}
+
+
+/********************************/
+/* retrive subspecies functions */
+/********************************/
+
+/* tax_SSget(@tax_id int, @subtype tinyint, @subname varchar(120)) proc */
+
+_subspecPtr tax_SSget(Int4 tax_id, _subspecPtr ssrec)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ char rname[132];
+ CS_INT res_type, rows_read;
+ CS_INT rname_ln;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+
+ if(tax_id < 2) return NULL;
+
+ if((ssrec == NULL) || (ssrec->sname == NULL)) return NULL;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return NULL;
+
+ /* build command: tax_checkUnique @name_txt, @tax_id */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_SSget", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@tax_id");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.maxlength= sizeof(CS_INT);
+ if(ct_param(cmd, &parfmt, &tax_id, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ strcpy(parfmt.name, "@subtype");
+ parfmt.datatype= CS_TINYINT_TYPE;
+ parfmt.maxlength= 1;
+ if(ct_param(cmd, &parfmt, &ssrec->stype, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ strcpy(parfmt.name, "@subname");
+ strncpy(rname, ssrec->sname, 116);
+ rname[116]= '\0';
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.maxlength= strlen(rname);
+ if(ct_param(cmd, &parfmt, rname, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ if(ssrec->rname != NULL) ssrec->rname= MemFree(ssrec->rname);
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return NULL;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if(ct_bind(cmd, 1, &parfmt, &ssrec->r_id, NULL, NULL) != CS_SUCCEED) break;
+
+ parfmt.datatype= CS_TINYINT_TYPE;
+ parfmt.maxlength= 1;
+ if(ct_bind(cmd, 2, &parfmt, &ssrec->rtype, NULL, NULL) != CS_SUCCEED) break;
+
+
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 132;
+ if(ct_bind(cmd, 3, &parfmt, rname, &rname_ln, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(rname_ln >= 0) {
+ rname[rname_ln]= '\0';
+ if(ssrec->rname != NULL) MemFree(ssrec->rname);
+ ssrec->rname= StringSave(rname);
+ }
+ continue;
+
+ case CS_ROW_FAIL :
+ continue;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+
+ return (ssrec->rname == NULL)? NULL : ssrec;
+}
+
+tax_OrgModPtr tax_SSgetLegal(Int4 tax_id)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read;
+ CS_TINYINT subtype;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ char subname[256];
+ CS_INT subname_ln;
+ tax_OrgModPtr first= NULL;
+ tax_OrgModPtr last, tmp;
+
+ if(tax_id < 2) return NULL;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return NULL;
+
+
+ /* call tax_SSgetLegal (@tax_id int) proc */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_SSgetLegal", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@tax_id");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.maxlength= sizeof(Int4);
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ if(ct_param(cmd, &parfmt, &tax_id, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ /* send this command to the server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return NULL;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return first;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_TINYINT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 1;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if(ct_bind(cmd, 1, &parfmt, &subtype, NULL, NULL) != CS_SUCCEED) break;
+
+
+ parfmt.datatype= CS_CHAR_TYPE;
+ parfmt.format= CS_FMT_NULLTERM;
+ parfmt.maxlength= 240;
+ if(ct_bind(cmd, 2, &parfmt, subname, &subname_ln, NULL) != CS_SUCCEED) break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(subname_ln >= 0) subname[subname_ln]= '\0';
+ tmp= MemNew(sizeof(tax_OrgMod));
+ if(tmp == NULL) continue;
+ tmp->next= NULL;
+ tmp->subname= StringSave(subname);
+ tmp->subtype= subtype;
+ if(first == NULL) {
+ first= last= tmp;
+ }
+ else {
+ last->next= tmp;
+ last= tmp;
+ }
+
+ continue;
+
+ case CS_ROW_FAIL :
+ continue;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return first;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+
+ return first;
+}
+
+/* tax_SSgetNodes(@tax_id int, @subtype tinyint, @subname varchar(120)) proc */
+
+Int4 tax_SSgetNodes(Uint1 stype, CharPtr sname, Uint1 mode, Int4Ptr* ids)
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT parfmt;
+ CS_INT res_type, rows_read;
+ int nnn= 64;
+ Boolean more_results= TRUE;
+ Boolean more_fetch;
+ Int4Ptr p_id;
+ Int4 nof_nodes= 0, nof_rooms;
+ CS_INT tax_id;
+ char tname[120];
+
+ if((sname == NULL) || (*sname == '\0')) return 0;
+
+ if(ct_cmd_alloc(te_link, &cmd) != CS_SUCCEED) return 0;
+
+ /* build command: tax_SSgetNodes @subtype, @subname, @mode */
+
+ if(ct_command(cmd, CS_RPC_CMD, "tax_SSgetNodes", CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ memset(&parfmt, 0, sizeof(CS_DATAFMT));
+ strcpy(parfmt.name, "@subtype");
+ parfmt.namelen= CS_NULLTERM;
+ parfmt.status= CS_INPUTVALUE;
+ parfmt.locale= NULL;
+ parfmt.datatype= CS_TINYINT_TYPE;
+ parfmt.maxlength= sizeof(CS_TINYINT);
+ if(ct_param(cmd, &parfmt, &stype, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ strcpy(parfmt.name, "@subname");
+ parfmt.datatype= CS_CHAR_TYPE;
+ strncpy(tname, sname, 116);
+ tname[116]= '\0';
+ parfmt.maxlength= strlen(tname);
+ if(ct_param(cmd, &parfmt, tname, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ strcpy(parfmt.name, "@mode");
+ parfmt.datatype= CS_TINYINT_TYPE;
+ parfmt.maxlength= 1;
+ if(ct_param(cmd, &parfmt, &mode, parfmt.maxlength, CS_UNUSED) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ /* send this command to server */
+ if(ct_send(cmd) != CS_SUCCEED) {
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+
+ while(more_results && (--nnn > 0)) {
+ switch(ct_results(cmd, &res_type)) {
+ case CS_FAIL :
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ case CS_CANCELED :
+ ct_cmd_drop(cmd);
+ return 0;
+
+ case CS_END_RESULTS :
+ more_results= FALSE;
+ break;
+
+ case CS_SUCCEED :
+ if(res_type == CS_ROW_RESULT) {
+ /* bind and fetch these data */
+ more_fetch= TRUE;
+ parfmt.datatype= CS_INT_TYPE;
+ parfmt.format= CS_FMT_UNUSED;
+ parfmt.maxlength= 4;
+ parfmt.scale= CS_SRC_VALUE;
+ parfmt.precision= CS_SRC_VALUE;
+ parfmt.count= 1;
+ parfmt.locale= NULL;
+ if(ct_bind(cmd, 1, &parfmt, &tax_id, NULL, NULL) != CS_SUCCEED) break;
+ p_id= MemNew(4 * sizeof(Int4));
+ if(p_id != NULL) {
+ nof_rooms= 4;
+ }
+ else break;
+
+ while(more_fetch) {
+ switch(ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,&rows_read)) {
+ case CS_SUCCEED :
+ if(nof_nodes >= nof_rooms) {
+ nof_rooms+= 8;
+ *ids= p_id;
+ p_id= MemMore(p_id, nof_rooms*(sizeof(Int4)));
+ if(p_id == NULL) {
+ p_id= *ids;
+ nof_rooms-= 8;
+ continue;
+ }
+ }
+
+ p_id[nof_nodes++]= tax_id;
+ continue;
+
+ case CS_ROW_FAIL :
+ continue;
+
+ case CS_END_DATA :
+ more_fetch= FALSE;
+ continue;
+
+ default :
+ /* this is an error */
+ more_fetch= FALSE;
+ if(ct_cancel(NULL, cmd, CS_CANCEL_ALL) != CS_SUCCEED) {
+ ct_close(te_link, CS_FORCE_CLOSE);
+ }
+ ct_cmd_drop(cmd);
+ return 0;
+ }
+ }
+ }
+ continue;
+
+ default : break;
+ }
+ }
+ ct_cmd_drop(cmd);
+
+ *ids= p_id;
+ return nof_nodes;
+}
diff --git a/network/vibnet/docsum.c b/network/vibnet/docsum.c
new file mode 100644
index 00000000..b66b1d28
--- /dev/null
+++ b/network/vibnet/docsum.c
@@ -0,0 +1,4354 @@
+/* docsum.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information (NCBI)
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government do not place any restriction on its use or reproduction.
+* We would, however, appreciate having the NCBI and the author cited in
+* any work or product based on this material
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* ===========================================================================
+*
+* File Name: docsum.c
+*
+* Author: Jonathan Kans, Jonathan Epstein
+*
+* Version Creation Date: 9/13/96
+*
+* $Revision: 6.39 $
+*
+* File Description:
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* $Log: docsum.c,v $
+* Revision 6.39 1999/01/14 19:18:46 kans
+* new parameters for Cn3DWin_Entrez
+*
+* Revision 6.38 1999/01/13 19:26:46 kans
+* added RetrieveSimpleSeqs, switched from tracking SeqEntry to SimpleSeq, to allow lower case, avoid Bioseq ID collision
+*
+* Revision 6.37 1999/01/11 16:25:49 kans
+* forgot to add parameter to ReadAsnFastaOrFlatFile
+*
+* Revision 6.36 1998/11/20 19:01:06 kans
+* set refine button count if setting retrieve button to evaluate
+*
+* Revision 6.35 1998/11/18 16:21:29 kans
+* added UseDelayedNeighbor to control from preference
+*
+* Revision 6.34 1998/11/18 15:55:06 kans
+* added controls for user to change immediate/delayed neighbor mode
+*
+* Revision 6.33 1998/11/18 15:14:02 kans
+* added retrieveMode to Evaluate neighbors/links only on command
+*
+* Revision 6.32 1998/08/14 16:23:01 kans
+* AddBlastAlignment now passed proper query bioseq
+*
+* Revision 6.31 1998/06/12 00:00:31 kans
+* now calling CleanupEntrezPrefsProc, other minor fixes
+*
+* Revision 6.30 1998/05/11 21:48:10 kans
+* calls GetIdStringsForSeqEntryAligns for count to avoid database hit until retrieve
+*
+* Revision 6.29 1998/05/07 01:38:56 kans
+* retrieve generation hides fasta format control of instantiated uid-less bioseqs
+*
+* Revision 6.28 1998/05/05 15:13:02 kans
+* added lgp->onlyFromThis, control (hidden)
+*
+* Revision 6.27 1998/05/02 23:09:56 kans
+* calls SeqnSeqEntrysToFasta to trim long deflines
+*
+* Revision 6.26 1998/04/29 15:15:57 kans
+* double click only if uids present
+*
+* Revision 6.25 1998/04/23 12:48:08 kans
+* read asn/fasta bioseq collection tries to use sep already attached to bsp
+*
+* Revision 6.24 1998/04/22 18:07:47 kans
+* docsum import label says FASTA or Uid List
+*
+* Revision 6.23 1998/04/22 17:35:14 kans
+* docsum import collects bioseqs into a project, refine button disabled if 0 items
+*
+* Revision 6.22 1998/04/21 12:56:00 kans
+* support for blast choices in database alist, neighbor/link control for blasting a record that already has a uid
+*
+* Revision 6.21 1998/04/19 23:49:29 kans
+* added parseFastaSeqId parameter to ReadAsnFastaOrFlatFile
+*
+* Revision 6.20 1998/04/19 23:28:30 kans
+* initial implementation of import docsum function
+*
+* Revision 6.19 1998/04/19 22:56:11 kans
+* cast for ValNodeLink in building project
+*
+* Revision 6.18 1998/04/19 22:08:42 kans
+* nuc, prot flags to DocSumCanSaveFasta, ExportDocSumFasta
+*
+* Revision 6.17 1998/04/18 02:38:32 kans
+* export docsum fasta does not add newlines, for consistency with export bioseq view fasta
+*
+* Revision 6.16 1998/04/18 02:08:11 kans
+* added DocSumCanSaveFasta and ExportDocSumFasta
+*
+* Revision 6.15 1998/04/17 16:44:36 kans
+* empty function for ImportDocSumForm, implemented ExportDocSumForm
+*
+* Revision 6.14 1998/04/16 19:16:27 kans
+* fasta format sets group_segs to handle seg, delta sequences
+*
+* Revision 6.13 1998/04/14 21:46:48 kans
+* added FetchUid, xxx ID radio button choices
+*
+* Revision 6.12 1998/04/14 18:13:45 kans
+* SetDefaultFailureMessage for docsum items
+*
+* Revision 6.11 1998/04/13 19:26:54 kans
+* forgot to NULL out sfp->seqentry when MemFreeing it
+*
+* Revision 6.10 1998/04/13 16:47:16 kans
+* implemented SetDocSumImportExportItems
+*
+* Revision 6.9 1998/04/11 16:20:03 kans
+* can now read uid or sep project, save sep project
+*
+* Revision 6.8 1998/04/11 00:47:00 kans
+* initial work on handling instantiated bioseqs as projects
+*
+* Revision 6.7 1998/03/25 15:25:33 kans
+* use >PubMed instead of >MEDLINE
+*
+* Revision 6.6 1998/03/01 22:04:49 kans
+* blast wordsize 10 for 16-bit Windows
+*
+* Revision 6.5 1998/02/21 22:11:46 kans
+* implement copy to clipboard
+*
+* Revision 6.4 1998/01/07 19:11:47 kans
+* added UpdateViewerLinkTarget
+*
+* Revision 6.3 1997/12/03 22:47:30 kans
+* AddBlastAlignment returns if no alignments to do
+*
+* Revision 6.2 1997/11/01 22:58:36 kans
+* added alignDefault preference control
+*
+* Revision 6.1 1997/09/22 18:13:45 kans
+* removed obsolete explosion mode
+*
+* Revision 6.0 1997/08/25 18:48:42 madden
+* Revision changed to 6.0
+*
+* Revision 1.20 1997/08/12 18:43:36 kans
+* calls SaveDocumentItem if docsums checked
+*
+* Revision 1.19 1997/07/23 18:09:09 kans
+* DS and TL specific Save/LoadUidProcList functions
+*
+* Revision 1.18 1997/07/22 20:05:43 kans
+* new parameter to BLASTSetUpSearch
+*
+* Revision 1.17 1997/07/21 14:25:58 kans
+* load/save uid list now uses text database tag
+*
+* Revision 1.16 1997/06/27 17:07:05 kans
+* do not limit FileToString to 32K
+*
+* Revision 1.15 1997/06/01 23:25:07 kans
+* flat files use displayFont
+*
+* Revision 1.14 1997/04/29 18:47:15 kans
+* uses persistDefault field if parentsPersist not yet set (PC or UNIX)
+*
+ * Revision 1.13 1997/04/21 15:36:35 kans
+ * added LoadUidListProc and SaveUidListProc
+ *
+ * Revision 1.12 1997/03/31 18:54:00 kans
+ * watch cursor/arrow cursor calls flank export and print docsum
+ *
+ * Revision 1.11 1997/03/20 21:17:44 kans
+ * change display font should send redraw message on all platforms
+ *
+ * Revision 1.10 1997/03/20 19:05:10 vakatov
+ * [!WIN16] Included <cn3dentr.h>; now use Cn3DWin_Entrez() instead of Cn3DWin()
+ * In FetchPDB() and LaunchStructureViewer(), check for BiostrucAvail() [J.K.]
+ *
+*
+* ==========================================================================
+*/
+
+#include <vibrant.h>
+#include <document.h>
+#include <accentr.h>
+#include <objmgr.h>
+#include <gather.h>
+#include <asn2ff.h>
+#include <tomedlin.h>
+#include <tofasta.h>
+#include <simple.h>
+#include <dlogutil.h>
+#include <objproj.h>
+#include <mmdbapi.h>
+#ifndef WIN16
+#include <cn3dmain.h>
+#include <cn3dentr.h>
+#endif
+
+#include <blast.h>
+#include <blastpri.h>
+#include <simutil.h>
+
+#include <bspview.h>
+#include <medview.h>
+
+#include <entrez.h>
+
+#ifndef MAX_MDLNO
+#define MAX_MDLNO 1000
+#endif
+
+#define MAX_DBS 6
+
+#define FETCH_MODE 1
+#define EVAL_MODE 2
+
+typedef struct docsumstatedata {
+ Boolean checked : 1;
+ Boolean hasAbstract : 1;
+ Boolean noSuchUid : 1;
+} StateData, PNTR StateDataPtr;
+
+typedef struct summformdata {
+ FORM_MESSAGE_BLOCK
+
+ PopuP target;
+ DoC docsum;
+ GrouP formats [MAX_DBS + 1];
+ CharPtr label;
+ GrouP controls;
+
+ Int2 dsClickItem;
+ Int2 dsClickRow;
+ Int2 dsClickCol;
+ Boolean wasDoubleClick;
+
+ Boolean usingDelay;
+ Int2 retrieveMode;
+
+ ButtoN retrieve;
+ ButtoN refine;
+
+ EnumFieldAssocPtr dbalist;
+
+ Int4Ptr uids;
+ SimpleSeqPtr PNTR simple;
+ StateDataPtr state;
+ Int2 numUids;
+ Int2 numParents;
+
+ Int4Ptr neighbors;
+ Int2 numNeighbors;
+ Int2 neighborDb;
+ Int2 currDb;
+
+ Int2 lineHeight;
+ Int2 linesPerIcon;
+
+ CharPtr historyFile;
+ Int4Ptr historyOffsets;
+ Int2 generations;
+ Int2 present;
+
+ ButtoN nextBtn;
+ ButtoN prevBtn;
+
+ FonT docsumFont;
+} SummFormData, PNTR SummFormPtr;
+
+static Uint1 hasabstract [] = {
+ 0x07, 0xF8, 0x1F, 0xE0, 0x78, 0x07, 0xE0, 0x1E,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x4F, 0xF9, 0x9F, 0xF2,
+ 0x40, 0x01, 0x80, 0x02, 0x4F, 0xF9, 0x9F, 0xF2,
+ 0x40, 0x01, 0x80, 0x02, 0x4F, 0xF9, 0x9F, 0xF2,
+ 0x40, 0x01, 0x80, 0x02, 0x4F, 0xF9, 0x9F, 0xF2,
+ 0x40, 0x01, 0x80, 0x02, 0x4F, 0xF9, 0x9F, 0xF2,
+ 0x40, 0x01, 0x80, 0x02, 0x4F, 0xF9, 0x9F, 0xF2,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x47, 0xF9, 0x9F, 0xE2,
+ 0x7F, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFE
+};
+
+static Uint1 noabstract [] = {
+ 0x07, 0xF8, 0x1F, 0xE0, 0x78, 0x07, 0xE0, 0x1E,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x40, 0x01, 0x80, 0x02,
+ 0x40, 0x01, 0x80, 0x02, 0x47, 0xF9, 0x9F, 0xE2,
+ 0x7F, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFE
+};
+
+static Uint1 proteinicon [] = {
+ 0x7F, 0xFF, 0xFF, 0xFE, 0x40, 0x00, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x43, 0x83, 0x80, 0x02,
+ 0x44, 0x44, 0x40, 0x02, 0x43, 0xC3, 0xC0, 0x02,
+ 0x44, 0x44, 0x40, 0x02, 0x44, 0x44, 0x40, 0x02,
+ 0x44, 0x44, 0x40, 0x02, 0x43, 0xE3, 0xE0, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x47, 0xE7, 0xE7, 0xE2,
+ 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02,
+ 0x47, 0xE7, 0xE7, 0xE2, 0x40, 0x00, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x47, 0xE7, 0xE7, 0xE2,
+ 0x40, 0x00, 0x00, 0x02, 0x7F, 0xFF, 0xFF, 0xFE
+};
+
+static Uint1 dnaicon [] = {
+ 0x7F, 0xFF, 0xFF, 0xFE, 0x40, 0x00, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x45, 0x81, 0x00, 0x02,
+ 0x46, 0x41, 0x00, 0x02, 0x44, 0x47, 0xC0, 0x02,
+ 0x44, 0x41, 0x00, 0x02, 0x44, 0x41, 0x00, 0x02,
+ 0x44, 0x41, 0x00, 0x02, 0x44, 0x60, 0xC0, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x4F, 0x7B, 0xDE, 0xF2,
+ 0x40, 0x00, 0x00, 0x02, 0x4F, 0x7B, 0xDE, 0xF2,
+ 0x40, 0x00, 0x00, 0x02, 0x4F, 0x7B, 0xDE, 0xF2,
+ 0x40, 0x00, 0x00, 0x02, 0x4F, 0x7B, 0xDE, 0xF2,
+ 0x40, 0x00, 0x00, 0x02, 0x7F, 0xFF, 0xFF, 0xFE
+};
+
+static Uint1 threedicon [] = {
+ 0x7F, 0xFF, 0xFF, 0xFE, 0x40, 0x00, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x4E, 0x0E, 0x00, 0x02,
+ 0x41, 0x09, 0x00, 0x02, 0x40, 0x88, 0x80, 0x02,
+ 0x47, 0x08, 0x80, 0x02, 0x40, 0x88, 0x80, 0x02,
+ 0x41, 0x09, 0x00, 0x02, 0x4E, 0x0E, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x47, 0xE0, 0x00, 0x02,
+ 0x40, 0x07, 0xE0, 0x02, 0x40, 0x00, 0x07, 0xE2,
+ 0x47, 0xE0, 0x00, 0x02, 0x40, 0x07, 0xE0, 0x02,
+ 0x40, 0x00, 0x07, 0xE2, 0x47, 0xE0, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x7F, 0xFF, 0xFF, 0xFE
+};
+
+static Uint1 genomeicon [] = {
+ 0x7F, 0xFF, 0xFF, 0xFE, 0x40, 0x00, 0x00, 0x02,
+ 0x40, 0xF0, 0xF0, 0x02, 0x41, 0x01, 0x08, 0x02,
+ 0x41, 0x01, 0x00, 0x02, 0x41, 0x01, 0x00, 0x02,
+ 0x41, 0x01, 0x38, 0x02, 0x41, 0x01, 0x10, 0x02,
+ 0x40, 0xF0, 0xE0, 0x02, 0x40, 0x00, 0x00, 0x02,
+#ifdef USE_CHROMOSOME_BANDS_IN_ICON
+/* chromosome bands */
+ 0x40, 0x00, 0x00, 0x02, 0x4F, 0xEF, 0xFF, 0xF2,
+ 0x50, 0x10, 0xC4, 0xEA, 0x50, 0x10, 0xC4, 0xEA,
+ 0x50, 0x10, 0xC4, 0xEA, 0x50, 0x10, 0xC4, 0xEA,
+ 0x50, 0x10, 0xC4, 0xEA, 0x50, 0x10, 0xC4, 0xEA,
+ 0x50, 0x10, 0xC4, 0xEA, 0x4F, 0xEF, 0xFF, 0xF2,
+ 0x40, 0x00, 0x00, 0x02, 0x7F, 0xFF, 0xFF, 0xFE
+#else
+/* show alignment */
+ 0x40, 0x00, 0x00, 0x02, 0x4F, 0xFF, 0xFF, 0xF2,
+ 0x48, 0x00, 0x00, 0x12, 0x4F, 0xFF, 0xFF, 0xF2,
+ 0x40, 0x00, 0x00, 0x02, 0x40, 0xE0, 0xFF, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x4F, 0x0F, 0x80, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02,
+ 0x40, 0x00, 0x00, 0x02, 0x7F, 0xFF, 0xFF, 0xFE
+#endif
+};
+
+static Uint1 checkmark [] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x80, 0x01, 0x00, 0x22, 0x00, 0x14, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static Uint1Ptr iconLists [] = {
+ noabstract, hasabstract, proteinicon, proteinicon, dnaicon,
+ dnaicon, threedicon, threedicon, genomeicon, genomeicon
+};
+
+static ParData docsumParFmt = {TRUE, FALSE, FALSE, FALSE, FALSE, 0, 0};
+static ColData docsumColFmt [] = {
+ {0, 0, 15, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, FALSE}, /* caption */
+ {0, 5, 65, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, TRUE} /* term */
+};
+static ColData textColFmt [] = {
+ {0, 0, 80, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, TRUE} /* text */
+};
+
+static void SetDocSumImportExportItems (SummFormPtr sfp);
+
+static BioseqPtr BioseqLockByGi (Int4 uid)
+
+{
+ ValNode vn;
+
+ if (uid <= 0) return NULL;
+ vn.choice = SEQID_GI;
+ vn.data.intvalue = uid;
+ return BioseqLockById (&vn);
+}
+
+static Boolean BioseqUnlockByGi (Int4 uid)
+
+{
+ ValNode vn;
+
+ if (uid <= 0) return FALSE;
+ vn.choice = SEQID_GI;
+ vn.data.intvalue = uid;
+ return BioseqUnlockById (&vn);
+}
+
+static SeqEntryPtr SeqEntryLockByGi (Int4 uid)
+
+{
+ BioseqPtr bsp;
+ Uint2 entityID;
+ SeqEntryPtr sep;
+
+ bsp = BioseqLockByGi (uid);
+ if (bsp == NULL) return NULL;
+ entityID = ObjMgrGetEntityIDForPointer (bsp);
+ if (entityID == 0) return NULL;
+ sep = GetTopSeqEntryForEntityID (entityID);
+ return sep;
+}
+
+static Uint2 BioseqFindEntityByGi (Int4 uid, Uint2Ptr itemIDptr)
+
+{
+ ValNode vn;
+
+ if (uid <= 0) return 0;
+ vn.choice = SEQID_GI;
+ vn.data.intvalue = uid;
+ return BioseqFindEntity (&vn, itemIDptr);
+}
+
+static void DoDrawCheck (SummFormPtr sfp, RectPtr r, Int2 item, Int2 frst, Boolean docsum)
+
+{
+ Int2 checked;
+ RecT rct;
+
+ if (sfp == NULL || sfp->state == NULL) return;
+ if (item < 1) return;
+ if (item > sfp->numUids) return;
+ checked = sfp->state [item - 1].checked;
+ if (frst == 0) {
+ rct = *r;
+ rct.right = rct.left + sfp->lineHeight;
+ rct.bottom = rct.top + sfp->lineHeight;
+ if (RectInRgn (&rct, updateRgn)) {
+ FrameRect (&rct);
+ if (checked) {
+ MoveTo (rct.left, rct.top);
+ LineTo (rct.right - 1, rct.bottom - 1);
+ MoveTo (rct.left, rct.bottom - 1);
+ LineTo (rct.right - 1, rct.top);
+ }
+ }
+ if (item <= sfp->numParents) {
+ rct = *r;
+ if (docsum) {
+ rct.left += docsumColFmt [0].pixInset - 6;
+ rct.top += (sfp->lineHeight - 4) / 2;
+ rct.right = rct.left + 4;
+ rct.bottom = rct.top + 4;
+ } else {
+ rct.left += textColFmt [0].pixInset - 6;
+ rct.top += (sfp->lineHeight - 4) / 2;
+ rct.right = rct.left + 4;
+ rct.bottom = rct.top + 4;
+ }
+ if (RectInRgn (&rct, updateRgn)) {
+ PaintOval (&rct);
+ }
+ }
+ }
+}
+
+static void DrawUidCheck (SummFormPtr sfp, RectPtr r, Int2 item, Int2 frst, Boolean docsum)
+
+{
+ Int4 uid;
+
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return;
+ if (item < 1) return;
+ if (item > sfp->numUids) return;
+ uid = sfp->uids [item - 1];
+ if (uid < 1) return;
+ DoDrawCheck (sfp, r, item, frst, docsum);
+}
+
+static void DrawLocalCheck (SummFormPtr sfp, RectPtr r, Int2 item, Int2 frst, Boolean docsum)
+
+{
+ SimpleSeqPtr ssp;
+
+ if (sfp == NULL || sfp->simple == NULL || sfp->state == NULL) return;
+ if (item < 1) return;
+ if (item > sfp->numUids) return;
+ ssp = sfp->simple [item - 1];
+ if (ssp == NULL) return;
+ DoDrawCheck (sfp, r, item, frst, docsum);
+}
+
+static void DrawIcon (SummFormPtr sfp, RectPtr r, Int2 item, Int2 frst)
+
+{
+ Int2 db;
+ Int2 hasAbstract;
+ Uint1Ptr icon;
+ Int2 index;
+ RecT rct;
+ Int4 uid;
+
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return;
+ if (item < 1) return;
+ if (item > sfp->numUids) return;
+ db = sfp->currDb;
+ uid = sfp->uids [item - 1];
+ hasAbstract = sfp->state [item - 1].hasAbstract;
+ if (uid < 1) return;
+ if (frst < sfp->linesPerIcon) {
+ if (db >= 0 && db <= 4) {
+ index = db * 2;
+ if (hasAbstract) {
+ index++;
+ }
+ rct = *r;
+ /*
+ rct.left += sfp->lineHeight + 4;
+ */
+ rct.left += 3 * stdCharWidth - 8;
+ rct.right = rct.left + 32;
+ rct.bottom = MIN (rct.bottom, rct.top + 22 - frst * sfp->lineHeight);
+ if (RectInRgn (&rct, updateRgn)) {
+ icon = iconLists [index];
+ if (icon != NULL) {
+ CopyBits (&rct, icon + 4 * frst * sfp->lineHeight);
+ }
+ }
+ }
+ }
+}
+
+static void DrawDocSum (DoC d, RectPtr r, Int2 item, Int2 frst)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ DrawUidCheck (sfp, r, item, frst, TRUE);
+ DrawIcon (sfp, r, item, frst);
+}
+
+static void DrawTextSum (DoC d, RectPtr r, Int2 item, Int2 frst)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ DrawUidCheck (sfp, r, item, frst, FALSE);
+}
+
+static void DrawLocalSum (DoC d, RectPtr r, Int2 item, Int2 frst)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ DrawLocalCheck (sfp, r, item, frst, FALSE);
+}
+
+static CharPtr SetDefaultFailureMessage (SummFormPtr sfp, Int2 item, CharPtr prefix)
+
+{
+ Char buf [40];
+ CharPtr dbname = NULL;
+ SimpleSeqPtr ssp;
+ Char tmp [64];
+ Int4 uid;
+
+ tmp [0] = '\0';
+ if (prefix == NULL) {
+ prefix = "";
+ }
+ if (sfp == NULL) return StringSave ("?");
+ if (sfp->currDb >= 0 && sfp->currDb < MAX_DBS) {
+ dbname = GetEnumName ((UIEnum) sfp->currDb, sfp->dbalist);
+ }
+ if (dbname == NULL) {
+ dbname = "[?]";
+ }
+ if (item < 1) {
+ sprintf (tmp, "%sItem < 1 for database %s", prefix, dbname);
+ } else if (sfp->uids != NULL && sfp->simple == NULL) {
+ uid = sfp->uids [item - 1];
+ if (uid < 1) {
+ sprintf (tmp, "%sID < 1 for database %s", prefix, dbname);
+ } else {
+ sprintf (tmp, "%sFailure for ID %ld in %s database", prefix, (long) uid, dbname);
+ }
+ } else if (sfp->simple != NULL && sfp->uids == NULL) {
+ ssp = sfp->simple [item - 1];
+ if (ssp == NULL) {
+ sprintf ("%sIncorrect seq-entry for database %s", prefix, dbname);
+ } else {
+ StringCpy (buf, "?");
+ if (ssp->numid > 0 && ssp->bestid < ssp->numid) {
+ StringNCpy_0 (buf, ssp->id [ssp->bestid], sizeof (buf));
+ }
+ sprintf ("%sProblem with sequence %s in %s database", prefix, buf, dbname);
+ }
+ } else {
+ sprintf ("%sInternal confusion for database %s", prefix, dbname);
+ }
+ return StringSave (tmp);
+}
+
+static CharPtr FetchDocSum (DoC d, Int2 item, Pointer ptr)
+
+{
+ DocSumPtr dsp;
+ CharPtr failed;
+ Int2 j;
+ SummFormPtr sfp;
+ Char str [1024];
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, "\r\t");
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ dsp = EntrezDocSum (sfp->currDb, uid);
+ if (dsp == NULL) return failed;
+ if (dsp->caption == NULL && dsp->title == NULL && dsp->extra == NULL) {
+ DocSumFree (dsp);
+ return failed;
+ }
+ MemFree (failed);
+ str [0] = '\0';
+ if (dsp->caption != NULL) {
+ StringCat (str, dsp->caption);
+ }
+ j = 0;
+ while (str [j] != '\0' && str [j] != ',') {
+ j++;
+ }
+ if (str [j] == ',' && str [j + 1] == ' ') {
+ str [j + 1] = '\r';
+ }
+ StringCat (str, "\r");
+ StringCat (str, "\t");
+ if (dsp->title != NULL || dsp->extra != NULL) {
+ if (dsp->title != NULL) {
+ j = 0;
+ while (dsp->title [j] != '\0') {
+ if (dsp->title [j] == '\n' || dsp->title [j] == '\r') {
+ dsp->title [j] = ' ';
+ }
+ j++;
+ }
+ StringCat (str, dsp->title);
+ }
+ if (dsp->extra != NULL) {
+ StringCat (str, "\r");
+ j = 0;
+ while (dsp->extra [j] != '\0') {
+ if (dsp->extra [j] == '\n' || dsp->extra [j] == '\r') {
+ dsp->extra [j] = ' ';
+ }
+ j++;
+ }
+ StringCat (str, dsp->extra);
+ }
+ } else {
+ StringCat (str, "?");
+ }
+ StringCat (str, "\n");
+ sfp->state [item - 1].hasAbstract = (Boolean) (! dsp->no_abstract);
+ DocSumFree (dsp);
+ return StringSave (str);
+}
+
+static CharPtr FetchUid (DoC d, Int2 item, Pointer ptr)
+
+{
+ CharPtr failed;
+ SummFormPtr sfp;
+ Char str [64];
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ if (uid < 1) return failed;
+ MemFree (failed);
+ sprintf (str, "%ld\n", (long) uid);
+ return StringSave (str);
+}
+
+static CharPtr FileToString (CharPtr path)
+
+{
+ FILE *fp;
+ Int4 len;
+ CharPtr ptr;
+
+ if (path == NULL) return NULL;
+ ptr = NULL;
+ len = FileLength (path);
+ if (len > 0 && len < MAXALLOC /* && len < 32760 */) {
+ fp = FileOpen (path, "r");
+ if (fp != NULL) {
+ ptr = MemNew (sizeof (Char) * (size_t) (len + 4));
+ if (ptr != NULL) {
+ FileRead (ptr, 1, (size_t) len, fp);
+ ptr [len] = '\n';
+ ptr [len + 1] = '\0';
+ }
+ FileClose (fp);
+ }
+ }
+ return ptr;
+}
+
+static CharPtr FetchAbstract (DoC d, Int2 item, Pointer ptr)
+
+{
+ CharPtr failed;
+ FILE *fp;
+ MedlineEntryPtr mep;
+ Char path [PATH_MAX];
+ SummFormPtr sfp;
+ CharPtr str;
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ mep = EntrezMedlineEntryGet (uid);
+ if (mep == NULL) return failed;
+ str = NULL;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ if (MedlineEntryToAbsFile (mep, fp)) {
+ FileClose (fp);
+ str = FileToString (path);
+ } else {
+ FileClose (fp);
+ }
+ }
+ FileRemove (path);
+ MedlineEntryFree (mep);
+ if (str == NULL) return failed;
+ MemFree (failed);
+ return str;
+}
+
+static CharPtr FetchCitation (DoC d, Int2 item, Pointer ptr)
+
+{
+ CharPtr failed;
+ FILE *fp;
+ MedlineEntryPtr mep;
+ Char path [PATH_MAX];
+ SummFormPtr sfp;
+ CharPtr str;
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ mep = EntrezMedlineEntryGet (uid);
+ if (mep == NULL) return failed;
+ str = NULL;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ if (MedlineEntryToDocFile (mep, fp)) {
+ FileClose (fp);
+ str = FileToString (path);
+ } else {
+ FileClose (fp);
+ }
+ }
+ FileRemove (path);
+ MedlineEntryFree (mep);
+ if (str == NULL) return failed;
+ MemFree (failed);
+ return str;
+}
+
+static CharPtr FetchMedline (DoC d, Int2 item, Pointer ptr)
+
+{
+ CharPtr failed;
+ FILE *fp;
+ MedlineEntryPtr mep;
+ Char path [PATH_MAX];
+ SummFormPtr sfp;
+ CharPtr str;
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ mep = EntrezMedlineEntryGet (uid);
+ if (mep == NULL) return failed;
+ str = NULL;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ if (MedlineEntryToDataFile (mep, fp)) {
+ FileClose (fp);
+ str = FileToString (path);
+ } else {
+ FileClose (fp);
+ }
+ }
+ FileRemove (path);
+ MedlineEntryFree (mep);
+ if (str == NULL) return failed;
+ MemFree (failed);
+ return str;
+}
+
+static CharPtr FetchGenBank (DoC d, Int2 item, Pointer ptr)
+
+{
+ CharPtr failed;
+ FILE *fp;
+ Char path [PATH_MAX];
+ SeqEntryPtr sep;
+ SummFormPtr sfp;
+ CharPtr str;
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ /*
+ retcode = GetSequenceComplexity (sfp);
+ sep = EntrezSeqEntryGet (uid, retcode);
+ */
+ sep = SeqEntryLockByGi (uid);
+ if (sep == NULL) return failed;
+ str = NULL;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ if (SeqEntryToFlat (sep, fp, GENBANK_FMT, RELEASE_MODE)) {
+ FileClose (fp);
+ str = FileToString (path);
+ } else {
+ FileClose (fp);
+ }
+ }
+ FileRemove (path);
+ BioseqUnlockByGi (uid);
+ if (str == NULL) return failed;
+ MemFree (failed);
+ return str;
+}
+
+static CharPtr FetchEmbl (DoC d, Int2 item, Pointer ptr)
+
+{
+ CharPtr failed;
+ FILE *fp;
+ Char path [PATH_MAX];
+ SeqEntryPtr sep;
+ SummFormPtr sfp;
+ CharPtr str;
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ /*
+ retcode = GetSequenceComplexity (sfp);
+ sep = EntrezSeqEntryGet (uid, retcode);
+ */
+ sep = SeqEntryLockByGi (uid);
+ if (sep == NULL) return failed;
+ str = NULL;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ if (SeqEntryToFlat (sep, fp, EMBL_FMT, RELEASE_MODE)) {
+ FileClose (fp);
+ str = FileToString (path);
+ } else {
+ FileClose (fp);
+ }
+ }
+ FileRemove (path);
+ BioseqUnlockByGi (uid);
+ if (str == NULL) return failed;
+ MemFree (failed);
+ return str;
+}
+
+static CharPtr FetchGenPept (DoC d, Int2 item, Pointer ptr)
+
+{
+ CharPtr failed;
+ FILE *fp;
+ Char path [PATH_MAX];
+ SeqEntryPtr sep;
+ SummFormPtr sfp;
+ CharPtr str;
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ /*
+ retcode = GetSequenceComplexity (sfp);
+ sep = EntrezSeqEntryGet (uid, retcode);
+ */
+ sep = SeqEntryLockByGi (uid);
+ if (sep == NULL) return failed;
+ str = NULL;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ if (spop == NULL) {
+ spop = StdPrintOptionsNew (NULL);
+ if (spop != NULL) {
+ spop->newline = "\r";
+ spop->indent = "";
+ } else {
+ Message (MSG_ERROR, "StdPrintOptionsNew failed");
+ }
+ }
+ if (SeqEntryToFlat (sep, fp, GENPEPT_FMT, RELEASE_MODE)) {
+ FileClose (fp);
+ str = FileToString (path);
+ } else {
+ FileClose (fp);
+ }
+ }
+ FileRemove (path);
+ BioseqUnlockByGi (uid);
+ if (str == NULL) return failed;
+ MemFree (failed);
+ return str;
+}
+
+static CharPtr FetchFasta (DoC d, Int2 item, Pointer ptr, Boolean is_na)
+
+{
+ BioseqPtr bsp;
+ CharPtr failed;
+ FILE *fp;
+ Uint1 group_segs = 0;
+ Char path [PATH_MAX];
+ SeqEntryPtr sep;
+ SummFormPtr sfp;
+ CharPtr str;
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ /*
+ retcode = GetSequenceComplexity (sfp);
+ sep = EntrezSeqEntryGet (uid, retcode);
+ */
+ /*
+ sep = SeqEntryLockByGi (uid);
+ if (sep == NULL) return failed;
+ */
+ bsp = BioseqLockByGi (uid);
+ if (bsp == NULL) return failed;
+ sep = SeqMgrGetSeqEntryForData (bsp);
+ str = NULL;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ if (bsp->repr == Seq_repr_seg) {
+ group_segs = 1;
+ } else if (bsp->repr == Seq_repr_delta) {
+ group_segs = 3;
+ }
+ if (SeqEntrysToFasta (sep, fp, is_na, group_segs)) {
+ FileClose (fp);
+ str = FileToString (path);
+ } else {
+ FileClose (fp);
+ }
+ }
+ FileRemove (path);
+ BioseqUnlockByGi (uid);
+ if (str == NULL) return failed;
+ MemFree (failed);
+ return str;
+}
+
+static CharPtr FetchFastaNuc (DoC d, Int2 item, Pointer ptr)
+
+{
+ return FetchFasta (d, item, ptr, TRUE);
+}
+
+static CharPtr FetchFastaProt (DoC d, Int2 item, Pointer ptr)
+
+{
+ return FetchFasta (d, item, ptr, FALSE);
+}
+
+static CharPtr FetchPDB (DoC d, Int2 item, Pointer ptr)
+
+{
+ BiostrucPtr bsp;
+ Int4 complexity;
+ CharPtr failed;
+ FILE *fp;
+ Int2 maxModels;
+ Char path [PATH_MAX];
+ PDNMS pdnms;
+ SummFormPtr sfp;
+ CharPtr str;
+ Int4 uid;
+
+ if (! BiostrucAvail ()) {
+ return StringSave ("Structure libraries are not linked in.");
+ }
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->uids == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ uid = sfp->uids [item - 1];
+ /* complexity = GetBiostrucComplexity (sfp); */
+ complexity = VECMODEL;
+ /* maxModels = GetBiostrucMaxModels (sfp); */
+ maxModels = 1;
+ bsp = EntrezBiostrucGet (uid, complexity, maxModels);
+ if (bsp == NULL) return failed;
+ pdnms = MakeAModelstruc (bsp);
+ if (pdnms == NULL) return failed;
+ str = NULL;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ WriteStructSummary (pdnms, fp);
+ fprintf (fp, "\n\n\n");
+ WritePDBRemarks (pdnms, fp);
+ FileClose (fp);
+ str = FileToString (path);
+ }
+ FileRemove (path);
+ FreeAModelstruc (pdnms);
+ if (str == NULL) return failed;
+ MemFree (failed);
+ return str;
+}
+
+static CharPtr FetchLocalBioseq (DoC d, Int2 item, Pointer ptr)
+
+{
+ CharPtr failed;
+ FILE *fp;
+ Char path [PATH_MAX];
+ SummFormPtr sfp;
+ SimpleSeqPtr ssp;
+ CharPtr str;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ failed = SetDefaultFailureMessage (sfp, item, NULL);
+ if (sfp == NULL || sfp->simple == NULL || sfp->state == NULL) return failed;
+ if (item < 1) return failed;
+ ssp = sfp->simple [item - 1];
+ if (ssp == NULL) return failed;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ if (SimpleSeqPrint (ssp, fp, TRUE)) {
+ FileClose (fp);
+ str = FileToString (path);
+ } else {
+ FileClose (fp);
+ }
+ }
+ FileRemove (path);
+ if (str == NULL) return failed;
+ MemFree (failed);
+ return str;
+}
+
+static DocPrntProc mlDocProcs [] = {FetchDocSum, FetchAbstract, FetchCitation, FetchMedline, FetchUid, NULL};
+static DocPrntProc aaDocProcs [] = {FetchDocSum, FetchGenPept, FetchFastaProt, FetchUid, NULL};
+static DocPrntProc ntDocProcs [] = {FetchDocSum, FetchGenBank, FetchEmbl, FetchFastaNuc, FetchUid, NULL};
+static DocPrntProc stDocProcs [] = {FetchDocSum, FetchPDB, FetchUid, NULL};
+static DocPrntProc chDocProcs [] = {FetchDocSum, FetchUid, NULL};
+
+static void RepopulateDocSum (SummFormPtr sfp, Boolean needToReset)
+
+{
+ ColPtr colFmt;
+ DocDrawProc ddp;
+ Int2 estLines;
+ Int2 firstLine;
+ Int2 firstShown;
+ FonT font;
+ MedlineViewProcsPtr mvpp;
+ DocPrntProc proc;
+ BaR sb;
+ Int4 startsAt;
+ SeqViewProcsPtr svpp;
+ Int2 typ_aa;
+ Int2 typ_ch;
+ Int2 typ_ml;
+ Int2 typ_nt;
+ Int2 typ_st;
+ Int2 val;
+
+ if (sfp == NULL) return;
+ WatchCursor ();
+ SafeHide (sfp->docsum);
+ Update ();
+ if (! GetScrlParams4 (sfp->docsum, NULL, &firstShown, &firstLine)) {
+ firstShown = 0;
+ firstLine = 0;
+ }
+ sb = GetSlateVScrollBar ((SlatE) sfp->docsum);
+ if (needToReset) {
+ Reset (sfp->docsum);
+ SetDocShade (sfp->docsum, NULL, NULL, NULL, NULL);
+ SetDocCache (sfp->docsum, NULL, NULL, NULL);
+ }
+ /*
+ for (i = 0; i < num; i++) {
+ sprintf (str, "Item %d UID %ld\n", (int) (i + 1), (long) uids [i]);
+ AppendText (sfp->docsum, str, &docsumParFmt, docsumColFmt, programFont);
+ }
+ */
+ typ_ml = DatabaseFromName ("MEDLINE");
+ typ_aa = DatabaseFromName ("Protein");
+ typ_nt = DatabaseFromName ("Nucleotide");
+ typ_st = DatabaseFromName ("Structure");
+ typ_ch = DatabaseFromName ("Genome");
+ proc = FetchDocSum;
+ ddp = DrawDocSum;
+ colFmt = docsumColFmt;
+ estLines = 3;
+ font = sfp->docsumFont;
+ if (sfp->simple != NULL) {
+ proc = FetchLocalBioseq;
+ ddp = DrawLocalSum;
+ colFmt = textColFmt;
+ svpp = (SeqViewProcsPtr) GetAppProperty ("SeqDisplayForm");
+ if (svpp != NULL && svpp->displayFont != NULL) {
+ font = svpp->displayFont;
+ }
+ } else if (sfp->currDb >= 0 && sfp->currDb < MAX_DBS) {
+ val = GetValue (sfp->formats [sfp->currDb]);
+ if (val > 0) {
+ if (val > 1) {
+ ddp = DrawTextSum;
+ colFmt = textColFmt;
+ estLines = 30;
+ if (sfp->currDb == typ_ml && val == 4) {
+ mvpp = (MedlineViewProcsPtr) GetAppProperty ("MedlineDisplayForm");
+ if (mvpp != NULL && mvpp->displayFont != NULL) {
+ font = mvpp->displayFont;
+ }
+ } else if (sfp->currDb == typ_aa || sfp->currDb == typ_nt) {
+ svpp = (SeqViewProcsPtr) GetAppProperty ("SeqDisplayForm");
+ if (svpp != NULL && svpp->displayFont != NULL) {
+ font = svpp->displayFont;
+ }
+ }
+ }
+ if (sfp->currDb == typ_ml) {
+ proc = mlDocProcs [val - 1];
+ } else if (sfp->currDb == typ_aa) {
+ proc = aaDocProcs [val - 1];
+ } else if (sfp->currDb == typ_nt) {
+ proc = ntDocProcs [val - 1];
+ } else if (sfp->currDb == typ_st) {
+ proc = stDocProcs [val - 1];
+ } else if (sfp->currDb == typ_ch) {
+ proc = chDocProcs [val - 1];
+ }
+ }
+ }
+ BulkAppendItem (sfp->docsum, sfp->numUids, proc, estLines,
+ &docsumParFmt, colFmt, font);
+ SetDocShade (sfp->docsum, ddp, NULL, NULL, NULL);
+ SetDocCache (sfp->docsum, StdPutDocCache, StdGetDocCache, StdResetDocCache);
+ /*
+ InvalDocument (sfp->docsum);
+ Update ();
+ */
+ AdjustDocScroll (sfp->docsum);
+ GetItemParams4 (sfp->docsum, firstShown, &startsAt, NULL, NULL, NULL, NULL);
+ CorrectBarValue (sb, startsAt + firstLine);
+ ResetClip ();
+ SafeShow (sfp->docsum);
+ ArrowCursor ();
+ Update ();
+}
+
+static void SetPrevAndNextButtons (SummFormPtr sfp)
+
+{
+ if (sfp->present > 1) {
+ SafeEnable (sfp->prevBtn);
+ } else {
+ SafeDisable (sfp->prevBtn);
+ }
+ if (sfp->present < sfp->generations) {
+ SafeEnable (sfp->nextBtn);
+ } else {
+ SafeDisable (sfp->nextBtn);
+ }
+}
+
+static void RetrieveGeneration (SummFormPtr sfp, Int2 num, Int2 parents, Int4Ptr uids, Int2 db)
+
+{
+ Int2 i;
+ Char title [32];
+
+ if (sfp == NULL || uids == NULL) return;
+ Reset (sfp->docsum);
+ SetDocShade (sfp->docsum, NULL, NULL, NULL, NULL);
+ SetDocCache (sfp->docsum, NULL, NULL, NULL);
+ sfp->uids = MemFree (sfp->uids);
+ if (sfp->simple != NULL) {
+ for (i = 0; i < sfp->numUids; i++) {
+ SimpleSeqFree (sfp->simple [i]);
+ }
+ sfp->simple = MemFree (sfp->simple);
+ }
+ sfp->state = MemFree (sfp->state);
+ sfp->numUids = 0;
+ sfp->numParents = 0;
+ sfp->neighbors = MemFree (sfp->neighbors);
+ sfp->numNeighbors = 0;
+ SafeSetTitle (sfp->retrieve, "Neighbor 0");
+ SafeDisable (sfp->retrieve);
+ sprintf (title, "Refine %d", (int) num);
+ SafeSetTitle (sfp->refine, title);
+ if (num > 0) {
+ SafeEnable (sfp->refine);
+ } else {
+ SafeDisable (sfp->refine);
+ }
+ SetEnumPopup (sfp->target, sfp->dbalist, (UIEnum) db);
+ SafeShow (sfp->target);
+ SetPrevAndNextButtons (sfp);
+ Update ();
+ Hide (sfp->formats [MAX_DBS]);
+ for (i = 0; i < MAX_DBS; i++) {
+ if (i != db) {
+ Hide (sfp->formats [i]);
+ }
+ }
+ if (db < MAX_DBS) {
+ Show (sfp->formats [db]);
+ }
+ if (num > 0) {
+ sfp->uids = MemDup ((Pointer) uids, (size_t) (num * sizeof(DocUid)));
+ if (sfp->uids == NULL) return;
+ sfp->state = MemNew (sizeof (StateData) * (size_t) num);
+ if (sfp->state == NULL) return;
+ sfp->numUids = num;
+ sfp->numParents = parents;
+ sfp->currDb = db;
+ Show (sfp->form);
+ Select (sfp->form);
+ RepopulateDocSum (sfp, FALSE);
+ SetDocSumImportExportItems (sfp);
+ SendMessageToForm (sfp->form, VIB_MSG_CHANGE);
+#ifdef WIN_MAC
+ if (sfp->activate != NULL) {
+ sfp->activate ((WindoW) sfp->form);
+ }
+#endif
+ } else {
+ Show (sfp->form);
+ Select (sfp->form);
+#ifdef WIN_MAC
+ if (sfp->activate != NULL) {
+ sfp->activate ((WindoW) sfp->form);
+ }
+#endif
+ }
+ Update ();
+}
+
+extern void RetrieveDocuments (ForM f, Int2 num, Int2 parents, Int4Ptr uids, Int2 db)
+
+{
+ FILE *fp;
+ Char path [PATH_MAX];
+ SummFormPtr sfp;
+ Int2 val;
+
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp == NULL) return;
+ (sfp->generations)++;
+ sfp->present = sfp->generations;
+ if (sfp->historyFile == NULL) {
+ TmpNam (path);
+ sfp->historyFile = StringSave (path);
+#ifdef WIN_MAC
+ if (sfp->historyFile != NULL) {
+ FileCreate (sfp->historyFile, "????", "ENTZ");
+ }
+#endif
+ }
+ if (sfp->historyOffsets == NULL) {
+ sfp->historyOffsets = MemNew (100 * sizeof (Int4));
+ }
+ if (sfp->historyFile != NULL && sfp->historyOffsets != NULL) {
+ fp = FileOpen (sfp->historyFile, "ab");
+ if (fp != NULL) {
+ fseek (fp, 0, SEEK_END);
+ sfp->historyOffsets [(sfp->present) % 100] = ftell (fp);
+ val = db;
+ FileWrite (&val, sizeof (val), 1, fp);
+ val = num;
+ FileWrite (&val, sizeof (val), 1, fp);
+ val = parents;
+ FileWrite (&val, sizeof (val), 1, fp);
+ FileWrite (uids, sizeof (Int4), (size_t) num, fp);
+ FileClose (fp);
+ } else {
+ sfp->historyOffsets [sfp->present % 100] = 0;
+ }
+ }
+ RetrieveGeneration (sfp, num, parents, uids, db);
+}
+
+static void StripNewLine (CharPtr str)
+
+{
+ CharPtr chptr;
+
+ if (StringHasNoText (str)) return;
+ chptr = StringRChr (str, '\n');
+ if (chptr != NULL) {
+ *chptr = '\0';
+ }
+ chptr = StringRChr (str, '\r');
+ if (chptr != NULL) {
+ *chptr = '\0';
+ }
+}
+
+extern void DSLoadUidListProc (IteM i)
+
+{
+ ByteStorePtr bsp;
+ Int2 db = -1;
+ FILE *fp;
+ Int2 num;
+ Char path [PATH_MAX];
+ SummFormPtr sfp;
+ Char str [32];
+ Int4 uid;
+ Int4Ptr uids;
+
+
+#ifdef WIN_MAC
+ sfp = (SummFormPtr) currentFormDataPtr;
+#else
+ sfp = (SummFormPtr) GetObjectExtra (i);
+#endif
+ if (sfp == NULL) return;
+ if (! GetInputFileName (path, sizeof (path), "", "TEXT")) return;
+ fp = FileOpen (path, "r");
+ if (fp == NULL) return;
+ bsp = BSNew (128);
+ if (bsp == NULL) {
+ FileClose (fp);
+ return;
+ }
+ if (FileGets (str, sizeof (str), fp)) {
+ StripNewLine (str);
+ if (StringStr (str, ">PubMed")) {
+ db = 0;
+ } else if (StringStr (str, ">Protein")) {
+ db = 1;
+ } else if (StringStr (str, ">Nucleotide")) {
+ db = 2;
+ } else if (StringStr (str, ">Structure")) {
+ db = 3;
+ } else if (StringStr (str, ">Genome")) {
+ db = 4;
+ }
+ if (db != -1) {
+ while (FileGets (str, sizeof (str), fp)) {
+ StripNewLine (str);
+ if (str [0] != '\0' && StrToLong (str, &uid)) {
+ BSWrite (bsp, &uid, sizeof (DocUid));
+ }
+ }
+ BSSeek (bsp, 0L, 0);
+ num = (Int2) ((BSLen (bsp)) / sizeof (Int4));
+ uids = (Int4Ptr) BSMerge (bsp, NULL);
+ if (uids != NULL) {
+ RetrieveDocuments (sfp->form, num, 0, uids, db);
+ }
+ MemFree (uids);
+ } else {
+ Message (MSG_POSTERR,
+ "First line must be >PubMed, >Protein, >Nucleotide, >Structure, or >Genome");
+ }
+ }
+ BSFree (bsp);
+ FileClose (fp);
+}
+
+extern void DSSaveUidListProc (IteM i)
+
+{
+ FILE *fp;
+ Int2 j;
+ Char path [PATH_MAX];
+ SummFormPtr sfp;
+ Char str [32];
+
+
+#ifdef WIN_MAC
+ sfp = (SummFormPtr) currentFormDataPtr;
+#else
+ sfp = (SummFormPtr) GetObjectExtra (i);
+#endif
+ if (sfp == NULL || sfp->uids == NULL) return;
+ if (! GetOutputFileName (path, sizeof (path), NULL)) return;
+#ifdef WIN_MAC
+ FileCreate (path, "TEXT", "ttxt");
+#endif
+ fp = FileOpen (path, "w");
+ if (fp == NULL) return;
+ WatchCursor ();
+ switch (sfp->currDb) {
+ case 0 :
+ StringCpy (str, ">PubMed\n");
+ break;
+ case 1 :
+ StringCpy (str, ">Protein\n");
+ break;
+ case 2 :
+ StringCpy (str, ">Nucleotide\n");
+ break;
+ case 3 :
+ StringCpy (str, ">Structure\n");
+ break;
+ case 4 :
+ StringCpy (str, ">Genome\n");
+ break;
+ default :
+ StringCpy (str, ">?\n");
+ break;
+ }
+ FilePuts (str, fp);
+ for (j = 0; j < sfp->numUids; j++) {
+ sprintf (str, "%ld\n", (long) (sfp->uids [j]));
+ FilePuts (str, fp);
+ }
+ FileClose (fp);
+ ArrowCursor ();
+}
+
+static void LoadPresentGeneration (SummFormPtr sfp)
+
+{
+ Int2 db;
+ FILE *fp;
+ Int2 num;
+ Int2 parents;
+ Int4Ptr uids;
+
+ if (sfp == NULL) return;
+ WatchCursor ();
+ if (sfp->historyFile != NULL && sfp->historyOffsets != NULL) {
+ fp = FileOpen (sfp->historyFile, "rb");
+ if (fp != NULL) {
+ fseek (fp, sfp->historyOffsets [(sfp->present) % 100], SEEK_SET);
+ FileRead (&db, sizeof (db), 1, fp);
+ FileRead (&num, sizeof (num), 1, fp);
+ FileRead (&parents, sizeof (parents), 1, fp);
+ uids = (Int4Ptr) MemNew ((size_t) num * sizeof (Int4) + 4);
+ if (uids != NULL) {
+ FileRead (uids, sizeof (Int4), (size_t) num, fp);
+ }
+ FileClose (fp);
+ if (uids != NULL) {
+ RetrieveGeneration (sfp, num, parents, uids, db);
+ MemFree (uids);
+ }
+ }
+ }
+ ArrowCursor ();
+}
+
+static void PrevProc (ButtoN b)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (b);
+ if (sfp == NULL) return;
+ (sfp->present)--;
+ if (sfp->present < 1) {
+ sfp->present = 1;
+ }
+ SetPrevAndNextButtons (sfp);
+ LoadPresentGeneration (sfp);
+ SetDocSumImportExportItems (sfp);
+}
+
+static void NextProc (ButtoN b)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (b);
+ if (sfp == NULL) return;
+ (sfp->present)++;
+ if (sfp->present > sfp->generations) {
+ sfp->present = sfp->generations;
+ }
+ SetPrevAndNextButtons (sfp);
+ LoadPresentGeneration (sfp);
+ SetDocSumImportExportItems (sfp);
+}
+
+extern Boolean UsingDelayedNeighbor (ForM f)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp == NULL) return FALSE;
+ return sfp->usingDelay;
+}
+
+extern void UseDelayedNeighbor (ForM f, Boolean delayMode)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp == NULL) return;
+ sfp->usingDelay = delayMode;
+}
+
+static void NeighborDelayProc (ChoicE c)
+
+{
+ SummFormPtr sfp;
+
+#ifdef WIN_MAC
+ sfp = (SummFormPtr) currentFormDataPtr;
+#else
+ sfp = (SummFormPtr) GetObjectExtra (c);
+#endif
+ if (sfp == NULL) return;
+ if (GetValue (c) == 1) {
+ sfp->usingDelay = FALSE;
+ } else {
+ sfp->usingDelay = TRUE;
+ }
+}
+
+extern ChoicE CreateNeighborDelayChoice (MenU m, BaseFormPtr bfp)
+
+{
+ ChoicE c;
+
+ c = ChoiceGroup (m, NeighborDelayProc);
+ SetObjectExtra (c, bfp, NULL);
+ ChoiceItem (c, "Immediate");
+ ChoiceItem (c, "Delayed");
+ SetValue (c, 1);
+ return c;
+}
+
+static void RecalculateDocSum (SummFormPtr sfp)
+
+{
+ Int2 i;
+ LinkSetPtr lsp;
+ Int2 num;
+ Int2 targetDb;
+ Char title [32];
+ Int4Ptr uids;
+ UIEnum val;
+
+ if (sfp == NULL) return;
+ if (GetEnumPopup (sfp->target, sfp->dbalist, &val)) {
+ targetDb = (Int2) val;
+ } else {
+ targetDb = sfp->currDb;
+ }
+ if (sfp->uids == NULL || sfp->state == NULL) {
+ if (targetDb == sfp->currDb) {
+ SafeSetTitle (sfp->retrieve, "Neighbor 0");
+ } else {
+ SafeSetTitle (sfp->retrieve, "Lookup 0");
+ }
+ SafeDisable (sfp->retrieve);
+ return;
+ }
+ sfp->neighbors = MemFree (sfp->neighbors);
+ sfp->numNeighbors = 0;
+ sfp->neighborDb = targetDb;
+
+ uids = NULL;
+ num = 0;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ num++;
+ }
+ }
+
+ if (sfp->retrieveMode == EVAL_MODE && sfp->usingDelay) {
+ if (num == 0) {
+ if (targetDb == sfp->currDb) {
+ SafeSetTitle (sfp->retrieve, "Neighbor 0");
+ } else {
+ SafeSetTitle (sfp->retrieve, "Lookup 0");
+ }
+ SafeDisable (sfp->retrieve);
+ } else {
+ SafeSetTitle (sfp->retrieve, "Evaluate");
+ SafeEnable (sfp->retrieve);
+ }
+ if (num == 0) {
+ num = sfp->numUids;
+ }
+ sprintf (title, "Refine %d", (int) num);
+ SafeSetTitle (sfp->refine, title);
+ if (num > 0) {
+ SafeEnable (sfp->refine);
+ } else {
+ SafeDisable (sfp->refine);
+ }
+ return;
+ }
+
+ if (num > 0) {
+ uids = MemNew ((size_t) (num + 1) * sizeof (DocUid));
+ if (uids != NULL) {
+ num = 0;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ uids [num] = sfp->uids [i];
+ num++;
+ }
+ }
+ lsp = NULL;
+ EntrezLinkUidList (&lsp, sfp->currDb, targetDb,
+ num, uids, FALSE);
+ if (lsp != NULL) {
+ sfp->numNeighbors = (Int2) lsp->num;
+ sfp->neighbors = lsp->uids;
+ lsp->uids = NULL;
+ lsp->weights = MemFree (lsp->weights);
+ LinkSetFree (lsp);
+ }
+ }
+ }
+ if (targetDb == sfp->currDb) {
+ sprintf (title, "Neighbor %d", (int) sfp->numNeighbors);
+ } else {
+ sprintf (title, "Lookup %d", (int) sfp->numNeighbors);
+ }
+ SafeSetTitle (sfp->retrieve, title);
+ if (sfp->numNeighbors > 0) {
+ SafeEnable (sfp->retrieve);
+ } else {
+ SafeDisable (sfp->retrieve);
+ }
+ if (num == 0) {
+ num = sfp->numUids;
+ }
+ sprintf (title, "Refine %d", (int) num);
+ SafeSetTitle (sfp->refine, title);
+ if (num > 0) {
+ SafeEnable (sfp->refine);
+ } else {
+ SafeDisable (sfp->refine);
+ }
+ MemFree (uids);
+}
+
+static void ChangeTarget (PopuP p)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (p);
+ if (sfp == NULL) return;
+ sfp->retrieveMode = EVAL_MODE;
+ RecalculateDocSum (sfp);
+}
+
+static Boolean UidInList (Int4 uid, Int4Ptr sorted, Int2 num)
+
+{
+ Boolean found;
+ Int2 left;
+ Int2 mid;
+ Int2 right;
+
+ found = FALSE;
+ if (sorted != NULL && num > 0) {
+ mid = 0;
+ left = 0;
+ right = num - 1;
+ while (left <= right) {
+ mid = (left + right) / 2;
+ if (uid <= sorted [mid]) {
+ right = mid - 1;
+ }
+ if (uid >= sorted [mid]) {
+ left = mid + 1;
+ }
+ }
+ if (left > right + 1) {
+ found = TRUE;
+ }
+ }
+ return found;
+}
+
+static void RetrieveNeighbors (ButtoN b)
+
+{
+ EntrezGlobalsPtr egp;
+ Int2 i, j;
+ Int2 num;
+ Int2 parents;
+ Boolean persist;
+ SummFormPtr sfp;
+ Int4Ptr sorted;
+ Int4 tmp;
+ Int4Ptr uids;
+
+ sfp = (SummFormPtr) GetObjectExtra (b);
+ if (sfp == NULL) return;
+ if (sfp->retrieveMode == EVAL_MODE && sfp->usingDelay) {
+ WatchCursor ();
+ Update ();
+ sfp->retrieveMode = FETCH_MODE;
+ RecalculateDocSum (sfp);
+ ArrowCursor ();
+ Update ();
+ return;
+ }
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL || egp->retrieveDocsProc == NULL) return;
+ persist = FALSE;
+ if (sfp->currDb == sfp->neighborDb) {
+ persist = GetStatus (egp->parentsPersist);
+ }
+ parents = 0;
+ if (persist) {
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ parents++;
+ }
+ }
+ }
+ uids = NULL;
+ sorted = NULL;
+ num = parents + sfp->numNeighbors;
+ if (num > 0) {
+ uids = MemNew ((size_t) (num + 1) * sizeof (DocUid));
+ sorted = MemNew ((size_t) (parents + 1) * sizeof (DocUid));
+ if (uids != NULL && sorted != NULL) {
+ num = 0;
+ if (persist && sfp->uids != NULL) {
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ uids [num] = sfp->uids [i];
+ sorted [num] = sfp->uids [i];
+ num++;
+ }
+ }
+ for (i = 1; i < parents; i++) {
+ for (j = 0; j < i; j++) {
+ if (sorted [j] > sorted [i]) {
+ tmp = sorted [i];
+ sorted [i] = sorted [j];
+ sorted [j] = tmp;
+ }
+ }
+ }
+ }
+ if (sfp->neighbors != NULL) {
+ for (i = 0; i < sfp->numNeighbors; i++) {
+ if (! UidInList (sfp->neighbors [i], sorted, parents)) {
+ uids [num] = sfp->neighbors [i];
+ num++;
+ }
+ }
+ }
+ }
+ }
+ sfp->neighbors = NULL;
+ sfp->numNeighbors = 0;
+ egp->retrieveDocsProc (sfp->form, num, parents, uids, sfp->neighborDb);
+ MemFree (uids);
+ MemFree (sorted);
+}
+
+static int refinement = 0; /* guarantees that each refinement has a unique name */
+
+static void RefineProc (ButtoN b)
+
+{
+ EntrezGlobalsPtr egp;
+ Int2 i;
+ Int2 num;
+ SummFormPtr sfp;
+ Char str [64];
+ Int4Ptr uids;
+
+ sfp = (SummFormPtr) GetObjectExtra (b);
+ if (sfp == NULL) return;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL || egp->loadNamedUidProc == NULL) return;
+ num = 0;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ num++;
+ }
+ }
+ refinement++;
+ sprintf (str, "*generation_%d_refinement_%d", (int) sfp->present, (int) refinement);
+ if (num > 0) {
+ uids = MemNew ((size_t) (num + 1) * sizeof (DocUid));
+ if (uids != NULL) {
+ num = 0;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ uids [num] = sfp->uids [i];
+ num++;
+ }
+ }
+ egp->loadNamedUidProc (sfp->form, str, num, uids, sfp->currDb);
+ }
+ MemFree (uids);
+ } else {
+ egp->loadNamedUidProc (sfp->form, str, sfp->numUids, sfp->uids, sfp->currDb);
+ }
+}
+
+static void CopyDocsumToClipboard (BaseFormPtr bfp)
+
+{
+ FILE *fp;
+ Int2 i;
+ Boolean newline;
+ Int2 num;
+ Char path [PATH_MAX];
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) bfp;
+ if (sfp == NULL) return;
+ TmpNam (path);
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ num = 0;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ num++;
+ }
+ }
+ if (num == 0) {
+ SaveDocument (sfp->docsum, fp);
+ } else {
+ newline = FALSE;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ if (newline) {
+ fputc ('\n', fp);
+ }
+ SaveDocumentItem (sfp->docsum, fp, i + 1);
+ newline = TRUE;
+ }
+ }
+ }
+ FileClose (fp);
+ FileToClipboard (path);
+ }
+ FileRemove (path);
+}
+
+static void ClickDocSum (DoC d, PoinT pt)
+
+{
+ Int2 col;
+ Int2 item;
+ Int2 row;
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ if (sfp == NULL) return;
+ MapDocPoint (d, pt, &item, &row, &col, NULL);
+ sfp->dsClickItem = item;
+ sfp->dsClickRow = row;
+ sfp->dsClickCol = col;
+ sfp->wasDoubleClick = dblClick;
+}
+
+static Int4Ptr GetCheckedUids (SummFormPtr sfp, Int2Ptr nump)
+
+{
+ Int2 i;
+ Int2 num;
+ Int4Ptr uids;
+
+ if (sfp == NULL || nump == NULL) return NULL;
+ uids = NULL;
+ num = 0;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ num++;
+ }
+ }
+ if (num > 0) {
+ uids = MemNew ((size_t) (num + 1) * sizeof (DocUid));
+ if (uids != NULL) {
+ num = 0;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ uids [num] = sfp->uids [i];
+ num++;
+ }
+ }
+ }
+ }
+ if (nump != NULL) {
+ *nump = num;
+ }
+ return uids;
+}
+
+static void ReleaseDocSum (DoC d, PoinT pt)
+
+{
+ Int2 checked;
+ Int2 col;
+ Int2 db;
+ EntrezGlobalsPtr egp;
+ Int2 item;
+ Int2 num;
+ RecT r;
+ Int2 row;
+ SummFormPtr sfp;
+ Int4 uid;
+ Int4Ptr uids;
+
+ sfp = (SummFormPtr) GetObjectExtra (d);
+ if (sfp == NULL) return;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL || egp->launchViewerProc == NULL) return;
+ MapDocPoint (d, pt, &item, &row, &col, &r);
+ if (item < 1 || item > sfp->numUids || row == 0 || col == 0) return;
+ if (sfp->dsClickItem != item) return;
+ if (row == 1 && col == 1 &&
+ sfp->dsClickRow == 1 && sfp->dsClickCol == 1) {
+ r.right = r.left + sfp->lineHeight;
+ r.bottom = r.top + sfp->lineHeight;
+ if (PtInRect (pt, &r)) {
+ checked = sfp->state [item - 1].checked;
+ sfp->state [item - 1].checked = (Boolean) (! checked);
+ ObjectRect (d, &r);
+ InsetRect (&r, 4, 4);
+ r.right = r.left + sfp->lineHeight;
+ InsetRect (&r, -1, -1);
+ InvalRect (&r);
+ ResetClip ();
+ WatchCursor ();
+ Update ();
+ sfp->retrieveMode = EVAL_MODE;
+ RecalculateDocSum (sfp);
+ ArrowCursor ();
+ Update ();
+ return;
+ }
+ }
+ if (sfp->wasDoubleClick && sfp->uids != NULL && sfp->simple == NULL) {
+ db = sfp->currDb;
+ uid = sfp->uids [item - 1];
+ uids = GetCheckedUids (sfp, &num);
+ egp->launchViewerProc (sfp->form, uid, num, uids, db);
+ MemFree (uids);
+ }
+}
+
+static void RefreshAndRecalculateDocSum (SummFormPtr sfp)
+
+{
+ RecT r;
+
+ if (sfp == NULL) return;
+ Select (sfp->docsum);
+ ObjectRect (sfp->docsum, &r);
+ InsetRect (&r, 4, 4);
+ r.right = r.left + sfp->lineHeight;
+ InsetRect (&r, -1, -1);
+ InvalRect (&r);
+ ResetClip ();
+ WatchCursor ();
+ Update ();
+ sfp->retrieveMode = EVAL_MODE;
+ RecalculateDocSum (sfp);
+ ArrowCursor ();
+ Update ();
+}
+
+static void SelectAllProc (ButtoN b)
+
+{
+ Int2 i;
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (b);
+ if (sfp == NULL) return;
+ for (i = 0; i < sfp->numUids; i++) {
+ sfp->state [i].checked = TRUE;
+ }
+ RefreshAndRecalculateDocSum (sfp);
+}
+
+static void SelectParentsProc (ButtoN b)
+
+{
+ Int2 i;
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (b);
+ if (sfp == NULL) return;
+ for (i = 0; i < sfp->numUids; i++) {
+ sfp->state [i].checked = (Boolean) (i < sfp->numParents);
+ }
+ RefreshAndRecalculateDocSum (sfp);
+}
+
+static void ClearAllProc (ButtoN b)
+
+{
+ Int2 i;
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (b);
+ if (sfp == NULL) return;
+ for (i = 0; i < sfp->numUids; i++) {
+ sfp->state [i].checked = FALSE;
+ }
+ RefreshAndRecalculateDocSum (sfp);
+}
+
+static void ChangeFormat (GrouP g)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (g);
+ if (sfp == NULL) return;
+ RepopulateDocSum (sfp, TRUE);
+ SetDocSumImportExportItems (sfp);
+}
+
+static CharPtr medRadios [] = {"Summary", "Abstract", "Citation", "MEDLINE", "PubMed ID", NULL};
+
+static CharPtr prtRadios [] = {"Summary", "GenPept", "FASTA", "Protein ID", NULL};
+
+static CharPtr nucRadios [] = {"Summary", "GenBank", "EMBL", "FASTA", "Nucleotide ID", NULL};
+
+static CharPtr strucRadios [] = {"Summary", "Report", "Structure ID", NULL};
+
+static CharPtr genRadios [] = {"Summary", "Genome ID", NULL};
+
+static CharPtr localBioseqRadios [] = {"FASTA", NULL};
+
+static CharPtr PNTR radioLabels [] = {
+ medRadios, prtRadios, nucRadios, strucRadios, genRadios, NULL
+};
+
+static void ProcessProjectAsn (ProjectPtr proj)
+
+{
+ Int2 db = -1;
+ EntrezGlobalsPtr egp;
+ Int4 i;
+ ValNodePtr list;
+ Int4 num;
+ ValNodePtr pip;
+ Int4Ptr uids;
+ ValNodePtr vnp;
+
+ if (proj == NULL) return;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL) return;
+ pip = proj->data;
+ if (pip == NULL) return;
+ list = (ValNodePtr) pip->data.ptrvalue;
+ if (list == NULL) return;
+ if (pip->choice >= ProjectItem_protent && pip->choice <= ProjectItem_genomeent) {
+ if (egp->retrieveProjectProc == NULL) return;
+ egp->retrieveProjectProc (NULL, (Pointer) proj);
+ Update ();
+ return;
+ }
+ if (egp->retrieveDocsProc == NULL) return;
+ switch (pip->choice) {
+ case ProjectItem_pmuid :
+ db = 0;
+ break;
+ case ProjectItem_protuid :
+ db = 1;
+ break;
+ case ProjectItem_nucuid :
+ db = 2;
+ break;
+ case ProjectItem_genomeuid :
+ db = 4;
+ break;
+ case ProjectItem_structuid :
+ db = 3;
+ break;
+ default :
+ break;
+ }
+ if (db == -1) return;
+ num = ValNodeLen (list);
+ uids = MemNew ((size_t) (num * sizeof (Int4)));
+ if (uids == NULL) return;
+ for (i = 0, vnp = list; i < 32766 && vnp != NULL; i++, vnp = vnp->next) {
+ uids [i] = vnp->data.intvalue;
+ }
+ if (egp->retrieveDocsProc != NULL) {
+ egp->retrieveDocsProc (NULL, (Int2) num, 0, uids, db);
+ }
+ MemFree (uids);
+ Update ();
+}
+
+static Boolean ImportDocSumForm (ForM f, CharPtr filename)
+
+{
+ Uint1 choice = 0;
+ Pointer dataptr;
+ Uint2 datatype;
+ EntrezGlobalsPtr egp;
+ FILE *fp;
+ ValNodePtr head = NULL;
+ Boolean is_na = TRUE;
+ Char path [PATH_MAX];
+ SeqEntryPtr sephead = NULL;
+ ValNodePtr simples;
+ SummFormPtr sfp;
+ ValNodePtr vnp;
+
+ path [0] = '\0';
+ StringNCpy_0 (path, filename, sizeof (path));
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp != NULL) {
+ if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
+ fp = FileOpen (path, "r");
+ if (fp != NULL) {
+ while ((dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, NULL, FALSE,
+ FALSE, TRUE, TRUE)) != NULL) {
+ ValNodeAddPointer (&head, datatype, dataptr);
+ }
+ FileClose (fp);
+ simples = ValNodeExtractList (&head, OBJ_FASTA);
+ if (simples != NULL) {
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp != NULL && egp->retrieveSimpleProc != NULL) {
+ egp->retrieveSimpleProc (NULL, simples);
+ }
+ }
+ ValNodeFree (simples);
+ if (head != NULL) {
+ for (vnp = head; vnp != NULL; vnp = vnp->next) {
+ datatype = vnp->choice;
+ dataptr = vnp->data.ptrvalue;
+ if (datatype == OBJ_PROJECT) {
+ ProcessProjectAsn ((ProjectPtr) dataptr);
+ }
+ }
+ }
+ ValNodeFree (head);
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+static Boolean ExportDocSumForm (ForM f, CharPtr filename)
+
+{
+ FILE *fp;
+ Int2 i;
+ CharPtr PNTR labels;
+ Boolean lastChoiceIsUidList = FALSE;
+ Boolean newline;
+ Int2 num;
+ Char path [PATH_MAX];
+ SummFormPtr sfp;
+ Char str [32];
+ Int2 val;
+
+ path [0] = '\0';
+ StringNCpy_0 (path, filename, sizeof (path));
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp != NULL) {
+ if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
+#ifdef WIN_MAC
+ fp = FileOpen (path, "r");
+ if (fp != NULL) {
+ FileClose (fp);
+ } else {
+ FileCreate (path, "TEXT", "ttxt");
+ }
+#endif
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ WatchCursor ();
+ Update ();
+ if (sfp->simple != NULL) {
+ } else if (sfp->currDb >= 0 && sfp->currDb < MAX_DBS) {
+ labels = radioLabels [sfp->currDb];
+ val = GetValue (sfp->formats [sfp->currDb]);
+ if (val > 0) {
+ if (labels [val] == NULL) {
+ lastChoiceIsUidList = TRUE;
+ }
+ }
+ }
+ if (lastChoiceIsUidList) {
+ switch (sfp->currDb) {
+ case 0 :
+ fprintf (fp, ">PubMed\n");
+ break;
+ case 1 :
+ fprintf (fp, ">Protein\n");
+ break;
+ case 2 :
+ fprintf (fp, ">Nucleotide\n");
+ break;
+ case 3 :
+ fprintf (fp, ">Structure\n");
+ break;
+ case 4 :
+ fprintf (fp, ">Genome\n");
+ break;
+ default :
+ fprintf (fp, ">?\n");
+ break;
+ }
+ }
+ num = 0;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ num++;
+ }
+ }
+ if (lastChoiceIsUidList) {
+ if (num == 0) {
+ for (i = 0; i < sfp->numUids; i++) {
+ sprintf (str, "%ld\n", (long) (sfp->uids [i]));
+ FilePuts (str, fp);
+ }
+ } else {
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ sprintf (str, "%ld\n", (long) (sfp->uids [i]));
+ FilePuts (str, fp);
+ }
+ }
+ }
+ } else if (num == 0) {
+ SaveDocument (sfp->docsum, fp);
+ } else {
+ newline = FALSE;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ if (newline) {
+ fputc ('\n', fp);
+ }
+ SaveDocumentItem (sfp->docsum, fp, i + 1);
+ newline = TRUE;
+ }
+ }
+ }
+ FileClose (fp);
+ sfp->filepath = MemFree (sfp->filepath);
+ sfp->filepath = StringSave (path);
+ ArrowCursor ();
+ Update ();
+ return TRUE;
+ } else {
+ Message (MSG_ERROR, "Unable to write file.");
+ return FALSE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+static void PrintDocsumProc (BaseFormPtr bfp)
+
+{
+ SummFormPtr sfp;
+
+ if (bfp == NULL) return;
+ sfp = (SummFormPtr) bfp;
+ WatchCursor ();
+ Update ();
+ PrintDocument (sfp->docsum);
+ ArrowCursor ();
+ Update ();
+}
+
+extern void LoadDocsumOptionsMenu (MenU m)
+
+{
+ EntrezGlobalsPtr egp;
+ MenU sub;
+
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL) return;
+ egp->parentsPersist = StatusItem (m, "Parents Persist", NULL);
+ SetStatus (egp->parentsPersist, egp->persistDefault);
+ egp->alignWithChecked = StatusItem (m, "Align Checked Items", NULL);
+ SetStatus (egp->alignWithChecked, egp->alignDefault);
+ SeparatorItem (m);
+ /*
+ sub = SubMenu (m, "Sequence Complexity");
+ egp->seqComplex = ChoiceGroup (sub, NULL);
+ ChoiceItem (egp->seqComplex, "NucProt");
+ ChoiceItem (egp->seqComplex, "SegSet");
+ ChoiceItem (egp->seqComplex, "BioSeq");
+ SetValue (egp->seqComplex, 2);
+ SeparatorItem (m);
+ */
+ sub = SubMenu (m, "Structure Complexity");
+ egp->strucComplex = ChoiceGroup (sub, NULL);
+ ChoiceItem (egp->strucComplex, "NCBI one XYZ per atom model");
+ ChoiceItem (egp->strucComplex, "NCBI backbone model");
+ ChoiceItem (egp->strucComplex, "Original PDB models 1-n");
+ ChoiceItem (egp->strucComplex, "NCBI vector model");
+ ChoiceItem (egp->strucComplex, "Everything");
+ SetValue (egp->strucComplex, 1);
+ sub = SubMenu (m, "Number of Models");
+ egp->strucModels = ChoiceGroup (sub, NULL);
+ ChoiceItem (egp->strucModels, "1");
+ ChoiceItem (egp->strucModels, "2");
+ ChoiceItem (egp->strucModels, "5");
+ ChoiceItem (egp->strucModels, "10");
+ ChoiceItem (egp->strucModels, "15");
+ ChoiceItem (egp->strucModels, "20");
+ ChoiceItem (egp->strucModels, "maximum");
+ SetValue (egp->strucModels, 7);
+}
+
+extern void DocSumFontChangeProc (IteM i)
+
+{
+ BaseFormPtr bfp;
+ EntrezGlobalsPtr egp;
+ Uint2 flags;
+ FonT fnt;
+ FontSpec fs;
+ Char str [FONT_NAME_SIZE + 10];
+
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+#ifdef WIN_MAC
+ bfp = currentFormDataPtr;
+#else
+ bfp = GetObjectExtra (i);
+#endif
+ if (bfp != NULL) {
+ MemSet ((Pointer) (&fs), 0, sizeof (FontSpec));
+ fnt = programFont;
+ if (egp != NULL && egp->docsumFont != NULL) {
+ fnt = egp->docsumFont;
+ }
+ flags = 0;
+ fs.name [0] = '\0';
+ fs.size = 0;
+ fs.style = 0;
+ fs.charset = 0;
+ fs.pitch = 0;
+ fs.family = 0;
+ if (GetFontSpec (fnt, &fs)) {
+ flags = CFF_READ_FSP;
+ }
+ if (ChooseFont (&fs, flags, NULL)) {
+ sprintf (str, "%s,%d", fs.name, (int) fs.size);
+ if ((fs.style & STYLE_BOLD) != 0 ||
+ (fs.style & STYLE_ITALIC) != 0 ||
+ (fs.style & STYLE_UNDERLINE) != 0) {
+ StringCat (str, ",");
+ if ((fs.style & STYLE_BOLD) != 0) {
+ StringCat (str, "b");
+ }
+ if ((fs.style & STYLE_ITALIC) != 0) {
+ StringCat (str, "i");
+ }
+ if ((fs.style & STYLE_UNDERLINE) != 0) {
+ StringCat (str, "u");
+ }
+ }
+ /* SetEntrezAppParam ("FONTS", "FETCHED", str); */
+ if (egp != NULL) {
+ egp->docsumFont = CreateFont (&fs);
+ }
+ SendMessageToForm (bfp->form, VIB_MSG_REDRAW);
+ }
+ }
+}
+
+extern void DisplayFontChangeProc (IteM i)
+
+{
+ BaseFormPtr bfp;
+ Uint2 flags;
+ FonT fnt;
+ FontSpec fs;
+ MedlineViewProcsPtr mvpp;
+ Char str [FONT_NAME_SIZE + 10];
+ SeqViewProcsPtr svpp;
+
+ svpp = (SeqViewProcsPtr) GetAppProperty ("SeqDisplayForm");
+ mvpp = (MedlineViewProcsPtr) GetAppProperty ("MedlineDisplayForm");
+#ifdef WIN_MAC
+ bfp = currentFormDataPtr;
+#else
+ bfp = GetObjectExtra (i);
+#endif
+ if (bfp != NULL) {
+ MemSet ((Pointer) (&fs), 0, sizeof (FontSpec));
+ fnt = programFont;
+ if (svpp != NULL && svpp->displayFont != NULL) {
+ fnt = svpp->displayFont;
+ } else if (mvpp != NULL && mvpp->displayFont != NULL) {
+ fnt = mvpp->displayFont;
+ }
+ flags = 0;
+ fs.name [0] = '\0';
+ fs.size = 0;
+ fs.style = 0;
+ fs.charset = 0;
+ fs.pitch = 0;
+ fs.family = 0;
+ if (GetFontSpec (fnt, &fs)) {
+ flags = CFF_READ_FSP | CFF_MONOSPACE;
+ }
+ if (ChooseFont (&fs, flags, NULL)) {
+ sprintf (str, "%s,%d", fs.name, (int) fs.size);
+ if ((fs.style & STYLE_BOLD) != 0 ||
+ (fs.style & STYLE_ITALIC) != 0 ||
+ (fs.style & STYLE_UNDERLINE) != 0) {
+ StringCat (str, ",");
+ if ((fs.style & STYLE_BOLD) != 0) {
+ StringCat (str, "b");
+ }
+ if ((fs.style & STYLE_ITALIC) != 0) {
+ StringCat (str, "i");
+ }
+ if ((fs.style & STYLE_UNDERLINE) != 0) {
+ StringCat (str, "u");
+ }
+ }
+ /* SetEntrezAppParam ("FONTS", "DISPLAY", str); */
+ if (svpp != NULL) {
+ svpp->displayFont = CreateFont (&fs);
+ }
+ if (mvpp != NULL) {
+ mvpp->displayFont = CreateFont (&fs);
+ }
+ SendMessageToForm (bfp->form, VIB_MSG_REDRAW);
+ }
+ }
+}
+
+extern Boolean DocSumCanSaveFasta (ForM f, Boolean nucs, Boolean prots)
+
+{
+ Int2 i;
+ SummFormPtr sfp;
+ SimpleSeqPtr ssp;
+
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp == NULL) return FALSE;
+ if (sfp->uids != NULL && sfp->simple == NULL) {
+ switch (sfp->currDb) {
+ case 1 :
+ if (prots) return TRUE;
+ break;
+ case 2 :
+ case 4 :
+ if (nucs) return TRUE;
+ break;
+ default :
+ break;
+ }
+ } else if (sfp->simple != NULL && sfp->uids == NULL) {
+ for (i = 0; i < sfp->numUids; i++) {
+ ssp = sfp->simple [i];
+ if (ssp != NULL) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ return FALSE;
+}
+
+extern Boolean ExportDocSumFasta (ForM f, CharPtr filename, Boolean nucs, Boolean prots)
+
+{
+ BioseqPtr bsp;
+ Boolean fastaOK = FALSE;
+ Boolean fastaNucOK;
+ Boolean fastaPrtOK;
+ FILE *fp;
+ Uint1 group_segs;
+ Int2 i;
+ Int2 num;
+ Char path [PATH_MAX];
+ SeqEntryPtr sep;
+ SummFormPtr sfp;
+ SimpleSeqPtr ssp;
+ Int4 uid;
+
+ path [0] = '\0';
+ StringNCpy_0 (path, filename, sizeof (path));
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp != NULL) {
+ if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
+#ifdef WIN_MAC
+ fp = FileOpen (path, "r");
+ if (fp != NULL) {
+ FileClose (fp);
+ } else {
+ FileCreate (path, "TEXT", "ttxt");
+ }
+#endif
+ fp = FileOpen (path, "w");
+ if (fp != NULL) {
+ WatchCursor ();
+ Update ();
+ num = 0;
+ for (i = 0; i < sfp->numUids; i++) {
+ if (sfp->state [i].checked) {
+ num++;
+ }
+ }
+ for (i = 0; i < sfp->numUids; i++) {
+ fastaNucOK = FALSE;
+ fastaPrtOK = FALSE;
+ if (sfp->state [i].checked || num == 0) {
+ if (sfp->uids != NULL && sfp->simple == NULL) {
+ uid = sfp->uids [i];
+ bsp = BioseqLockByGi (uid);
+ if (bsp != NULL) {
+ sep = SeqMgrGetSeqEntryForData (bsp);
+ if (sep != NULL) {
+ if (ISA_na (bsp->mol) && nucs) {
+ group_segs = 0;
+ if (bsp->repr == Seq_repr_seg) {
+ group_segs = 1;
+ } else if (bsp->repr == Seq_repr_delta) {
+ group_segs = 3;
+ }
+ fastaNucOK = SeqnSeqEntrysToFasta (sep, fp, TRUE, group_segs);
+ }
+ if (ISA_aa (bsp->mol) && prots) {
+ fastaPrtOK = SeqnSeqEntrysToFasta (sep, fp, FALSE, 0);
+ }
+ }
+ }
+ BioseqUnlockByGi (uid);
+ } else if (sfp->simple != NULL && sfp->uids == NULL) {
+ ssp = sfp->simple [i];
+ if (ssp != NULL) {
+ SimpleSeqPrint (ssp, fp, TRUE);
+ }
+ }
+ }
+ fastaOK |= fastaNucOK || fastaPrtOK;
+ }
+ FileClose (fp);
+ ArrowCursor ();
+ Update ();
+ return fastaOK;
+ }
+ }
+ }
+ return FALSE;
+}
+
+extern void RetrieveSimpleSeqs (ForM f, ValNodePtr simpleSeqs)
+
+{
+ Int4 i;
+ Int4 num;
+ SummFormPtr sfp;
+ ValNodePtr vnp;
+
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp == NULL) return;
+ Reset (sfp->docsum);
+ SetDocShade (sfp->docsum, NULL, NULL, NULL, NULL);
+ SetDocCache (sfp->docsum, NULL, NULL, NULL);
+ sfp->uids = MemFree (sfp->uids);
+ if (sfp->simple != NULL) {
+ for (i = 0; i < sfp->numUids; i++) {
+ SimpleSeqFree (sfp->simple [i]);
+ }
+ sfp->simple = MemFree (sfp->simple);
+ }
+ sfp->state = MemFree (sfp->state);
+ sfp->numUids = 0;
+ sfp->numParents = 0;
+ sfp->neighbors = MemFree (sfp->neighbors);
+ sfp->numNeighbors = 0;
+ SafeSetTitle (sfp->retrieve, "Neighbor 0");
+ SafeDisable (sfp->retrieve);
+ SafeSetTitle (sfp->refine, "Refine 0");
+ SafeDisable (sfp->refine);
+ SafeHide (sfp->target);
+ SetValue (sfp->target, 0);
+ SetPrevAndNextButtons (sfp);
+ Update ();
+ for (i = 0; i < MAX_DBS; i++) {
+ Hide (sfp->formats [i]);
+ }
+ Show (sfp->formats [MAX_DBS]);
+ if (simpleSeqs == NULL) return;
+ num = ValNodeLen (simpleSeqs);
+ if (num > 0) {
+ sfp->simple = MemNew ((size_t) (num * sizeof (SimpleSeqPtr)));
+ if (sfp->simple == NULL) {
+ Show (sfp->form);
+ Select (sfp->form);
+ SendMessageToForm (sfp->form, VIB_MSG_CHANGE);
+#ifdef WIN_MAC
+ if (sfp->activate != NULL) {
+ sfp->activate ((WindoW) sfp->form);
+ }
+#endif
+ return;
+ }
+ sfp->state = MemNew (sizeof (StateData) * (size_t) num);
+ if (sfp->state == NULL) return;
+ for (i = 0, vnp = simpleSeqs; i < 32766 && vnp != NULL; i++, vnp = vnp->next) {
+ sfp->simple [i] = (SimpleSeqPtr) vnp->data.ptrvalue;
+ }
+ sfp->numUids = num;
+ sfp->numParents = 0;
+ sfp->currDb = -1;
+ Show (sfp->form);
+ Select (sfp->form);
+ RepopulateDocSum (sfp, FALSE);
+ SetDocSumImportExportItems (sfp);
+ SendMessageToForm (sfp->form, VIB_MSG_CHANGE);
+#ifdef WIN_MAC
+ if (sfp->activate != NULL) {
+ sfp->activate ((WindoW) sfp->form);
+ }
+#endif
+ } else {
+ Show (sfp->form);
+ Select (sfp->form);
+#ifdef WIN_MAC
+ if (sfp->activate != NULL) {
+ sfp->activate ((WindoW) sfp->form);
+ }
+#endif
+ }
+ Update ();
+}
+
+static void ProjectPtrToDocSumForm (ForM f, Pointer data)
+
+{
+ /*
+ Int4 i;
+ ValNodePtr list;
+ Int4 num;
+ ValNodePtr pip;
+ ProjectPtr proj;
+ SummFormPtr sfp;
+ ValNodePtr vnp;
+
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp == NULL) return;
+ Reset (sfp->docsum);
+ SetDocShade (sfp->docsum, NULL, NULL, NULL, NULL);
+ SetDocCache (sfp->docsum, NULL, NULL, NULL);
+ sfp->uids = MemFree (sfp->uids);
+ if (sfp->simple != NULL) {
+ for (i = 0; i < sfp->numUids; i++) {
+ SimpleSeqFree (sfp->simple [i]);
+ }
+ sfp->simple = MemFree (sfp->simple);
+ }
+ sfp->state = MemFree (sfp->state);
+ sfp->numUids = 0;
+ sfp->numParents = 0;
+ sfp->neighbors = MemFree (sfp->neighbors);
+ sfp->numNeighbors = 0;
+ SafeSetTitle (sfp->retrieve, "Neighbor 0");
+ SafeDisable (sfp->retrieve);
+ SafeSetTitle (sfp->refine, "Refine 0");
+ SafeDisable (sfp->refine);
+ SafeHide (sfp->target);
+ SetValue (sfp->target, 0);
+ SetPrevAndNextButtons (sfp);
+ Update ();
+ for (i = 0; i < MAX_DBS; i++) {
+ Hide (sfp->formats [i]);
+ }
+ Show (sfp->formats [MAX_DBS]);
+ proj = (ProjectPtr) data;
+ if (proj == NULL) return;
+ pip = proj->data;
+ if (pip == NULL) return;
+ list = (ValNodePtr) pip->data.ptrvalue;
+ if (list == NULL) return;
+ num = ValNodeLen (list);
+ if (num > 0) {
+ if (pip->choice >= ProjectItem_protent && pip->choice <= ProjectItem_genomeent) {
+ sfp->simple = MemNew ((size_t) (num * sizeof (SimpleSeqPtr)));
+ if (sfp->seqentry == NULL) {
+ Show (sfp->form);
+ Select (sfp->form);
+ SendMessageToForm (sfp->form, VIB_MSG_CHANGE);
+#ifdef WIN_MAC
+ if (sfp->activate != NULL) {
+ sfp->activate ((WindoW) sfp->form);
+ }
+#endif
+ return;
+ }
+ sfp->state = MemNew (sizeof (StateData) * (size_t) num);
+ if (sfp->state == NULL) return;
+ for (i = 0, vnp = list; i < 32766 && vnp != NULL; i++, vnp = vnp->next) {
+ sfp->seqentry [i] = vnp;
+ }
+ sfp->numUids = num;
+ sfp->numParents = 0;
+ sfp->currDb = -1;
+ Show (sfp->form);
+ Select (sfp->form);
+ RepopulateDocSum (sfp, FALSE);
+ SetDocSumImportExportItems (sfp);
+ SendMessageToForm (sfp->form, VIB_MSG_CHANGE);
+#ifdef WIN_MAC
+ if (sfp->activate != NULL) {
+ sfp->activate ((WindoW) sfp->form);
+ }
+#endif
+ } else {
+ Show (sfp->form);
+ Select (sfp->form);
+#ifdef WIN_MAC
+ if (sfp->activate != NULL) {
+ sfp->activate ((WindoW) sfp->form);
+ }
+#endif
+ }
+ } else {
+ Show (sfp->form);
+ Select (sfp->form);
+#ifdef WIN_MAC
+ if (sfp->activate != NULL) {
+ sfp->activate ((WindoW) sfp->form);
+ }
+#endif
+ }
+ Update ();
+ */
+}
+
+static Pointer DocSumFormToProjectPtr (ForM f)
+
+{
+ /*
+ BioseqPtr bsp;
+ Char buf [40];
+ Char ch;
+ Uint1 choice = 0;
+ Boolean is_na = TRUE;
+ Int2 j;
+ ObjectIdPtr oid;
+ ValNodePtr pip;
+ ProjectPtr proj;
+ CharPtr ptr;
+ SeqEntryPtr sep;
+ SummFormPtr sfp;
+ SeqIdPtr sip;
+ BioseqPtr tmp;
+ Int4 uid;
+
+ sfp = (SummFormPtr) GetObjectExtra (f);
+ if (sfp == NULL) return NULL;
+ proj = ProjectNew ();
+ if (proj == NULL) return NULL;
+ pip = ValNodeNew (NULL);
+ if (pip == NULL) return NULL;
+ if (sfp->uids != NULL) {
+ switch (sfp->currDb) {
+ case 1 :
+ is_na = FALSE;
+ break;
+ case 2 :
+ case 4 :
+ is_na = TRUE;
+ break;
+ default :
+ return NULL;
+ }
+ } else if (sfp->seqentry != NULL) {
+ sep = sfp->seqentry [0];
+ if (sep == NULL || (! IS_Bioseq (sep))) return NULL;
+ bsp = (BioseqPtr) sep->data.ptrvalue;
+ if (bsp == NULL) return NULL;
+ is_na = (Boolean) (ISA_na (bsp->mol));
+ } else return NULL;
+ if (is_na) {
+ choice = ProjectItem_nucent;
+ } else {
+ choice = ProjectItem_protent;
+ }
+ pip->choice = choice;
+ proj->data = pip;
+ for (j = 0; j < sfp->numUids; j++) {
+ sep = NULL;
+ if (sfp->uids != NULL) {
+ uid = sfp->uids [j];
+ bsp = BioseqLockByGi (uid);
+ if (bsp != NULL && bsp->repr == Seq_repr_raw) {
+ tmp = BioseqNew ();
+ if (tmp != NULL) {
+ SeqIdWrite (bsp->id, buf, PRINTID_FASTA_LONG, sizeof (buf) - 1);
+ ptr = buf;
+ ch = *ptr;
+ while (ch != '\0') {
+ if (ch == '|') {
+ *ptr = '/';
+ }
+ ptr++;
+ ch = *ptr;
+ }
+ oid = ObjectIdNew ();
+ oid->str = StringSave (buf);
+ sip = ValNodeNew (NULL);
+ sip->choice = SEQID_LOCAL;
+ sip->data.ptrvalue = (Pointer) oid;
+ tmp->id = sip;
+ tmp->repr = bsp->repr;
+ tmp->mol = bsp->mol;
+ tmp->length = bsp->length;
+ tmp->seq_data_type = bsp->seq_data_type;
+ tmp->seq_data = BSDup (bsp->seq_data);
+ sep = SeqEntryNew ();
+ if (sep != NULL) {
+ sep->choice = 1;
+ sep->data.ptrvalue = (Pointer) tmp;
+ SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) tmp, sep);
+ }
+ }
+ }
+ BioseqUnlockByGi (uid);
+ } else if (sfp->seqentry != NULL) {
+ sep = AsnIoMemCopy ((Pointer) sfp->seqentry [j],
+ (AsnReadFunc) SeqEntryAsnRead,
+ (AsnWriteFunc) SeqEntryAsnWrite);
+ }
+ if (sep != NULL) {
+ ValNodeLink ((ValNodePtr PNTR) (&(pip->data.ptrvalue)), sep);
+ }
+ }
+ return (Pointer) proj;
+ */
+ return NULL;
+}
+
+static Boolean SaveDocsumProject (BaseFormPtr bfp, Boolean saveAs)
+
+{
+ AsnIoPtr aop;
+ Char path [PATH_MAX];
+ ProjectPtr proj;
+ SummFormPtr sfp;
+#ifdef WIN_MAC
+ FILE *fp;
+#endif
+
+ if (bfp != NULL) {
+ sfp = (SummFormPtr) bfp;
+ path [0] = '\0';
+ StringNCpy_0 (path, bfp->filepath, sizeof (path));
+ if (StringHasNoText (path) || saveAs) {
+ if (! (GetOutputFileName (path, sizeof (path), ""))) return FALSE;
+ }
+#ifdef WIN_MAC
+ fp = FileOpen (path, "r");
+ if (fp != NULL) {
+ FileClose (fp);
+ } else {
+ FileCreate (path, "TEXT", "ttxt");
+ }
+#endif
+ WatchCursor ();
+ Update ();
+ proj = (ProjectPtr) FormToPointer (bfp->form);
+ if (proj == NULL) {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_ERROR, "Unable to create project data.");
+ return FALSE;
+ }
+ aop = AsnIoOpen (path, "w");
+ if (aop != NULL) {
+ ProjectAsnWrite (proj, aop, NULL);
+ AsnIoFlush (aop);
+ AsnIoClose (aop);
+ bfp->filepath = MemFree (bfp->filepath);
+ bfp->filepath = StringSave (path);
+ ArrowCursor ();
+ Update ();
+ return TRUE;
+ } else {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_ERROR, "Unable to write file.");
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+static void EntrezDocSumFormMessage (ForM f, Int2 mssg)
+
+{
+ BaseFormPtr bfp;
+ EntrezGlobalsPtr egp;
+ SummFormPtr sfp;
+
+ bfp = (BaseFormPtr) GetObjectExtra (f);
+ if (bfp != NULL) {
+ switch (mssg) {
+ case VIB_MSG_REDRAW :
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp != NULL) {
+ sfp = (SummFormPtr) bfp;
+ sfp->docsumFont = egp->docsumFont;
+ RepopulateDocSum (sfp, TRUE);
+ }
+ break;
+ case VIB_MSG_COPY :
+ CopyDocsumToClipboard (bfp);
+ break;
+ case VIB_MSG_IMPORT :
+ ImportDocSumForm (f, NULL);
+ break;
+ case VIB_MSG_EXPORT :
+ ExportDocSumForm (f, NULL);
+ break;
+ case VIB_MSG_PRINT :
+ PrintDocsumProc (bfp);
+ break;
+ case VIB_MSG_SAVE_AS :
+ SaveDocsumProject (bfp, TRUE);
+ break;
+ default :
+ if (bfp->appmessage != NULL) {
+ bfp->appmessage (f, mssg);
+ }
+ break;
+ }
+ }
+}
+
+static void EntrezDocSumFormActivate (WindoW w)
+
+{
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) GetObjectExtra (w);
+ if (sfp != NULL) {
+ if (sfp->activate != NULL) {
+ sfp->activate (w);
+ }
+ SetDocSumImportExportItems (sfp);
+ }
+}
+
+static void CleanupEntrezDocSumForm (GraphiC g, VoidPtr data)
+
+{
+ Int2 j;
+ SummFormPtr sfp;
+
+ sfp = (SummFormPtr) data;
+ if (sfp != NULL) {
+ MemFree (sfp->uids);
+ if (sfp->simple != NULL) {
+ for (j = 0; j < sfp->numUids; j++) {
+ SimpleSeqFree (sfp->simple [j]);
+ }
+ sfp->simple = MemFree (sfp->simple);
+ }
+ MemFree (sfp->state);
+ MemFree (sfp->neighbors);
+ FileRemove (sfp->historyFile);
+ MemFree (sfp->historyFile);
+ MemFree (sfp->historyOffsets);
+ if (sfp->dbalist != NULL) {
+ for (j = 0; sfp->dbalist [j].name != NULL; j++) {
+ MemFree (sfp->dbalist [j].name);
+ }
+ }
+ MemFree (sfp->dbalist);
+ }
+ StdCleanupFormProc (g, data);
+}
+
+static void ResizeDocSumForm (WindoW w)
+
+{
+ Int2 diff;
+ Int2 gap;
+ Int2 height;
+ Int2 quarter;
+ RecT r;
+ Int2 remaining;
+ RecT s;
+ SummFormPtr sfp;
+ RecT t;
+ Int2 width;
+
+ sfp = (SummFormPtr) GetObjectExtra (w);
+ if (sfp == NULL) return;
+ WatchCursor ();
+ ObjectRect (w, &r);
+ width = r.right - r.left;
+ height = r.bottom - r.top;
+ GetPosition (sfp->docsum, &s);
+ GetPosition (sfp->controls, &t);
+ diff = t.bottom - t.top;
+ gap = t.top - s.bottom;
+ t.bottom = height - s.left;
+ t.top = t.bottom - diff;
+ s.right = width - s.left;
+ /*
+ s.bottom = height - s.left;
+ */
+ s.bottom = t.top - gap;
+ SafeHide (sfp->controls);
+ SetPosition (sfp->controls, &t);
+ AdjustPrnt (sfp->controls, &t, FALSE);
+ SetPosition (sfp->docsum, &s);
+ AdjustPrnt (sfp->docsum, &s, FALSE);
+ ObjectRect (sfp->docsum, &s);
+ InsetRect (&s, 4, 4);
+ docsumColFmt [0].pixInset = 6 * stdCharWidth;
+ remaining = s.right - s.left - 6 * stdCharWidth;
+ quarter = remaining / 4;
+ docsumColFmt [0].pixWidth = quarter + 6 * stdCharWidth;
+ docsumColFmt [1].pixWidth = remaining - quarter;
+ /*
+ if (Visible (sfp->docsum) && AllParentsVisible (sfp->docsum)) {
+ UpdateDocument (sfp->docsum, 0, 0);
+ }
+ */
+ SafeShow (sfp->controls);
+ RepopulateDocSum (sfp, TRUE);
+ ArrowCursor ();
+ Update ();
+}
+
+static void SetDocSumImportExportItems (SummFormPtr sfp)
+
+{
+ IteM exportItm;
+ IteM importItm;
+ CharPtr PNTR labels;
+ Boolean lastChoiceIsUidList = FALSE;
+ Char tmp [64];
+ Int2 val;
+
+ if (sfp == NULL) return;
+ importItm = FindFormMenuItem ((BaseFormPtr) sfp, VIB_MSG_IMPORT);
+ if (importItm != NULL) {
+ SafeSetTitle (importItm, "Import FASTA or Uid List...");
+ }
+ exportItm = FindFormMenuItem ((BaseFormPtr) sfp, VIB_MSG_EXPORT);
+ if (exportItm == NULL) return;
+ sfp->label = medRadios [0];
+ if (sfp->simple != NULL) {
+ sfp->label = localBioseqRadios [0];
+ } else if (sfp->currDb >= 0 && sfp->currDb < MAX_DBS) {
+ labels = radioLabels [sfp->currDb];
+ val = GetValue (sfp->formats [sfp->currDb]);
+ if (val > 0) {
+ sfp->label = labels [val - 1];
+ if (labels [val] == NULL) {
+ lastChoiceIsUidList = TRUE;
+ }
+ }
+ }
+ StringCpy (tmp, "Export ");
+ StringCat (tmp, sfp->label);
+ if (lastChoiceIsUidList) {
+ StringCat (tmp, " List");
+ }
+ StringCat (tmp, "...");
+ SafeSetTitle (exportItm, tmp);
+}
+
+extern ForM CreateDocSumForm (Int2 left, Int2 top, CharPtr title,
+ WndActnProc activate, FormMessageFunc messages)
+
+{
+ ButtoN b1, b2, b3;
+ EntrezGlobalsPtr egp;
+ EntrezInfoPtr eip;
+ GrouP g;
+ GrouP h;
+ Int2 i;
+ Int2 j;
+ GrouP k;
+ CharPtr PNTR labels;
+ Boolean macLike;
+ PrompT ppt, ppt1, ppt2;
+ GrouP q;
+ Int2 quarter;
+ RecT r;
+ Int2 remaining;
+ SummFormPtr sfp;
+ Int2 typ_ml;
+ WindoW w;
+ GrouP x;
+ GrouP y;
+
+ w = NULL;
+ eip = EntrezGetInfo ();
+ if (eip == NULL || eip->type_info == NULL ||
+ eip->types == NULL || eip->field_info == NULL) return NULL;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL) return NULL;
+ macLike = egp->popdownBehavior;
+ sfp = (SummFormPtr) MemNew (sizeof (SummFormData));
+ if (sfp != NULL) {
+ w = DocumentWindow (-50, -33, -10, -10, title,
+ StdSendCloseWindowMessageProc, ResizeDocSumForm);
+ SetObjectExtra (w, sfp, CleanupEntrezDocSumForm);
+ sfp->form = (ForM) w;
+ sfp->toform = ProjectPtrToDocSumForm;
+ sfp->fromform = DocSumFormToProjectPtr;
+ sfp->formmessage = EntrezDocSumFormMessage;
+ sfp->importform = ImportDocSumForm;
+ sfp->exportform = ExportDocSumForm;
+
+ sfp->appmessage = messages;
+ sfp->activate = activate;
+ SetActivate (w, EntrezDocSumFormActivate);
+
+ sfp->docsumFont = egp->docsumFont;
+ if (sfp->docsumFont == NULL) {
+ sfp->docsumFont = programFont;
+ }
+
+ if (egp->createDocSumMenus != NULL) {
+ egp->createDocSumMenus (w);
+ }
+
+ h = HiddenGroup (w, -1, 0, NULL);
+
+ k = HiddenGroup (h, 2, 0, NULL);
+ ppt = StaticPrompt (k, "Format:", 0, 0, programFont, 'l');
+ q = HiddenGroup (k, 0, 0, NULL);
+ for (i = 0; i < MAX_DBS && radioLabels [i] != NULL; i++) {
+ sfp->formats [i] = HiddenGroup (q, 5, 0, ChangeFormat);
+ SetObjectExtra (sfp->formats [i], sfp, NULL);
+ labels = radioLabels [i];
+ for (j = 0; labels [j] != NULL; j++) {
+ RadioButton (sfp->formats [i], labels [j]);
+ }
+ SetValue (sfp->formats [i], 1);
+ Hide (sfp->formats [i]);
+ }
+ sfp->formats [MAX_DBS] = HiddenGroup (q, 5, 0, NULL);
+ SetObjectExtra (sfp->formats [MAX_DBS], sfp, NULL);
+ labels = localBioseqRadios;
+ for (j = 0; labels [j] != NULL; j++) {
+ RadioButton (sfp->formats [MAX_DBS], labels [j]);
+ }
+ SetValue (sfp->formats [MAX_DBS], 1);
+ Hide (sfp->formats [MAX_DBS]);
+ sfp->label = medRadios [0];
+ AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt, (HANDLE) q, NULL);
+
+ g = HiddenGroup (h, -1, 0, NULL);
+ SetGroupSpacing (g, 5, 5);
+
+ sfp->dbalist = MakeDatabaseAlist (eip->type_info, eip->type_count, FALSE);
+
+ sfp->docsum = DocumentPanel (g, 32 * stdCharWidth, 20 * stdLineHeight);
+ SetObjectExtra (sfp->docsum, sfp, NULL);
+ SetDocProcs (sfp->docsum, ClickDocSum, NULL, ReleaseDocSum, NULL);
+ SetDocCache (sfp->docsum, NULL, NULL, NULL);
+ Hide (sfp->docsum);
+
+ sfp->controls = HiddenGroup (g, 5, 0, NULL);
+ SetGroupSpacing (sfp->controls, 10, 10);
+
+ x = HiddenGroup (sfp->controls, 0, 2, NULL);
+ sfp->retrieve = PushButton (x, "Neighbor 00000", RetrieveNeighbors);
+ SetObjectExtra (sfp->retrieve, sfp, NULL);
+ SetTitle (sfp->retrieve, "Neighbor 0");
+ Disable (sfp->retrieve);
+ sfp->refine = PushButton (x, "Refine 0000", RefineProc);
+ SetObjectExtra (sfp->refine , sfp, NULL);
+ SetTitle (sfp->refine, "Refine");
+ Disable (sfp->refine);
+ sfp->retrieveMode = FETCH_MODE;
+ sfp->usingDelay = FALSE;
+
+ sfp->neighbors = NULL;
+ sfp->numNeighbors = 0;
+
+ sfp->historyFile = NULL;
+ sfp->historyOffsets = NULL;
+ sfp->generations = 0;
+ sfp->present = 0;
+
+ x = HiddenGroup (sfp->controls, 0, -3, NULL);
+ SetGroupMargins (x, 3, 0);
+ SetGroupSpacing (x, 3, 5);
+
+ y = HiddenGroup (x, 5, 0, NULL);
+ ppt1 = StaticPrompt (y, "Target:", 0, popupMenuHeight, programFont, 'l');
+ sfp->target = PopupList (y, macLike, ChangeTarget);
+ SetObjectExtra (sfp->target, sfp, NULL);
+ InitEnumPopup (sfp->target, sfp->dbalist, NULL);
+ typ_ml = DatabaseFromName ("MEDLINE");
+ SetEnumPopup (sfp->target, sfp->dbalist, (UIEnum) typ_ml);
+
+ y = HiddenGroup (x, 4, 0, NULL);
+ SetGroupSpacing (y, 8, 0);
+ ppt2 = StaticPrompt (y, "Select:", 0, 0, programFont, 'l');
+ b1 = PushButton (y, "All", SelectAllProc);
+ SetObjectExtra (b1, sfp, NULL);
+ b2 = PushButton (y, "None", ClearAllProc);
+ SetObjectExtra (b2, sfp, NULL);
+ b3 = PushButton (y, "Parents", SelectParentsProc);
+ SetObjectExtra (b3, sfp, NULL);
+
+ x = HiddenGroup (sfp->controls, 0, 2, NULL);
+ sfp->prevBtn = PushButton (x, "Prev", PrevProc);
+ SetObjectExtra (sfp->prevBtn, sfp, NULL);
+ Disable (sfp->prevBtn);
+ sfp->nextBtn = PushButton (x, "Next", NextProc);
+ SetObjectExtra (sfp->nextBtn, sfp, NULL);
+ Disable (sfp->nextBtn);
+
+ AlignObjects (ALIGN_MIDDLE, (HANDLE) sfp->retrieve, (HANDLE) ppt1,
+ (HANDLE) sfp->target, (HANDLE) sfp->prevBtn, NULL);
+ AlignObjects (ALIGN_MIDDLE, (HANDLE) sfp->refine , (HANDLE) ppt2, (HANDLE) b1,
+ (HANDLE) b2, (HANDLE) b3, (HANDLE) sfp->nextBtn, NULL);
+
+ RealizeWindow (w);
+
+ SelectFont (programFont);
+ sfp->lineHeight = LineHeight ();
+ SelectFont (systemFont);
+ sfp->linesPerIcon = (22 + sfp->lineHeight - 1) / sfp->lineHeight;
+ docsumParFmt.minLines = sfp->linesPerIcon;
+
+ ObjectRect (sfp->docsum, &r);
+ InsetRect (&r, 4, 4);
+ docsumColFmt [0].pixInset = 6 * stdCharWidth;
+ remaining = r.right - r.left - 6 * stdCharWidth;
+ quarter = remaining / 4;
+ docsumColFmt [0].pixWidth = quarter + 6 * stdCharWidth;
+ docsumColFmt [1].pixWidth = remaining - quarter;
+ textColFmt [0].pixInset = 3 * stdCharWidth;
+ textColFmt [0].pixWidth = screenRect.right - screenRect.left;
+
+ SetDocAutoAdjust (sfp->docsum, FALSE);
+ }
+ return (ForM) w;
+}
+
+typedef struct linkgroup {
+ DIALOG_MESSAGE_BLOCK
+ BaseFormPtr bfp;
+ ButtoN retrieve;
+ PopuP target;
+ LinkSetPtr lsp;
+ Int2 currDb;
+ Int2 targetDb;
+ Int4 docuid;
+ Uint2 align_type;
+ ButtoN onlyFromThis;
+ EnumFieldAssocPtr dbalist;
+} LinkGroup, PNTR LinkGroupPtr;
+
+static void RetrieveViewerLinks (ButtoN b)
+
+{
+ BaseFormPtr bfp;
+ BioseqPtr bsp;
+ EntrezGlobalsPtr egp;
+ ValNodePtr head;
+ Int2 i;
+ LinkGroupPtr lgp;
+ LinkSetPtr lsp;
+ Int2 num;
+ Int2 parents;
+ Boolean persist;
+ SeqEntryPtr sep;
+ Int4Ptr uids;
+ ValNodePtr vnp;
+
+ lgp = (LinkGroupPtr) GetObjectExtra (b);
+ if (lgp == NULL) return;
+ bfp = (BaseFormPtr) GetObjectExtra (ParentWindow (b));
+ if (bfp == NULL) return;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL || egp->retrieveDocsProc == NULL) return;
+ if (lgp->align_type != 0) {
+ uids = NULL;
+ sep = NULL;
+ if (GetStatus (lgp->onlyFromThis)) {
+ bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
+ if (bsp != NULL) {
+ sep = SeqMgrGetSeqEntryForData (bsp);
+ }
+ } else {
+ sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
+ }
+ head = GetUidsForSeqEntryAligns (sep);
+ num = 0;
+ for (vnp = head; vnp != NULL; vnp = vnp->next) {
+ if (vnp->choice == lgp->align_type && vnp->data.intvalue != lgp->docuid) {
+ num++;
+ }
+ }
+ if (num > 0) {
+ uids = MemNew ((size_t) (num + 1) * sizeof (DocUid));
+ if (uids != NULL) {
+ i = 0;
+ for (vnp = head; i < num && vnp != NULL; vnp = vnp->next) {
+ if (vnp->choice == lgp->align_type && vnp->data.intvalue != lgp->docuid) {
+ uids [i] = vnp->data.intvalue;
+ i++;
+ }
+ }
+ }
+ egp->retrieveDocsProc (bfp->form, num, 0, uids, lgp->targetDb);
+ MemFree (uids);
+ }
+ ValNodeFree (head);
+ return;
+ }
+ lsp = lgp->lsp;
+ if (lsp == NULL) return;
+ persist = FALSE;
+ if (lgp->currDb == lgp->targetDb) {
+ if (egp->parentsPersist != NULL) {
+ persist = GetStatus (egp->parentsPersist);
+ } else {
+ persist = egp->persistDefault;
+ }
+ }
+ parents = 0;
+ if (persist) {
+ parents++;
+ }
+ uids = NULL;
+ num = lsp->num + parents;
+ if (num > 0) {
+ uids = MemNew ((size_t) (num + 1) * sizeof (DocUid));
+ if (uids != NULL) {
+ num = 0;
+ if (persist) {
+ uids [num] = lgp->docuid;
+ num++;
+ }
+ for (i = 0; i < lsp->num; i++) {
+ uids [num] = lsp->uids [i];
+ num++;
+ }
+ }
+ }
+ egp->retrieveDocsProc (bfp->form, num, parents, uids, lgp->targetDb);
+ MemFree (uids);
+}
+
+static void ChangeViewerLinkData (LinkGroupPtr lgp, Int2 currDb, Int4 theuid)
+
+{
+ BaseFormPtr bfp;
+ BioseqPtr bsp;
+ ValNodePtr head = NULL;
+ Int4 num;
+ SeqEntryPtr sep;
+ SeqIdPtr sip;
+ Char str [64];
+ Char title [32];
+ Int4 uid;
+ UIEnum val;
+ ValNode vn;
+ ValNodePtr vnp;
+
+ if (lgp == NULL) return;
+ if (lgp->lsp != NULL) {
+ lgp->lsp = LinkSetFree (lgp->lsp);
+ }
+ lgp->align_type = 0;
+ if (GetEnumPopup (lgp->target, lgp->dbalist, &val)) {
+ lgp->targetDb = (Int2) val;
+ if (lgp->targetDb >= ALIST_BLASTN && lgp->targetDb <= ALIST_TBLASTX) {
+ /* SafeShow (lgp->onlyFromThis); */
+ lgp->docuid = theuid;
+ lgp->currDb = currDb;
+ num = 0;
+ bfp = lgp->bfp;
+ if (bfp != NULL) {
+ sep = NULL;
+ if (GetStatus (lgp->onlyFromThis)) {
+ bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
+ if (bsp != NULL) {
+ sep = SeqMgrGetSeqEntryForData (bsp);
+ }
+ } else {
+ sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
+ }
+ head = GetIdStringsForSeqEntryAligns (sep);
+ lgp->targetDb = TYP_NT;
+ switch (val) {
+ case ALIST_BLASTN :
+ lgp->align_type = ALIGN_BLASTN;
+ lgp->targetDb = TYP_NT;
+ break;
+ case ALIST_BLASTP :
+ lgp->align_type = ALIGN_BLASTP;
+ lgp->targetDb = TYP_AA;
+ break;
+ case ALIST_BLASTX :
+ lgp->align_type = ALIGN_BLASTX;
+ lgp->targetDb = TYP_AA;
+ break;
+ case ALIST_TBLASTN :
+ lgp->align_type = ALIGN_TBLASTN;
+ lgp->targetDb = TYP_NT;
+ break;
+ default :
+ break;
+ }
+ vn.choice = SEQID_GI;
+ vn.data.intvalue = theuid;
+ sip = (SeqIdPtr) (&vn);
+ SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str));
+ for (vnp = head; vnp != NULL; vnp = vnp->next) {
+ if (vnp->choice == lgp->align_type && StringICmp ((CharPtr) vnp->data.intvalue, str) != 0) {
+ num++;
+ }
+ }
+ ValNodeFreeData (head);
+ }
+ sprintf (title, "Retrieve %ld", (long) num);
+ SafeSetTitle (lgp->retrieve, title);
+ if (num > 0) {
+ SafeEnable (lgp->retrieve);
+ } else {
+ SafeDisable (lgp->retrieve);
+ }
+ return;
+ } else {
+ /* SafeHide (lgp->onlyFromThis); */
+ }
+ } else {
+ lgp->targetDb = currDb;
+ }
+ lgp->currDb = currDb;
+ lgp->docuid = theuid;
+ if (theuid > 0) {
+ lgp->lsp = NULL;
+ uid = theuid;
+ EntrezLinkUidList (&(lgp->lsp), lgp->currDb, lgp->targetDb, 1, &uid, FALSE);
+ }
+ num = 0;
+ if (lgp->lsp != NULL) {
+ num = (Int4) lgp->lsp->num;
+ }
+ if (lgp->targetDb == lgp->currDb) {
+ sprintf (title, "Neighbor %ld", (long) num);
+ } else {
+ sprintf (title, "Lookup %ld", (long) num);
+ }
+ SafeSetTitle (lgp->retrieve, title);
+ if (num > 0) {
+ SafeEnable (lgp->retrieve);
+ } else {
+ SafeDisable (lgp->retrieve);
+ }
+}
+
+extern void UpdateViewerLinkTarget (GrouP g)
+
+{
+ BaseFormPtr bfp;
+ Int2 currDb;
+ LinkGroupPtr lgp;
+ Int4 uid = 0;
+ UIEnum val;
+
+ lgp = (LinkGroupPtr) GetObjectExtra (g);
+ if (lgp == NULL) return;
+ bfp = lgp->bfp;
+ if (bfp == NULL) return;
+ currDb = bfp->doctype;
+ uid = bfp->docuid;
+ if (GetEnumPopup (lgp->target, lgp->dbalist, &val)) {
+ if (! (val >= ALIST_BLASTN && val <= ALIST_TBLASTX)) {
+ SetEnumPopup (lgp->target, lgp->dbalist, (UIEnum) currDb);
+ }
+ }
+ ChangeViewerLinkData (lgp, currDb, uid);
+}
+
+static void ChangeViewerLinkTarget (GraphiC g)
+
+{
+ BaseFormPtr bfp;
+ Int2 currDb;
+ LinkGroupPtr lgp;
+ Int4 uid = 0;
+
+ lgp = (LinkGroupPtr) GetObjectExtra (g);
+ if (lgp == NULL) return;
+ bfp = lgp->bfp;
+ if (bfp == NULL) return;
+ currDb = bfp->doctype;
+ uid = bfp->docuid;
+ ChangeViewerLinkData (lgp, currDb, uid);
+}
+
+static void CleanupLinkGroup (GraphiC g, VoidPtr data)
+
+{
+ Int2 j;
+ LinkGroupPtr lgp;
+
+ lgp = (LinkGroupPtr) data;
+ if (lgp != NULL) {
+ LinkSetFree (lgp->lsp);
+ if (lgp->dbalist != NULL) {
+ for (j = 0; lgp->dbalist [j].name != NULL; j++) {
+ MemFree (lgp->dbalist [j].name);
+ }
+ }
+ MemFree (lgp->dbalist);
+ }
+ MemFree (data);
+}
+
+extern GrouP MakeViewerLinkControls (GrouP prnt, BaseFormPtr bfp, Int2 doctype, Int4 uid, Boolean blast)
+
+{
+ EntrezGlobalsPtr egp;
+ EntrezInfoPtr eip;
+ LinkGroupPtr lgp;
+ Boolean macLike;
+ GrouP p;
+ PrompT ppt;
+
+ if (prnt == NULL || bfp == NULL) return NULL;
+
+ eip = EntrezGetInfo ();
+ if (eip == NULL || eip->type_info == NULL ||
+ eip->types == NULL || eip->field_info == NULL) return NULL;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL) return NULL;
+ macLike = egp->popdownBehavior;
+
+ p = HiddenGroup (prnt, 5, 0, NULL);
+ SetGroupSpacing (p, 10, 10);
+
+ lgp = (LinkGroupPtr) MemNew (sizeof (LinkGroup));
+ if (lgp == NULL) return p;
+
+ SetObjectExtra (p, lgp, CleanupLinkGroup);
+ lgp->dialog = (DialoG) p;
+
+ lgp->bfp = bfp;
+ lgp->lsp = NULL;
+ lgp->dbalist = MakeDatabaseAlist (eip->type_info, eip->type_count, blast);
+
+ lgp->retrieve = PushButton (p, "Neighbor 00000", RetrieveViewerLinks);
+ SetObjectExtra (lgp->retrieve, lgp, NULL);
+ SetTitle (lgp->retrieve, "Neighbor 0");
+ Disable (lgp->retrieve);
+
+ ppt = StaticPrompt (p, "Target:", 0, popupMenuHeight, programFont, 'l');
+ lgp->target = PopupList (p, macLike, (PupActnProc) ChangeViewerLinkTarget);
+ SetObjectExtra (lgp->target, lgp, NULL);
+ InitEnumPopup (lgp->target, lgp->dbalist, NULL);
+ SetEnumPopup (lgp->target, lgp->dbalist, (UIEnum) doctype);
+
+ lgp->onlyFromThis = CheckBox (p, "Just from this sequence", (BtnActnProc) ChangeViewerLinkTarget);
+ SetObjectExtra (lgp->onlyFromThis, lgp, NULL);
+ SetStatus (lgp->onlyFromThis, TRUE);
+ SafeHide (lgp->onlyFromThis);
+
+ AlignObjects (ALIGN_MIDDLE, (HANDLE) lgp->retrieve, (HANDLE) ppt,
+ (HANDLE) lgp->target, (HANDLE) lgp->onlyFromThis, NULL);
+
+ ChangeViewerLinkData (lgp, doctype, uid);
+
+ return p;
+}
+
+static void LaunchMedlineViewer (Int4 uid, Int2 numAlign, Int4Ptr alignuids, Int2 db)
+
+{
+ Pointer dataptr;
+ Uint2 datatype;
+ Uint2 entityID;
+ Int2 handled;
+ MedlineEntryPtr mep;
+
+ WatchCursor ();
+ Update ();
+ mep = EntrezMedlineEntryGet (uid);
+ if (mep == NULL) {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_OK, "Unable to find this record in the database.");
+ return;
+ }
+ datatype = OBJ_MEDLINE_ENTRY;
+ dataptr = (Pointer) mep;
+ entityID = ObjMgrRegister (datatype, dataptr);
+ if (dataptr == NULL || entityID == 0) {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_OK, "Unable to find this record in the database.");
+ return;
+ }
+ handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, 1,
+ OBJ_MEDLINE_ENTRY, 0, 0, OBJ_MEDLINE_ENTRY, 0);
+ ArrowCursor ();
+ if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
+ Message (MSG_FATAL, "Unable to launch viewer.");
+ MedlineEntryFree (mep);
+ } else {
+ ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
+ }
+}
+
+static void AddBlastAlignment (Int4 uid, Int2 numAlign, Int4Ptr alignuids, Uint2 entityID, SeqEntryPtr sep, BioseqPtr subject)
+
+{
+ Uint1 align_type = 0;
+ BioseqPtr bsp;
+ BioseqSetPtr bssp;
+ SeqAnnotPtr curr;
+ Int2 i;
+ BLAST_OptionsBlkPtr options = NULL;
+ SeqAlignPtr prev;
+ BioseqPtr query;
+ SeqAlignPtr salp;
+ SeqAnnotPtr sap;
+ SeqAnnotPtr PNTR sapp;
+ BlastSearchBlkPtr search;
+
+ if (sep == NULL || numAlign == 0 || alignuids == NULL) return;
+ sap = NULL;
+ salp = NULL;
+ if (subject == NULL) return;
+ if (ISA_na (subject->mol)) {
+ align_type = 1;
+ options = BLASTOptionNew ("blastn", TRUE);
+ if (options != NULL) {
+ options->gapped_calculation = TRUE;
+ options->db_length = 100000000;
+#ifdef WIN16
+ options->wordsize = 10;
+#else
+ options->wordsize = 12;
+#endif
+ }
+ } else if (ISA_aa (subject->mol)) {
+ align_type = 2;
+ options = BLASTOptionNew ("blastp", TRUE);
+ if (options != NULL) {
+ options->gapped_calculation = TRUE;
+ options->db_length = 20000000;
+ options->threshold_second = 12;
+ }
+ } else return;
+ search = BLASTSetUpSearch (subject, options->program_name, 0, 0, NULL, options, NULL);
+
+ for (i = 0; i < numAlign; i++) {
+ if (alignuids [i] != uid) {
+ query = BioseqLockByGi (alignuids [i]);
+ if (query != NULL) {
+ salp = BlastSequencesOnTheFly (search, query);
+ BioseqUnlockByGi (alignuids [i]);
+ if (salp != NULL) {
+ if (sap == NULL) {
+ sap = SeqAnnotNew ();
+ if (sap != NULL) {
+ sap->type = 2;
+ }
+ }
+ if (sap != NULL) {
+ if (sap->data != NULL) {
+ prev = sap->data;
+ while (prev->next != NULL) {
+ prev = prev->next;
+ }
+ prev->next = salp;
+ } else {
+ sap->data = (Pointer) salp;
+ }
+ }
+ }
+ }
+ }
+ }
+ BLASTOptionDelete (options);
+ BlastSearchBlkDestruct (search);
+
+ if (sap == NULL) return;
+
+ AddAlignInfoToSeqAnnot (sap, align_type);
+ /*
+ ObjMgrRegister (OBJ_SEQANNOT, (Pointer) sap);
+ */
+ sapp = NULL;
+ if (IS_Bioseq (sep)) {
+ bsp = (BioseqPtr) sep->data.ptrvalue;
+ sapp = &(bsp->annot);
+ } else if (IS_Bioseq_set (sep)) {
+ bssp = (BioseqSetPtr) sep->data.ptrvalue;
+ sapp = &(bssp->annot);
+ }
+ if (sapp != NULL) {
+ if (*sapp != NULL) {
+ curr = *sapp;
+ while (curr->next != NULL) {
+ curr = curr->next;
+ }
+ curr->next = sap;
+ } else {
+ *sapp = sap;
+ }
+ }
+}
+
+/*
+static Int2 GetSequenceComplexity (void)
+
+{
+ Int2 retcode = 0;
+ EntrezGlobalsPtr egp;
+ Int2 val;
+
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL || egp->seqComplex == NULL) return retcode;
+ val = GetValue (egp->seqComplex);
+ switch (val) {
+ case 1 :
+ retcode = -2;
+ break;
+ case 2 :
+ retcode = SEQENTRY_READ_SEG_SET;
+ break;
+ case 3 :
+ retcode = SEQENTRY_READ_BIOSEQ;
+ break;
+ default :
+ retcode = 0;
+ break;
+ }
+ return retcode;
+}
+*/
+
+static void LaunchSequenceViewer (Int4 uid, Int2 numAlign, Int4Ptr alignuids, Int2 db)
+
+{
+ BioseqPtr bsp;
+ EntrezGlobalsPtr egp;
+ Uint2 entityID;
+ Int2 handled;
+ Uint2 itemID;
+ SeqEntryPtr sep;
+
+ WatchCursor ();
+ Update ();
+ /* retcode = GetSequenceComplexity (); */
+ bsp = BioseqLockByGi (uid);
+ if (bsp == NULL) {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_OK, "Unable to find this record in the database.");
+ return;
+ }
+ entityID = BioseqFindEntityByGi (uid, &itemID);
+ if (entityID == 0 || itemID == 0) {
+ BioseqUnlockByGi (uid);
+ return;
+ }
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp != NULL) {
+ if (GetStatus (egp->alignWithChecked)) {
+ sep = GetTopSeqEntryForEntityID (entityID);
+ AddBlastAlignment (uid, numAlign, alignuids, entityID, sep, bsp);
+ }
+ }
+ handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, itemID,
+ OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
+ ArrowCursor ();
+ if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
+ Message (MSG_FATAL, "Unable to launch viewer.");
+ } else {
+ ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
+ }
+ BioseqUnlockByGi (uid);
+}
+
+static void LaunchGenomeViewer (Int4 uid, Int2 numAlign, Int4Ptr alignuids, Int2 db)
+
+{
+ Pointer dataptr;
+ Uint2 datatype;
+ Uint2 entityID;
+ Int2 handled;
+ Uint2 itemID;
+ SeqEntryPtr sep;
+
+ WatchCursor ();
+ Update ();
+ sep = EntrezSeqEntryGet (uid, -1);
+ if (sep == NULL) {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_OK, "Unable to find this record in the database.");
+ return;
+ }
+ if (IS_Bioseq (sep)) {
+ datatype = OBJ_BIOSEQ;
+ } else if (IS_Bioseq_set (sep)) {
+ datatype = OBJ_BIOSEQSET;
+ } else {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_OK, "Unable to find this record in the database.");
+ return;
+ }
+ dataptr = (Pointer) sep->data.ptrvalue;
+ entityID = ObjMgrRegister (datatype, dataptr);
+ if (dataptr == NULL || entityID == 0) {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_OK, "Unable to find this record in the database.");
+ return;
+ }
+ itemID = 1;
+ handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, itemID,
+ OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
+ ArrowCursor ();
+ if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
+ Message (MSG_FATAL, "Unable to launch viewer.");
+ SeqEntryFree (sep);
+ } else {
+ ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
+ }
+}
+
+static Int4 GetBiostrucComplexity (void)
+
+{
+ Int4 complexity = ALLMDL;
+ EntrezGlobalsPtr egp;
+ Int2 val;
+
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL) return complexity;
+ val = GetValue (egp->strucComplex);
+ switch (val) {
+ case 1 :
+ complexity = ONECOORDATOM;
+ break;
+ case 2 :
+ complexity = ONECOORDRES;
+ break;
+ case 3 :
+ complexity = ALLMDL;
+ break;
+ case 4 :
+ complexity = VECMODEL;
+ break;
+ case 5 :
+ complexity = BSEVERYTHING;
+ break;
+ default :
+ complexity = ONECOORDATOM;
+ break;
+ }
+ return complexity;
+}
+
+static Int2 GetBiostrucMaxModels (void)
+
+{
+ EntrezGlobalsPtr egp;
+ Int2 maxModels = INT2_MAX;
+ Int2 val;
+
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL) return maxModels;
+ val = GetValue (egp->strucModels);
+ switch (val) {
+ case 1 :
+ maxModels = 1;
+ break;
+ case 2 :
+ maxModels = 2;
+ break;
+ case 3 :
+ maxModels = 5;
+ break;
+ case 4 :
+ maxModels = 10;
+ break;
+ case 5 :
+ maxModels = 15;
+ break;
+ case 6 :
+ maxModels = 20;
+ break;
+ case 7:
+ maxModels = MAX_MDLNO;
+ break;
+ default :
+ maxModels = 1;
+ break;
+ }
+ return maxModels;
+}
+
+static void LaunchStructureViewer (Int4 uid, Int2 numAlign, Int4Ptr alignuids, Int2 db)
+
+{
+#if defined(WIN16)
+ Message (MSG_OK, "Structure views not supported on this platform.");
+#else
+ BiostrucPtr bsp;
+ Int4 complexity;
+ Int2 maxModels;
+ PDNMS pdnms;
+ WindoW w;
+
+ if (! BiostrucAvail ()) {
+ Message (MSG_OK, "Structure libraries are not linked in.");
+ return;
+ }
+ WatchCursor ();
+ Update ();
+ complexity = GetBiostrucComplexity ();
+ maxModels = GetBiostrucMaxModels ();
+ bsp = EntrezBiostrucGet (uid, complexity, maxModels);
+ if (bsp == NULL) {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_OK, "Unable to find this record in the database.");
+ return;
+ }
+ pdnms = MakeAModelstruc (bsp);
+ if (pdnms == NULL) {
+ ArrowCursor ();
+ Update ();
+ Message (MSG_OK, "Unable to convert this biostruc to a modelstruc.");
+ return;
+ }
+ w = (WindoW) Cn3DWin_Entrez(NULL, TRUE);
+ if (w != NULL) {
+ Cn3D_ResetActiveStrucProc ();
+ Show (w);
+ Select (w);
+ }
+ ArrowCursor ();
+#endif
+}
+
+extern void LaunchRecordViewer (Int4 uid, Int2 numAlign, Int4Ptr alignuids, Int2 db)
+
+{
+ Int2 typ_aa;
+ Int2 typ_ch;
+ Int2 typ_ml;
+ Int2 typ_nt;
+ Int2 typ_st;
+
+ if (uid == 0) return;
+ typ_ml = DatabaseFromName ("MEDLINE");
+ typ_aa = DatabaseFromName ("Protein");
+ typ_nt = DatabaseFromName ("Nucleotide");
+ typ_st = DatabaseFromName ("Structure");
+ typ_ch = DatabaseFromName ("Genome");
+ if (db == typ_ml) {
+ LaunchMedlineViewer (uid, numAlign, alignuids, db);
+ } else if (db == typ_aa || db == typ_nt) {
+ LaunchSequenceViewer (uid, numAlign, alignuids, db);
+ } else if (db == typ_st) {
+ LaunchStructureViewer (uid, numAlign, alignuids, db);
+ } else if (db == typ_ch) {
+ LaunchGenomeViewer (uid, numAlign, alignuids, db);
+ }
+}
+
+typedef struct prefspage {
+ DIALOG_MESSAGE_BLOCK
+ ButtoN persist;
+ ButtoN align;
+ GrouP lookup;
+ ButtoN showAsn;
+ PopuP initDb;
+ PopuP initFld;
+ PopuP initMode;
+ PopuP initMed;
+ PopuP initNuc;
+ PopuP initProt;
+ PopuP initGenome;
+ TexT minWidth;
+ TexT minHeight;
+ EnumFieldAssocPtr dbalist;
+ EnumFieldAssocPtr fldalist;
+ EnumFieldAssocPtr nucalist;
+ EnumFieldAssocPtr protalist;
+ EnumFieldAssocPtr gnomalist;
+} PrefsPage, PNTR PrefsPagePtr;
+
+static ENUM_ALIST(all_mode_alist)
+ {"Automatic", 1},
+ {"Lookup", 2},
+ {"MeSH Tree", 3},
+ {"Range", 4},
+ {"Selection", 5},
+ {"Taxonomy", 6},
+ {"Truncation", 7},
+END_ENUM_ALIST
+
+static ENUM_ALIST(med_views_alist)
+ {"Abstract", 1},
+ {"Citation", 2},
+ {"MEDLINE", 3},
+ {"ASN.1", 4},
+END_ENUM_ALIST
+
+static void PrefsPtrToPrefsPage (DialoG d, Pointer data)
+
+{
+ EntrezPrefsPtr epp;
+ PrefsPagePtr ppp;
+
+ ppp = (PrefsPagePtr) GetObjectExtra (d);
+ if (ppp == NULL) return;
+ epp = (EntrezPrefsPtr) data;
+ if (epp != NULL) {
+ SetStatus (ppp->persist, epp->persistDefault);
+ SetStatus (ppp->align, epp->alignDefault);
+ if (epp->lookupDirect) {
+ SetValue (ppp->lookup, 2);
+ } else {
+ SetValue (ppp->lookup, 1);
+ }
+ SetStatus (ppp->showAsn, epp->showAsn);
+ SetEnumPopupByName (ppp->initDb, ppp->dbalist, epp->initDatabase);
+ SetEnumPopupByName (ppp->initFld, ppp->fldalist, epp->initField);
+ SetEnumPopupByName (ppp->initMode, all_mode_alist, epp->initMode);
+ SetEnumPopupByName (ppp->initMed, med_views_alist, epp->initMedLabel);
+ SetEnumPopupByName (ppp->initNuc, ppp->nucalist, epp->initNucLabel);
+ SetEnumPopupByName (ppp->initProt, ppp->protalist, epp->initProtLabel);
+ SetEnumPopupByName (ppp->initGenome, ppp->gnomalist, epp->initGenomeLabel);
+ } else {
+ SetStatus (ppp->persist, TRUE);
+ SetStatus (ppp->align, TRUE);
+ SetValue (ppp->lookup, 1);
+ SetStatus (ppp->showAsn, FALSE);
+ SetEnumPopupByName (ppp->initDb, ppp->dbalist, "MEDLINE");
+ SetEnumPopupByName (ppp->initFld, ppp->fldalist, "All Fields");
+ SetEnumPopupByName (ppp->initMode, all_mode_alist, "Automatic");
+ SetEnumPopupByName (ppp->initMed, med_views_alist, "Abstract");
+ SetEnumPopupByName (ppp->initNuc, ppp->nucalist, "GenBank");
+ SetEnumPopupByName (ppp->initProt, ppp->protalist, "GenPept");
+ SetEnumPopupByName (ppp->initGenome, ppp->gnomalist, "Map");
+ }
+}
+
+static Pointer PrefsPageToPrefsPtr (DialoG d)
+
+{
+ EntrezPrefsPtr epp;
+ PrefsPagePtr ppp;
+
+ ppp = (PrefsPagePtr) GetObjectExtra (d);
+ if (ppp == NULL) return NULL;
+ epp = (EntrezPrefsPtr) MemNew (sizeof (EntrezPrefs));
+ if (epp == NULL) return NULL;
+ epp->persistDefault = GetStatus (ppp->persist);
+ epp->alignDefault = GetStatus (ppp->align);
+ epp->lookupDirect = (GetValue (ppp->lookup) == 2);
+ epp->showAsn = GetStatus (ppp->showAsn);
+ epp->initDatabase = GetEnumPopupByName (ppp->initDb, ppp->dbalist);
+ epp->initField = GetEnumPopupByName (ppp->initFld, ppp->fldalist);
+ epp->initMode = GetEnumPopupByName (ppp->initMode, all_mode_alist);
+ epp->initMedLabel = GetEnumPopupByName (ppp->initMed, med_views_alist);
+ epp->initNucLabel = GetEnumPopupByName (ppp->initNuc, ppp->nucalist);
+ epp->initProtLabel = GetEnumPopupByName (ppp->initProt, ppp->protalist);
+ epp->initGenomeLabel = GetEnumPopupByName (ppp->initGenome, ppp->gnomalist);
+ return (Pointer) epp;
+}
+
+static EnumFieldAssocPtr MakePageSpecAlist (SeqViewProcsPtr svpp, Boolean nucOK,
+ Boolean protOK, Boolean genomeOK)
+
+{
+ EnumFieldAssocPtr alist;
+ EnumFieldAssocPtr ap;
+ BioseqPagePtr bpp;
+ Int2 i;
+
+ if (svpp == NULL) return NULL;
+ bpp = svpp->pageSpecs;
+ i = 0;
+ while (bpp != NULL) {
+ i++;
+ bpp = bpp->next;
+ }
+ alist = MemNew (sizeof (EnumFieldAssoc) * (i + 2));
+ if (alist == NULL) return NULL;
+ ap = alist;
+ bpp = svpp->pageSpecs;
+ i = 0;
+ while (bpp != NULL) {
+ if ((nucOK && bpp->nucOK) ||
+ (protOK && bpp->protOK) ||
+ (genomeOK && bpp->genomeOK)) {
+ ap->name = StringSave (bpp->label);
+ ap->value = i;
+ ap++;
+ i++;
+ }
+ bpp = bpp->next;
+ }
+ ap->name = NULL;
+ return alist;
+}
+
+extern EntrezPrefsPtr EntrezPrefsNew (void)
+
+{
+ EntrezPrefsPtr epp;
+
+ epp = (EntrezPrefsPtr) MemNew (sizeof (EntrezPrefs));
+ return epp;
+}
+
+extern EntrezPrefsPtr EntrezPrefsFree (EntrezPrefsPtr epp)
+
+{
+ if (epp == NULL) return NULL;
+ epp->initDatabase = MemFree (epp->initDatabase);
+ epp->initField = MemFree (epp->initField);
+ epp->initMode = MemFree (epp->initMode);
+ epp->initMedLabel = MemFree (epp->initMedLabel);
+ epp->initNucLabel = MemFree (epp->initNucLabel);
+ epp->initProtLabel = MemFree (epp->initProtLabel);
+ epp->initGenomeLabel = MemFree (epp->initGenomeLabel);
+ return NULL;
+}
+
+static void CleanupEntrezPrefsProc (GraphiC g, VoidPtr data)
+
+{
+ PrefsPagePtr ppp;
+
+ ppp = (PrefsPagePtr) data;
+ if (ppp != NULL) {
+ ppp->dbalist = FreeEnumFieldAlist (ppp->dbalist);
+ ppp->fldalist = FreeEnumFieldAlist (ppp->fldalist);
+ ppp->nucalist = FreeEnumFieldAlist (ppp->nucalist);
+ ppp->protalist = FreeEnumFieldAlist (ppp->protalist);
+ ppp->gnomalist = FreeEnumFieldAlist (ppp->gnomalist);
+ }
+ StdCleanupExtraProc (g, data);
+}
+
+extern DialoG CreateEntrezPrefsDialog (GrouP prnt, CharPtr title)
+
+{
+ EntrezGlobalsPtr egp;
+ EntrezInfoPtr eip;
+ GrouP g1, g2, g3, g4, g5;
+ Boolean macLike;
+ GrouP p;
+ PrefsPagePtr ppp;
+ GrouP s;
+ SeqViewProcsPtr svpp;
+
+ p = HiddenGroup (prnt, 1, 0, NULL);
+ SetGroupSpacing (p, 10, 10);
+
+ eip = EntrezGetInfo ();
+ if (eip == NULL || eip->type_info == NULL ||
+ eip->types == NULL || eip->field_info == NULL) return (DialoG) p;
+
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL) return (DialoG) p;
+ macLike = egp->popdownBehavior;
+
+ svpp = (SeqViewProcsPtr) GetAppProperty ("SeqDisplayForm");
+ if (svpp == NULL) return (DialoG) p;
+
+ ppp = (PrefsPagePtr) MemNew (sizeof (PrefsPage));
+ if (ppp != NULL) {
+
+ SetObjectExtra (p, ppp, CleanupEntrezPrefsProc);
+ ppp->dialog = (DialoG) p;
+ ppp->todialog = PrefsPtrToPrefsPage;
+ ppp->fromdialog = PrefsPageToPrefsPtr;
+
+ ppp->dbalist = MakeDatabaseAlist (eip->type_info, eip->type_count, FALSE);
+ ppp->fldalist = MakeFieldAlist (eip->types, eip->field_info, eip->field_count, 0, TRUE);
+
+ ppp->nucalist = MakePageSpecAlist (svpp, TRUE, FALSE, FALSE);
+ ppp->protalist = MakePageSpecAlist (svpp, FALSE, TRUE, FALSE);
+ ppp->gnomalist = MakePageSpecAlist (svpp, FALSE, FALSE, TRUE);
+
+ if (title != NULL && title [0] != '\0') {
+ s = NormalGroup (p, -1, 0, title, systemFont, NULL);
+ } else {
+ s = HiddenGroup (p, -1, 0, NULL);
+ }
+ SetGroupSpacing (s, 10, 10);
+
+ g1 = HiddenGroup (s, -1, 0, NULL);
+ g5 = HiddenGroup (g1, 3, 0, NULL);
+ SetGroupSpacing (g5, 10, 3);
+ ppp->persist = CheckBox (g5, "Parents Persist", NULL);
+ ppp->align = CheckBox (g5, "Align Checked", NULL);
+ ppp->showAsn = CheckBox (g5, "Show ASN.1 Report", NULL);
+ g2 = HiddenGroup (g1, 2, 0, NULL);
+ StaticPrompt (g2, "Lookup Mode Launches", 0, stdLineHeight, programFont, 'l');
+ ppp->lookup = HiddenGroup (g2, 2, 0, NULL);
+ RadioButton (ppp->lookup, "DocSum");
+ RadioButton (ppp->lookup, "Record");
+ AlignObjects (ALIGN_CENTER, (HANDLE) g2, (HANDLE) g5, NULL);
+
+ g3 = HiddenGroup (s, 0, 2, NULL);
+
+ StaticPrompt (g3, "Database", 0, 0, programFont, 'l');
+ ppp->initDb = PopupList (g3, macLike, NULL);
+ InitEnumPopup (ppp->initDb, ppp->dbalist, NULL);
+ SetEnumPopupByName (ppp->initDb, ppp->dbalist, "MEDLINE");
+
+ StaticPrompt (g3, "Field", 0, 0, programFont, 'l');
+ ppp->initFld = PopupList (g3, macLike, NULL);
+ InitEnumPopup (ppp->initFld, ppp->fldalist, NULL);
+ SetEnumPopupByName (ppp->initFld, ppp->fldalist, "All Fields");
+
+ StaticPrompt (g3, "Mode", 0, 0, programFont, 'l');
+ ppp->initMode = PopupList (g3, macLike, NULL);
+ InitEnumPopup (ppp->initMode, all_mode_alist, NULL);
+ SetEnumPopupByName (ppp->initMode, all_mode_alist, "Automatic");
+
+ g4 = HiddenGroup (s, 0, 2, NULL);
+
+ StaticPrompt (g4, "MEDLINE", 0, 0, programFont, 'l');
+ ppp->initMed = PopupList (g4, macLike, NULL);
+ InitEnumPopup (ppp->initMed, med_views_alist, NULL);
+ SetEnumPopupByName (ppp->initMed, med_views_alist, "Abstract");
+
+ StaticPrompt (g4, "Nucleotide", 0, 0, programFont, 'l');
+ ppp->initNuc = PopupList (g4, macLike, NULL);
+ InitEnumPopup (ppp->initNuc, ppp->nucalist, NULL);
+ SetEnumPopupByName (ppp->initNuc, ppp->nucalist, "GenBank");
+
+ StaticPrompt (g4, "Protein", 0, 0, programFont, 'l');
+ ppp->initProt = PopupList (g4, macLike, NULL);
+ InitEnumPopup (ppp->initProt, ppp->protalist, NULL);
+ SetEnumPopupByName (ppp->initProt, ppp->protalist, "GenPept");
+
+ StaticPrompt (g4, "Genome", 0, 0, programFont, 'l');
+ ppp->initGenome = PopupList (g4, macLike, NULL);
+ InitEnumPopup (ppp->initGenome, ppp->gnomalist, NULL);
+ SetEnumPopupByName (ppp->initGenome, ppp->gnomalist, "Map");
+
+ AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g3, (HANDLE) g4, NULL);
+ }
+
+ return (DialoG) p;
+}
+
diff --git a/network/vibnet/entrez.h b/network/vibnet/entrez.h
new file mode 100644
index 00000000..b2afe302
--- /dev/null
+++ b/network/vibnet/entrez.h
@@ -0,0 +1,191 @@
+/* entrez.h
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information (NCBI)
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government do not place any restriction on its use or reproduction.
+* We would, however, appreciate having the NCBI and the author cited in
+* any work or product based on this material
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* ===========================================================================
+*
+* File Name: entrez.h
+*
+* Author: Jonathan Kans, Jonathan Epstein
+*
+* Version Creation Date: 8/5/96
+*
+* $Revision: 6.10 $
+*
+* File Description:
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+*
+* ==========================================================================
+*/
+
+#ifndef _ENTREZ_
+#define _ENTREZ_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <vibrant.h>
+#include <objacces.h>
+#include <objentr.h>
+
+/*
+* The EntrezGlobalsPtr may be registered with a call to SetAppProperty
+* e.g., SetAppProperty ("EntrezGlobals", &entrezglobals), where entrezglobals
+* is a persistent structure filled with Vibrant objects or callback
+* function pointers specific for a given application.
+*/
+
+/*
+* The following callback types help process requests between forms. The
+* form passed in belongs to the calling form, not the target form. It is
+* up to the application to pass the request to the appropriate form. This
+* way, there can be multiple term list and docsum forms, and the window
+* handles are not global to the libraries.
+*/
+
+typedef void (*EntrezRetrieveDocsProc) (ForM f, Int2 num, Int2 parents, Int4Ptr uids, Int2 db);
+typedef void (*EntrezProjectToFormProc) (ForM f, Pointer proj);
+typedef void (*EntrezSimpleSeqProc) (ForM f, ValNodePtr simpleSeqs);
+typedef void (*EntrezNamedUidListProc) (ForM f, CharPtr term, Int2 num, Int4Ptr uids, Int2 db);
+typedef void (*EntrezLaunchViewerProc) (ForM f, Int4 uid, Int2 numAlign, Int4Ptr alignuids, Int2 db);
+
+typedef struct entrezglobals {
+ IteM parentsPersist;
+ IteM alignWithChecked;
+ ChoicE seqComplex;
+ ChoicE strucComplex;
+ ChoicE strucModels;
+ FonT docsumFont;
+
+ Boolean persistDefault;
+ Boolean alignDefault;
+ Boolean popdownBehavior;
+ Boolean lookupDirect;
+ Boolean showAsn;
+ Boolean sortFields;
+ CharPtr initDatabase;
+ CharPtr initField;
+ CharPtr initMode;
+
+ WndActnProc createTrmLstMenus;
+ WndActnProc createDocSumMenus;
+
+ EntrezRetrieveDocsProc retrieveDocsProc;
+ EntrezProjectToFormProc retrieveProjectProc;
+ EntrezSimpleSeqProc retrieveSimpleProc;
+ EntrezNamedUidListProc loadNamedUidProc;
+ EntrezLaunchViewerProc launchViewerProc;
+} EntrezGlobals, PNTR EntrezGlobalsPtr;
+
+extern ForM CreateTermListForm (Int2 left, Int2 top, CharPtr title,
+ WndActnProc activate, FormMessageFunc messages);
+
+extern ForM CreateDocSumForm (Int2 left, Int2 top, CharPtr title,
+ WndActnProc activate, FormMessageFunc messages);
+
+/* The following functions are called by the application in response to request */
+
+extern void RetrieveDocuments (ForM f, Int2 num, Int2 parents, Int4Ptr uids, Int2 db);
+
+extern void RetrieveSimpleSeqs (ForM f, ValNodePtr simpleSeqs);
+
+extern void LoadNamedUidList (ForM f, CharPtr term, Int2 num, Int4Ptr uids, Int2 db);
+
+extern void LaunchRecordViewer (Int4 uid, Int2 numAlign, Int4Ptr alignuids, Int2 db);
+
+/* The following functions are used to toggle between query styles */
+
+extern ChoicE CreateQueryTypeChoice (MenU m, BaseFormPtr bfp);
+extern IteM CreateClearUnusedItem (MenU m, BaseFormPtr bfp);
+extern Boolean UsingTextQuery (ForM f);
+
+/* The following functions are used to toggle between immediate/delayed neighbor styles */
+
+extern ChoicE CreateNeighborDelayChoice (MenU m, BaseFormPtr bfp);
+extern Boolean UsingDelayedNeighbor (ForM f);
+extern void UseDelayedNeighbor (ForM f, Boolean delayMode);
+
+/* The following functions are used when creating windows */
+
+extern GrouP MakeViewerLinkControls (GrouP prnt, BaseFormPtr bfp, Int2 doctype, Int4 uid, Boolean blast);
+extern void UpdateViewerLinkTarget (GrouP g);
+extern void LoadDocsumOptionsMenu (MenU m);
+extern void DocSumFontChangeProc (IteM i);
+extern void DisplayFontChangeProc (IteM i);
+
+extern void DSLoadUidListProc (IteM i);
+extern void DSSaveUidListProc (IteM i);
+
+extern void TLLoadUidListProc (IteM i);
+extern void TLSaveUidListProc (IteM i);
+
+extern Boolean DocSumCanSaveFasta (ForM f, Boolean nucs, Boolean prots);
+extern Boolean ExportDocSumFasta (ForM f, CharPtr filename, Boolean nucs, Boolean prots);
+
+/* The following dialog function is used within a preferences form */
+
+typedef struct entrezprefs {
+ Boolean persistDefault;
+ Boolean alignDefault;
+ Boolean lookupDirect;
+ Boolean showAsn;
+ CharPtr initDatabase;
+ CharPtr initField;
+ CharPtr initMode;
+ CharPtr initMedLabel;
+ CharPtr initNucLabel;
+ CharPtr initProtLabel;
+ CharPtr initGenomeLabel;
+ Int2 minPixelWidth;
+ Int2 minPixelHeight;
+} EntrezPrefs, PNTR EntrezPrefsPtr;
+
+extern DialoG CreateEntrezPrefsDialog (GrouP prnt, CharPtr title);
+extern EntrezPrefsPtr EntrezPrefsNew (void);
+extern EntrezPrefsPtr EntrezPrefsFree (EntrezPrefsPtr epp);
+
+/* The following functions are normally for internal use */
+
+#define ALIST_BLASTN 201
+#define ALIST_BLASTP 202
+#define ALIST_BLASTX 203
+#define ALIST_TBLASTN 204
+#define ALIST_TBLASTX 205
+
+extern EnumFieldAssocPtr MakeDatabaseAlist (EntrezTypeInfo *type_info, short type_count, Boolean blast);
+extern EnumFieldAssocPtr MakeFieldAlist (EntrezTypeData *types, EntrezFieldInfo *field_info,
+ short field_count, Int2 db, Boolean allFields);
+
+extern Int2 DatabaseFromName (CharPtr name);
+extern Int2 FieldFromTag (CharPtr tag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ndef _ENTREZ_ */
diff --git a/network/vibnet/netcnfg.c b/network/vibnet/netcnfg.c
new file mode 100644
index 00000000..e55d956f
--- /dev/null
+++ b/network/vibnet/netcnfg.c
@@ -0,0 +1,452 @@
+/* netcnfg.c
+ * ===========================================================================
+ *
+ * PUBLIC DOMAIN NOTICE
+ * National Center for Biotechnology Information
+ *
+ * This software/database is a "United States Government Work" under the
+ * terms of the United States Copyright Act. It was written as part of
+ * the author's official duties as a United States Government employee and
+ * thus cannot be copyrighted. This software/database is freely available
+ * to the public for use. The National Library of Medicine and the U.S.
+ * Government have not placed any restriction on its use or reproduction.
+ *
+ * Although all reasonable efforts have been taken to ensure the accuracy
+ * and reliability of the software and data, the NLM and the U.S.
+ * Government do not and cannot warrant the performance or results that
+ * may be obtained by using this software or data. The NLM and the U.S.
+ * Government disclaim all warranties, express or implied, including
+ * warranties of performance, merchantability or fitness for any particular
+ * purpose.
+ *
+ * Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * RCS $Id: netcnfg.c,v 6.10 1998/12/15 22:42:22 kans Exp $
+ *
+ * Author: Kans, Epstein
+ *
+ * Version Creation Date: 9/10/96
+ *
+ * File Description:
+ * Network Entrez configuration
+ *
+ * Modifications:
+ * --------------------------------------------------------------------------
+ * Date Name Description of modification
+ * ------- ---------- -----------------------------------------------------
+ */
+
+#include <vibrant.h>
+#include <netcnfg.h>
+
+typedef struct netconfigdata {
+ FORM_MESSAGE_BLOCK
+
+ GrouP srvConnMode;
+ GrouP netGroup;
+
+ TexT proxyHost;
+ TexT proxyPort;
+ ButtoN transparentProxy;
+
+ Char proxyValue [256];
+ Char portValue [16];
+ Boolean transValue;
+
+ ButtoN dnsAvailable;
+ PopuP timeOut;
+
+ VoidProc accepted;
+ VoidProc cancelled;
+ VoidProc turnedOff;
+
+ ButtoN accept;
+} NetConfigData, PNTR NetConfigPtr;
+
+static void ConfigMessageProc (ForM f, Int2 mssg)
+
+{
+ VoidProc cancelled;
+ NetConfigPtr ncp;
+
+ ncp = (NetConfigPtr) GetObjectExtra (f);
+ if (ncp != NULL) {
+ switch (mssg) {
+ case VIB_MSG_CLOSE:
+ cancelled = ncp->cancelled;
+ Remove (f);
+ if (cancelled != NULL) {
+ cancelled ();
+ }
+ break;
+ case VIB_MSG_CUT:
+ StdCutTextProc (NULL);
+ break;
+ case VIB_MSG_COPY:
+ StdCopyTextProc (NULL);
+ break;
+ case VIB_MSG_PASTE:
+ StdPasteTextProc (NULL);
+ break;
+ case VIB_MSG_DELETE:
+ StdDeleteTextProc (NULL);
+ break;
+ default:
+ if (ncp->appmessage != NULL) {
+ ncp->appmessage (f, mssg);
+ }
+ break;
+ }
+ }
+}
+
+static void ConfigFormActivate (WindoW w)
+
+{
+ NetConfigPtr ncp;
+
+ ncp = (NetConfigPtr) GetObjectExtra (w);
+ if (ncp != NULL) {
+ if (ncp->activate != NULL) {
+ ncp->activate (w);
+ }
+ }
+}
+
+static Boolean NoEntryExists (CharPtr type)
+
+{
+ Char str [256];
+
+ if (GetAppParam ("NCBI", "NET_SERV", type, NULL, str, sizeof (str))) {
+ if (! StringHasNoText (str)) return FALSE;
+ }
+ return TRUE;
+}
+
+static void AcceptNetConfigForm (ButtoN b)
+
+{
+ VoidProc accepted;
+ NetConfigPtr ncp;
+ Char str [256];
+ VoidProc turnedOff;
+ Int2 val;
+
+ ncp = (NetConfigPtr) GetObjectExtra (b);
+ if (ncp == NULL) return;
+
+ val = GetValue (ncp->srvConnMode);
+ if (val == 1) {
+ turnedOff = ncp->turnedOff;
+ Remove (ncp->form);
+ if (turnedOff != NULL) {
+ turnedOff ();
+ }
+ Update ();
+ return;
+ } else if (val == 3) {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_CONN_MODE", "FIREWALL");
+ GetTitle (ncp->proxyHost, str, sizeof (str));
+ if (! StringHasNoText (str)) {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_HOST", str);
+ GetTitle (ncp->proxyPort, str, sizeof (str));
+ if (StringICmp (str, "80") == 0) {
+ str [0] = '\0';
+ }
+ if (! StringHasNoText (str)) {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_PORT", str);
+ } else {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_PORT", NULL);
+ }
+ if (GetStatus (ncp->transparentProxy)) {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_TRANSPARENT", "TRUE");
+ } else {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_TRANSPARENT", NULL);
+ }
+ } else {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_HOST", NULL);
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_PORT", NULL);
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_TRANSPARENT", NULL);
+ }
+ } else {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_CONN_MODE", NULL);
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_HOST", NULL);
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_PORT", NULL);
+ SetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_TRANSPARENT", NULL);
+ }
+
+ if (GetStatus (ncp->dnsAvailable)) {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_ENGINE_HOST", NULL);
+ } else {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_ENGINE_HOST", "130.14.22.106");
+ }
+
+ switch (GetValue (ncp->timeOut)) {
+ case 1 :
+ SetAppParam ("NCBI", "NET_SERV", "SRV_CONN_TIMEOUT", "10");
+ break;
+ case 3 :
+ SetAppParam ("NCBI", "NET_SERV", "SRV_CONN_TIMEOUT", "60");
+ break;
+ case 4 :
+ SetAppParam ("NCBI", "NET_SERV", "SRV_CONN_TIMEOUT", "300");
+ break;
+ default :
+ SetAppParam ("NCBI", "NET_SERV", "SRV_CONN_TIMEOUT", NULL);
+ break;
+ }
+
+ if (GetAppParam ("NCBI", "NET_SERV", "SRV_ENGINE_PORT", NULL, str, sizeof (str))) {
+ if (StringICmp (str, "80") == 0) {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_ENGINE_PORT", NULL);
+ }
+ }
+
+ if (GetAppParam ("NCBI", "NET_SERV", "SRV_ENGINE_URL", NULL, str, sizeof (str))) {
+ if (StringICmp (str, "/Service/nph-dispd.cgi") == 0) {
+ SetAppParam ("NCBI", "NET_SERV", "SRV_ENGINE_URL", NULL);
+ }
+ }
+
+ if (NoEntryExists ("SRV_CONN_MODE") &&
+ NoEntryExists ("SRV_CONN_TIMEOUT") &&
+ NoEntryExists ("SRV_ENGINE_HOST") &&
+ NoEntryExists ("SRV_ENGINE_PORT") &&
+ NoEntryExists ("SRV_ENGINE_URL") &&
+ NoEntryExists ("SRV_PROXY_HOST") &&
+ NoEntryExists ("SRV_PROXY_PORT") &&
+ NoEntryExists ("SRV_PROXY_TRANSPARENT")) {
+ SetAppParam ("NCBI", "NET_SERV", NULL, NULL);
+ }
+
+ accepted = ncp->accepted;
+ Remove (ncp->form);
+ if (accepted != NULL) {
+ accepted ();
+ }
+ Update ();
+}
+
+static void ChangeConfigControls (NetConfigPtr ncp)
+
+{
+ Boolean hasProxy;
+ Int2 val;
+
+ if (ncp == NULL) return;
+ val = GetValue (ncp->srvConnMode);
+ if (val == 1) {
+ SafeHide (ncp->netGroup);
+ }
+ if (val == 3) {
+ if (! Enabled (ncp->proxyHost)) {
+ SafeSetTitle (ncp->proxyHost, ncp->proxyValue);
+ }
+ Enable (ncp->proxyHost);
+ } else {
+ if (Enabled (ncp->proxyHost)) {
+ GetTitle (ncp->proxyHost, ncp->proxyValue, sizeof (ncp->proxyValue));
+ SafeSetTitle (ncp->proxyHost, NULL);
+ }
+ Disable (ncp->proxyHost);
+ }
+ hasProxy = (Boolean) (! TextHasNoText (ncp->proxyHost));
+ if (hasProxy) {
+ if (! Enabled (ncp->proxyHost)) {
+ SafeSetTitle (ncp->proxyHost, ncp->proxyValue);
+ }
+ Enable (ncp->proxyHost);
+ if (! Enabled (ncp->proxyPort)) {
+ SafeSetTitle (ncp->proxyPort, ncp->portValue);
+ }
+ Enable (ncp->proxyPort);
+ if (! Enabled (ncp->transparentProxy)) {
+ SafeSetStatus (ncp->transparentProxy, ncp->transValue);
+ }
+ Enable (ncp->transparentProxy);
+ } else {
+ if (Enabled (ncp->proxyPort)) {
+ GetTitle (ncp->proxyPort, ncp->portValue, sizeof (ncp->portValue));
+ SafeSetTitle (ncp->proxyPort, NULL);
+ }
+ Disable (ncp->proxyPort);
+ if (Enabled (ncp->transparentProxy)) {
+ ncp->transValue = GetStatus (ncp->transparentProxy);
+ SafeSetStatus (ncp->transparentProxy, FALSE);
+ }
+ Disable (ncp->transparentProxy);
+ }
+ if (val != 1) {
+ SafeShow (ncp->netGroup);
+ }
+}
+
+static void ChangeConnection (GrouP g)
+
+{
+ NetConfigPtr ncp;
+
+ ncp = (NetConfigPtr) GetObjectExtra (g);
+ ChangeConfigControls (ncp);
+}
+
+static void ChangeProxy (TexT t)
+
+{
+ NetConfigPtr ncp;
+
+ ncp = (NetConfigPtr) GetObjectExtra (t);
+ ChangeConfigControls (ncp);
+}
+
+extern void ShowNetConfigForm (WndActnProc activate, FormMessageFunc messages,
+ VoidProc accepted, VoidProc cancelled,
+ VoidProc turnedOff, Boolean netCurrentlyOn)
+{
+ ButtoN b;
+ GrouP c;
+ GrouP g;
+ GrouP h;
+ GrouP j;
+ NetConfigPtr ncp;
+ PrompT ppt0, ppt1;
+ ButtoN rb;
+ Char str [256];
+ WindoW w;
+ GrouP z;
+
+ w = NULL;
+ ncp = (NetConfigPtr) MemNew (sizeof (NetConfigData));
+ if (ncp != NULL) {
+
+ w = FixedWindow (-50, -33, -10, -10, "Network Configuration",
+ StdSendCloseWindowMessageProc);
+ SetObjectExtra (w, ncp, StdCleanupFormProc);
+ ncp->form = (ForM) w;
+ ncp->formmessage = ConfigMessageProc;
+
+ ncp->appmessage = messages;
+ ncp->activate = activate;
+ SetActivate (w, ConfigFormActivate);
+
+ ncp->accepted = accepted;
+ ncp->cancelled = cancelled;
+ ncp->turnedOff = turnedOff;
+
+ h = HiddenGroup (w, -1, 0, NULL);
+ SetGroupSpacing (h, 5, 10);
+
+ j = HiddenGroup (h, 2, 0, NULL);
+ ppt0 = StaticPrompt (j, "Connection", 0, 0, programFont, 'l');
+ ncp->srvConnMode = HiddenGroup (j, 4, 0, ChangeConnection);
+ SetObjectExtra (ncp->srvConnMode, ncp, NULL);
+ rb = RadioButton (ncp->srvConnMode, "None");
+ RadioButton (ncp->srvConnMode, "Normal");
+ RadioButton (ncp->srvConnMode, "Firewall");
+ /* RadioButton (ncp->srvConnMode, "Stateless"); */
+ SetValue (ncp->srvConnMode, 2);
+ if (turnedOff == NULL) {
+ Disable (rb);
+ }
+ AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt0, (HANDLE) ncp->srvConnMode, NULL);
+
+ ncp->netGroup = HiddenGroup (h, -1, 0, NULL);
+ SetGroupSpacing (ncp->netGroup, 5, 10);
+
+ z = HiddenGroup (ncp->netGroup, -4, 0, NULL);
+ StaticPrompt (z, "Proxy", 0, dialogTextHeight, programFont, 'l');
+ ncp->proxyHost = DialogText (z, "", 15, ChangeProxy);
+ SetObjectExtra (ncp->proxyHost, ncp, NULL);
+ StaticPrompt (z, "", 0, 0, programFont, 'l');
+ StaticPrompt (z, "", 0, 0, programFont, 'l');
+ ppt0 = StaticPrompt (z, "Port ", 0, dialogTextHeight, programFont, 'l');
+ ncp->proxyPort = DialogText (z, "", 3, NULL);
+ StaticPrompt (z, " ", 0, 0, programFont, 'l');
+ ncp->transparentProxy = CheckBox (z, "Transparent Proxy", NULL);
+ AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt0, (HANDLE) ncp->proxyPort,
+ (HANDLE) ncp->transparentProxy, NULL);
+
+ g = HiddenGroup (ncp->netGroup, 5, 0, NULL);
+ /*
+ ppt0 = StaticPrompt (g, "Domain name server", 0, 0, programFont, 'l');
+ ncp->dnsAvailable = CheckBox (g, "Available", NULL);
+ */
+ ncp->dnsAvailable = CheckBox (g, "Domain Name Server", NULL);
+ SetStatus (ncp->dnsAvailable, TRUE);
+ /* StaticPrompt (g, " ", 0, 0, programFont, 'l'); */
+ ppt1 = StaticPrompt (g, "Timeout", 0, popupMenuHeight, programFont, 'l');
+ ncp->timeOut = PopupList (g, TRUE, NULL);
+ PopupItem (ncp->timeOut, "10 seconds");
+ PopupItem (ncp->timeOut, "30 seconds");
+ PopupItem (ncp->timeOut, "60 seconds");
+ PopupItem (ncp->timeOut, " 5 minutes");
+ SetValue (ncp->timeOut, 2);
+ AlignObjects (ALIGN_MIDDLE, /* (HANDLE) ppt0, */ (HANDLE) ncp->dnsAvailable,
+ (HANDLE) ppt1, (HANDLE) ncp->timeOut, NULL);
+
+ c = HiddenGroup (w, 4, 0, NULL);
+ SetGroupSpacing (c, 10, 2);
+ ncp->accept = PushButton (c, "Accept", AcceptNetConfigForm);
+ SetObjectExtra (ncp->accept, ncp, NULL);
+ b = PushButton (c, "Cancel", StdSendCancelButtonMessageProc);
+ SetObjectExtra (b, ncp, NULL);
+
+ AlignObjects (ALIGN_CENTER, (HANDLE) h, (HANDLE) c, NULL);
+
+ RealizeWindow (w);
+
+ if (! netCurrentlyOn) {
+ SafeSetValue (ncp->srvConnMode, 1);
+ Hide (ncp->netGroup);
+ } else if (GetAppParam ("NCBI", "NET_SERV", "SRV_CONN_MODE", "WWW", str, sizeof (str))) {
+ if (StringICmp (str, "FIREWALL") == 0) {
+ SafeSetValue (ncp->srvConnMode, 3);
+ }
+ }
+ if (GetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_HOST", NULL, str, sizeof (str))) {
+ if (! StringHasNoText (str)) {
+ SafeSetTitle (ncp->proxyHost, str);
+ if (GetValue (ncp->srvConnMode) == 2) {
+ SafeSetValue (ncp->srvConnMode, 3);
+ }
+ }
+ }
+ if (GetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_PORT", NULL, str, sizeof (str))) {
+ if (! StringHasNoText (str)) {
+ SafeSetTitle (ncp->proxyPort, str);
+ }
+ }
+ if (GetAppParam ("NCBI", "NET_SERV", "SRV_PROXY_TRANSPARENT", NULL, str, sizeof (str))) {
+ if (StringICmp (str, "1") == 0 ||
+ StringICmp (str, "YES") == 0 ||
+ StringICmp (str, "TRUE") == 0) {
+ SafeSetStatus (ncp->transparentProxy, TRUE);
+ }
+ }
+ if (GetAppParam ("NCBI", "NET_SERV", "SRV_ENGINE_HOST", NULL, str, sizeof (str))) {
+ if (StringICmp (str, "130.14.22.106") == 0 || StringICmp (str, "130.14.22.107") == 0 ) {
+ SafeSetStatus (ncp->dnsAvailable, FALSE);
+ }
+ }
+ if (GetAppParam ("NCBI", "NET_SERV", "SRV_CONN_TIMEOUT", "30", str, sizeof (str))) {
+ if (StringICmp (str, "10") == 0) {
+ SafeSetValue (ncp->timeOut, 1);
+ } else if (StringICmp (str, "60") == 0) {
+ SafeSetValue (ncp->timeOut, 3);
+ } else if (StringICmp (str, "300") == 0) {
+ SafeSetValue (ncp->timeOut, 4);
+ } else {
+ SafeSetValue (ncp->timeOut, 2);
+ }
+ }
+
+ ChangeConfigControls (ncp);
+
+ Show (w);
+ Select (w);
+ Select (ncp->proxyHost);
+ }
+}
diff --git a/network/vibnet/netcnfg.h b/network/vibnet/netcnfg.h
new file mode 100644
index 00000000..27a4b1ce
--- /dev/null
+++ b/network/vibnet/netcnfg.h
@@ -0,0 +1,73 @@
+#ifndef NETCNFG__H
+#define NETCNFG__H
+
+/* netcnfg.h
+ * ===========================================================================
+ *
+ * PUBLIC DOMAIN NOTICE
+ * National Center for Biotechnology Information
+ *
+ * This software/database is a "United States Government Work" under the
+ * terms of the United States Copyright Act. It was written as part of
+ * the author's official duties as a United States Government employee and
+ * thus cannot be copyrighted. This software/database is freely available
+ * to the public for use. The National Library of Medicine and the U.S.
+ * Government have not placed any restriction on its use or reproduction.
+ *
+ * Although all reasonable efforts have been taken to ensure the accuracy
+ * and reliability of the software and data, the NLM and the U.S.
+ * Government do not and cannot warrant the performance or results that
+ * may be obtained by using this software or data. The NLM and the U.S.
+ * Government disclaim all warranties, express or implied, including
+ * warranties of performance, merchantability or fitness for any particular
+ * purpose.
+ *
+ * Please cite the author in any work or product based on this material.
+ *
+ * ===========================================================================
+ *
+ * RCS $Id: netcnfg.h,v 6.2 1998/12/08 16:51:00 kans Exp $
+ *
+ * Author: Kans
+ *
+ * Version Creation Date: 9/10/96
+ *
+ * File Description:
+ * Network Entrez configuration
+ *
+ * Modifications:
+ * --------------------------------------------------------------------------
+ * Date Name Description of modification
+ * ------- ---------- -----------------------------------------------------
+ */
+
+#undef NLM_EXTERN
+#ifdef NLM_IMPORT
+#define NLM_EXTERN NLM_IMPORT
+#else
+#define NLM_EXTERN extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+NLM_EXTERN void ShowNetConfigForm(WndActnProc activate,
+ FormMessageFunc messages,
+ VoidProc accepted,
+ VoidProc cancelled,
+ VoidProc turnedOff,
+ Boolean netCurrentlyOn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef NLM_EXTERN
+#ifdef NLM_EXPORT
+#define NLM_EXTERN NLM_EXPORT
+#else
+#define NLM_EXTERN
+#endif
+
+#endif /* NETCNFG__H */
diff --git a/network/vibnet/trmlst.c b/network/vibnet/trmlst.c
new file mode 100644
index 00000000..4bbb05b0
--- /dev/null
+++ b/network/vibnet/trmlst.c
@@ -0,0 +1,3562 @@
+/* trmlst.c
+* ===========================================================================
+*
+* PUBLIC DOMAIN NOTICE
+* National Center for Biotechnology Information (NCBI)
+*
+* This software/database is a "United States Government Work" under the
+* terms of the United States Copyright Act. It was written as part of
+* the author's official duties as a United States Government employee and
+* thus cannot be copyrighted. This software/database is freely available
+* to the public for use. The National Library of Medicine and the U.S.
+* Government do not place any restriction on its use or reproduction.
+* We would, however, appreciate having the NCBI and the author cited in
+* any work or product based on this material
+*
+* Although all reasonable efforts have been taken to ensure the accuracy
+* and reliability of the software and data, the NLM and the U.S.
+* Government do not and cannot warrant the performance or results that
+* may be obtained by using this software or data. The NLM and the U.S.
+* Government disclaim all warranties, express or implied, including
+* warranties of performance, merchantability or fitness for any particular
+* purpose.
+*
+* ===========================================================================
+*
+* File Name: trmlst.c
+*
+* Author: Jonathan Kans, Jonathan Epstein
+*
+* Version Creation Date: 8/5/96
+*
+* $Revision: 6.23 $
+*
+* File Description:
+*
+* Modifications:
+* --------------------------------------------------------------------------
+* Date Name Description of modification
+* ------- ---------- -----------------------------------------------------
+*
+*
+* ==========================================================================
+*/
+
+#include <vibrant.h>
+#include <document.h>
+#include <accentr.h>
+#include <accutils.h>
+#include <vsm.h>
+#include <fstyle.h>
+#include <maputil.h>
+
+#include <entrez.h>
+
+#define MAX_MODES 11
+
+#define STATE_OFF 0
+#define STATE_ON 1
+
+#define GROUP_NONE 0
+#define GROUP_SINGLE 1
+#define GROUP_FIRST 2
+#define GROUP_MIDDLE 3
+#define GROUP_LAST 4
+
+#define OP_NONE 0
+#define OP_OR 1
+#define OP_AND 2
+#define OP_NOT 3
+
+#define FETCH_MODE 1
+#define EVAL_MODE 2
+
+typedef struct trmstatedata {
+ CharPtr term;
+ CharPtr field;
+ Int4 count;
+ Int2 db;
+ Int2 fld;
+ Int2 group;
+ Int2 above;
+ Int2 below;
+ Int2 state;
+ struct trmstatedata PNTR prev;
+ struct trmstatedata PNTR next;
+} StateData, PNTR StateDataPtr;
+
+typedef struct termformdata {
+ FORM_MESSAGE_BLOCK
+
+ PopuP database;
+ PopuP PNTR fields;
+ PopuP modes [MAX_MODES];
+ ButtoN accept;
+ GrouP termGrp;
+ TexT term;
+ GrouP rangeGrp;
+ TexT from;
+ TexT to;
+ PopuP taxParents;
+ ValNodePtr taxStrings;
+
+ DoC avail;
+ Int2 avItem;
+ Int2 avRow;
+ Int2 avClickItem;
+ Int2 avClickRow;
+
+ Boolean wasDoubleClick;
+ Boolean textChanged;
+ Int2 currentPage;
+ Int2 okayToAccept;
+
+ DoC chosen;
+ Int2 chItem;
+ Int2 chClickItem;
+ Int2 chClickRow;
+ Int2 chClickCol;
+ Boolean inAboveBox;
+ Boolean inBelowBox;
+ RecT trackRect;
+ PoinT trackPt;
+
+ Int2 numChosenLines;
+ StateDataPtr state;
+
+ TexT advBoolText;
+ Boolean usingAdv;
+ Int2 retrieveMode;
+
+ ButtoN retrieve;
+ ButtoN reset;
+
+ EnumFieldAssocPtr dbalist;
+ EnumFieldAssocPtr PNTR fldalists;
+ Int2Ptr modeFromField;
+ Int2Ptr fieldModeValues;
+
+ Int2 numdbs;
+ Int2 numflds;
+ Int2 nummods;
+
+ Int4Ptr uids;
+ ValNodePtr elst;
+
+ Int2 currDb;
+ Int2 currFld;
+ Int2 currMod;
+
+ Int2 chosenDb;
+} TermFormData, PNTR TermFormPtr;
+
+#define SELECTION_MODE 1
+#define AUTOMATIC_MODE 2
+#define TRUNC_MULT_MODE 3
+#define TRUNCATION_MODE 4
+#define MESH_TREE_MODE 5
+#define TAXONOMY_MODE 6
+#define RANGE_MODE 7
+#define LOOKUP_ACCN_MODE 8
+#define LOOKUP_UID_MODE 9
+
+static ENUM_ALIST(selmultrm_mode_alist)
+ {"Automatic", AUTOMATIC_MODE},
+ {"Range", RANGE_MODE},
+ {"Selection", SELECTION_MODE},
+ {"Truncation", TRUNC_MULT_MODE},
+END_ENUM_ALIST
+
+static ENUM_ALIST(selmultru_mode_alist)
+ {"Automatic", AUTOMATIC_MODE},
+ {"Range", RANGE_MODE},
+ {"Selection", SELECTION_MODE},
+ {"Truncation", TRUNCATION_MODE},
+END_ENUM_ALIST
+
+static ENUM_ALIST(seltru_mode_alist)
+ {"Range", RANGE_MODE},
+ {"Selection", SELECTION_MODE},
+ {"Truncation", TRUNCATION_MODE},
+END_ENUM_ALIST
+
+static ENUM_ALIST(seltrulkp_mode_alist)
+ {"Lookup", LOOKUP_ACCN_MODE},
+ {"Range", RANGE_MODE},
+ {"Selection", SELECTION_MODE},
+ {"Truncation", TRUNCATION_MODE},
+END_ENUM_ALIST
+
+static ENUM_ALIST(seltrumsh_mode_alist)
+ {"MeSH Tree", MESH_TREE_MODE},
+ {"Range", RANGE_MODE},
+ {"Selection", SELECTION_MODE},
+ {"Truncation", TRUNCATION_MODE},
+END_ENUM_ALIST
+
+static ENUM_ALIST(seltrutax_mode_alist)
+ {"Range", RANGE_MODE},
+ {"Selection", SELECTION_MODE},
+ {"Taxonomy", TAXONOMY_MODE},
+ {"Truncation", TRUNCATION_MODE},
+END_ENUM_ALIST
+
+static ENUM_ALIST(lkp_mode_alist)
+ {"Lookup", LOOKUP_UID_MODE},
+END_ENUM_ALIST
+
+static EnumFieldAssocPtr mode_alists [] = {
+ selmultrm_mode_alist, selmultru_mode_alist, seltru_mode_alist,
+ seltrulkp_mode_alist, seltrumsh_mode_alist,
+ seltrutax_mode_alist, lkp_mode_alist, NULL
+};
+
+#define POPUP_SEL_MUL_TRM 0
+#define POPUP_SEL_MUL_TRU 1
+#define POPUP_SEL_TRU 2
+#define POPUP_SEL_TRU_LKP 3
+#define POPUP_SEL_TRU_MSH 4
+#define POPUP_SEL_TRU_TAX 5
+#define POPUP_LKP 6
+
+extern Int2 DatabaseFromName (CharPtr name)
+
+{
+ Int2 db;
+ EntrezInfoPtr eip;
+
+ if (name == NULL) return 0;
+ eip = EntrezGetInfo ();
+ if (eip == NULL || eip->type_info == NULL) return 0;
+ for (db = 0; db < eip->type_count; db++) {
+ if (StringICmp (eip->type_info [db].name, name) == 0) {
+ return eip->type_info [db].id;
+ }
+ }
+ return 0;
+}
+
+extern Int2 FieldFromTag (CharPtr tag)
+
+{
+ EntrezInfoPtr eip;
+ Int2 fld;
+
+ if (tag == NULL) return 0;
+ eip = EntrezGetInfo ();
+ if (eip == NULL || eip->field_info == NULL) return 0;
+ for (fld = 0; fld < eip->field_count; fld++) {
+ if (StringICmp (eip->field_info [fld].tag, tag) == 0) {
+ return eip->field_info [fld].id;
+ }
+ }
+ return 0;
+}
+
+static CharPtr TagFromField (Int2 fld)
+
+{
+ EntrezInfoPtr eip;
+
+ eip = EntrezGetInfo ();
+ if (eip == NULL || eip->field_info == NULL) return NULL;
+ if (fld >= eip->field_count) return NULL;
+ return eip->field_info [fld].tag;
+}
+
+static void StripNewLine (CharPtr str)
+
+{
+ CharPtr chptr;
+
+ if (StringHasNoText (str)) return;
+ chptr = StringRChr (str, '\n');
+ if (chptr != NULL) {
+ *chptr = '\0';
+ }
+ chptr = StringRChr (str, '\r');
+ if (chptr != NULL) {
+ *chptr = '\0';
+ }
+}
+
+static int loadedlist = 0; /* guarantees that each loaded list has a unique name */
+
+static void DoTLLoadUidList (TermFormPtr tfp)
+
+{
+ ByteStorePtr bsp;
+ Int2 db = -1;
+ EntrezGlobalsPtr egp;
+ FILE *fp;
+ Int2 num;
+ Char path [PATH_MAX];
+ Char str [32];
+ Int4 uid;
+ Int4Ptr uids;
+
+
+ if (tfp == NULL) return;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL || egp->loadNamedUidProc == NULL) return;
+ if (! GetInputFileName (path, sizeof (path), "", "TEXT")) return;
+ fp = FileOpen (path, "r");
+ if (fp == NULL) return;
+ bsp = BSNew (128);
+ if (bsp == NULL) {
+ FileClose (fp);
+ return;
+ }
+ if (FileGets (str, sizeof (str), fp)) {
+ StripNewLine (str);
+ if (StringStr (str, ">PubMed")) {
+ db = 0;
+ } else if (StringStr (str, ">Protein")) {
+ db = 1;
+ } else if (StringStr (str, ">Nucleotide")) {
+ db = 2;
+ } else if (StringStr (str, ">Structure")) {
+ db = 3;
+ } else if (StringStr (str, ">Genome")) {
+ db = 4;
+ }
+ if (db != -1) {
+ while (FileGets (str, sizeof (str), fp)) {
+ StripNewLine (str);
+ if (str [0] != '\0' && StrToLong (str, &uid)) {
+ BSWrite (bsp, &uid, sizeof (DocUid));
+ }
+ }
+ BSSeek (bsp, 0L, 0);
+ num = (Int2) ((BSLen (bsp)) / sizeof (Int4));
+ uids = (Int4Ptr) BSMerge (bsp, NULL);
+ if (uids != NULL) {
+ loadedlist++;
+ sprintf (str, "*loaded_list_%d", (int) loadedlist);
+ egp->loadNamedUidProc (tfp->form, str, num, uids, db);
+ }
+ MemFree (uids);
+ } else {
+ Message (MSG_POSTERR,
+ "First line must be >PubMed, >Protein, >Nucleotide, >Structure, or >Genome");
+ }
+ }
+ BSFree (bsp);
+ FileClose (fp);
+}
+
+static void DoTLSaveUidList (TermFormPtr tfp)
+
+{
+ ByteStorePtr bs;
+ CharPtr curstr;
+ FILE *fp;
+ Int4 j;
+ Int4 numLinks;
+ Char path [PATH_MAX];
+ Char str [32];
+ Int4 uid;
+
+ if (tfp == NULL) return;
+ if (! GetOutputFileName (path, sizeof (path), NULL)) return;
+#ifdef WIN_MAC
+ FileCreate (path, "TEXT", "ttxt");
+#endif
+ fp = FileOpen (path, "w");
+ if (fp == NULL) return;
+ WatchCursor ();
+ switch (tfp->currDb) {
+ case 0 :
+ StringCpy (str, ">PubMed\n");
+ break;
+ case 1 :
+ StringCpy (str, ">Protein\n");
+ break;
+ case 2 :
+ StringCpy (str, ">Nucleotide\n");
+ break;
+ case 3 :
+ StringCpy (str, ">Structure\n");
+ break;
+ case 4 :
+ StringCpy (str, ">Genome\n");
+ break;
+ default :
+ StringCpy (str, ">?\n");
+ break;
+ }
+ FilePuts (str, fp);
+ bs = NULL;
+ if (tfp->usingAdv) {
+ curstr = SaveStringFromText (tfp->advBoolText);
+ bs = EntrezTLEvalXString (curstr, tfp->currDb, -1, NULL, NULL);
+ MemFree (curstr);
+ } else {
+ bs = EntrezTLEvalX (tfp->elst);
+ }
+ if (bs == NULL) {
+ ArrowCursor ();
+ return;
+ }
+ numLinks = BSLen (bs) / sizeof (DocUid);
+ BSSeek (bs, 0L, 0);
+ for (j = 0; j < numLinks; j++) {
+ BSRead (bs, &uid, sizeof(DocUid));
+ sprintf (str, "%ld\n", (long) uid);
+ FilePuts (str, fp);
+ }
+ BSFree (bs);
+ FileClose (fp);
+ ArrowCursor ();
+}
+
+extern void TLLoadUidListProc (IteM i)
+
+{
+ TermFormPtr tfp;
+
+#ifdef WIN_MAC
+ tfp = (TermFormPtr) currentFormDataPtr;
+#else
+ tfp = (TermFormPtr) GetObjectExtra (i);
+#endif
+ if (tfp == NULL) return;
+ DoTLLoadUidList (tfp);
+}
+
+extern void TLSaveUidListProc (IteM i)
+
+{
+ TermFormPtr tfp;
+
+#ifdef WIN_MAC
+ tfp = (TermFormPtr) currentFormDataPtr;
+#else
+ tfp = (TermFormPtr) GetObjectExtra (i);
+#endif
+ if (tfp == NULL) return;
+ DoTLSaveUidList (tfp);
+}
+
+static void EntrezTermListFormMessage (ForM f, Int2 mssg)
+
+{
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (f);
+ if (tfp != NULL) {
+ switch (mssg) {
+ case VIB_MSG_CUT :
+ StdCutTextProc (NULL);
+ break;
+ case VIB_MSG_COPY :
+ StdCopyTextProc (NULL);
+ break;
+ case VIB_MSG_IMPORT :
+ DoTLLoadUidList (tfp);
+ break;
+ case VIB_MSG_EXPORT :
+ DoTLSaveUidList (tfp);
+ break;
+ case VIB_MSG_PASTE :
+ StdPasteTextProc (NULL);
+ break;
+ case VIB_MSG_DELETE :
+ StdDeleteTextProc (NULL);
+ break;
+ default :
+ if (tfp->appmessage != NULL) {
+ tfp->appmessage (f, mssg);
+ }
+ break;
+ }
+ }
+}
+
+static void SetTermListImportExportItems (TermFormPtr tfp)
+
+{
+ IteM importItm;
+ IteM exportItm;
+
+ importItm = FindFormMenuItem ((BaseFormPtr) tfp, VIB_MSG_IMPORT);
+ if (importItm != NULL) {
+ SafeSetTitle (importItm, "Import Uid List...");
+ }
+ exportItm = FindFormMenuItem ((BaseFormPtr) tfp, VIB_MSG_EXPORT);
+ if (exportItm != NULL) {
+ SafeSetTitle (exportItm, "Export Uid List...");
+ }
+}
+
+static void EntrezTermListFormActivate (WindoW w)
+
+{
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (w);
+ if (tfp != NULL) {
+ if (tfp->activate != NULL) {
+ tfp->activate (w);
+ }
+ SetTermListImportExportItems (tfp);
+ }
+}
+
+static StateDataPtr StateDataNew (StateDataPtr sdp)
+
+{
+ StateDataPtr newnode;
+
+ newnode = (StateDataPtr) MemNew (sizeof (StateData));
+ if (sdp != NULL) {
+ while (sdp->next != NULL) {
+ sdp = sdp->next;
+ }
+ sdp->next = newnode;
+ newnode->prev = sdp;
+ }
+ return newnode;
+}
+
+static StateDataPtr StateDataFree (StateDataPtr sdp)
+
+{
+ StateDataPtr next;
+
+ if (sdp != NULL && sdp->prev != NULL) {
+ sdp->prev->next = NULL;
+ }
+ while (sdp != NULL) {
+ next = sdp->next;
+ MemFree (sdp->term);
+ MemFree (sdp->field);
+ MemFree (sdp);
+ sdp = next;
+ }
+ return NULL;
+}
+
+static ParData availParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
+static ColData availColFmt [] = {
+ {0, 5, 70, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE}, /* term */
+ {0, 5, 10, 0, NULL, 'r', FALSE, TRUE, FALSE, FALSE, FALSE}, /* count */
+ {0, 5, 10, 0, NULL, 'r', FALSE, FALSE, FALSE, FALSE, TRUE} /* leaf */
+};
+
+static ParData chosenParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
+static ColData chosenColFmt [] = {
+ {0, 23, 70, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE}, /* term */
+ {0, 5, 10, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE}, /* field */
+ {0, 5, 10, 0, NULL, 'r', FALSE, TRUE, FALSE, FALSE, TRUE} /* count */
+};
+
+static void DoResetAvail (TermFormPtr tfp, Boolean clearTerm)
+
+{
+ Int2 i;
+
+ if (tfp == NULL) return;
+ if (clearTerm) {
+ SafeSetTitle (tfp->term, "");
+ SafeSetTitle (tfp->to, "");
+ SafeSetTitle (tfp->from, "");
+ SafeDisable (tfp->accept);
+ } else if (tfp->currMod == RANGE_MODE) {
+ if (TextHasNoText (tfp->from) && TextHasNoText (tfp->to)) {
+ SafeDisable (tfp->accept);
+ } else {
+ SafeEnable (tfp->accept);
+ }
+ } else {
+ if (TextHasNoText (tfp->term)) {
+ SafeDisable (tfp->accept);
+ } else {
+ SafeEnable (tfp->accept);
+ }
+ }
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ SetDocCache (tfp->avail, NULL, NULL, NULL);
+ for (i = 0; i < 7; i++) {
+ AppendText (tfp->avail, " \n", &availParFmt, availColFmt, systemFont);
+ }
+ InvalDocument (tfp->avail);
+ SafeHide (tfp->taxParents);
+ Reset (tfp->taxParents);
+ tfp->taxStrings = ValNodeFreeData (tfp->taxStrings);
+ if (tfp->currMod == TAXONOMY_MODE || tfp->currMod == MESH_TREE_MODE) {
+ SafeHide (tfp->termGrp);
+ SafeHide (tfp->rangeGrp);
+ SafeShow (tfp->taxParents);
+ } else if (tfp->currMod == RANGE_MODE) {
+ SafeHide (tfp->termGrp);
+ SafeHide (tfp->taxParents);
+ SafeShow (tfp->rangeGrp);
+ Select (tfp->from);
+ } else {
+ SafeHide (tfp->rangeGrp);
+ SafeHide (tfp->taxParents);
+ SafeShow (tfp->termGrp);
+ Select (tfp->term);
+ }
+}
+
+static void DoResetChosen (TermFormPtr tfp)
+
+{
+ Int2 i;
+
+ if (tfp == NULL) return;
+ tfp->uids = MemFree (tfp->uids);
+ tfp->elst = EntrezTLFree (tfp->elst);
+ Reset (tfp->chosen);
+ tfp->state = StateDataFree (tfp->state);
+ for (i = 0; i < 7; i++) {
+ AppendText (tfp->chosen, " \n", &chosenParFmt, chosenColFmt, systemFont);
+ }
+ InvalDocument (tfp->chosen);
+ tfp->numChosenLines = 0;
+ Reset (tfp->advBoolText);
+ SafeSetTitle (tfp->retrieve, "Retrieve 0 Documents");
+ SafeDisable (tfp->retrieve);
+}
+
+static void DoReset (TermFormPtr tfp, Boolean clearTerm)
+
+{
+ DoResetAvail (tfp, clearTerm);
+ DoResetChosen (tfp);
+}
+
+static void ResetProc (ButtoN b)
+
+{
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (b);
+ DoReset (tfp, TRUE);
+}
+
+static ValNodePtr SmartEntrezTLAddTerm (ValNodePtr elst, CharPtr term, DocType type,
+ DocField field, Boolean special)
+
+{
+ CharPtr ptr;
+ CharPtr str;
+ CharPtr tmp;
+ ValNodePtr vnp;
+
+ vnp = NULL;
+ str = StringSave (term);
+ ptr = StringChr (str, ':');
+ if (ptr != NULL) {
+ *ptr = '\0';
+ ptr++;
+ tmp = str;
+ TrimSpacesAroundString (str);
+ TrimSpacesAroundString (ptr);
+ vnp = EntrezTLAddTermWithRange (elst, tmp, type, field, special, ptr);
+ } else {
+ vnp = EntrezTLAddTerm (elst, str, type, field, special);
+ }
+ MemFree (str);
+ return vnp;
+}
+
+static void RecalculateChosen (TermFormPtr tfp)
+
+{
+ Int4 count;
+ CharPtr curstr;
+ Int2 group;
+ Int2 last;
+ StateDataPtr sdp;
+ Char tmp [32];
+
+ if (tfp == NULL) return;
+ count = 0;
+ if (tfp->usingAdv) {
+ tfp->chosenDb = tfp->currDb;
+ tfp->elst = EntrezTLFree (tfp->elst);
+ curstr = SaveStringFromText (tfp->advBoolText);
+ count = EntrezTLEvalCountString (curstr, tfp->chosenDb, -1, NULL, NULL);
+ MemFree (curstr);
+ } else {
+ if (tfp->state == NULL) {
+ SafeSetTitle (tfp->retrieve, "Retrieve 0 Documents");
+ SafeDisable (tfp->retrieve);
+ return;
+ }
+ sdp = tfp->state;
+ if (tfp->numChosenLines < 1) {
+ SafeSetTitle (tfp->retrieve, "Retrieve 0 Documents");
+ SafeDisable (tfp->retrieve);
+ return;
+ }
+ tfp->chosenDb = sdp->db;
+ if (tfp->chosenDb < 0) {
+ SafeSetTitle (tfp->retrieve, "Retrieve 0 Documents");
+ SafeDisable (tfp->retrieve);
+ return;
+ }
+ tfp->elst = EntrezTLFree (tfp->elst);
+ tfp->elst = EntrezTLNew (tfp->chosenDb);
+ group = 0;
+ last = 0;
+ for (sdp = tfp->state; sdp != NULL; sdp = sdp->next) {
+ if (sdp->group == GROUP_SINGLE || sdp->group == GROUP_FIRST) {
+ group++;
+ }
+ if (sdp->state == STATE_ON) {
+ if (last == 0) {
+ EntrezTLAddLParen (tfp->elst);
+ EntrezTLAddLParen (tfp->elst);
+ } else if (last == group) {
+ EntrezTLAddOR (tfp->elst);
+ } else if (sdp->above == OP_NOT) {
+ EntrezTLAddRParen (tfp->elst);
+ EntrezTLAddRParen (tfp->elst);
+ EntrezTLAddBUTNOT (tfp->elst);
+ EntrezTLAddLParen (tfp->elst);
+ EntrezTLAddLParen (tfp->elst);
+ } else {
+ EntrezTLAddRParen (tfp->elst);
+ EntrezTLAddAND (tfp->elst);
+ EntrezTLAddLParen (tfp->elst);
+ }
+ SmartEntrezTLAddTerm (tfp->elst, sdp->term, sdp->db, sdp->fld, FALSE);
+ last = group;
+ }
+ }
+ if (group > 0 && last > 0) {
+ EntrezTLAddRParen (tfp->elst);
+ EntrezTLAddRParen (tfp->elst);
+ }
+ count = EntrezTLEvalCount (tfp->elst);
+ }
+ if (count < 1) {
+ SafeSetTitle (tfp->retrieve, "Retrieve 0 Documents");
+ SafeDisable (tfp->retrieve);
+ return;
+ } else if (count > 1) {
+ sprintf (tmp, "Retrieve %ld Documents", (long) count);
+ } else {
+ sprintf (tmp, "Retrieve %ld Document", (long) count);
+ }
+ SafeSetTitle (tfp->retrieve, tmp);
+ if (count < 1 || count > 32000) {
+ SafeDisable (tfp->retrieve);
+ } else {
+ SafeEnable (tfp->retrieve);
+ }
+}
+
+static void RetrieveDocsProc (ButtoN b)
+
+{
+ ByteStorePtr bs;
+ CharPtr curstr;
+ EntrezGlobalsPtr egp;
+ /*
+ Int2 i, j;
+ */
+ LinkSetPtr lsp;
+ Int4 numLinks;
+ StateDataPtr sdp;
+ TermFormPtr tfp;
+ /*
+ DocUid tmp;
+ Int2 typ_ml;
+ DocUidPtr uids;
+ */
+
+ tfp = (TermFormPtr) GetObjectExtra (b);
+ if (tfp == NULL) return;
+ if (tfp->retrieveMode == EVAL_MODE) {
+ WatchCursor ();
+ Update ();
+ RecalculateChosen (tfp);
+ ArrowCursor ();
+ tfp->retrieveMode = FETCH_MODE;
+ return;
+ }
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL || egp->retrieveDocsProc == NULL) return;
+ SafeSetTitle (tfp->retrieve, "Retrieve 0 Documents");
+ SafeDisable (tfp->retrieve);
+ bs = NULL;
+ if (tfp->usingAdv) {
+ Update ();
+ tfp->chosenDb = tfp->currDb;
+ curstr = SaveStringFromText (tfp->advBoolText);
+ bs = EntrezTLEvalXString (curstr, tfp->chosenDb, -1, NULL, NULL);
+ MemFree (curstr);
+ } else {
+ for (sdp = tfp->state; sdp != NULL; sdp = sdp->next) {
+ sdp->state = STATE_OFF;
+ }
+ InvalDocument (tfp->chosen);
+ Update ();
+ bs = EntrezTLEvalX (tfp->elst);
+ }
+ if (bs == NULL) return;
+ numLinks = BSLen (bs) / sizeof (DocUid);
+ if (numLinks < 32766 /* EntrezGetUserMaxLinks () */ ) {
+ lsp = LinkSetNew ();
+ if (lsp != NULL) {
+ lsp->num = numLinks;
+ lsp->uids = MemNew ((size_t) (numLinks * sizeof(DocUid)));
+ BSSeek (bs, 0L, 0);
+ BSRead (bs, lsp->uids, (numLinks * sizeof(DocUid)));
+ /*
+ typ_ml = DatabaseFromName ("MEDLINE");
+ if (tfp->chosenDb == typ_ml) {
+ i = 0;
+ j = numLinks - 1;
+ uids = lsp->uids;
+ while (i < j) {
+ tmp = uids [i];
+ uids [i] = uids [j];
+ uids [j] = tmp;
+ i++;
+ j--;
+ }
+ }
+ */
+ egp->retrieveDocsProc (tfp->form, (Int2) numLinks, 0, lsp->uids, tfp->chosenDb);
+ LinkSetFree (lsp);
+ }
+ }
+ BSFree (bs);
+ Update ();
+}
+
+static void LoadChosen (TermFormPtr tfp, CharPtr strs, Int2 state,
+ Boolean force, Int4 num, Boolean nofield)
+
+{
+ ValNodePtr elst;
+ Boolean found;
+ StateDataPtr prev;
+ RecT r;
+ BaR sb;
+ StateDataPtr sdp;
+ Int4 special;
+ Char strn [256];
+ Int4 total;
+
+ if (force) {
+ found = TRUE;
+ } else if (tfp->currMod == RANGE_MODE) {
+ found = TRUE;
+ } else {
+ found = EntrezFindTerm (tfp->currDb, tfp->currFld, strs, &special, &total);
+ }
+ if (found) {
+ total = 0;
+ if (force) {
+ total = num;
+ } else {
+ elst = EntrezTLNew (tfp->currDb);
+ SmartEntrezTLAddTerm (elst, strs, tfp->currDb, tfp->currFld, FALSE);
+ total = EntrezTLEvalCount (elst);
+ EntrezTLFree (elst);
+ }
+ if (total > 0) {
+ for (sdp = tfp->state; sdp != NULL; sdp = sdp->next) {
+ if (MeshStringICmp (sdp->term, strs) == 0 &&
+ sdp->db == tfp->currDb && sdp->fld == tfp->currFld) {
+ return;
+ }
+ }
+ (tfp->numChosenLines)++;
+ sdp = StateDataNew (tfp->state);
+ if (tfp->state == NULL) {
+ tfp->state = sdp;
+ }
+ if (sdp != NULL) {
+ sdp->term = StringSave (strs);
+ sdp->count = total;
+ sdp->db = tfp->currDb;
+ if (force) {
+ sdp->fld = 0;
+ } else {
+ sdp->fld = tfp->currFld;
+ }
+ if (nofield) {
+ sdp->field = StringSave ("----");
+ } else {
+ sdp->field = StringSave (TagFromField (sdp->fld));
+ }
+ sdp->group = GROUP_SINGLE;
+ sdp->above = OP_NONE;
+ prev = sdp->prev;
+ if (prev != NULL) {
+ sdp->above = OP_AND;
+ prev->below = OP_AND;
+ }
+ sdp->below = OP_NONE;
+ sdp->state = state;
+ sprintf (strn, "%s\t[%s]\t%ld\n", strs, sdp->field, (long) total);
+ if (tfp->numChosenLines <= 6) {
+ ReplaceText (tfp->chosen, tfp->numChosenLines, strn,
+ &chosenParFmt, chosenColFmt, systemFont);
+ } else {
+ InsertText (tfp->chosen, tfp->numChosenLines, strn,
+ &chosenParFmt, chosenColFmt, systemFont);
+ }
+ InvalDocRows (tfp->chosen, tfp->numChosenLines, 1, 1);
+ AdjustDocScroll (tfp->chosen);
+ sb = GetSlateVScrollBar ((SlatE) tfp->chosen);
+ ResetClip ();
+ SetBarValue (sb, MAX (tfp->numChosenLines - 7, 0));
+ ObjectRect (tfp->chosen, &r);
+ InsetRect (&r, 4, 4);
+ r.right = r.left + 16;
+ InsetRect (&r, -1, -1);
+ Select (tfp->chosen);
+ InvalRect (&r);
+ }
+ Update ();
+ }
+ }
+}
+
+static void RepopulateChosen (TermFormPtr tfp)
+
+{
+ Int2 i;
+ Int4 off;
+ BaR sb;
+ StateDataPtr sdp;
+ Char strn [256];
+
+ if (tfp == NULL) return;
+ sb = GetSlateVScrollBar ((SlatE) tfp->chosen);
+ off = GetBarValue (sb);
+ Reset (tfp->chosen);
+ for (i = 0; i < 7; i++) {
+ AppendText (tfp->chosen, " \n", &chosenParFmt, chosenColFmt, systemFont);
+ }
+ InvalDocument (tfp->chosen);
+ tfp->numChosenLines = 0;
+ for (sdp = tfp->state; sdp != NULL; sdp = sdp->next) {
+ (tfp->numChosenLines)++;
+ sprintf (strn, "%s\t[%s]\t%ld\n", sdp->term, sdp->field, (long) sdp->count);
+ if (tfp->numChosenLines <= 6) {
+ ReplaceText (tfp->chosen, tfp->numChosenLines, strn,
+ &chosenParFmt, chosenColFmt, systemFont);
+ } else {
+ InsertText (tfp->chosen, tfp->numChosenLines, strn,
+ &chosenParFmt, chosenColFmt, systemFont);
+ }
+ }
+ InvalDocument (tfp->chosen);
+ AdjustDocScroll (tfp->chosen);
+ CorrectBarValue (sb, off);
+ Update ();
+}
+
+static void AlphabetizeChosenGroups (TermFormPtr tfp)
+
+{
+ Int2 compare;
+ Boolean keepGoing;
+ StateDataPtr next;
+ StateDataPtr sdp;
+ StateData tmp;
+
+ if (tfp == NULL || tfp->state == NULL) return;
+ keepGoing = TRUE;
+ while (keepGoing) {
+ keepGoing = FALSE;
+ for (sdp = tfp->state; sdp->next != NULL; sdp = sdp->next) {
+ next = sdp->next;
+ if (sdp->group == GROUP_FIRST || sdp->group == GROUP_MIDDLE) {
+ compare = MeshStringICmp (sdp->term, next->term);
+ if (compare > 0) {
+ tmp.term = next->term;
+ tmp.field = next->field;
+ tmp.count = next->count;
+ tmp.db = next->db;
+ tmp.fld = next->fld;
+ next->term = sdp->term;
+ next->field = sdp->field;
+ next->count = sdp->count;
+ next->db = sdp->db;
+ next->fld = sdp->fld;
+ sdp->term = tmp.term;
+ sdp->field = tmp.field;
+ sdp->count = tmp.count;
+ sdp->db = tmp.db;
+ sdp->fld = tmp.fld;
+ keepGoing = TRUE;
+ }
+ }
+ }
+ }
+}
+
+static ValNodePtr termStrings = NULL;
+
+static CharPtr MergeTermStrings (void)
+
+{
+ size_t len;
+ CharPtr str;
+ CharPtr to;
+ ValNodePtr vnp;
+
+ len = 0;
+ vnp = termStrings;
+ while (vnp != NULL) {
+ len += StringLen ((CharPtr) vnp->data.ptrvalue);
+ vnp = vnp->next;
+ }
+ str = (CharPtr) MemNew (len + 4);
+ if (str != NULL) {
+ vnp = termStrings;
+ to = str;
+ while (vnp != NULL) {
+ to = StringMove (to, (CharPtr) vnp->data.ptrvalue);
+ vnp = vnp->next;
+ }
+ }
+ termStrings = ValNodeFreeData (termStrings);
+ return str;
+}
+
+static Boolean ReadTermProc (CharPtr term, Int4 special, Int4 total)
+
+{
+ Char str [256];
+ Char tmp [16];
+
+ StringNCpy_0 (str, term, sizeof (str) - 16);
+ sprintf (tmp, "\t%ld\n", (long) total);
+ StringCat (str, tmp);
+ ValNodeCopyStr (&termStrings, 0, str);
+ MemFree (term);
+ return TRUE;
+}
+
+static CharPtr FetchFromTermList (DoC d, Int2 item, Pointer ptr)
+
+{
+ Int2 numRead;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (d);
+ if (tfp == NULL) return NULL;
+ if (item < 1) return NULL;
+ termStrings = NULL;
+ numRead = EntrezTermListByPage (tfp->currDb, tfp->currFld,
+ item - 1, 1, ReadTermProc);
+ return MergeTermStrings ();
+}
+
+static Boolean ReadOneProc (CharPtr term, Int4 special, Int4 total)
+
+{
+ MemFree (term);
+ return FALSE;
+}
+
+static void ChangeMeshSlashSymbol (CharPtr str)
+
+{
+ Char ch;
+ CharPtr ptr;
+
+ if (str == NULL) return;
+ ptr = str;
+ ch = *ptr;
+ while (ch != '\0') {
+ if (ch == '/') {
+ *ptr = '\31';
+ }
+ ptr++;
+ ch = *ptr;
+ }
+}
+
+/* FindLineOfText assumes a string of text separated by newline,
+ characters, and terminated by a newline */
+
+static Int2 FindLineOfText (CharPtr text, CharPtr str)
+
+{
+ Char ch;
+ Int2 compare;
+ Int2 idx;
+ CharPtr PNTR index;
+ Int2 left;
+ CharPtr lookfor;
+ size_t len;
+ Int2 mid;
+ Int2 numLines;
+ CharPtr ptr;
+ Int2 right;
+
+ mid = 0;
+ if (StringLen (text) == 0 || StringLen (str) == 0) return 0;
+ lookfor = StringSave (str);
+ ChangeMeshSlashSymbol (lookfor);
+ numLines = 0;
+ ptr = text;
+ ch = *ptr;
+ while (ch != '\0') {
+ if (ch == '\n') {
+ numLines++;
+ }
+ ptr++;
+ ch = *ptr;
+ }
+ index = MemNew (sizeof (CharPtr) * (size_t) (numLines + 3));
+ if (index != NULL) {
+ idx = 0;
+ ptr = text;
+ ch = *ptr;
+ index [idx] = ptr;
+ while (ch != '\0') {
+ if (ch == '\n') {
+ idx++;
+ *ptr = '\0';
+ ptr++;
+ ch = *ptr;
+ index [idx] = ptr;
+ } else {
+ ptr++;
+ ch = *ptr;
+ }
+ }
+ }
+ if (numLines > 0) {
+ left = 1;
+ right = numLines;
+ while (left <= right) {
+ mid = (left + right) / 2;
+ compare = StringICmp (lookfor, index [mid - 1]);
+ if (compare <= 0) {
+ right = mid - 1;
+ }
+ if (compare >= 0) {
+ left = mid + 1;
+ }
+ }
+ if (left <= right + 1) {
+ len = StringLen (lookfor);
+ compare = StringNICmp (lookfor, index [mid - 1], len);
+ if (compare > 0) {
+ mid++;
+ if (mid <= numLines) {
+ compare = StringNICmp (lookfor, index [mid - 1], len);
+ if (compare > 0) {
+ mid = 0;
+ }
+ } else {
+ mid = 0;
+ }
+ }
+ }
+ }
+ MemFree (index);
+ MemFree (lookfor);
+ return mid;
+}
+
+static void ChangeUnderscoreToSpace (CharPtr str)
+
+{
+ Char ch;
+ CharPtr ptr;
+
+ if (str == NULL) return;
+ ptr = str;
+ ch = *ptr;
+ while (ch != '\0') {
+ if (ch == '_') {
+ *ptr = ' ';
+ }
+ ptr++;
+ ch = *ptr;
+ }
+}
+
+static void ScrollToText (TermFormPtr tfp, CharPtr str, Int2 page,
+ Boolean hard, Boolean exact)
+
+{
+ Int2 compare;
+ size_t len;
+ Int4 numLines;
+ Int2 oldItem;
+ Int2 oldRow;
+ Int2 perfect;
+ Int2 row;
+ Int4 startsAt;
+ BaR sb;
+ Char temp [256];
+ CharPtr text;
+
+ if (page == 0) return;
+ StringNCpy_0 (temp, str, sizeof (temp));
+ ChangeUnderscoreToSpace (temp);
+ ChangeMeshSlashSymbol (temp);
+ text = GetDocText (tfp->avail, page, 0, 1); /* forces format if not before */
+ GetItemParams4 (tfp->avail, page, &startsAt, NULL, NULL, NULL, NULL);
+ GetDocParams4 (tfp->avail, NULL, &numLines);
+ ChangeMeshSlashSymbol (text);
+ row = FindLineOfText (text, temp);
+ MemFree (text);
+ if (row < 1 || row > numLines) {
+ row = 1;
+ }
+ startsAt += row - 1;
+ sb = GetSlateVScrollBar ((SlatE) tfp->avail);
+ CorrectBarMax (sb, numLines - 7);
+ if (! RowIsVisible (tfp->avail, page, row, NULL, NULL)) {
+ ForceFormat (tfp->avail, page); /* forces UpdateLineStarts */
+ GetItemParams4 (tfp->avail, page, &startsAt, NULL, NULL, NULL, NULL);
+ GetDocParams4 (tfp->avail, NULL, &numLines);
+ startsAt += row - 1;
+ sb = GetSlateVScrollBar ((SlatE) tfp->avail);
+ CorrectBarMax (sb, numLines - 7);
+ if (hard) {
+ SetBarValue (sb, startsAt);
+ } else {
+ CorrectBarValue (sb, startsAt);
+ }
+ }
+ text = GetDocText (tfp->avail, page, row, 1);
+ ChangeMeshSlashSymbol (text);
+ perfect = StringICmp (text, temp);
+ len = StringLen (temp);
+ compare = StringNICmp (text, temp, len);
+ MemFree (text);
+ if (compare == 0) {
+ oldItem = tfp->avItem;
+ oldRow = tfp->avRow;
+ if (oldItem != page || oldRow != row) {
+ tfp->avItem = page;
+ tfp->avRow = row;
+ InvalDocRows (tfp->avail, oldItem, oldRow, oldRow);
+ InvalDocRows (tfp->avail, tfp->avItem, tfp->avRow, tfp->avRow);
+ }
+ if (exact) {
+ if (perfect == 0) {
+ tfp->textChanged = FALSE;
+ }
+ } else {
+ tfp->textChanged = FALSE;
+ }
+ } else {
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ }
+}
+
+static Int2 SmartEntrezTermListByTerm (DocType type, DocField field, CharPtr term,
+ Int2 numterms, TermListProc proc, Int2Ptr first_page)
+
+{
+ Char temp [256];
+
+ StringNCpy_0 (temp, term, sizeof (temp));
+ ChangeUnderscoreToSpace (temp);
+ return EntrezTermListByTerm (type, field, temp, numterms, proc, first_page);
+}
+
+static Boolean LoadAvailList (TermFormPtr tfp, CharPtr str)
+
+{
+ EntrezInfoPtr eip;
+ Int2 page = 0;
+ Boolean rsult;
+ Int2 totalPages;
+
+ rsult = FALSE;
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ SetDocCache (tfp->avail, NULL, NULL, NULL);
+ Update ();
+ if (str [0] != '\0') {
+ eip = EntrezGetInfo ();
+ if (eip != NULL) {
+ totalPages = eip->types [tfp->currDb].fields [tfp->currFld].num_bucket;
+ } else {
+ totalPages = 0;
+ }
+ if (totalPages > 0) {
+ if (StringHasNoText (str) && str [0] == ' ') {
+ page = 0;
+ } else {
+ SmartEntrezTermListByTerm (tfp->currDb, tfp->currFld, str,
+ 1, ReadOneProc, &page);
+ }
+ /*
+ for (i = 0; i < totalPages; i++) {
+ AppendItem (tfp->avail, FetchFromTermList, NULL, FALSE, 30,
+ &availParFmt, availColFmt, systemFont);
+ }
+ */
+ BulkAppendItem (tfp->avail, totalPages, FetchFromTermList, 30,
+ &availParFmt, availColFmt, systemFont);
+ AppendText (tfp->avail, "\n\n\n\n\n\n\n\n\n\n\n\n \n",
+ &availParFmt, availColFmt, systemFont);
+ /*
+ twoBlankPages = "\n\n\n\n\n\n\n\n\n\n\n\n \n";
+ AppendText (tfp->avail, twoBlankPages,
+ &availParFmt, availColFmt, systemFont);
+ */
+ page++;
+ SetDocCache (tfp->avail, StdPutDocCache, StdGetDocCache, StdResetDocCache);
+ tfp->currentPage = page;
+ ScrollToText (tfp, str, page, FALSE, FALSE);
+ InvalDocument (tfp->avail);
+ Update ();
+ AdjustDocScroll (tfp->avail);
+ }
+ }
+ return rsult;
+}
+
+static void TruncateTerm (TermFormPtr tfp, CharPtr strs)
+
+{
+ if (StringChr (strs, '*') == NULL && StringChr (strs, '?') == NULL) {
+ StringCat (strs, "...");
+ }
+ LoadChosen (tfp, strs, STATE_ON, FALSE, 0, FALSE);
+}
+
+static Boolean ReadAFew (TermFormPtr tfp, CharPtr str, CharPtr actual, size_t maxsize)
+
+{
+ Char first [256];
+ Boolean found;
+ Int2 page;
+ CharPtr ptr;
+ CharPtr txt;
+
+ found = FALSE;
+ termStrings = NULL;
+ SmartEntrezTermListByTerm (tfp->currDb, tfp->currFld, str,
+ 7, ReadTermProc, &page);
+ if (termStrings != NULL) {
+ StringNCpy_0 (first, termStrings->data.ptrvalue, sizeof (first));
+ ptr = StringChr (first, '\t');
+ if (ptr != NULL) {
+ *ptr = '\0';
+ }
+ if (StringICmp (str, first) == 0) {
+ found = TRUE;
+ } else {
+ StringNCpy_0 (actual, first, maxsize);
+ }
+ }
+ txt = MergeTermStrings ();
+ AppendText (tfp->avail, txt, &availParFmt, availColFmt, systemFont);
+ MemFree (txt);
+ if (found) {
+ tfp->avItem = 1;
+ tfp->avRow = 1;
+ }
+ InvalDocument (tfp->avail);
+ return found;
+}
+
+static void ProcessMultipleTerms (TermFormPtr tfp, CharPtr strs)
+
+{
+ Char actual [256];
+ Char ch;
+ Boolean found;
+ Int2 i;
+ Int2 j;
+ Int2 k;
+ Char str [256];
+
+ i = 0;
+ while (StringLen (strs + i) > 0) {
+ StringNCpy_0 (str, strs + i, sizeof (str));
+ k = 0;
+ ch = str [k];
+ while (ch == ' ') {
+ k++;
+ ch = str [k];
+ }
+ j = 0;
+ if (ch == '"') {
+ k++;
+ ch = str [j + k];
+ while (ch != '\0' && ch != '"') {
+ j++;
+ ch = str [j + k];
+ }
+ if (ch == '"') {
+ str [j + k] = '\0';
+ i += j + k + 1;
+ } else {
+ i += j + k;
+ }
+ } else {
+ while (ch != '\0' && ch != ' ') {
+ j++;
+ ch = str [j + k];
+ }
+ if (ch == ' ') {
+ str [j + k] = '\0';
+ i += j + k + 1;
+ } else {
+ i += j + k;
+ }
+ }
+ if (StringLen (str + k) > 0) {
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ actual [0] = '\0';
+ found = ReadAFew (tfp, str + k, actual, sizeof (actual));
+ Update ();
+ if (tfp->currMod == TRUNC_MULT_MODE) {
+ TruncateTerm (tfp, str + k);
+ } else if (found) {
+ LoadChosen (tfp, str + k, STATE_ON, FALSE, 0, FALSE);
+ } else {
+ LoadChosen (tfp, actual, STATE_OFF, FALSE, 0, FALSE);
+ }
+ }
+ }
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ for (i = 0; i < 7; i++) {
+ AppendText (tfp->avail, " \n", &availParFmt, availColFmt, systemFont);
+ }
+ InvalDocument (tfp->avail);
+ SafeSetTitle (tfp->term, "");
+ SafeSetTitle (tfp->from, "");
+ SafeSetTitle (tfp->to, "");
+ SafeDisable (tfp->accept);
+ if (Visible (tfp->term)) {
+ Select (tfp->term);
+ }
+}
+
+static void ProcessDirectLookup (TermFormPtr tfp, CharPtr str)
+
+{
+ DocSumPtr dsp;
+ EntrezGlobalsPtr egp;
+ LinkSetPtr lsp;
+ Int4 uid;
+
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL || egp->retrieveDocsProc == NULL) return;
+ uid = 0;
+ if (tfp->currMod == LOOKUP_ACCN_MODE) {
+ if (StringLen (str) > 0) {
+ lsp = EntrezTLEvalString (str, tfp->currDb, tfp->currFld, NULL, NULL);
+ if (lsp != NULL && lsp->num > 0 && lsp->uids != NULL) {
+ uid = lsp->uids [0];
+ }
+ LinkSetFree (lsp);
+ }
+ } else if (tfp->currMod == LOOKUP_UID_MODE) {
+ if (! StrToLong (str, &uid)) {
+ Message (MSG_OK, "You must enter an integer");
+ return;
+ }
+ } else return;
+ if (uid > 0) {
+ dsp = EntrezDocSum (tfp->currDb, uid);
+ if (dsp != NULL) {
+ DocSumFree (dsp);
+ if (egp->lookupDirect) {
+ if (egp->launchViewerProc != NULL) {
+ egp->launchViewerProc (tfp->form, uid, 0, NULL, tfp->currDb);
+ }
+ } else {
+ egp->retrieveDocsProc (tfp->form, 1, 0, &uid, tfp->currDb);
+ }
+ } else {
+ Message (MSG_OK, "This record is not present in the database");
+ }
+ } else {
+ if (tfp->currMod == LOOKUP_ACCN_MODE) {
+ Message (MSG_OK, "This accession is not present in the database");
+ } else {
+ Message (MSG_OK, "This UID is not present in the database");
+ }
+ }
+}
+
+static void AcceptProc (ButtoN b)
+
+{
+ Char ch;
+ Int2 i;
+ CharPtr ptr;
+ Char str [256];
+ CharPtr text;
+ TermFormPtr tfp;
+ Char tmp [128];
+
+ tfp = (TermFormPtr) GetObjectExtra (b);
+ if (tfp == NULL) return;
+ str [0] = '\0';
+ if (tfp->currMod == RANGE_MODE) {
+ GetTitle (CurrentText (), str, sizeof (str));
+ } else {
+ GetTitle (tfp->term, str, sizeof (str));
+ }
+ if (str [0] == '\0') return;
+ WatchCursor ();
+ switch (tfp->currMod) {
+ case SELECTION_MODE :
+ if (tfp->textChanged) {
+ LoadAvailList (tfp, str);
+ tfp->textChanged = FALSE;
+ tfp->okayToAccept = FALSE;
+ } else if (tfp->okayToAccept) {
+ if (tfp->avItem > 0 && tfp->avRow > 0) {
+ text = GetDocText (tfp->avail, tfp->avItem, tfp->avRow, 1);
+ if (text != NULL) {
+ ptr = text;
+ ch = *ptr;
+ while (ch != '\0' && ch >= ' ') {
+ ptr++;
+ ch = *ptr;
+ }
+ *ptr = '\0';
+ SafeSetTitle (tfp->term, text);
+ Select (tfp->term);
+ Update ();
+ StringNCpy_0 (str, text, sizeof (str));
+ }
+ MemFree (text);
+ LoadChosen (tfp, str, STATE_ON, FALSE, 0, FALSE);
+ Select (tfp->term);
+ /* tfp->okayToAccept = FALSE; */
+ }
+ }
+ break;
+ case AUTOMATIC_MODE :
+ case TRUNC_MULT_MODE :
+ ProcessMultipleTerms (tfp, str);
+ break;
+ case TRUNCATION_MODE :
+ TruncateTerm (tfp, str);
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ for (i = 0; i < 7; i++) {
+ AppendText (tfp->avail, " \n", &availParFmt, availColFmt, systemFont);
+ }
+ InvalDocument (tfp->avail);
+ SafeSetTitle (tfp->term, "");
+ SafeDisable (tfp->accept);
+ if (Visible (tfp->term)) {
+ Select (tfp->term);
+ }
+ break;
+ case MESH_TREE_MODE :
+ ptr = str;
+ while (*ptr != '\0' && *ptr != '{') {
+ ptr++;
+ }
+ *ptr = '\0';
+ LoadChosen (tfp, str, STATE_ON, FALSE, 0, FALSE);
+ case TAXONOMY_MODE :
+ LoadChosen (tfp, str, STATE_ON, FALSE, 0, FALSE);
+ break;
+ case RANGE_MODE :
+ if (tfp->textChanged) {
+ LoadAvailList (tfp, str);
+ tfp->textChanged = FALSE;
+ tfp->okayToAccept = FALSE;
+ } else if (tfp->okayToAccept) {
+ /*
+ if (tfp->avItem > 0 && tfp->avRow > 0) {
+ text = GetDocText (tfp->avail, tfp->avItem, tfp->avRow, 1);
+ if (text != NULL) {
+ ptr = text;
+ ch = *ptr;
+ while (ch != '\0' && ch >= ' ') {
+ ptr++;
+ ch = *ptr;
+ }
+ *ptr = '\0';
+ SafeSetTitle (CurrentText (), text);
+ Update ();
+ }
+ MemFree (text);
+ }
+ */
+ GetTitle (tfp->from, str, sizeof (str));
+ GetTitle (tfp->to, tmp, sizeof (tmp));
+ StringCat (str, ":");
+ StringCat (str, tmp);
+ LoadChosen (tfp, str, STATE_ON, FALSE, 0, FALSE);
+ Select (tfp->from);
+ tfp->okayToAccept = FALSE;
+ }
+ break;
+ case LOOKUP_ACCN_MODE :
+ case LOOKUP_UID_MODE :
+ ProcessDirectLookup (tfp, str);
+ ArrowCursor ();
+ Update ();
+ return;
+ default :
+ break;
+ }
+ Update ();
+ RecalculateChosen (tfp);
+ ArrowCursor ();
+ Update ();
+}
+
+static void AvailTimerProc (WindoW w)
+
+{
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (w);
+ if (tfp == NULL) return;
+ tfp->okayToAccept = TRUE;
+}
+
+static void TextAction (TexT t)
+
+{
+ Int2 i;
+ Char str [256];
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (t);
+ if (tfp == NULL) return;
+ if (tfp->currMod == RANGE_MODE) {
+ if (TextHasNoText (tfp->from) && TextHasNoText (tfp->to)) {
+ SafeDisable (tfp->accept);
+ } else {
+ SafeEnable (tfp->accept);
+ }
+ } else {
+ GetTitle (tfp->term, str, sizeof (str));
+ if (StringHasNoText (str)) {
+ if (tfp->currMod == SELECTION_MODE && str [0] == ' ') {
+ SafeEnable (tfp->accept);
+ } else {
+ SafeDisable (tfp->accept);
+ }
+ } else {
+ SafeEnable (tfp->accept);
+ }
+ }
+ GetTitle (t, str, sizeof (str));
+ if (str [0] == '\0') {
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ for (i = 0; i < 7; i++) {
+ AppendText (tfp->avail, " \n", &availParFmt, availColFmt, systemFont);
+ }
+ InvalDocument (tfp->avail);
+ tfp->textChanged = FALSE;
+ tfp->okayToAccept = FALSE;
+ tfp->currentPage = 0;
+ } else {
+ tfp->textChanged = TRUE;
+ tfp->okayToAccept = FALSE;
+ if (tfp->currentPage > 0) {
+ ScrollToText (tfp, str, tfp->currentPage, TRUE, TRUE);
+ }
+ Update ();
+ }
+}
+
+static void AddPopupItem (PopuP p, CharPtr str, Int2 maxwid)
+
+{
+ Char ch;
+ Int2 hbounds;
+ Int2 i;
+ CharPtr ptr;
+ Char title [256];
+ Int2 wid;
+
+ if (p != NULL && str != NULL) {
+ StringNCpy_0 (title, str, sizeof (title));
+ i = StringLen (title);
+ /*
+ while (i < sizeof (title) - 1) {
+ title [i] = ' ';
+ i++;
+ }
+ */
+ title [i] = '\0';
+ ptr = title;
+ ch = *ptr;
+ while (ch != '\0') {
+ if (ch == '/') {
+ *ptr = '-';
+ }
+ ptr++;
+ ch = *ptr;
+ }
+#ifdef WIN_MAC
+ hbounds = 13;
+#endif
+#ifdef WIN_MSWIN
+ hbounds = 13;
+#endif
+#ifdef WIN_MOTIF
+ hbounds = 24;
+#endif
+ maxwid -= StringWidth ("...") + hbounds * 2 + StringWidth (" ");
+ wid = 0;
+ i = 0;
+ ch = title [i];
+ while (ch != '\0' && wid <= maxwid) {
+ wid += CharWidth (ch);
+ i++;
+ ch = title [i];
+ }
+ title [i] = '\0';
+ if (ch != '\0' && i <= (Int2) StringLen (str)) {
+ StringCat (title, "...");
+ }
+ PopupItem (p, title);
+ }
+}
+
+static Boolean RepopulateTaxonomy (TermFormPtr tfp, CharPtr taxterm)
+
+{
+ CharPtr canonicalForm;
+ EntrezHierarchyChildPtr childPtr;
+ Int2 delta;
+ Int2 fld_mesh_hier;
+ Int2 fld_orgn_hier;
+ Int2 i;
+ Int2 maxwidth;
+ Boolean okay;
+ RecT r;
+ RecT s;
+ Char str [256];
+ EntrezHierarchyPtr taxy;
+ Int2 wid;
+
+ if (tfp == NULL) return FALSE;
+ okay = FALSE;
+ taxy = NULL;
+ if (tfp->currMod == TAXONOMY_MODE) {
+ fld_orgn_hier = FieldFromTag ("ORGN");
+ taxy = EntrezHierarchyGet (taxterm, tfp->currDb, fld_orgn_hier);
+ } else if (tfp->currMod == MESH_TREE_MODE) {
+ fld_mesh_hier = FieldFromTag ("MESH");
+ taxy = EntrezHierarchyGet (taxterm, tfp->currDb, fld_mesh_hier);
+ }
+ if (taxy != NULL) {
+ okay = TRUE;
+ SafeSetTitle (tfp->term, taxterm);
+ Hide (tfp->taxParents);
+ Reset (tfp->taxParents);
+ tfp->taxStrings = ValNodeFreeData (tfp->taxStrings);
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ SetDocCache (tfp->avail, NULL, NULL, NULL);
+ Update ();
+ maxwidth = availColFmt [0].pixWidth;
+ for (i = 0; i < taxy->numInLineage; i++) {
+ AddPopupItem (tfp->taxParents, taxy->lineage [i], maxwidth);
+ ValNodeCopyStr (&(tfp->taxStrings), 0, taxy->lineage [i]);
+ }
+ canonicalForm = taxy->canonicalForm;
+ if (canonicalForm != NULL && *canonicalForm != '\0') {
+ AddPopupItem (tfp->taxParents, canonicalForm, maxwidth);
+ ValNodeCopyStr (&(tfp->taxStrings), 0, canonicalForm);
+ } else {
+ AddPopupItem (tfp->taxParents, taxterm, maxwidth);
+ ValNodeCopyStr (&(tfp->taxStrings), 0, taxterm);
+ }
+ SetValue (tfp->taxParents, taxy->numInLineage + 1);
+ ObjectRect (tfp->taxParents, &r);
+ ObjectRect (tfp->avail, &s);
+ InsetRect (&s, 4, 4);
+ wid = r.right - r.left;
+ delta = (maxwidth - wid) / 2;
+ r.left = s.left + delta;
+ r.right = r.left + wid;
+ SetPosition (tfp->taxParents, &r);
+ childPtr = taxy->children;
+ for (i = 0; i < taxy->numChildren; i++) {
+ sprintf (str, "%s\t%ld\t%d\n", childPtr->name, (long) (childPtr->total),
+ (int) (childPtr->isLeafNode ? 1 : 0));
+ AppendText (tfp->avail, str, &availParFmt, availColFmt, systemFont);
+ childPtr++;
+ }
+ for (i = taxy->numChildren; i < 7; i++) {
+ AppendText (tfp->avail, " \n", &availParFmt, availColFmt, systemFont);
+ }
+ InvalDocument (tfp->avail);
+ Show (tfp->taxParents);
+ Update ();
+ AdjustDocScroll (tfp->avail);
+ EntrezHierarchyFree (taxy);
+ } else {
+ SafeSetTitle (tfp->term, taxterm);
+ Hide (tfp->taxParents);
+ Reset (tfp->taxParents);
+ tfp->taxStrings = ValNodeFreeData (tfp->taxStrings);
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ SetDocCache (tfp->avail, NULL, NULL, NULL);
+ Show (tfp->taxParents);
+ Update ();
+ }
+ return okay;
+}
+
+static void RepopulateTaxonomyRoot (TermFormPtr tfp)
+
+{
+ if (tfp == NULL) return;
+ if (tfp->currDb == DatabaseFromName ("MEDLINE")) {
+ RepopulateTaxonomy (tfp, ".MeSH Root.");
+ } else {
+ RepopulateTaxonomy (tfp, "root");
+ }
+}
+
+static void ChangeTaxParents (PopuP p)
+
+{
+ TermFormPtr tfp;
+ Int2 val;
+ ValNodePtr vnp;
+
+ tfp = (TermFormPtr) GetObjectExtra (p);
+ if (tfp == NULL) return;
+ val = GetValue (p);
+ if (val > 0) {
+ vnp = tfp->taxStrings;
+ while (val > 1 && vnp != NULL) {
+ val--;
+ vnp = vnp->next;
+ }
+ if (vnp != NULL) {
+ WatchCursor ();
+ RepopulateTaxonomy (tfp, (CharPtr) vnp->data.ptrvalue);
+ ArrowCursor ();
+ }
+ }
+}
+
+static Uint1 andsign [] = {
+ 0x30, 0x48, 0x50, 0x20, 0x50, 0x8A, 0x84, 0x8A, 0x71, 0x00
+};
+
+static Uint1 notsign [] = {
+ 0x00, 0x00, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00
+};
+
+static void DrawChosenBrackets (DoC d, RectPtr r, Int2 item, Int2 frst)
+
+{
+ RecT s;
+ StateDataPtr sdp;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (d);
+ if (tfp == NULL) return;
+ sdp = tfp->state;
+ while (sdp != NULL && item > 1) {
+ sdp = sdp->next;
+ item--;
+ }
+ if (sdp == NULL) return;
+ switch (sdp->group) {
+ case GROUP_SINGLE:
+ /*
+ MoveTo (r->left + 16 + 1, r->top + 1);
+ LineTo (r->left + 16 + 3, r->top + 1);
+ MoveTo (r->left + 16 + 1, r->top + 2);
+ LineTo (r->left + 16 + 3, r->top + 2);
+ MoveTo (r->left + 16 + 1, r->top + 1);
+ LineTo (r->left + 16 + 1, r->bottom - 1);
+ MoveTo (r->left + 16 + 1, r->bottom - 2);
+ LineTo (r->left + 16 + 3, r->bottom - 2);
+ MoveTo (r->left + 16 + 1, r->bottom - 1);
+ LineTo (r->left + 16 + 3, r->bottom - 1);
+ */
+ break;
+ case GROUP_FIRST:
+ MoveTo (r->left + 16 + 1, r->top + 1);
+ LineTo (r->left + 16 + 3, r->top + 1);
+ MoveTo (r->left + 16 + 1, r->top + 2);
+ LineTo (r->left + 16 + 3, r->top + 2);
+ MoveTo (r->left + 16 + 1, r->top + 1);
+ LineTo (r->left + 16 + 1, r->bottom);
+ break;
+ case GROUP_MIDDLE:
+ MoveTo (r->left + 16 + 1, r->top);
+ LineTo (r->left + 16 + 1, r->bottom);
+ break;
+ case GROUP_LAST:
+ MoveTo (r->left + 16 + 1, r->top);
+ LineTo (r->left + 16 + 1, r->bottom - 1);
+ MoveTo (r->left + 16 + 1, r->bottom - 2);
+ LineTo (r->left + 16 + 3, r->bottom - 2);
+ MoveTo (r->left + 16 + 1, r->bottom - 1);
+ LineTo (r->left + 16 + 3, r->bottom - 1);
+ break;
+ default:
+ break;
+ }
+ switch (sdp->above) {
+ case OP_NONE:
+ break;
+ case OP_AND:
+ LoadRect (&s, r->left + 6, r->top, r->left + 14, r->top + 5);
+ CopyBits (&s, andsign + 5);
+ break;
+ case OP_NOT:
+ LoadRect (&s, r->left, r->top, r->left + 8, r->top + 5);
+ CopyBits (&s, notsign + 5);
+ break;
+ default:
+ break;
+ }
+ switch (sdp->below) {
+ case OP_NONE:
+ break;
+ case OP_AND:
+ LoadRect (&s, r->left + 6, r->bottom - 5, r->left + 14, r->bottom);
+ CopyBits (&s, andsign);
+ break;
+ case OP_NOT:
+ LoadRect (&s, r->left, r->bottom - 5, r->left + 8, r->bottom);
+ CopyBits (&s, notsign);
+ break;
+ default:
+ break;
+ }
+}
+
+static Boolean HighlightChosen (DoC d, Int2 item, Int2 row, Int2 col)
+
+{
+ StateDataPtr sdp;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (d);
+ if (tfp == NULL) return FALSE;
+ if (col == 1 || col == 2) {
+ if (tfp->inAboveBox || tfp->inBelowBox) return FALSE;
+ /* if (item == tfp->chItem) return TRUE; */
+ return FALSE;
+ } else if (col == 3) {
+ sdp = tfp->state;
+ while (sdp != NULL && item > 1) {
+ sdp = sdp->next;
+ item--;
+ }
+ if (sdp == NULL) return FALSE;
+ return (Boolean) (sdp->state == STATE_ON);
+ } else return FALSE;
+}
+
+static void FrameChosen (TermFormPtr tfp)
+
+{
+ RecT sr;
+
+ if (tfp == NULL) return;
+ ObjectRect (tfp->chosen, &sr);
+ InsetRect (&sr, 4, 4);
+ if (RectInRect (&(tfp->trackRect), &sr)) {
+ Dotted ();
+ FrameRect (&(tfp->trackRect));
+ }
+}
+
+static void ClickChosen (DoC d, PoinT pt)
+
+{
+ Int2 col;
+ Int2 item;
+ RecT r;
+ Int2 row;
+ RecT s;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (d);
+ if (tfp == NULL) return;
+ MapDocPoint (d, pt, &item, &row, &col, &r);
+ if (item > 0 && row == 0 && col > 0) {
+ row = 1;
+ }
+ tfp->chClickItem = item;
+ tfp->chClickRow = row;
+ tfp->chClickCol = col;
+ tfp->wasDoubleClick = dblClick;
+ tfp->inAboveBox = FALSE;
+ tfp->inBelowBox = FALSE;
+ if ((col == 1 || col == 2) && item > 0 && item <= tfp->numChosenLines && row > 0) {
+ tfp->chItem = item;
+ LoadRect (&s, r.left, r.top, r.left + 16, r.top + 5);
+ if (PtInRect (pt, &s)) {
+ tfp->inAboveBox = TRUE;
+ }
+ LoadRect (&s, r.left, r.bottom - 5, r.left + 16, r.bottom);
+ if (PtInRect (pt, &s)) {
+ tfp->inBelowBox = TRUE;
+ }
+ if (tfp->inAboveBox || tfp->inBelowBox) return;
+ InvalDocCols (tfp->chosen, item, 1, 2);
+ Update ();
+ r.right = r.left + chosenColFmt [0].pixWidth + chosenColFmt [1].pixWidth;
+ LoadRect (&(tfp->trackRect), r.left + 22, r.top, r.right - 2, r.bottom);
+ tfp->trackPt = pt;
+ InvertMode ();
+ FrameChosen (tfp);
+ } else {
+ tfp->chItem = 0;
+ }
+}
+
+static void DragChosen (DoC d, PoinT pt)
+
+{
+ Int4 off;
+ BaR sb;
+ RecT sr;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (d);
+ if (tfp == NULL) return;
+ if (tfp->chItem == 0) return;
+ if (tfp->inAboveBox || tfp->inBelowBox) return;
+ InvertMode ();
+ FrameChosen (tfp);
+ Update ();
+ ObjectRect (tfp->chosen, &sr);
+ InsetRect (&sr, 4, 4);
+ if (PtInRect (pt, &sr)) {
+ OffsetRect (&(tfp->trackRect), 0, pt.y - tfp->trackPt.y);
+ tfp->trackPt = pt;
+ }
+ sb = GetSlateVScrollBar ((SlatE) tfp->chosen);
+ off = GetBarValue (sb);
+ ResetClip ();
+ if (pt.y < sr.top) {
+ SetBarValue (sb, off - 1);
+ } else if (pt.y > sr.bottom) {
+ SetBarValue (sb, off + 1);
+ }
+ Update ();
+ InvertMode ();
+ FrameChosen (tfp);
+ Update ();
+}
+
+static void FlipOperatorBelow (TermFormPtr tfp, Int2 item)
+
+{
+ StateDataPtr next;
+ RecT r;
+ StateDataPtr sdp;
+
+ if (tfp == NULL) return;
+ sdp = tfp->state;
+ while (item > 1 && sdp != NULL) {
+ item--;
+ sdp = sdp->next;
+ }
+ if (sdp != NULL) {
+ next = sdp->next;
+ if (next != NULL) {
+ if (sdp->below != next->above) {
+ Beep ();
+ }
+ if (sdp->below == OP_AND) {
+ sdp->below = OP_NOT;
+ next->above = OP_NOT;
+ } else if (sdp->below == OP_NOT) {
+ sdp->below = OP_AND;
+ next->above = OP_AND;
+ }
+ ObjectRect (tfp->chosen, &r);
+ InsetRect (&r, 4, 4);
+ r.right = r.left + 16;
+ Select (tfp->chosen);
+ InvalRect (&r);
+ ResetClip ();
+ WatchCursor ();
+ Update ();
+ RecalculateChosen (tfp);
+ ArrowCursor ();
+ }
+ }
+}
+
+static void ReleaseChosen (DoC d, PoinT pt)
+
+{
+ Int2 col;
+ Boolean goingDown;
+ Int2 inval;
+ Int2 item;
+ Boolean lastDraggedDown;
+ Boolean merge;
+ StateDataPtr next;
+ Int2 oldItem;
+ Int2 op;
+ StateDataPtr prev;
+ RecT r;
+ Int2 row;
+ RecT s;
+ StateDataPtr sdp;
+ RecT sr;
+ TermFormPtr tfp;
+ StateDataPtr tmp;
+
+ tfp = (TermFormPtr) GetObjectExtra (d);
+ if (tfp == NULL) return;
+ MapDocPoint (d, pt, &item, &row, &col, &r);
+ if (item > 0 && row == 0 && col > 0) {
+ row = 1;
+ }
+ if (tfp->inAboveBox || tfp->inBelowBox) {
+ LoadRect (&s, r.left, r.top, r.left + 16, r.top + 5);
+ if (PtInRect (pt, &s)) {
+ if (tfp->inAboveBox && item == tfp->chItem) {
+ FlipOperatorBelow (tfp, tfp->chItem - 1);
+ } else if (tfp->inBelowBox && item == tfp->chItem - 1) {
+ FlipOperatorBelow (tfp, tfp->chItem - 1);
+ }
+ }
+ LoadRect (&s, r.left, r.bottom - 5, r.left + 16, r.bottom);
+ if (PtInRect (pt, &s)) {
+ if (tfp->inBelowBox && item == tfp->chItem) {
+ FlipOperatorBelow (tfp, tfp->chItem);
+ } else if (tfp->inAboveBox && item == tfp->chItem + 1) {
+ FlipOperatorBelow (tfp, tfp->chItem);
+ }
+ }
+ return;
+ }
+ if (tfp->chItem > 0) {
+ oldItem = tfp->chItem;
+ tfp->chItem = 0;
+ InvertMode ();
+ FrameChosen (tfp);
+ Update ();
+ InvalDocCols (tfp->chosen, oldItem, 1, 2);
+ Update ();
+ if (item == oldItem) return;
+ if (tfp->numChosenLines < 2) return;
+ lastDraggedDown = FALSE;
+ if (oldItem == tfp->numChosenLines && item > tfp->numChosenLines) {
+ lastDraggedDown = TRUE;
+ }
+ merge = TRUE;
+ ObjectRect (tfp->chosen, &sr);
+ InsetRect (&sr, 4, 4);
+ if (item > tfp->numChosenLines && PtInRect (pt, &sr)) {
+ merge = FALSE;
+ item = INT2_MAX;
+ }
+ if (item > 0 && tfp->state != NULL) {
+ goingDown = FALSE;
+ if (item > oldItem) {
+ item--;
+ goingDown = TRUE;
+ }
+ sdp = tfp->state;
+ while (oldItem > 1 && sdp != NULL) {
+ oldItem--;
+ sdp = sdp->next;
+ }
+ if (sdp != NULL) {
+ next = sdp->next;
+ prev = sdp->prev;
+ switch (sdp->group) {
+ case GROUP_SINGLE :
+ if (lastDraggedDown) return;
+ break;
+ case GROUP_FIRST :
+ if (next != NULL) {
+ if (next->group == GROUP_MIDDLE) {
+ next->group = GROUP_FIRST;
+ } else if (next->group == GROUP_LAST) {
+ next->group = GROUP_SINGLE;
+ }
+ }
+ break;
+ case GROUP_MIDDLE :
+ break;
+ case GROUP_LAST :
+ if (prev != NULL) {
+ if (prev->group == GROUP_MIDDLE) {
+ prev->group = GROUP_LAST;
+ } else if (prev->group == GROUP_FIRST) {
+ prev->group = GROUP_SINGLE;
+ }
+ }
+ break;
+ default :
+ break;
+ }
+ sdp->prev = NULL;
+ sdp->next = NULL;
+ if (prev != NULL) {
+ prev->next = next;
+ }
+ if (next != NULL) {
+ next->prev = prev;
+ }
+ if (prev == NULL) {
+ tfp->state = next;
+ }
+ op = OP_NONE;
+ switch (sdp->group) {
+ case GROUP_SINGLE :
+ if (goingDown) {
+ if (prev != NULL) {
+ op = prev->below;
+ }
+ } else {
+ if (next != NULL) {
+ op = next->above;
+ }
+ }
+ if (prev != NULL) {
+ prev->below = op;
+ }
+ if (next != NULL) {
+ next->above = op;
+ }
+ break;
+ case GROUP_FIRST :
+ if (prev != NULL) {
+ op = prev->below;
+ }
+ if (next != NULL) {
+ next->above = op;
+ }
+ break;
+ case GROUP_MIDDLE :
+ break;
+ case GROUP_LAST :
+ if (next != NULL) {
+ op = next->above;
+ }
+ if (prev != NULL) {
+ prev->below = op;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+ tmp = sdp;
+ sdp = tfp->state;
+ if (sdp == NULL) {
+ tfp->state = tmp;
+ } else {
+ while (item > 1 && sdp->next != NULL) {
+ item--;
+ sdp = sdp->next;
+ }
+ next = sdp->next;
+ prev = sdp->prev;
+ sdp->next = tmp;
+ tmp->next = next;
+ tmp->prev = sdp;
+ if (next != NULL) {
+ next->prev = tmp;
+ }
+ op = OP_NONE;
+ if (prev != NULL) {
+ op = prev->below;
+ }
+ sdp->above = op;
+ tmp->below = sdp->below;
+ sdp->below = OP_NONE;
+ tmp->above = OP_NONE;
+ }
+ tmp->group = GROUP_SINGLE;
+ if (merge) {
+ switch (sdp->group) {
+ case GROUP_SINGLE :
+ sdp->group = GROUP_FIRST;
+ tmp->group = GROUP_LAST;
+ break;
+ case GROUP_FIRST :
+ tmp->group = GROUP_MIDDLE;
+ break;
+ case GROUP_MIDDLE :
+ tmp->group = GROUP_MIDDLE;
+ break;
+ case GROUP_LAST :
+ sdp->group = GROUP_MIDDLE;
+ tmp->group = GROUP_LAST;
+ break;
+ default :
+ break;
+ }
+ } else {
+ prev = tmp->prev;
+ if (prev != NULL) {
+ prev->below = OP_AND;
+ tmp->above = OP_AND;
+ }
+ }
+ ResetClip ();
+ WatchCursor ();
+ Update ();
+ AlphabetizeChosenGroups (tfp);
+ RepopulateChosen (tfp);
+ RecalculateChosen (tfp);
+ ArrowCursor ();
+ }
+ return;
+ }
+ if (tfp->chClickItem == item && tfp->chClickRow == row &&
+ tfp->chClickCol == col && col == 3) {
+ inval = item;
+ sdp = tfp->state;
+ while (sdp != NULL && item > 1) {
+ sdp = sdp->next;
+ item--;
+ }
+ if (sdp == NULL) return;
+ switch (sdp->state) {
+ case STATE_OFF :
+ sdp->state = STATE_ON;
+ break;
+ case STATE_ON :
+ sdp->state = STATE_OFF;
+ break;
+ default :
+ sdp->state = STATE_OFF;
+ break;
+ }
+ ResetClip ();
+ WatchCursor ();
+ InvalDocCols (tfp->chosen, inval, 3, 3);
+ Update ();
+ RecalculateChosen (tfp);
+ ArrowCursor ();
+ }
+}
+
+static void AdvBoolTextProc (TexT t)
+
+{
+ CharPtr curstr;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (t);
+ if (tfp == NULL) return;
+ curstr = SaveStringFromText (tfp->advBoolText);
+ tfp->retrieveMode = EVAL_MODE;
+ SafeSetTitle (tfp->retrieve, "Evaluate");
+ if (EntrezTLParseString (curstr, tfp->currDb, -1, NULL, NULL)) {
+ SafeEnable (tfp->retrieve);
+ } else {
+ SafeDisable (tfp->retrieve);
+ }
+ MemFree (curstr);
+}
+
+static CharPtr MakeStringFromChosen (TermFormPtr tfp)
+
+{
+ CharPtr fldStr;
+ Int2 group;
+ Int2 last;
+ CharPtr ptr;
+ StateDataPtr sdp;
+ CharPtr tmp;
+ CharPtr userString;
+
+ if (tfp == NULL || tfp->state == NULL || tfp->usingAdv) return NULL;
+ sdp = tfp->state;
+ tfp->chosenDb = sdp->db;
+ if (tfp->numChosenLines < 1 || tfp->chosenDb < 0) return NULL;
+ userString = MemNew (1000);
+ userString [0] = '\0';
+ group = 0;
+ last = 0;
+ for (sdp = tfp->state; sdp != NULL; sdp = sdp->next) {
+ if (sdp->group == GROUP_SINGLE || sdp->group == GROUP_FIRST) {
+ group++;
+ }
+ if (sdp->state == STATE_ON) {
+ if (last == 0) {
+ StrCat (userString, "( ");
+ StrCat (userString, "( ");
+ } else if (last == group) {
+ StrCat (userString, " | ");
+ } else if (sdp->above == OP_NOT) {
+ StrCat (userString, " )");
+ StrCat (userString, " )");
+ StrCat (userString, " - ");
+ StrCat (userString, "( ");
+ StrCat (userString, "( ");
+ } else {
+ StrCat (userString, " )");
+ StrCat (userString, " & ");
+ StrCat (userString, "( ");
+ }
+ StringCat (userString, "\"");
+ tmp = StringSave (sdp->term);
+ ptr = StringChr (tmp, ':');
+ if (ptr != NULL) {
+ *ptr = '\0';
+ ptr++;
+ TrimSpacesAroundString (tmp);
+ TrimSpacesAroundString (ptr);
+ StringCat (userString, tmp);
+ StringCat (userString, "\" : \"");
+ StringCat (userString, ptr);
+ } else {
+ StringCat (userString, tmp);
+ }
+ MemFree (tmp);
+ StringCat (userString, "\" [");
+ fldStr = EntrezFieldToString (tfp->chosenDb, sdp->fld);
+ StringCat (userString, fldStr);
+ StringCat (userString, "]");
+ last = group;
+ }
+ }
+ if (group > 0 && last > 0) {
+ StrCat (userString, " )");
+ StrCat (userString, " )");
+ }
+ return userString;
+}
+
+static int LIBCALLBACK SortByName (VoidPtr ptr1, VoidPtr ptr2)
+
+{
+ CharPtr str1;
+ CharPtr str2;
+ ValNodePtr vnp1;
+ ValNodePtr vnp2;
+
+ if (ptr1 != NULL && ptr2 != NULL) {
+ vnp1 = *((ValNodePtr PNTR) ptr1);
+ vnp2 = *((ValNodePtr PNTR) ptr2);
+ if (vnp1 != NULL && vnp2 != NULL) {
+ str1 = (CharPtr) vnp1->data.ptrvalue;
+ str2 = (CharPtr) vnp2->data.ptrvalue;
+ if (str1 != NULL && str2 != NULL) {
+ return StringICmp (str1, str2);
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+}
+
+#ifdef WIN_MAC
+#define textObjectReturnChar '\015'
+#else
+#define textObjectReturnChar '\n'
+#endif
+
+static Boolean InsertAdvText (TermFormPtr tfp, CharPtr str)
+
+{
+ CharPtr curstr;
+ EntrezInfoPtr eip;
+ CharPtr finalstr;
+ Int2 i;
+ Boolean retval = TRUE;
+ Int2 begin;
+ Int2 end;
+ Int2 curstrLen;
+ Char textObjectReturnStr [3];
+ Int2 strLen;
+ ValNodePtr head = NULL, vnp;
+
+ if (tfp == NULL) return TRUE;
+ if (StringHasNoText (str)) {
+ curstr = MemNew (512);
+ if (curstr != NULL) {
+ eip = EntrezGetInfo ();
+ if (eip != NULL && eip->field_info != NULL) {
+ StringCpy (curstr, "Field names are ");
+ head = NULL;
+ for (i = 0; i < eip->field_count; i++) {
+ ValNodeAddStr (&head, 0, eip->field_info [i].tag);
+ }
+ head = SortValNode (head, SortByName);
+ for (vnp = head; vnp != NULL; vnp = vnp->next) {
+ StringCat (curstr, "[");
+ StringCat (curstr, (CharPtr) vnp->data.ptrvalue);
+ StringCat (curstr, "], ");
+ }
+ ValNodeFree (head);
+ textObjectReturnStr [0] = textObjectReturnChar;
+ textObjectReturnStr [1] = '\0';
+ StringCat (curstr, "and [*] to search all fields. ");
+ StringCat (curstr, "Operators are & (and), | (or), - (butnot), ");
+ StringCat (curstr, "and : (range). For example:");
+ StringCat (curstr, textObjectReturnStr);
+ StringCat (curstr, "((\"glucagon\" [WORD] | \"insulin\" ");
+ StringCat (curstr, "[MESH]) & (\"1995\" : \"1996\" [PDAT]))");
+ SetTitle (tfp->advBoolText, curstr);
+ }
+ }
+ MemFree (curstr);
+ return TRUE;
+ }
+ curstr = MemNew ((curstrLen = TextLength (tfp->advBoolText)) + 1);
+ GetTitle (tfp->advBoolText, curstr, curstrLen + 1);
+ if (curstrLen == 0)
+ {
+ begin = 0;
+ end = 0;
+ } else {
+ TextSelectionRange (tfp->advBoolText, &begin, &end);
+ }
+
+ if (begin >= 0 && end <= curstrLen && begin <= end)
+ {
+ strLen = StrLen (str);
+ finalstr = MemNew (strLen + curstrLen + begin - end + 1);
+ StrNCpy (finalstr, curstr, begin);
+ StrCpy (&finalstr [begin], str);
+ StrCat (finalstr, &curstr[end]);
+ SetTitle (tfp->advBoolText, finalstr);
+ MemFree (finalstr);
+ SelectText (tfp->advBoolText, begin + strLen, begin + strLen);
+ /* AdvBoolTextProc (tfp->advBoolText); */
+ } else {
+ SelectText (tfp->advBoolText, curstrLen, curstrLen);
+ /* Beep(); */
+ retval = FALSE;
+ }
+
+ MemFree(curstr);
+
+ return retval;
+}
+
+static void ConvertChosenToAdvanced (TermFormPtr tfp)
+
+{
+ CharPtr str;
+
+ if (tfp == NULL) return;
+ str = MakeStringFromChosen (tfp);
+ InsertAdvText (tfp, str);
+ MemFree (str);
+ AdvBoolTextProc (tfp->advBoolText);
+}
+
+static Int4 GetValueFromField (DoC d, Int2 item, Int2 row, Int2 col)
+
+{
+ CharPtr str;
+ Int4 value;
+
+ value = -1;
+ str = GetDocText (d, item, row, col);
+ if (str != NULL) {
+ if (! StrToLong (str, &value)) {
+ value = -1;
+ }
+ }
+ MemFree (str);
+ return value;
+}
+
+static void DrawAvailLeaf (DoC d, RectPtr r, Int2 item, Int2 frst)
+
+{
+ RecT q;
+ Int2 value;
+
+ if (r == NULL || frst != 0) return;
+ value = GetValueFromField (d, item, 1, 3);
+ if (value == 1) {
+ q = *r;
+ q.left++;
+ q.right = q.left + 4;
+ q.top += stdLineHeight / 2 - 2;
+ q.bottom = q.top + 4;
+ value = GetValueFromField (d, item, 1, 6);
+ if (value == STATE_ON) {
+ InvertColors ();
+ EraseRect (&q);
+ PaintRect (&q);
+ InvertColors ();
+ } else {
+ PaintRect (&q);
+ }
+ }
+}
+
+static Boolean HighlightAvail (DoC d, Int2 item, Int2 row, Int2 col)
+
+{
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (d);
+ if (tfp == NULL) return FALSE;
+ if (item == tfp->avItem && row == tfp->avRow) return TRUE;
+ return FALSE;
+}
+
+static void ClickAvail (DoC d, PoinT pt)
+
+{
+ Int2 item;
+ Int2 row;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (d);
+ if (tfp == NULL) return;
+ MapDocPoint (d, pt, &item, &row, NULL, NULL);
+ tfp->avClickItem = item;
+ tfp->avClickRow = row;
+ tfp->wasDoubleClick = dblClick;
+}
+
+static void ReleaseAvail (DoC d, PoinT pt)
+
+{
+ Char ch;
+ Int2 item;
+ Int2 olditem;
+ Int2 oldrow;
+ CharPtr ptr;
+ Int2 row;
+ CharPtr text;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (d);
+ if (tfp == NULL) return;
+ MapDocPoint (d, pt, &item, &row, NULL, NULL);
+ if (tfp->avClickItem != item || tfp->avClickRow != row) return;
+ olditem = tfp->avItem;
+ oldrow = tfp->avRow;
+ tfp->avItem = item;
+ tfp->avRow = row;
+ if (olditem > 0 && oldrow > 0) {
+ InvalDocRows (tfp->avail, olditem, oldrow, oldrow);
+ }
+ if (item > 0 && row > 0) {
+ InvalDocRows (tfp->avail, item, row, row);
+ }
+ text = GetDocText (tfp->avail, item, row, 1);
+ if (text != NULL) {
+ ptr = text;
+ ch = *ptr;
+ while (ch != '\0' && ch >= ' ') {
+ ptr++;
+ ch = *ptr;
+ }
+ *ptr = '\0';
+ if (tfp->currMod == RANGE_MODE) {
+ if (CurrentText () == tfp->from) {
+ SafeSetTitle (tfp->from, text);
+ Select (tfp->from);
+ } else if (CurrentText () == tfp->to) {
+ SafeSetTitle (tfp->to, text);
+ Select (tfp->to);
+ }
+ } else {
+ SafeSetTitle (tfp->term, text);
+ Select (tfp->term);
+ }
+ Update ();
+ }
+ if (tfp->wasDoubleClick) {
+ WatchCursor ();
+ Update ();
+ if (tfp->currMod == TAXONOMY_MODE || tfp->currMod == MESH_TREE_MODE) {
+ Update ();
+ ResetClip (); /* clipped to panel, need to update popup */
+ RepopulateTaxonomy (tfp, text);
+ } else if (tfp->currMod == RANGE_MODE) {
+ ResetClip ();
+ LoadChosen (tfp, text, STATE_ON, FALSE, 0, FALSE);
+ Update ();
+ RecalculateChosen (tfp);
+ } else {
+ ResetClip ();
+ LoadChosen (tfp, text, STATE_ON, FALSE, 0, FALSE);
+ Update ();
+ RecalculateChosen (tfp);
+ }
+ ArrowCursor ();
+ }
+ MemFree (text);
+}
+
+static void ChangeMode (PopuP p)
+
+{
+ Char ch;
+ Int2 i;
+ Int2 idx;
+ Int2 md;
+ Int2 mode;
+ CharPtr ptr;
+ TermFormPtr tfp;
+ CharPtr text;
+ UIEnum val;
+
+ tfp = (TermFormPtr) GetObjectExtra (p);
+ if (tfp == NULL || tfp->fldalists == NULL) return;
+ mode = -1;
+ for (md = 0; md < MAX_MODES; md++) {
+ if (p == tfp->modes [md]) {
+ mode = md;
+ }
+ }
+ if (mode < 0) return;
+ if (GetEnumPopup (p, mode_alists [mode], &val) && val < MAX_MODES) {
+ mode = (Int2) val;
+ tfp->currMod = mode;
+ if (tfp->fieldModeValues != NULL && tfp->currFld < tfp->numflds) {
+ idx = tfp->currDb * tfp->numflds + tfp->currFld;
+ tfp->fieldModeValues [idx] = mode;
+ }
+ if (mode == TAXONOMY_MODE || mode == MESH_TREE_MODE) {
+ SafeHide (tfp->termGrp);
+ SafeHide (tfp->rangeGrp);
+ text = SaveStringFromText (tfp->term);
+ WatchCursor ();
+ Update ();
+ if (text != NULL) {
+ ptr = text;
+ ch = *ptr;
+ while (ch != '\0' && ch >= ' ') {
+ ptr++;
+ ch = *ptr;
+ }
+ *ptr = '\0';
+ if (*text == '\0' || (! RepopulateTaxonomy (tfp, text))) {
+ RepopulateTaxonomyRoot (tfp);
+ }
+ } else {
+ RepopulateTaxonomyRoot (tfp);
+ }
+ ArrowCursor ();
+ MemFree (text);
+ SafeShow (tfp->taxParents);
+ tfp->textChanged = FALSE;
+ tfp->okayToAccept = TRUE;
+ } else if (tfp->currMod == RANGE_MODE) {
+ SafeHide (tfp->termGrp);
+ SafeHide (tfp->taxParents);
+ SafeShow (tfp->rangeGrp);
+ TextAction (tfp->from);
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ SetDocCache (tfp->avail, NULL, NULL, NULL);
+ for (i = 0; i < 7; i++) {
+ AppendText (tfp->avail, " \n", &availParFmt, availColFmt, systemFont);
+ }
+ InvalDocument (tfp->avail);
+ Select (tfp->from);
+ } else {
+ SafeHide (tfp->rangeGrp);
+ SafeHide (tfp->taxParents);
+ SafeShow (tfp->termGrp);
+ TextAction (tfp->term);
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ Reset (tfp->avail);
+ SetDocCache (tfp->avail, NULL, NULL, NULL);
+ for (i = 0; i < 7; i++) {
+ AppendText (tfp->avail, " \n", &availParFmt, availColFmt, systemFont);
+ }
+ InvalDocument (tfp->avail);
+ Select (tfp->term);
+ }
+ Update ();
+ }
+}
+
+static void ChangeField (PopuP p)
+
+{
+ Int2 db;
+ Int2 fld;
+ Int2 md;
+ Int2 idx;
+ TermFormPtr tfp;
+ UIEnum val;
+
+ tfp = (TermFormPtr) GetObjectExtra (p);
+ if (tfp == NULL || tfp->fldalists == NULL) return;
+ fld = -1;
+ for (db = 0; db < tfp->numdbs; db++) {
+ if (p == tfp->fields [db]) {
+ fld = db;
+ }
+ }
+ if (fld < 0) return;
+ if (GetEnumPopup (p, tfp->fldalists [fld], &val) && val <= tfp->numflds) {
+ for (md = 0; md < tfp->nummods; md++) {
+ if (md != tfp->modeFromField [(Int2) val]) {
+ SafeHide (tfp->modes [md]);
+ }
+ }
+ fld = (Int2) val;
+ tfp->currFld = fld;
+ md = tfp->modeFromField [fld];
+ if (tfp->fieldModeValues != NULL && fld < tfp->numflds) {
+ idx = tfp->currDb * tfp->numflds + tfp->currFld;
+ SetEnumPopup (tfp->modes [md], mode_alists [md],
+ (UIEnum) tfp->fieldModeValues [idx]);
+ }
+ SafeShow (tfp->modes [md]);
+ ChangeMode (tfp->modes [md]);
+ }
+}
+
+static void ChangeDatabase (PopuP p)
+
+{
+ Int2 db;
+ Int2 dbase;
+ TermFormPtr tfp;
+ UIEnum val;
+
+ tfp = (TermFormPtr) GetObjectExtra (p);
+ if (tfp == NULL || tfp->dbalist == NULL) return;
+ if (GetEnumPopup (p, tfp->dbalist, &val) && val < tfp->numdbs) {
+ for (db = 0; db < tfp->numdbs; db++) {
+ if (db != (Int2) val) {
+ SafeHide (tfp->fields [db]);
+ }
+ }
+ dbase = (Int2) val;
+ tfp->currDb = dbase;
+ SafeShow (tfp->fields [dbase]);
+ ChangeField (tfp->fields [dbase]);
+ }
+ DoReset (tfp, FALSE);
+}
+
+extern void LoadNamedUidList (ForM f, CharPtr term, Int2 num, Int4Ptr uids, Int2 db)
+
+{
+ Char str [64];
+ WindoW tempPort;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (f);
+ if (tfp == NULL) return;
+ if (db >= tfp->numdbs) return;
+ if (num <= 0 || uids == NULL) return;
+ WatchCursor ();
+ Update ();
+ if (tfp->currDb != db) {
+ SetEnumPopup (tfp->database, tfp->dbalist, (UIEnum) db);
+ ChangeDatabase (tfp->database);
+ } else {
+ DoResetAvail (tfp, TRUE);
+ }
+ SafeSetTitle (tfp->term, "");
+ SafeSetTitle (tfp->from, "");
+ SafeSetTitle (tfp->to, "");
+ SafeDisable (tfp->accept);
+ if (StringHasNoText (term)) {
+ term = "*Current_Documents";
+ }
+ if (term [0] == '*') {
+ term++;
+ }
+ StringCpy (str, "*");
+ StringNCpy (str + 1, term, sizeof (str) - 3);
+ EntrezCreateNamedUidList (str, db, 0, (Int4) num, uids);
+ tempPort = SavePort (tfp->chosen);
+ LoadChosen (tfp, str, STATE_ON, TRUE, (Int4) num, TRUE);
+ SafeHide (tfp->advBoolText);
+ SafeShow (tfp->chosen);
+ tfp->usingAdv = FALSE;
+ Update ();
+ RecalculateChosen (tfp);
+ RestorePort (tempPort);
+ ArrowCursor ();
+ Update ();
+ Show (tfp->form);
+ Select (tfp->form);
+}
+
+extern Boolean UsingTextQuery (ForM f)
+
+{
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) GetObjectExtra (f);
+ if (tfp == NULL) return FALSE;
+ return tfp->usingAdv;
+}
+
+static void QueryTypeProc (ChoicE c)
+
+{
+ TermFormPtr tfp;
+
+#ifdef WIN_MAC
+ tfp = (TermFormPtr) currentFormDataPtr;
+#else
+ tfp = (TermFormPtr) GetObjectExtra (c);
+#endif
+ if (tfp == NULL) return;
+ if (GetValue (c) == 1) {
+ SafeHide (tfp->advBoolText);
+ Reset (tfp->advBoolText);
+ Update ();
+ SafeShow (tfp->chosen);
+ tfp->usingAdv = FALSE;
+ } else {
+ if (! tfp->usingAdv) {
+ ConvertChosenToAdvanced (tfp);
+ }
+ SafeHide (tfp->chosen);
+ SafeShow (tfp->advBoolText);
+ /* AdvBoolTextProc (tfp->advBoolText); */
+ tfp->usingAdv = TRUE;
+ }
+}
+
+extern ChoicE CreateQueryTypeChoice (MenU m, BaseFormPtr bfp)
+
+{
+ ChoicE c;
+
+ c = ChoiceGroup (m, QueryTypeProc);
+ SetObjectExtra (c, bfp, NULL);
+ ChoiceItem (c, "Regular");
+ ChoiceItem (c, "Advanced");
+ SetValue (c, 1);
+ return c;
+}
+
+static void ClearUnusedQueryTerms (IteM i)
+
+{
+ StateDataPtr last;
+ StateDataPtr next;
+ StateDataPtr PNTR prev;
+ StateDataPtr sdp;
+ TermFormPtr tfp;
+
+#ifdef WIN_MAC
+ tfp = (TermFormPtr) currentFormDataPtr;
+#else
+ tfp = (TermFormPtr) GetObjectExtra (i);
+#endif
+ if (tfp == NULL || tfp->state == NULL || tfp->usingAdv) return;
+ WatchCursor ();
+ Update ();
+ sdp = tfp->state;
+ prev = &(tfp->state);
+ while (sdp != NULL) {
+ last = sdp->prev;
+ next = sdp->next;
+ if (sdp->state == STATE_ON) {
+ prev = (StateDataPtr PNTR) &(sdp->next);
+ } else {
+ switch (sdp->group) {
+ case GROUP_SINGLE :
+ break;
+ case GROUP_FIRST :
+ if (next != NULL) {
+ if (next->group == GROUP_MIDDLE) {
+ next->group = GROUP_FIRST;
+ } else if (next->group == GROUP_LAST) {
+ next->group = GROUP_SINGLE;
+ }
+ }
+ break;
+ case GROUP_MIDDLE :
+ break;
+ case GROUP_LAST :
+ if (last != NULL) {
+ if (last->group == GROUP_MIDDLE) {
+ last->group = GROUP_LAST;
+ } else if (last->group == GROUP_FIRST) {
+ last->group = GROUP_SINGLE;
+ }
+ }
+ break;
+ default :
+ break;
+ }
+ *prev = sdp->next;
+ sdp->next = NULL;
+ sdp->prev = NULL;
+ StateDataFree (sdp);
+ }
+ sdp = next;
+ }
+ sdp = tfp->state;
+ while (sdp != NULL) {
+ last = sdp->prev;
+ next = sdp->next;
+ if (last == NULL) {
+ sdp->above = OP_NONE;
+ }
+ if (next == NULL) {
+ sdp->below = OP_NONE;
+ }
+ sdp = next;
+ }
+ AlphabetizeChosenGroups (tfp);
+ RepopulateChosen (tfp);
+ RecalculateChosen (tfp);
+ ArrowCursor ();
+}
+
+extern IteM CreateClearUnusedItem (MenU m, BaseFormPtr bfp)
+
+{
+ IteM i;
+
+ i = CommandItem (m, "Clear Unused Query Terms", ClearUnusedQueryTerms);
+ SetObjectExtra (i, bfp, NULL);
+ return i;
+}
+
+static void CleanupEntrezTermListForm (GraphiC g, VoidPtr data)
+
+{
+ Int2 i;
+ TermFormPtr tfp;
+
+ tfp = (TermFormPtr) data;
+ if (tfp != NULL) {
+ tfp->dbalist = FreeEnumFieldAlist (tfp->dbalist);
+ if (tfp->fldalists != NULL) {
+ for (i = 0; i < tfp->numdbs; i++) {
+ tfp->fldalists [i] = FreeEnumFieldAlist (tfp->fldalists [i]);
+ }
+ MemFree (tfp->fldalists);
+ }
+ MemFree (tfp->fields);
+ MemFree (tfp->modeFromField);
+ MemFree (tfp->fieldModeValues);
+ StateDataFree (tfp->state);
+ MemFree (tfp->uids);
+ ValNodeFreeData (tfp->taxStrings);
+ EntrezTLFree (tfp->elst);
+ }
+ StdCleanupFormProc (g, data);
+}
+
+static CharPtr blastnames [] = {
+ "BLASTN", "BLASTP", "BLASTX", "TBLASTN", NULL
+};
+
+extern EnumFieldAssocPtr MakeDatabaseAlist (EntrezTypeInfo *type_info,
+ short type_count, Boolean blast)
+
+{
+ EnumFieldAssocPtr alist;
+ EnumFieldAssocPtr ap;
+ Char ch;
+ Int2 i;
+ Int2 j;
+ CharPtr ptr;
+
+ if (type_info == NULL || type_count < 1) return NULL;
+ alist = MemNew (sizeof (EnumFieldAssoc) * (type_count + 7));
+ if (alist == NULL) return NULL;
+ ap = alist;
+ i = 0;
+ while (i < type_count) {
+ ap->name = StringSave (type_info [i].name);
+ ptr = StringStr (ap->name, " (");
+ if (ptr != NULL) {
+ *ptr = '\0';
+ }
+ if (ap->name != NULL) {
+ ptr = ap->name;
+ ch = *ptr;
+ while (ch != '\0') {
+ if (ch == '/') {
+ *ptr = '-';
+ }
+ ptr++;
+ ch = *ptr;
+ }
+ }
+ ap->value = i;
+ ap++;
+ i++;
+ }
+ if (blast) {
+ i = ALIST_BLASTN;
+ j = 0;
+ while (blastnames [j] != NULL) {
+ ap->name = StringSave (blastnames [j]);
+ ap->value = i;
+ ap++;
+ i++;
+ j++;
+ }
+ }
+ ap->name = NULL;
+ return alist;
+}
+
+extern EnumFieldAssocPtr MakeFieldAlist (EntrezTypeData *types,
+ EntrezFieldInfo *field_info,
+ short field_count, Int2 db,
+ Boolean allFields)
+
+{
+ EnumFieldAssocPtr alist;
+ EnumFieldAssocPtr ap;
+ Char ch;
+ EntrezGlobalsPtr egp;
+ Int2 fld;
+ Int2 fld_prot;
+ CharPtr ptr;
+ Boolean sortit;
+ Int2 typ_aa;
+ Int2 typ_ch;
+ Int2 typ_ml;
+ Int2 typ_nt;
+ Int2 typ_st;
+
+ if (types == NULL || field_info == NULL || field_count < 1) return NULL;
+ alist = MemNew (sizeof (EnumFieldAssoc) * (field_count + 5));
+ if (alist == NULL) return NULL;
+ ap = alist;
+ fld = 0;
+ typ_ml = DatabaseFromName ("MEDLINE");
+ typ_aa = DatabaseFromName ("Protein");
+ typ_nt = DatabaseFromName ("Nucleotide");
+ typ_st = DatabaseFromName ("Structure");
+ typ_ch = DatabaseFromName ("Genome");
+ fld_prot = FieldFromTag ("PROT");
+ while (fld < field_count) {
+ if (allFields || types [db].fields [fld].num_terms > 0) {
+ if (field_info [fld].name != NULL && field_info [fld].name [0] != '[') {
+ if (db == typ_ml && fld == fld_prot && (! allFields)) {
+ } else {
+ ap->name = StringSave (field_info [fld].name);
+ if (ap->name != NULL) {
+ ptr = ap->name;
+ ch = *ptr;
+ while (ch != '\0') {
+ if (ch == '/') {
+ *ptr = '-';
+ }
+ ptr++;
+ ch = *ptr;
+ }
+ }
+ ap->value = fld;
+ ap++;
+ }
+ }
+ }
+ fld++;
+ }
+ if (allFields) {
+ ap->name = StringSave ("NCBI Publication ID");
+ ap->value = fld;
+ ap++;
+ fld++;
+ ap->name = StringSave ("NCBI Sequence ID");
+ ap->value = fld;
+ ap++;
+ fld++;
+ ap->name = StringSave ("NCBI Structure ID");
+ ap->value = fld;
+ } else if (db == typ_ml) {
+ ap->name = StringSave ("NCBI Publication ID");
+ ap->value = fld;
+ } else if (db == typ_aa || db == typ_nt || db == typ_ch) {
+ ap->name = StringSave ("NCBI Sequence ID");
+ ap->value = fld;
+ } else if (db == typ_st) {
+ ap->name = StringSave ("NCBI Structure ID");
+ ap->value = fld;
+ } else {
+ ap->name = NULL;
+ ap->value = 0;
+ }
+ ap++;
+ ap->name = NULL;
+ sortit = TRUE;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp != NULL) {
+ sortit = egp->sortFields;
+ }
+ if (sortit) {
+ SortEnumFieldAlist (alist);
+ }
+ return alist;
+}
+
+static void ReadDefaultSettings (TermFormPtr tfp)
+
+{
+ EnumFieldAssocPtr alist;
+ Int2 db;
+ EntrezGlobalsPtr egp;
+ Int2 fld;
+ Int2 idx;
+ Int2 j;
+ Int2 md;
+ PopuP p;
+ CharPtr str;
+ UIEnum val;
+
+ if (tfp == NULL) return;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL) return;
+ str = egp->initDatabase;
+ if (str != NULL) {
+ alist = tfp->dbalist;
+ p = tfp->database;
+ for (j = 0; alist [j].name != NULL; j++) {
+ if (StringICmp (alist [j].name, str) == 0) {
+ val = (UIEnum) alist [j].value;
+ SetEnumPopup (p, alist, val);
+ tfp->currDb = (Int2) val;
+ }
+ }
+ }
+ str = egp->initField;
+ if (str != NULL) {
+ db = tfp->currDb;
+ if (db < tfp->numdbs) {
+ alist = tfp->fldalists [db];
+ p = tfp->fields [db];
+ for (j = 0; alist [j].name != NULL; j++) {
+ if (StringICmp (alist [j].name, str) == 0) {
+ val = (UIEnum) alist [j].value;
+ SetEnumPopup (p, alist, val);
+ tfp->currFld = (Int2) val;
+ }
+ }
+ }
+ }
+ str = egp->initMode;
+ if (str != NULL) {
+ fld = tfp->currFld;
+ md = tfp->modeFromField [fld];
+ if (tfp->fieldModeValues != NULL && fld < tfp->numflds) {
+ alist = mode_alists [md];
+ p = tfp->modes [md];
+ for (j = 0; alist [j].name != NULL; j++) {
+ if (StringICmp (alist [j].name, str) == 0) {
+ val = (UIEnum) alist [j].value;
+ SetEnumPopup (p, alist, val);
+ tfp->currMod = (Int2) val;
+ idx = tfp->currDb * tfp->numflds + tfp->currFld;
+ tfp->fieldModeValues [idx] = tfp->currMod;
+ }
+ }
+ }
+ }
+}
+
+extern ForM CreateTermListForm (Int2 left, Int2 top, CharPtr title,
+ WndActnProc activate, FormMessageFunc messages)
+
+{
+ GrouP c;
+ Int2 db;
+ EntrezGlobalsPtr egp;
+ EntrezInfoPtr eip;
+ Int2 fld;
+ Int2 fld_accn;
+ Int2 fld_all;
+ Int2 fld_majr;
+ Int2 fld_mesh;
+ Int2 fld_orgn;
+ Int2 fld_pacc;
+ Int2 fld_prot;
+ GrouP g;
+ GrouP h;
+ Int2 idx;
+ GrouP j;
+ Boolean macLike;
+ Int2 md;
+ PrompT ppt1, ppt2;
+ GrouP q1, q2, q3;
+ RecT r;
+ TermFormPtr tfp;
+ Int2 typ_ml;
+ WindoW w;
+ Int2 wid;
+
+ w = NULL;
+ eip = EntrezGetInfo ();
+ if (eip == NULL || eip->type_info == NULL ||
+ eip->types == NULL || eip->field_info == NULL) return NULL;
+ egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
+ if (egp == NULL) return NULL;
+ macLike = egp->popdownBehavior;
+ tfp = (TermFormPtr) MemNew (sizeof (TermFormData));
+
+ if (tfp != NULL) {
+ w = FixedWindow (-50, -33, -10, -10, title, StdSendCloseWindowMessageProc);
+ SetObjectExtra (w, tfp, CleanupEntrezTermListForm);
+ tfp->form = (ForM) w;
+ tfp->formmessage = EntrezTermListFormMessage;
+
+ tfp->appmessage = messages;
+ tfp->activate = activate;
+ SetActivate (w, EntrezTermListFormActivate);
+
+ if (egp->createTrmLstMenus != NULL) {
+ egp->createTrmLstMenus (w);
+ }
+
+ h = HiddenGroup (w, -1, 0, NULL);
+
+ g = HiddenGroup (h, -1, 0, NULL);
+ SetGroupSpacing (g, 5, 5);
+
+ c = HiddenGroup (g, 0, 2, NULL);
+ SetGroupSpacing (c, 15, 2);
+
+ tfp->numdbs = eip->type_count;
+ tfp->numflds = eip->field_count;
+ tfp->fieldModeValues = (Int2Ptr) MemNew (sizeof (Int2) * (tfp->numdbs * tfp->numflds + 1));
+ tfp->modeFromField = (Int2Ptr) MemNew (sizeof (Int2) * (tfp->numflds + 1));
+ for (fld = 0; fld <= tfp->numflds; fld++) {
+ tfp->modeFromField [fld] = POPUP_LKP;
+ }
+
+ typ_ml = DatabaseFromName ("MEDLINE");
+ fld_accn = FieldFromTag ("ACCN");
+ fld_all = FieldFromTag ("ALL");
+ fld_majr = FieldFromTag ("MAJR");
+ fld_mesh = FieldFromTag ("MESH");
+ fld_orgn = FieldFromTag ("ORGN");
+ fld_pacc = FieldFromTag ("PACC");
+ fld_prot = FieldFromTag ("PROT");
+
+ tfp->dbalist = MakeDatabaseAlist (eip->type_info, eip->type_count, FALSE);
+
+ StaticPrompt (c, "Database:", 0, 0, programFont, 'l');
+ q1 = HiddenGroup (c, 0, 0, NULL);
+ tfp->database = PopupList (q1, macLike, ChangeDatabase);
+ SetObjectExtra (tfp->database, tfp, NULL);
+ InitEnumPopup (tfp->database, tfp->dbalist, NULL);
+ SetEnumPopup (tfp->database, tfp->dbalist, (UIEnum) typ_ml);
+
+ tfp->fldalists = (EnumFieldAssocPtr PNTR) MemNew (sizeof (EnumFieldAssocPtr) * (eip->type_count + 2));
+ for (db = 0; db < eip->type_count; db++) {
+ tfp->fldalists [db] = MakeFieldAlist (eip->types, eip->field_info, eip->field_count, db, FALSE);
+ }
+
+ StaticPrompt (c, "Field:", 0, 0, programFont, 'l');
+ q2 = HiddenGroup (c, 0, 0, NULL);
+ tfp->fields = MemNew (sizeof (PopuP) * (eip->type_count + 2));
+ for (db = 0; db < eip->type_count; db++) {
+ tfp->fields [db] = PopupList (q2, macLike, ChangeField);
+ SetObjectExtra (tfp->fields [db], tfp, NULL);
+ InitEnumPopup (tfp->fields [db], tfp->fldalists [db], NULL);
+ SetEnumPopup (tfp->fields [db], tfp->fldalists [db], (UIEnum) fld_all);
+ Hide (tfp->fields [db]);
+ }
+
+ StaticPrompt (c, "Mode:", 0, 0, programFont, 'l');
+ q3 = HiddenGroup (c, 0, 0, NULL);
+ for (md = 0; mode_alists [md] != NULL; md++) {
+ tfp->modes [md] = PopupList (q3, macLike, ChangeMode);
+ SetObjectExtra (tfp->modes [md], tfp, NULL);
+ InitEnumPopup (tfp->modes [md], mode_alists [md], NULL);
+ if (md == POPUP_SEL_MUL_TRM) {
+ SetEnumPopup (tfp->modes [md], mode_alists [md], (UIEnum) AUTOMATIC_MODE);
+ } else if (md == POPUP_SEL_MUL_TRU) {
+ SetEnumPopup (tfp->modes [md], mode_alists [md], (UIEnum) AUTOMATIC_MODE);
+ } else if (md == POPUP_LKP) {
+ SetEnumPopup (tfp->modes [md], mode_alists [md], (UIEnum) LOOKUP_UID_MODE);
+ } else {
+ SetEnumPopup (tfp->modes [md], mode_alists [md], (UIEnum) SELECTION_MODE);
+ }
+ Hide (tfp->modes [md]);
+ }
+ tfp->nummods = md;
+
+ for (idx = 0; idx < tfp->numdbs * tfp->numflds; idx++) {
+ tfp->fieldModeValues [idx] = SELECTION_MODE;
+ }
+ for (db = 0; db < eip->type_count; db++) {
+ for (fld = 0; fld < eip->field_count; fld++) {
+ if (eip->types [db].fields [fld].num_terms > 0) {
+ if (eip->field_info [fld].name != NULL && eip->field_info [fld].name [0] != '[') {
+ md = -1;
+ if (fld == fld_all) {
+ md = POPUP_SEL_MUL_TRU;
+ } else if (db == typ_ml && fld == fld_prot) {
+ } else if (fld == fld_accn || fld == fld_pacc) {
+ md = POPUP_SEL_TRU_LKP;
+ } else if (fld == fld_orgn) {
+ md = POPUP_SEL_TRU_TAX;
+ } else if (fld == fld_mesh) {
+ md = POPUP_SEL_TRU_MSH;
+ } else if (fld == fld_majr) {
+ md = POPUP_SEL_TRU_MSH;
+ } else if (eip->field_info [fld].single_token) {
+ md = POPUP_SEL_MUL_TRM;
+ } else {
+ md = POPUP_SEL_TRU;
+ }
+ if (md >= 0) {
+ tfp->modeFromField [fld] = md;
+ idx = db * tfp->numflds + fld;
+ if (md == POPUP_SEL_MUL_TRM) {
+ tfp->fieldModeValues [idx] = AUTOMATIC_MODE;
+ } else if (md == POPUP_SEL_MUL_TRU) {
+ tfp->fieldModeValues [idx] = AUTOMATIC_MODE;
+ } else {
+ tfp->fieldModeValues [idx] = SELECTION_MODE;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ StaticPrompt (c, "", 0, 0, programFont, 'l');
+ tfp->accept = DefaultButton (c, "Accept", AcceptProc);
+ SetObjectExtra (tfp->accept, tfp, NULL);
+ Disable (tfp->accept);
+
+ AlignObjects (ALIGN_MIDDLE, (HANDLE) q1, (HANDLE) q2, (HANDLE) q3, (HANDLE) tfp->accept, NULL);
+
+ GetPosition (tfp->accept, &r);
+ SelectFont (programFont);
+ wid = r.right - (StringWidth ("From:") + StringWidth ("To:")) - 30;
+ SelectFont (systemFont);
+ wid /= 2 * stdCharWidth;
+
+ c = HiddenGroup (g, 0, 0, NULL);
+ tfp->termGrp = HiddenGroup (c, 2, 0, NULL);
+ StaticPrompt (tfp->termGrp, "Term:", 0, dialogTextHeight, programFont, 'l');
+ tfp->term = DialogText (tfp->termGrp, "", 20, TextAction);
+ SetObjectExtra (tfp->term, tfp, NULL);
+ tfp->rangeGrp = HiddenGroup (c, 4, 0, NULL);
+ StaticPrompt (tfp->rangeGrp, "From:", 0, dialogTextHeight, programFont, 'l');
+ tfp->from = DialogText (tfp->rangeGrp, "", wid, TextAction);
+ SetObjectExtra (tfp->from, tfp, NULL);
+ StaticPrompt (tfp->rangeGrp, "To:", 0, dialogTextHeight, programFont, 'l');
+ tfp->to = DialogText (tfp->rangeGrp, "", wid, TextAction);
+ SetObjectExtra (tfp->to, tfp, NULL);
+ Hide (tfp->rangeGrp);
+ tfp->taxParents = PopupList (c, TRUE, ChangeTaxParents);
+ SetObjectExtra (tfp->taxParents, tfp, NULL);
+ Hide (tfp->taxParents);
+ tfp->taxStrings = NULL;
+
+ /*
+ tfp->avail = DocumentPanel (g, 10 * stdCharWidth, 7 * stdLineHeight);
+ SetObjectExtra (tfp->avail, tfp, NULL);
+ c = HiddenGroup (g, 5, 0, NULL);
+ StaticPrompt (c, "Term Selection", 0, 0, programFont, 'l');
+ ppt = StaticPrompt (c, "Query Refinement", 0, 0, programFont, 'r');
+ tfp->chosen = DocumentPanel (g, 10 * stdCharWidth, 7 * stdLineHeight);
+ SetObjectExtra (tfp->chosen, tfp, NULL);
+ */
+
+ c = HiddenGroup (g, -1, 0, NULL);
+ ppt1 = StaticPrompt (c, "Term Selection", 0, 0, programFont, 'c');
+ tfp->avail = DocumentPanel (c, 10 * stdCharWidth, 7 * stdLineHeight);
+ SetObjectExtra (tfp->avail, tfp, NULL);
+ tfp->avItem = 0;
+ tfp->avRow = 0;
+ SetDocShade (tfp->avail, DrawAvailLeaf, NULL, HighlightAvail, NULL);
+ SetDocProcs (tfp->avail, ClickAvail, NULL, ReleaseAvail, NULL);
+ SetDocCache (tfp->avail, NULL, NULL, NULL);
+
+ ppt2 = StaticPrompt (c, "Query Refinement", 0, 0, programFont, 'c');
+ j = HiddenGroup (c, 0, 0, NULL);
+
+ tfp->advBoolText = ScrollText (j, 10, 7, programFont, TRUE, AdvBoolTextProc);
+ SetObjectExtra (tfp->advBoolText, tfp, NULL);
+ Hide (tfp->advBoolText);
+ tfp->usingAdv = FALSE;
+ tfp->retrieveMode = FETCH_MODE;
+
+ tfp->chosen = DocumentPanel (j, 10 * stdCharWidth, 7 * stdLineHeight);
+ SetObjectExtra (tfp->chosen, tfp, NULL);
+ SetDocProcs (tfp->chosen, ClickChosen, DragChosen, ReleaseChosen, NULL);
+ SetDocShade (tfp->chosen, DrawChosenBrackets, NULL, HighlightChosen, NULL);
+ tfp->numChosenLines = 0;
+
+ AlignObjects (ALIGN_CENTER, (HANDLE) tfp->taxParents,
+ (HANDLE) tfp->termGrp, NULL);
+ AlignObjects (ALIGN_MIDDLE, (HANDLE) tfp->taxParents,
+ (HANDLE) tfp->termGrp, (HANDLE) tfp->rangeGrp, NULL);
+ AlignObjects (ALIGN_RIGHT, (HANDLE) tfp->accept, (HANDLE) tfp->term,
+ (HANDLE) tfp->avail, (HANDLE) tfp->chosen, (HANDLE) tfp->advBoolText,
+ (HANDLE) tfp->to, (HANDLE) ppt1, (HANDLE) ppt2, NULL);
+
+ c = HiddenGroup (g, 5, 0, NULL);
+ SetGroupSpacing (c, 10, 10);
+ tfp->retrieve = PushButton (c, "Retrieve 000000000 Documents", RetrieveDocsProc);
+ SetObjectExtra (tfp->retrieve, tfp, NULL);
+ SetTitle (tfp->retrieve, "Retrieve 0 Documents");
+ Disable (tfp->retrieve);
+ tfp->reset = PushButton (c, "Reset", ResetProc);
+ SetObjectExtra (tfp->reset, tfp, NULL);
+
+ RealizeWindow (w);
+
+ ObjectRect (tfp->avail, &r);
+ InsetRect (&r, 4, 4);
+ SelectFont (systemFont);
+
+ availColFmt [1].pixWidth = StringWidth ("0000000") + 10;
+ availColFmt [0].pixWidth = (r.right - r.left) - availColFmt [1].pixWidth;
+ availColFmt [2].pixWidth = 0;
+ chosenColFmt [2].pixWidth = availColFmt [1].pixWidth;
+ chosenColFmt [1].pixWidth = StringWidth ("0000000") + 10;
+ chosenColFmt [0].pixWidth = availColFmt [0].pixWidth - chosenColFmt [1].pixWidth;
+
+ SetDocAutoAdjust (tfp->avail, FALSE);
+ SetDocAutoAdjust (tfp->chosen, FALSE);
+
+ tfp->currDb = typ_ml;
+ tfp->currFld = fld_all;
+ tfp->currMod = POPUP_SEL_MUL_TRU;
+
+ ReadDefaultSettings (tfp);
+
+ /* ChangeDatabase calls DoReset, which puts blank lines in avail and chosen */
+ ChangeDatabase (tfp->database);
+ SetWindowTimer (w, AvailTimerProc);
+
+ InvalDocument (tfp->avail);
+ InvalDocument (tfp->chosen);
+ }
+ return (ForM) w;
+}
+
diff --git a/network/winsock/README b/network/winsock/README
new file mode 100644
index 00000000..a7c0f97e
--- /dev/null
+++ b/network/winsock/README
@@ -0,0 +1,6 @@
+COPYRIGHT NOTICE:
+
+Portions of the Windows Sockets specification are derived from material
+which is Copyright (c) 1982-1986 by the Regents of the University of
+California. All rights are reserved. The Berkeley Software License Agreement
+specifies the terms and conditions for redistribution.
diff --git a/network/winsock/winsock.h b/network/winsock/winsock.h
new file mode 100644
index 00000000..52cf78e2
--- /dev/null
+++ b/network/winsock/winsock.h
@@ -0,0 +1,853 @@
+/* WINSOCK.H--definitions to be used with the WINSOCK.DLL
+ *
+ * This header file corresponds to version 1.1 of the Windows Sockets
+ * specification.
+ *
+ * This file includes parts which are Copyright (c) 1982-1986 Regents
+ * of the University of California. All rights reserved. The
+ * Berkeley Software License Agreement specifies the terms and
+ * conditions for redistribution.
+ *
+ * Change log:
+ *
+ * Fri Apr 23 16:31:01 1993 Mark Towfiq (towfiq@Microdyne.COM)
+ * New version from David Treadwell which adds extern "C" around
+ * __WSAFDIsSet() and removes "const" from buf param of
+ * WSAAsyncGetHostByAddr(). Added change log.
+ *
+ * Sat May 15 10:55:00 1993 David Treadwell (davidtr@microsoft.com)
+ * Fix the IN_CLASSC macro to account for class-D multicasts.
+ * Add AF_IPX == AF_NS.
+ *
+ * Tue Oct 19 13:05:02 1993 Mark Towfiq (Mark.Towfiq@Sun.COM)
+ * New version from David Treadwell which changes type of counter in
+ * fd_set to u_int instead of u_short, so that it is correctly
+ * promoted in Winsdows NT and other 32-bit environments.
+ */
+
+#ifndef _WINSOCKAPI_
+#define _WINSOCKAPI_
+
+/*
+ * Pull in WINDOWS.H if necessary
+ */
+#ifndef _INC_WINDOWS
+#include <windows.h>
+#endif /* _INC_WINDOWS */
+
+/*
+ * Basic system type definitions, taken from the BSD file sys/types.h.
+ */
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
+/*
+ * The new type to be used in all
+ * instances which refer to sockets.
+ */
+typedef u_int SOCKET;
+
+/*
+ * Select uses arrays of SOCKETs. These macros manipulate such
+ * arrays. FD_SETSIZE may be defined by the user before including
+ * this file, but the default here should be >= 64.
+ *
+ * CAVEAT IMPLEMENTOR and USER: THESE MACROS AND TYPES MUST BE
+ * INCLUDED IN WINSOCK.H EXACTLY AS SHOWN HERE.
+ */
+#ifndef FD_SETSIZE
+#define FD_SETSIZE 64
+#endif /* FD_SETSIZE */
+
+typedef struct fd_set {
+ u_int fd_count; /* how many are SET? */
+ SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
+} fd_set;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int PASCAL FAR __WSAFDIsSet(SOCKET, fd_set FAR *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#define FD_CLR(fd, set) do { \
+ u_int __i; \
+ for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count ; __i++) { \
+ if (((fd_set FAR *)(set))->fd_array[__i] == fd) { \
+ while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
+ ((fd_set FAR *)(set))->fd_array[__i] = \
+ ((fd_set FAR *)(set))->fd_array[__i+1]; \
+ __i++; \
+ } \
+ ((fd_set FAR *)(set))->fd_count--; \
+ break; \
+ } \
+ } \
+} while(0)
+
+#define FD_SET(fd, set) do { \
+ if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) \
+ ((fd_set FAR *)(set))->fd_array[((fd_set FAR *)(set))->fd_count++]=fd;\
+} while(0)
+
+#define FD_ZERO(set) (((fd_set FAR *)(set))->fd_count=0)
+
+#define FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)fd, (fd_set FAR *)set)
+
+/*
+ * Structure used in select() call, taken from the BSD file sys/time.h.
+ */
+struct timeval {
+ long tv_sec; /* seconds */
+ long tv_usec; /* and microseconds */
+};
+
+/*
+ * Operations on timevals.
+ *
+ * NB: timercmp does not work for >= or <=.
+ */
+#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#define timercmp(tvp, uvp, cmp) \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec || \
+ (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
+#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
+
+/*
+ * Commands for ioctlsocket(), taken from the BSD file fcntl.h.
+ *
+ *
+ * Ioctl's have the command encoded in the lower word,
+ * and the size of any in or out parameters in the upper
+ * word. The high 2 bits of the upper word are used
+ * to encode the in/out status of the parameter; for now
+ * we restrict parameters to at most 128 bytes.
+ */
+#define IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */
+#define IOC_VOID 0x20000000 /* no parameters */
+#define IOC_OUT 0x40000000 /* copy out parameters */
+#define IOC_IN 0x80000000 /* copy in parameters */
+#define IOC_INOUT (IOC_IN|IOC_OUT)
+ /* 0x20000000 distinguishes new &
+ old ioctl's */
+#define _IO(x,y) (IOC_VOID|(x<<8)|y)
+
+#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
+
+#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
+
+#define FIONREAD _IOR('f', 127, u_long) /* get # bytes to read */
+#define FIONBIO _IOW('f', 126, u_long) /* set/clear non-blocking i/o */
+#define FIOASYNC _IOW('f', 125, u_long) /* set/clear async i/o */
+
+/* Socket I/O Controls */
+#define SIOCSHIWAT _IOW('s', 0, u_long) /* set high watermark */
+#define SIOCGHIWAT _IOR('s', 1, u_long) /* get high watermark */
+#define SIOCSLOWAT _IOW('s', 2, u_long) /* set low watermark */
+#define SIOCGLOWAT _IOR('s', 3, u_long) /* get low watermark */
+#define SIOCATMARK _IOR('s', 7, u_long) /* at oob mark? */
+
+/*
+ * Structures returned by network data base library, taken from the
+ * BSD file netdb.h. All addresses are supplied in host order, and
+ * returned in network order (suitable for use in system calls).
+ */
+
+struct hostent {
+ char FAR * h_name; /* official name of host */
+ char FAR * FAR * h_aliases; /* alias list */
+ short h_addrtype; /* host address type */
+ short h_length; /* length of address */
+ char FAR * FAR * h_addr_list; /* list of addresses */
+#define h_addr h_addr_list[0] /* address, for backward compat */
+};
+
+/*
+ * It is assumed here that a network number
+ * fits in 32 bits.
+ */
+struct netent {
+ char FAR * n_name; /* official name of net */
+ char FAR * FAR * n_aliases; /* alias list */
+ short n_addrtype; /* net address type */
+ u_long n_net; /* network # */
+};
+
+struct servent {
+ char FAR * s_name; /* official service name */
+ char FAR * FAR * s_aliases; /* alias list */
+ short s_port; /* port # */
+ char FAR * s_proto; /* protocol to use */
+};
+
+struct protoent {
+ char FAR * p_name; /* official protocol name */
+ char FAR * FAR * p_aliases; /* alias list */
+ short p_proto; /* protocol # */
+};
+
+/*
+ * Constants and structures defined by the internet system,
+ * Per RFC 790, September 1981, taken from the BSD file netinet/in.h.
+ */
+
+/*
+ * Protocols
+ */
+#define IPPROTO_IP 0 /* dummy for IP */
+#define IPPROTO_ICMP 1 /* control message protocol */
+#define IPPROTO_GGP 2 /* gateway^2 (deprecated) */
+#define IPPROTO_TCP 6 /* tcp */
+#define IPPROTO_PUP 12 /* pup */
+#define IPPROTO_UDP 17 /* user datagram protocol */
+#define IPPROTO_IDP 22 /* xns idp */
+#define IPPROTO_ND 77 /* UNOFFICIAL net disk proto */
+
+#define IPPROTO_RAW 255 /* raw IP packet */
+#define IPPROTO_MAX 256
+
+/*
+ * Port/socket numbers: network standard functions
+ */
+#define IPPORT_ECHO 7
+#define IPPORT_DISCARD 9
+#define IPPORT_SYSTAT 11
+#define IPPORT_DAYTIME 13
+#define IPPORT_NETSTAT 15
+#define IPPORT_FTP 21
+#define IPPORT_TELNET 23
+#define IPPORT_SMTP 25
+#define IPPORT_TIMESERVER 37
+#define IPPORT_NAMESERVER 42
+#define IPPORT_WHOIS 43
+#define IPPORT_MTP 57
+
+/*
+ * Port/socket numbers: host specific functions
+ */
+#define IPPORT_TFTP 69
+#define IPPORT_RJE 77
+#define IPPORT_FINGER 79
+#define IPPORT_TTYLINK 87
+#define IPPORT_SUPDUP 95
+
+/*
+ * UNIX TCP sockets
+ */
+#define IPPORT_EXECSERVER 512
+#define IPPORT_LOGINSERVER 513
+#define IPPORT_CMDSERVER 514
+#define IPPORT_EFSSERVER 520
+
+/*
+ * UNIX UDP sockets
+ */
+#define IPPORT_BIFFUDP 512
+#define IPPORT_WHOSERVER 513
+#define IPPORT_ROUTESERVER 520
+ /* 520+1 also used */
+
+/*
+ * Ports < IPPORT_RESERVED are reserved for
+ * privileged processes (e.g. root).
+ */
+#define IPPORT_RESERVED 1024
+
+/*
+ * Link numbers
+ */
+#define IMPLINK_IP 155
+#define IMPLINK_LOWEXPER 156
+#define IMPLINK_HIGHEXPER 158
+
+/*
+ * Internet address (old style... should be updated)
+ */
+struct in_addr {
+ union {
+ struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
+ struct { u_short s_w1,s_w2; } S_un_w;
+ u_long S_addr;
+ } S_un;
+#define s_addr S_un.S_addr
+ /* can be used for most tcp & ip code */
+#define s_host S_un.S_un_b.s_b2
+ /* host on imp */
+#define s_net S_un.S_un_b.s_b1
+ /* network */
+#define s_imp S_un.S_un_w.s_w2
+ /* imp */
+#define s_impno S_un.S_un_b.s_b4
+ /* imp # */
+#define s_lh S_un.S_un_b.s_b3
+ /* logical host */
+};
+
+/*
+ * Definitions of bits in internet address integers.
+ * On subnets, the decomposition of addresses to host and net parts
+ * is done according to subnet mask, not the masks here.
+ */
+#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST 0x00ffffff
+#define IN_CLASSA_MAX 128
+
+#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST 0x0000ffff
+#define IN_CLASSB_MAX 65536
+
+#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST 0x000000ff
+
+#define INADDR_ANY (u_long)0x00000000
+#define INADDR_LOOPBACK 0x7f000001
+#define INADDR_BROADCAST (u_long)0xffffffff
+#define INADDR_NONE 0xffffffff
+
+/*
+ * Socket address, internet style.
+ */
+struct sockaddr_in {
+ short sin_family;
+ u_short sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+};
+
+#define WSADESCRIPTION_LEN 256
+#define WSASYS_STATUS_LEN 128
+
+typedef struct WSAData {
+ WORD wVersion;
+ WORD wHighVersion;
+ char szDescription[WSADESCRIPTION_LEN+1];
+ char szSystemStatus[WSASYS_STATUS_LEN+1];
+ unsigned short iMaxSockets;
+ unsigned short iMaxUdpDg;
+ char FAR * lpVendorInfo;
+} WSADATA;
+
+typedef WSADATA FAR *LPWSADATA;
+
+/*
+ * Options for use with [gs]etsockopt at the IP level.
+ */
+#define IP_OPTIONS 1 /* set/get IP per-packet options */
+
+/*
+ * Definitions related to sockets: types, address families, options,
+ * taken from the BSD file sys/socket.h.
+ */
+
+/*
+ * This is used instead of -1, since the
+ * SOCKET type is unsigned.
+ */
+#define INVALID_SOCKET (SOCKET)(~0)
+#define SOCKET_ERROR (-1)
+
+/*
+ * Types
+ */
+#define SOCK_STREAM 1 /* stream socket */
+#define SOCK_DGRAM 2 /* datagram socket */
+#define SOCK_RAW 3 /* raw-protocol interface */
+#define SOCK_RDM 4 /* reliably-delivered message */
+#define SOCK_SEQPACKET 5 /* sequenced packet stream */
+
+/*
+ * Option flags per-socket.
+ */
+#define SO_DEBUG 0x0001 /* turn on debugging info recording */
+#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
+#define SO_REUSEADDR 0x0004 /* allow local address reuse */
+#define SO_KEEPALIVE 0x0008 /* keep connections alive */
+#define SO_DONTROUTE 0x0010 /* just use interface addresses */
+#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
+#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
+#define SO_LINGER 0x0080 /* linger on close if data present */
+#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
+
+#define SO_DONTLINGER (u_int)(~SO_LINGER)
+
+/*
+ * Additional options.
+ */
+#define SO_SNDBUF 0x1001 /* send buffer size */
+#define SO_RCVBUF 0x1002 /* receive buffer size */
+#define SO_SNDLOWAT 0x1003 /* send low-water mark */
+#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
+#define SO_SNDTIMEO 0x1005 /* send timeout */
+#define SO_RCVTIMEO 0x1006 /* receive timeout */
+#define SO_ERROR 0x1007 /* get error status and clear */
+#define SO_TYPE 0x1008 /* get socket type */
+
+/*
+ * TCP options.
+ */
+#define TCP_NODELAY 0x0001
+
+/*
+ * Address families.
+ */
+#define AF_UNSPEC 0 /* unspecified */
+#define AF_UNIX 1 /* local to host (pipes, portals) */
+#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
+#define AF_IMPLINK 3 /* arpanet imp addresses */
+#define AF_PUP 4 /* pup protocols: e.g. BSP */
+#define AF_CHAOS 5 /* mit CHAOS protocols */
+#define AF_NS 6 /* XEROX NS protocols */
+#define AF_IPX 6 /* IPX and SPX */
+#define AF_ISO 7 /* ISO protocols */
+#define AF_OSI AF_ISO /* OSI is ISO */
+#define AF_ECMA 8 /* european computer manufacturers */
+#define AF_DATAKIT 9 /* datakit protocols */
+#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
+#define AF_SNA 11 /* IBM SNA */
+#define AF_DECnet 12 /* DECnet */
+#define AF_DLI 13 /* Direct data link interface */
+#define AF_LAT 14 /* LAT */
+#define AF_HYLINK 15 /* NSC Hyperchannel */
+#define AF_APPLETALK 16 /* AppleTalk */
+#define AF_NETBIOS 17 /* NetBios-style addresses */
+
+#define AF_MAX 18
+
+/*
+ * Structure used by kernel to store most
+ * addresses.
+ */
+struct sockaddr {
+ u_short sa_family; /* address family */
+ char sa_data[14]; /* up to 14 bytes of direct address */
+};
+
+/*
+ * Structure used by kernel to pass protocol
+ * information in raw sockets.
+ */
+struct sockproto {
+ u_short sp_family; /* address family */
+ u_short sp_protocol; /* protocol */
+};
+
+/*
+ * Protocol families, same as address families for now.
+ */
+#define PF_UNSPEC AF_UNSPEC
+#define PF_UNIX AF_UNIX
+#define PF_INET AF_INET
+#define PF_IMPLINK AF_IMPLINK
+#define PF_PUP AF_PUP
+#define PF_CHAOS AF_CHAOS
+#define PF_NS AF_NS
+#define PF_IPX AF_IPX
+#define PF_ISO AF_ISO
+#define PF_OSI AF_OSI
+#define PF_ECMA AF_ECMA
+#define PF_DATAKIT AF_DATAKIT
+#define PF_CCITT AF_CCITT
+#define PF_SNA AF_SNA
+#define PF_DECnet AF_DECnet
+#define PF_DLI AF_DLI
+#define PF_LAT AF_LAT
+#define PF_HYLINK AF_HYLINK
+#define PF_APPLETALK AF_APPLETALK
+
+#define PF_MAX AF_MAX
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+ u_short l_onoff; /* option on/off */
+ u_short l_linger; /* linger time */
+};
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define SOL_SOCKET 0xffff /* options for socket level */
+
+/*
+ * Maximum queue length specifiable by listen.
+ */
+#define SOMAXCONN 5
+
+#define MSG_OOB 0x1 /* process out-of-band data */
+#define MSG_PEEK 0x2 /* peek at incoming message */
+#define MSG_DONTROUTE 0x4 /* send without using routing tables */
+
+#define MSG_MAXIOVLEN 16
+
+/*
+ * Define constant based on rfc883, used by gethostbyxxxx() calls.
+ */
+#define MAXGETHOSTSTRUCT 1024
+
+/*
+ * Define flags to be used with the WSAAsyncSelect() call.
+ */
+#define FD_READ 0x01
+#define FD_WRITE 0x02
+#define FD_OOB 0x04
+#define FD_ACCEPT 0x08
+#define FD_CONNECT 0x10
+#define FD_CLOSE 0x20
+
+/*
+ * All Windows Sockets error constants are biased by WSABASEERR from
+ * the "normal"
+ */
+#define WSABASEERR 10000
+/*
+ * Windows Sockets definitions of regular Microsoft C error constants
+ */
+#define WSAEINTR (WSABASEERR+4)
+#define WSAEBADF (WSABASEERR+9)
+#define WSAEACCES (WSABASEERR+13)
+#define WSAEFAULT (WSABASEERR+14)
+#define WSAEINVAL (WSABASEERR+22)
+#define WSAEMFILE (WSABASEERR+24)
+
+/*
+ * Windows Sockets definitions of regular Berkeley error constants
+ */
+#define WSAEWOULDBLOCK (WSABASEERR+35)
+#define WSAEINPROGRESS (WSABASEERR+36)
+#define WSAEALREADY (WSABASEERR+37)
+#define WSAENOTSOCK (WSABASEERR+38)
+#define WSAEDESTADDRREQ (WSABASEERR+39)
+#define WSAEMSGSIZE (WSABASEERR+40)
+#define WSAEPROTOTYPE (WSABASEERR+41)
+#define WSAENOPROTOOPT (WSABASEERR+42)
+#define WSAEPROTONOSUPPORT (WSABASEERR+43)
+#define WSAESOCKTNOSUPPORT (WSABASEERR+44)
+#define WSAEOPNOTSUPP (WSABASEERR+45)
+#define WSAEPFNOSUPPORT (WSABASEERR+46)
+#define WSAEAFNOSUPPORT (WSABASEERR+47)
+#define WSAEADDRINUSE (WSABASEERR+48)
+#define WSAEADDRNOTAVAIL (WSABASEERR+49)
+#define WSAENETDOWN (WSABASEERR+50)
+#define WSAENETUNREACH (WSABASEERR+51)
+#define WSAENETRESET (WSABASEERR+52)
+#define WSAECONNABORTED (WSABASEERR+53)
+#define WSAECONNRESET (WSABASEERR+54)
+#define WSAENOBUFS (WSABASEERR+55)
+#define WSAEISCONN (WSABASEERR+56)
+#define WSAENOTCONN (WSABASEERR+57)
+#define WSAESHUTDOWN (WSABASEERR+58)
+#define WSAETOOMANYREFS (WSABASEERR+59)
+#define WSAETIMEDOUT (WSABASEERR+60)
+#define WSAECONNREFUSED (WSABASEERR+61)
+#define WSAELOOP (WSABASEERR+62)
+#define WSAENAMETOOLONG (WSABASEERR+63)
+#define WSAEHOSTDOWN (WSABASEERR+64)
+#define WSAEHOSTUNREACH (WSABASEERR+65)
+#define WSAENOTEMPTY (WSABASEERR+66)
+#define WSAEPROCLIM (WSABASEERR+67)
+#define WSAEUSERS (WSABASEERR+68)
+#define WSAEDQUOT (WSABASEERR+69)
+#define WSAESTALE (WSABASEERR+70)
+#define WSAEREMOTE (WSABASEERR+71)
+
+/*
+ * Extended Windows Sockets error constant definitions
+ */
+#define WSASYSNOTREADY (WSABASEERR+91)
+#define WSAVERNOTSUPPORTED (WSABASEERR+92)
+#define WSANOTINITIALISED (WSABASEERR+93)
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (when using the resolver). Note that these errors are
+ * retrieved via WSAGetLastError() and must therefore follow
+ * the rules for avoiding clashes with error numbers from
+ * specific implementations or language run-time systems.
+ * For this reason the codes are based at WSABASEERR+1001.
+ * Note also that [WSA]NO_ADDRESS is defined only for
+ * compatibility purposes.
+ */
+
+#define h_errno WSAGetLastError()
+
+/* Authoritative Answer: Host not found */
+#define WSAHOST_NOT_FOUND (WSABASEERR+1001)
+#define HOST_NOT_FOUND WSAHOST_NOT_FOUND
+
+/* Non-Authoritative: Host not found, or SERVERFAIL */
+#define WSATRY_AGAIN (WSABASEERR+1002)
+#define TRY_AGAIN WSATRY_AGAIN
+
+/* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define WSANO_RECOVERY (WSABASEERR+1003)
+#define NO_RECOVERY WSANO_RECOVERY
+
+/* Valid name, no data record of requested type */
+#define WSANO_DATA (WSABASEERR+1004)
+#define NO_DATA WSANO_DATA
+
+/* no address, look for MX record */
+#define WSANO_ADDRESS WSANO_DATA
+#define NO_ADDRESS WSANO_ADDRESS
+
+/*
+ * Windows Sockets errors redefined as regular Berkeley error constants
+ */
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#define EINPROGRESS WSAEINPROGRESS
+#define EALREADY WSAEALREADY
+#define ENOTSOCK WSAENOTSOCK
+#define EDESTADDRREQ WSAEDESTADDRREQ
+#define EMSGSIZE WSAEMSGSIZE
+#define EPROTOTYPE WSAEPROTOTYPE
+#define ENOPROTOOPT WSAENOPROTOOPT
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+#define EOPNOTSUPP WSAEOPNOTSUPP
+#define EPFNOSUPPORT WSAEPFNOSUPPORT
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define EADDRINUSE WSAEADDRINUSE
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#define ENETDOWN WSAENETDOWN
+#define ENETUNREACH WSAENETUNREACH
+#define ENETRESET WSAENETRESET
+#define ECONNABORTED WSAECONNABORTED
+#define ECONNRESET WSAECONNRESET
+#define ENOBUFS WSAENOBUFS
+#define EISCONN WSAEISCONN
+#define ENOTCONN WSAENOTCONN
+#define ESHUTDOWN WSAESHUTDOWN
+#define ETOOMANYREFS WSAETOOMANYREFS
+#define ETIMEDOUT WSAETIMEDOUT
+#define ECONNREFUSED WSAECONNREFUSED
+#define ELOOP WSAELOOP
+#define ENAMETOOLONG WSAENAMETOOLONG
+#define EHOSTDOWN WSAEHOSTDOWN
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#define ENOTEMPTY WSAENOTEMPTY
+#define EPROCLIM WSAEPROCLIM
+#define EUSERS WSAEUSERS
+#define EDQUOT WSAEDQUOT
+#define ESTALE WSAESTALE
+#define EREMOTE WSAEREMOTE
+
+/* Socket function prototypes */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SOCKET PASCAL FAR accept (SOCKET s, struct sockaddr FAR *addr,
+ int FAR *addrlen);
+
+int PASCAL FAR bind (SOCKET s, const struct sockaddr FAR *addr, int namelen);
+
+int PASCAL FAR closesocket (SOCKET s);
+
+int PASCAL FAR connect (SOCKET s, const struct sockaddr FAR *name, int namelen);
+
+int PASCAL FAR ioctlsocket (SOCKET s, long cmd, u_long FAR *argp);
+
+int PASCAL FAR getpeername (SOCKET s, struct sockaddr FAR *name,
+ int FAR * namelen);
+
+int PASCAL FAR getsockname (SOCKET s, struct sockaddr FAR *name,
+ int FAR * namelen);
+
+int PASCAL FAR getsockopt (SOCKET s, int level, int optname,
+ char FAR * optval, int FAR *optlen);
+
+u_long PASCAL FAR htonl (u_long hostlong);
+
+u_short PASCAL FAR htons (u_short hostshort);
+
+unsigned long PASCAL FAR inet_addr (const char FAR * cp);
+
+char FAR * PASCAL FAR inet_ntoa (struct in_addr in);
+
+int PASCAL FAR listen (SOCKET s, int backlog);
+
+u_long PASCAL FAR ntohl (u_long netlong);
+
+u_short PASCAL FAR ntohs (u_short netshort);
+
+int PASCAL FAR recv (SOCKET s, char FAR * buf, int len, int flags);
+
+int PASCAL FAR recvfrom (SOCKET s, char FAR * buf, int len, int flags,
+ struct sockaddr FAR *from, int FAR * fromlen);
+
+int PASCAL FAR select (int nfds, fd_set FAR *readfds, fd_set FAR *writefds,
+ fd_set FAR *exceptfds, const struct timeval FAR *timeout);
+
+int PASCAL FAR send (SOCKET s, const char FAR * buf, int len, int flags);
+
+int PASCAL FAR sendto (SOCKET s, const char FAR * buf, int len, int flags,
+ const struct sockaddr FAR *to, int tolen);
+
+int PASCAL FAR setsockopt (SOCKET s, int level, int optname,
+ const char FAR * optval, int optlen);
+
+int PASCAL FAR shutdown (SOCKET s, int how);
+
+SOCKET PASCAL FAR socket (int af, int type, int protocol);
+
+/* Database function prototypes */
+
+struct hostent FAR * PASCAL FAR gethostbyaddr(const char FAR * addr,
+ int len, int type);
+
+struct hostent FAR * PASCAL FAR gethostbyname(const char FAR * name);
+
+int PASCAL FAR gethostname (char FAR * name, int namelen);
+
+struct servent FAR * PASCAL FAR getservbyport(int port, const char FAR * proto);
+
+struct servent FAR * PASCAL FAR getservbyname(const char FAR * name,
+ const char FAR * proto);
+
+struct protoent FAR * PASCAL FAR getprotobynumber(int proto);
+
+struct protoent FAR * PASCAL FAR getprotobyname(const char FAR * name);
+
+/* Microsoft Windows Extension function prototypes */
+
+int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);
+
+int PASCAL FAR WSACleanup(void);
+
+void PASCAL FAR WSASetLastError(int iError);
+
+int PASCAL FAR WSAGetLastError(void);
+
+BOOL PASCAL FAR WSAIsBlocking(void);
+
+int PASCAL FAR WSAUnhookBlockingHook(void);
+
+FARPROC PASCAL FAR WSASetBlockingHook(FARPROC lpBlockFunc);
+
+int PASCAL FAR WSACancelBlockingCall(void);
+
+HANDLE PASCAL FAR WSAAsyncGetServByName(HWND hWnd, u_int wMsg,
+ const char FAR * name,
+ const char FAR * proto,
+ char FAR * buf, int buflen);
+
+HANDLE PASCAL FAR WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,
+ const char FAR * proto, char FAR * buf,
+ int buflen);
+
+HANDLE PASCAL FAR WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,
+ const char FAR * name, char FAR * buf,
+ int buflen);
+
+HANDLE PASCAL FAR WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,
+ int number, char FAR * buf,
+ int buflen);
+
+HANDLE PASCAL FAR WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
+ const char FAR * name, char FAR * buf,
+ int buflen);
+
+HANDLE PASCAL FAR WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,
+ const char FAR * addr, int len, int type,
+ char FAR * buf, int buflen);
+
+int PASCAL FAR WSACancelAsyncRequest(HANDLE hAsyncTaskHandle);
+
+int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
+ long lEvent);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Microsoft Windows Extended data types */
+typedef struct sockaddr SOCKADDR;
+typedef struct sockaddr *PSOCKADDR;
+typedef struct sockaddr FAR *LPSOCKADDR;
+
+typedef struct sockaddr_in SOCKADDR_IN;
+typedef struct sockaddr_in *PSOCKADDR_IN;
+typedef struct sockaddr_in FAR *LPSOCKADDR_IN;
+
+typedef struct linger LINGER;
+typedef struct linger *PLINGER;
+typedef struct linger FAR *LPLINGER;
+
+typedef struct in_addr IN_ADDR;
+typedef struct in_addr *PIN_ADDR;
+typedef struct in_addr FAR *LPIN_ADDR;
+
+typedef struct fd_set FD_SET;
+typedef struct fd_set *PFD_SET;
+typedef struct fd_set FAR *LPFD_SET;
+
+typedef struct hostent HOSTENT;
+typedef struct hostent *PHOSTENT;
+typedef struct hostent FAR *LPHOSTENT;
+
+typedef struct servent SERVENT;
+typedef struct servent *PSERVENT;
+typedef struct servent FAR *LPSERVENT;
+
+typedef struct protoent PROTOENT;
+typedef struct protoent *PPROTOENT;
+typedef struct protoent FAR *LPPROTOENT;
+
+typedef struct timeval TIMEVAL;
+typedef struct timeval *PTIMEVAL;
+typedef struct timeval FAR *LPTIMEVAL;
+
+/*
+ * Windows message parameter composition and decomposition
+ * macros.
+ *
+ * WSAMAKEASYNCREPLY is intended for use by the Windows Sockets implementation
+ * when constructing the response to a WSAAsyncGetXByY() routine.
+ */
+#define WSAMAKEASYNCREPLY(buflen,error) MAKELONG(buflen,error)
+/*
+ * WSAMAKESELECTREPLY is intended for use by the Windows Sockets implementation
+ * when constructing the response to WSAAsyncSelect().
+ */
+#define WSAMAKESELECTREPLY(event,error) MAKELONG(event,error)
+/*
+ * WSAGETASYNCBUFLEN is intended for use by the Windows Sockets application
+ * to extract the buffer length from the lParam in the response
+ * to a WSAGetXByY().
+ */
+#define WSAGETASYNCBUFLEN(lParam) LOWORD(lParam)
+/*
+ * WSAGETASYNCERROR is intended for use by the Windows Sockets application
+ * to extract the error code from the lParam in the response
+ * to a WSAGetXByY().
+ */
+#define WSAGETASYNCERROR(lParam) HIWORD(lParam)
+/*
+ * WSAGETSELECTEVENT is intended for use by the Windows Sockets application
+ * to extract the event code from the lParam in the response
+ * to a WSAAsyncSelect().
+ */
+#define WSAGETSELECTEVENT(lParam) LOWORD(lParam)
+/*
+ * WSAGETSELECTERROR is intended for use by the Windows Sockets application
+ * to extract the error code from the lParam in the response
+ * to a WSAAsyncSelect().
+ */
+#define WSAGETSELECTERROR(lParam) HIWORD(lParam)
+
+#endif /* _WINSOCKAPI_ */
+
diff --git a/network/winsock/winsock.lib b/network/winsock/winsock.lib
new file mode 100644
index 00000000..ee649617
--- /dev/null
+++ b/network/winsock/winsock.lib
Binary files differ