1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <mach.h>
include <config.h>
include <chars.h>
include "ki.h"
# KI_OPENKS -- Physically open a kernel server process on a remote node.
# Spawn the process and initialize the environment list and iraf root
# directory on the remote node. The KS channel or NULL is returned as the
# function value.
int procedure ki_openks (node)
int node # node descriptor to open kernel on
bool hostdep
pointer sp, ksname, env, el, valp, ip, op, sv
int show, kschan, nchars, status, junk
pointer env_first(), env_next()
int strlen(), stridx(), strncmp()
int gstrcpy(), ki_send(), ki_receive()
data show /NO/
include "kii.com"
include "kinode.com"
define quit_ 91
begin
call smark (sp)
call salloc (ksname, SZ_FNAME, TY_CHAR)
call salloc (sv, SZB_PACKET / SZB_CHAR, TY_CHAR)
status = ERR
# Our caller may have already prepped a packet in the kii common, which
# we are going to clobber below. Save packet and restore when done.
call amovc (FIRSTINTFIELD, Memc[sv], SZB_PACKET / SZB_CHAR)
# Spawn the kernel server process.
call strpak (n_server[1,node], Memc[ksname], SZ_FNAME)
call zopnks (Memc[ksname], READ_WRITE, kschan)
if (kschan == ERR) {
call sfree (sp)
return (ERR)
} else
n_kschan[node] = kschan
# Read the environment list into a string buffer. Scan the list once
# to determine its size, then allocate the buffer and format a series
# of "set name=value" lines in the buffer.
# Note 4 + 1 comes from len("set ") + \n.
nchars = 0
for (el=env_first(valp); el != NULL; el=env_next(el,valp,show))
nchars = nchars + strlen (Memc[valp]) + 4 + 2 + 1
call salloc (env, nchars, TY_CHAR)
op = env
for (el=env_first(valp); el != NULL; el=env_next(el,valp,show)) {
# Do not pass on the values of the host dependent environment
# variables HOST, IRAF, and TMP. If we do not set the values
# here, the remote kernel will fetch the values automatically
# from the HSI global include file <iraf.h> on the server node.
hostdep = false
if (stridx (Memc[valp], "hit") > 0)
hostdep = ((strncmp (Memc[valp], "host=", 5) == 0) ||
(strncmp (Memc[valp], "iraf=", 5) == 0) ||
(strncmp (Memc[valp], "tmp=", 4) == 0))
if (!hostdep) {
call strcpy ("set ", Memc[op], ARB)
op = op + 4
for (ip=valp; Memc[ip] != '='; ip=ip+1) {
Memc[op] = Memc[ip]
op = op + 1
}
Memc[op] = '='; op = op + 1
Memc[op] = '"'; op = op + 1
op = op + gstrcpy (Memc[ip+1], Memc[op], ARB)
Memc[op] = '"'; op = op + 1
Memc[op] = '\n'; op = op + 1
}
}
Memc[op] = EOS
# Transmit the environment list to the server process, preceded by the
# KI_ENVINIT instruction packet. The ENVINIT function does not return
# a status (to permit pipelining of multiple setenv packets).
p_arg[1] = nchars
if (nchars <= SZ_SBUF)
call strcpy (Memc[env], p_sbuf, nchars)
if (ki_send (node, KI_ENVINIT, 0) == ERR)
goto quit_
if (nchars > SZ_SBUF) {
# Transmit the data record.
call strpak (Memc[env], Memc[env], nchars)
call zawrks (kschan, Memc[env], nchars, long(0))
call zawtks (kschan, status)
if (status != nchars) {
status = ERR
goto quit_
}
# We do expect a status return for large packets.
if (ki_receive (node, KI_ENVINIT, 0) == ERR)
goto quit_
if (p_arg[1] == ERR)
goto quit_
}
status = OK
quit_
if (status == ERR) {
call zclsks (kschan, junk)
n_kschan[node] = NULL
}
# Restore the caller's kii packet.
call amovc (Memc[sv], FIRSTINTFIELD, SZB_PACKET / SZB_CHAR)
call sfree (sp)
return (status)
end
|