aboutsummaryrefslogtreecommitdiff
path: root/sys/ki/kfmkcp.x
blob: 675aa1b38d610dcb12bb24489ad435f0dccf6bde (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
134
135
136
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<mach.h>
include	"ki.h"


# KFMKCP -- Make a null length copy of a file.  The new file inherits the
# attributes of the existing file.  This works provided both files are on
# the same node; since the kernel routine is atomic and must access both
# files, and the attributes are OS dependent, there is no way to inherit
# the attributes if the files reside on different nodes.

procedure kfmkcp (old_osfn, new_osfn, status)

char	old_osfn[ARB]		# packed os filename of existing file
char	new_osfn[ARB]		# packed os filename of new file
int	status			# answer; ok or err

pointer	sp, fname
int	server1, server2, chan, junk, old, new
int	ki_connect(), ki_sendrcv(), strlen()
include	"kii.com"

begin
	call smark (sp)
	call salloc (fname, SZ_FNAME, TY_CHAR)

	server2 = ki_connect (new_osfn)
	call strcpy (p_sbuf[p_arg[1]], Memc[fname], SZ_FNAME)
	server1 = ki_connect (old_osfn)
	old = p_arg[1]

	if (server1 == NULL && server2 == NULL) {
	    # Both files reside on the local node.

	    call strpak (p_sbuf[old], p_sbuf[old], SZ_SBUF)
            call strpak (Memc[fname], Memc[fname], SZ_FNAME)
	    call zfmkcp (p_sbuf[old], Memc[fname], status)

	} else if (server1 == server2) {
	    # Both files reside on the same remote node.

	    new = old + strlen(p_sbuf[old])+1 + 1
	    if (new + strlen(Memc[fname])+1 > SZ_SBUF)
		status = ERR
	    else {
		call strcpy (Memc[fname], p_sbuf[new], SZ_SBUF-new+1)
	    
		p_arg[2]  = new
		p_sbuflen = SZ_SBUF

		if (ki_sendrcv (server1, KI_ZFMKCP, 0) == ERR)
		    status = ERR
		else
		    status = p_arg[1]
	    }

	} else if (server1 != NULL && server2 != NULL) {
	    # Both files are remote.  Cannot transfer all attributes;
	    # the best we can do is create either a text or binary file.

	    call kfacss (old_osfn, 0, TEXT_FILE, status)
            call strpak (Memc[fname], Memc[fname], SZ_FNAME)

	    if (status == YES) {
		# Create a text file.
		call kopntx (new_osfn, NEW_FILE, chan)
		if (chan != ERR) {
		    call kclstx (chan, junk)
		    status = chan
		} else
		    status = ERR
	    } else {
		# Create a binary file.
		call kopnbf (new_osfn, NEW_FILE, chan)
		if (chan != ERR) {
		    call kclsbf (chan, junk)
		    status = chan
		} else
		    status = ERR
	    }

	} else if (server1 != NULL) {
	    # The existing file is remote.  Cannot transfer all attributes;
	    # the best we can do is create either a text or binary file.
	    # Call ZFACSS to determine the file type of the existing file
	    # and create a null length text or binary file.

	    call kfacss (old_osfn, 0, TEXT_FILE, status)
            call strpak (Memc[fname], Memc[fname], SZ_FNAME)

	    if (status == YES) {
		# Create a text file.
		call zopntx (Memc[fname], NEW_FILE, chan)
		if (chan != ERR) {
		    call zclstx (chan, junk)
		    status = chan
		} else
		    status = ERR
	    } else {
		# Create a binary file.
		call zopnbf (Memc[fname], NEW_FILE, chan)
		if (chan != ERR) {
		    call zclsbf (chan, junk)
		    status = chan
		} else
		    status = ERR
	    }

	} else {
	    # The new file is remote.

	    call strpak (p_sbuf[old], p_sbuf[old], SZ_SBUF)
	    call zfacss (p_sbuf[old], 0, TEXT_FILE, status)

	    if (status == YES) {
		# Create a text file.
		call kopntx (new_osfn, NEW_FILE, chan)
		if (chan != ERR) {
		    call kclstx (chan, junk)
		    status = chan
		} else
		    status = ERR
	    } else {
		# Create a binary file.
		call kopnbf (new_osfn, NEW_FILE, chan)
		if (chan != ERR) {
		    call kclsbf (chan, junk)
		    status = chan
		} else
		    status = ERR
	    }
	}

	call sfree (sp)
end