summaryrefslogtreecommitdiffstats
path: root/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt.d/setup_virtual_floppy.inc
blob: f589d2b6af4d2f9fdf090dce98d7a8f1fdce583a (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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
##############################################
# Include: Setup virtual floppy for drive b: #
##############################################
## Functions ##
setup_virtual_floppy() {
	declare -rg SLX_FLOPPY_IMG="${TMPDIR}/floppy.img"
	declare -r TMPHOME="${HOME}"

	# create floppy disk file + filesystem
	dd "if=/dev/zero" "of=${SLX_FLOPPY_IMG}" count=1440 bs=1024
	chmod 0600 "${SLX_FLOPPY_IMG}"
	mkfs.fat "${SLX_FLOPPY_IMG}" || mkfs.vfat "${SLX_FLOPPY_IMG}" || mkdosfs "${SLX_FLOPPY_IMG}"
	
	if [ -s "${TMPHOME}/.openslx/shares" ]; then
		$(safesource "${TMPHOME}/.openslx/shares")
	elif [ -s "/opt/openslx/inc/shares" ]; then
		$(safesource "/opt/openslx/inc/shares")
	fi

	# Directory for files that go into the virtual floppy
	declare -r FLOPPYDIR="$TMPDIR/floppy"
	mkdir -p "$FLOPPYDIR"
	chmod 0700 "$FLOPPYDIR"

	if notempty SHARE_REMAP_MODE; then
		local SHARE_REMAP_MODE_INI="$SHARE_REMAP_MODE"
	else
		local SHARE_REMAP_MODE_INI="0"
		local SHARE_REMAP_MODE="3"
	fi
	notempty SHARE_CREATE_MISSING_REMAP || local SHARE_CREATE_MISSING_REMAP="1"
	
	# Create file for network shares to mount
	declare -g SHARES="${FLOPPYDIR}/shares.dat"
	touch "${SHARES}"
	chmod 0600 "${SHARES}"
	if ! pwdaemon --query "${TMPHOME}/.pwsocket" > "${SHARES}"; then
		slxlog "run-virt-pwdaemon" "Could not query pwdaemon"
		echo -e '-\t-\t-\t-\t-' > "${SHARES}"
	else
		sed -i 's/^/192.168.101.1\t/' "${SHARES}" # TODO: Depending on nettype (in case we have != nat some day)
		if [ "${SHARE_REMAP_MODE}" = 1 -o "${SHARE_REMAP_MODE}" = 2 ] && [ -s "${TMPHOME}/.openslx/home" ]; then
			NETHOME=$(cat "${TMPHOME}/.openslx/home")
			notempty SHARE_HOME_DRIVE || local SHARE_HOME_DRIVE="H:"
			# Tab between items, so spaces can be used!
			echo "${NETHOME}	${SHARE_HOME_DRIVE}	Home-Verzeichnis" >> "${SHARES}"
		fi
		for VAR in ${!SHARE_LINE_*}; do
			echo "${!VAR}" >> "${SHARES}"
		done
	fi

	declare -r NETSHARES="$CONFDIR/netshares"
	declare -r RUNSCRIPT="$CONFDIR/runscript"
	## Network shares
	# openslx.exe expects network shares line in the following format:
	#		<path> <letter> <shortcut> <username> <password>
	# which is coincidentally the one we received from dmsd :)
	if [ -f "$NETSHARES" ] && [ -s "${NETSHARES}" ]; then
		# try to detect if we are running windows and replace '/' with '\'
		# in an attempt to fix an improperly given samba path
		cmd=(cat)
		if [[ "$( tr 'A-Z' 'a-z' <<< ${VM_OS_TYPE})" = *windows* ]]; then
			cmd=(tr / '\\')
		fi
		# replace the tag for the username, if present; the variable expansion escapes all ':' in $USER
		sed -i "s:%loginuser%:${USER//:/\\:}:g" "${NETSHARES}"
		< "${NETSHARES}"  "${cmd[@]}" >> "${SHARES}"
	fi

	## Runscript
	declare -A OPTIONS
	# Check downloaded runscript and handle options like
	# extension, visibility flag, ...
	# options are 'key=value' pairs separated with ';'
	if [ -f "$RUNSCRIPT" ] && [ -s "$RUNSCRIPT" ]; then
		IFS=$'\n'
		for OPT in $( head -n 1 "$RUNSCRIPT" | tr ";" "\n" ); do
			KEY=$( cut -s -d '=' -f 1 <<< "${OPT^^}" )
			[ -n "$KEY" ] && OPTIONS["$KEY"]="$( cut -s -d '=' -f 2- <<< "$OPT" )"
		done
		unset IFS

		[ -n "${OPTIONS[EXT]}" ] && [ "x${OPTIONS[EXT]:0:1}" != "x." ] && OPTIONS[EXT]=".${OPTIONS[EXT]}"
	fi

	# Default to muted
	local MUTED=1
	# Satellite/location setting can override
	[[ "$SLX_VM_SOUND" = *_ACTIVE ]] && MUTED="0"
	# finally, lecture override
	if [[ "$SLX_VM_SOUND" != FORCE_* ]]; then
		if [ -n "${OPTIONS[SOUNDMUTED]}" ] && [ "${OPTIONS[SOUNDMUTED]}" != -1 ]; then
			MUTED="${OPTIONS[SOUNDMUTED]}"
		fi
	fi

	# Write info file
	local UNAME=
	[ -s "${HOME}/.openslx/account" ] && UNAME=$(cat "${HOME}/.openslx/account")
	notempty UNAME || UNAME=$(whoami)

	# Only warn for non-demo
	if [ "$SHARE_NO_HOME_WARN" = "2" ] && [ "$UNAME" != "demo" ]; then
		SHARE_NO_HOME_WARN=0
	fi

	# Legacy: openslx.exe expects HOSTRES.TXT
	local RESOLUTION=$(xrandr | grep -o -E 'connected\s*(primary)?\s*[0-9]+x[0-9]+\+0\+0' \
		| grep -o -E -m1 '[0-9]+x[0-9]+')
	cat > "${FLOPPYDIR}/HOSTRES.TXT" <<-EOF
	${RESOLUTION}
	EOF

	(
	echo '[openslx]'
	# Ugly hack for multi-monitor support with virtualbox.
	# The guest additions properly set up the resolutions of multiple
	# monitor, thus we need to disable the resolution feature of
	# the openslx.exe as it would break what virtualbox did.
	if [ "$PLUGIN_ID" = "vmware" ] || [ "$PLUGIN_ID" = "virtualbox" -a "$DISPLAY_COUNT" -eq 1 ]; then
		echo "resolution=$RESOLUTION"
	fi
	cat <<-EOF
	username=${UNAME}
	createMissingRemap=${SHARE_CREATE_MISSING_REMAP}
	remapMode=${SHARE_REMAP_MODE_INI}
	homeDrive=${SHARE_HOME_DRIVE}
	scriptExt=${OPTIONS[EXT]}
	scriptVisibility=${OPTIONS[VISIBILITY]}
	passCreds=${SHARE_CREDENTIAL_PASSTHROUGH}
	bootIp=${SLX_PXE_CLIENT_IP}
	muteSound=${MUTED}
	noHomeWarn=${SHARE_NO_HOME_WARN}
	
	[remap]
	documents=${SHARE_DOCUMENTS}
	downloads=${SHARE_DOWNLOADS}
	desktop=${SHARE_DESKTOP}
	media=${SHARE_MEDIA}
	other=${SHARE_OTHER}
	EOF
	) > "${FLOPPYDIR}/openslx.ini"
	ln -n -s "${VMCHOOSER_DIR}/data/openslx.exe" "${FLOPPYDIR}/openslx.exe"
	# If we have a kerberos ticket, copy that one too (TODO: Copy keytab too?)
	if [ -n "$KRB5CCNAME" ]; then
		kf=${KRB5CCNAME#FILE:}
		kf=${kf#file:}
		if [ -n "$kf" ] && [ -f "$kf" ]; then
			ln -n -s "$kf" "${FLOPPYDIR}/krb5user.key"
		fi
	fi
	
	# Linux directory
	ln -n -s "$VMCHOOSER_DIR/data/linux" "${FLOPPYDIR}/linux"
	
	# User supplied runscript
	if [ -n "${OPTIONS[EXT]}" ]; then
		sed -i '1d' "${RUNSCRIPT}"
		ln -n -s "${RUNSCRIPT}" "${FLOPPYDIR}/runscript${OPTIONS[EXT]}"
	fi
	
	# Admin supplied runscript(s)
	if [ -d "${CONFDIR}/adminrun" ]; then
		ln -n -s "${CONFDIR}/adminrun" "${FLOPPYDIR}/adminrun"
	fi

	# Hook
	run_hooks "floppy" "$FLOPPYDIR"

	local size="$( du -s -l -L "${FLOPPYDIR}" | awk '{print $1}' )"
	if [ -n "$size" ] && [ "$size" -ge 1400 ]; then
		writelog "WARNING: Floppydir contains $size kb of data, will most likely not fit..."
	fi
	
	if ! mcopy -s -i "${SLX_FLOPPY_IMG}" "${FLOPPYDIR}"/* "::/"; then
		writelog "Error creating floppy image from ${FLOPPYDIR}"
	elif ! $DEBUG; then
		rm -rf -- "${FLOPPYDIR}"
	fi
}

## MAIN ##
# Sanity checks #
# Check if we have any filesystem tool
if ! check_dep --oneof mkfs.fat mkfs.vfat mkdosfs; then
	# no tools found in minilinux, this means no floppy/openslx.exe will be supported
	slxlog "virt-fstool-missing" "Could not find any of 'mkfs.fat', 'mkfs.vfat', 'mkdosfs'!"
	writelog "Could not find any filesystem-related tools to create the floppy's filesystem with!"
	error_user "Konnte kein virtuelles Floppy anlegen! Setzen der Auflösung oder Einhängen von Netzwerkfreigaben werden nicht funktionieren. Bitte kontaktieren Sie den Support."
	# still continue as this is not really critical
fi

# separate check for other deps
if ! check_dep dd chmod pwdaemon sed head grep cut whoami mcopy; then
	writelog "Missing core tools to setup the virtual floppy!"
else
	reg_feature_handler "slxfloppy" "setup_virtual_floppy"
fi