aboutsummaryrefslogtreecommitdiff
path: root/sys/ki/kiopenks.x
blob: 64bfb6267ce0c8117f8252e94db2b78188625cf5 (plain) (blame)
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