Commit dabc663a authored by Kirk Webb's avatar Kirk Webb

Initial changes required to compile / install the Emulab client-side on

Windows 7 under Cygwin 1.7.  Mostly tweaks to makefiles to recognize Win7 in
addition to Windows XP.

New directory for Win7-specific files: clientside/tmcc/cygwinseven
parent d0955715
...@@ -241,7 +241,7 @@ outfiles="Makeconf GNUmakefile \ ...@@ -241,7 +241,7 @@ outfiles="Makeconf GNUmakefile \
tmcc/freebsd7/supfile tmcc/freebsd7/netif-emulab \ tmcc/freebsd7/supfile tmcc/freebsd7/netif-emulab \
tmcc/cygwinxp/GNUmakefile tmcc/dp/GNUmakefile \ tmcc/cygwinxp/GNUmakefile tmcc/dp/GNUmakefile \
tmcc/openbsd/GNUmakefile tmcc/ron/GNUmakefile \ tmcc/openbsd/GNUmakefile tmcc/ron/GNUmakefile \
tmcc/plab/GNUmakefile \ tmcc/plab/GNUmakefile tmcc/cygwinseven/GNUmakefile \
os/GNUmakefile os/syncd/GNUmakefile \ os/GNUmakefile os/syncd/GNUmakefile \
os/dijkstra/GNUmakefile os/genhostsfile/GNUmakefile \ os/dijkstra/GNUmakefile os/genhostsfile/GNUmakefile \
os/frisbee.redux/GNUmakefile \ os/frisbee.redux/GNUmakefile \
......
...@@ -62,8 +62,8 @@ YCFLAGS += -I. -I$(TGSRCDIR) -DUSEEVENTS -DFREEBSD ...@@ -62,8 +62,8 @@ YCFLAGS += -I. -I$(TGSRCDIR) -DUSEEVENTS -DFREEBSD
LIBS += -ll -lcompat LIBS += -ll -lcompat
endif endif
ifeq ($(SYSTEM),CYGWIN_NT-5.1) ifeq ($(findstring CYGWIN_NT,$(SYSTEM)),CYGWIN_NT)
# Cygwin on Windows XP (a.k.a. NT 5.1) - resembles the Linux case. # Cygwin on Windows XP/7 - resembles the Linux case.
CFLAGS += -DCYGWIN -DLINUX CFLAGS += -DCYGWIN -DLINUX
YCFLAGS += -I. -I$(TGSRCDIR) -DUSEEVENTS -DCYGWIN -DLINUX YCFLAGS += -I. -I$(TGSRCDIR) -DUSEEVENTS -DCYGWIN -DLINUX
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
#define TPM_CERTFILE "tpm.cert" #define TPM_CERTFILE "tpm.cert"
#define TPM_KEYFILE "tpm.key" #define TPM_KEYFILE "tpm.key"
#ifdef linux #if defined(linux) || defined(__CYGWIN__)
#define EAUTH EPERM #define EAUTH EPERM
#endif #endif
......
...@@ -17,6 +17,13 @@ SUBDIRS = syncd dijkstra genhostsfile imagezip frisbee.redux ...@@ -17,6 +17,13 @@ SUBDIRS = syncd dijkstra genhostsfile imagezip frisbee.redux
ifeq ($(SYSTEM),FreeBSD) ifeq ($(SYSTEM),FreeBSD)
SUBDIRS += growdisk SUBDIRS += growdisk
endif endif
# XXX: Remove dijkstra from win7 for now as g++4 doesn't like Boost
# XXX: also remove imagezip and frisbee - oy vey...
ifeq ($(findstring CYGWIN_NT,$(SYSTEM)),CYGWIN_NT)
SUBDIRS := $(filter-out dijkstra imagezip frisbee.redux,$(SUBDIRS))
endif
all: all-subdirs all: all-subdirs
include $(TESTBED_SRCDIR)/GNUmakerules include $(TESTBED_SRCDIR)/GNUmakerules
...@@ -42,13 +49,16 @@ client-install: client ...@@ -42,13 +49,16 @@ client-install: client
$(INSTALL) -m 644 $(SRCDIR)/install-tarfile.1 $(DESTDIR)$(CLIENT_MANDIR)/man1/install-tarfile.1 $(INSTALL) -m 644 $(SRCDIR)/install-tarfile.1 $(DESTDIR)$(CLIENT_MANDIR)/man1/install-tarfile.1
$(INSTALL_PROGRAM) $(SRCDIR)/install-rpm $(LBINDIR)/install-rpm $(INSTALL_PROGRAM) $(SRCDIR)/install-rpm $(LBINDIR)/install-rpm
$(MAKE) -C syncd client-install $(MAKE) -C syncd client-install
ifneq ($(findstring CYGWIN_NT,$(SYSTEM)),CYGWIN_NT) # Filter out again...
$(MAKE) -C dijkstra client-install $(MAKE) -C dijkstra client-install
$(MAKE) -C genhostsfile client-install
$(MAKE) -C imagezip client-install $(MAKE) -C imagezip client-install
$(MAKE) -C frisbee.redux client-install
endif
$(MAKE) -C genhostsfile client-install
ifeq ($(SYSTEM),FreeBSD) ifeq ($(SYSTEM),FreeBSD)
$(MAKE) -C growdisk client-install $(MAKE) -C growdisk client-install
endif endif
$(MAKE) -C frisbee.redux client-install
subboss: client subboss: client
......
...@@ -27,8 +27,8 @@ SDLIBS+= -ltb -lmysqlclient ...@@ -27,8 +27,8 @@ SDLIBS+= -ltb -lmysqlclient
LIBS= $(MLIBS) LIBS= $(MLIBS)
CP= cp -pf CP= cp -pf
ifeq ($(SYSTEM),CYGWIN_NT-5.1) ifeq ($(findstring CYGWIN_NT,$(SYSTEM)),CYGWIN_NT)
# Cygwin on Windows XP (a.k.a. NT 5.1). # Cygwin on Windows XP/7
MLIBS += -liphlpapi MLIBS += -liphlpapi
WINCLIENT = idlemon WINCLIENT = idlemon
...@@ -70,7 +70,7 @@ boss-install: $(addprefix $(INSTALL_SBINDIR)/, $(SBIN_SCRIPTS) sdcollectd) webfe ...@@ -70,7 +70,7 @@ boss-install: $(addprefix $(INSTALL_SBINDIR)/, $(SBIN_SCRIPTS) sdcollectd) webfe
client-install: client client-install: client
$(INSTALL_PROGRAM) slothd$(EXE) $(DESTDIR)$(CLIENT_BINDIR)/slothd$(EXE) $(INSTALL_PROGRAM) slothd$(EXE) $(DESTDIR)$(CLIENT_BINDIR)/slothd$(EXE)
ifeq ($(SYSTEM),CYGWIN_NT-5.1) ifeq ($(findstring CYGWIN_NT,$(SYSTEM)),CYGWIN_NT)
# If there are any RDP logins active, idlemon will be busy. Try moving it. # If there are any RDP logins active, idlemon will be busy. Try moving it.
-mv $(IDLEMONEXE) $(IDLEMONEXE).prev -mv $(IDLEMONEXE) $(IDLEMONEXE).prev
$(INSTALL_PROGRAM) idlemon$(EXE) $(IDLEMONEXE) $(INSTALL_PROGRAM) idlemon$(EXE) $(IDLEMONEXE)
......
...@@ -104,9 +104,14 @@ endif ...@@ -104,9 +104,14 @@ endif
ifeq ($(SYSTEM),Cygwin) ifeq ($(SYSTEM),Cygwin)
# Cygwin on Windows XP (a.k.a. NT 5.1) - resembles the Linux case. # Cygwin on Windows XP (a.k.a. NT 5.1) - resembles the Linux case.
ifeq ($(MDSUBDIR),CYGWIN_NT-5.1) ifeq ($(MDREL),5.1)
MDSUBDIR = cygwinxp MDSUBDIR = cygwinxp
TMSLIBS += -lminires TMSLIBS += -lminires
else
# Cygwin on Windows 7 (a.k.a. NT 6.1) - resembles the Linux case.
ifeq ($(MDREL),6.1)
MDSUBDIR = cygwinseven
endif
endif endif
endif endif
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
#
# XXX ONLY RUN THIS INSTALL ON A CYGWIN / WINDOWS XP NODE!
# Similar to linux9, cygwinxp is an overlay on linux, which is an overlay
# on common.
#
# Trivial. These things just need to be installed into the right place
# on a testbed node before cutting an image.
#
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = @top_builddir@
SUBDIR = $(subst $(TESTBED_SRCDIR)/,,$(SRCDIR))
include $(OBJDIR)/Makeconf
SCRIPTS =
#
# Force dependencies on the scripts so that they will be rerun through
# configure if the .in file is changed.
#
all: $(SCRIPTS)
include $(TESTBED_SRCDIR)/GNUmakerules
DESTDIR =
SYSETCDIR = $(DESTDIR)/etc
ETCDIR = $(DESTDIR)$(CLIENT_ETCDIR)
BINDIR = $(DESTDIR)$(CLIENT_BINDIR)
VARDIR = $(DESTDIR)$(CLIENT_VARDIR)
RCDIR = $(SYSETCDIR)/rc.d
INSTALL = /usr/bin/install -c
COMMON = $(SRCDIR)/../common
install client-install: baselinux-install common-install etc-install \
sup-install script-install ##bin-install
@echo "Remember to install the PEM files if necessary"
simple-install: common-install script-install ##bin-install
dir-install:
baselinux-install: dir-install
(cd ../linux; $(MAKE) DIRGROUP=wheel client-install)
rm -f $(BINDIR)/rc/rc.healthd
rm -f $(BINDIR)/rc/rc.slothd
common-install: dir-install
(cd ../common; $(MAKE) local-install)
sup-install: dir-install
SYSTEM32 = /cygdrive/c/Windows/System32
WBEM = $(SYSTEM32)/Wbem
bin-install: dir-install
# These are found in the /share/windows directory.
$(INSTALL) -m 755 $(SRCDIR)/WSName.exe $(BINDIR)/WSName.exe
$(INSTALL) -m 755 $(SRCDIR)/addusers.exe $(BINDIR)/addusers.exe
$(INSTALL) -m 755 $(SRCDIR)/usrtogrp.exe $(BINDIR)/usrtogrp.exe
# Setx is run under CMD early in the user login to make HOME for Emacs.
$(INSTALL) -m 755 $(SRCDIR)/setx.exe $(SYSTEM32)/setx.exe
# Devcon is used by rc.cygwin and rc.ifc to disable/enable NIC's.
$(INSTALL) -m 755 $(SRCDIR)/devcon.exe $(BINDIR)/devcon.exe
# These are used by tmcd/findif.
$(INSTALL) -m 755 $(SYSTEM32)/getmac.exe $(BINDIR)/getmac.exe
$(INSTALL) -m 755 $(WBEM)/framedyn.dll $(BINDIR)/framedyn.dll
etc-install: dir-install sysetc-install
sysetc-install: dir-install ###ifcfgs
# Watchdog assumes the ssh keys are in /etc/ssh.
mkdir -p /etc/ssh
ln -f -s /etc/ssh* /etc/ssh
# Boot log files have to be writable by root under rc.cygwin .
$(INSTALL) -c -m 775 -o root -d /var/log
$(INSTALL) -c -m 775 -o root -d /var/db
script-install: dir-install $(SCRIPTS)
$(INSTALL) -m 755 $(SRCDIR)/liblocsetup.pm $(BINDIR)/liblocsetup.pm
$(INSTALL) -m 755 $(SRCDIR)/prepare $(BINDIR)/prepare
$(INSTALL) -m 755 $(SRCDIR)/tbshutdown $(BINDIR)/tbshutdown
$(INSTALL) -c -m 755 -o root -d /sbin
#$(INSTALL) -m 755 $(SRCDIR)/reboot /sbin/reboot
# Put the tcsh desktop startup script in the CygWin root directory.
#$(INSTALL) -m 755 $(SRCDIR)/cygwin-tcsh.bat /
ln -f -s /bin/shutdown /sbin/shutdown
ln -f -s /bin/reboot /sbin/reboot
# Everybody is in the Administrators group already, so sudo is irrelevant.
$(INSTALL) -m 755 $(SRCDIR)/sudo.dummy /bin/sudo
$(INSTALL) -m 755 $(SRCDIR)/rc.firstboot $(BINDIR)/rc/rc.firstboot
$(INSTALL) -m 755 $(SRCDIR)/rc.cygwinxp $(BINDIR)/rc/rc.cygwin
#$(INSTALL) -m 755 $(SRCDIR)/clean_logonui $(BINDIR)/clean_logonui
$(INSTALL) -m 755 $(SRCDIR)/rc.reboot $(BINDIR)/rc/rc.reboot
$(INSTALL) -m 755 $(SRCDIR)/rc.lmhosts $(BINDIR)/rc/rc.lmhosts
$(INSTALL) -m 755 $(SRCDIR)/netbt $(BINDIR)/netbt
sfs-install:
# create ifcfg-eth? files
ifcfgs: $(SRCDIR)/mkifcfgs $(SRCDIR)/ifcfg.template
$(SRCDIR)/mkifcfgs $(SRCDIR)/ifcfg.template
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
#
# CygWin specific routines and constants for the client bootime setup stuff.
#
package liblocsetup;
use Exporter;
@ISA = "Exporter";
@EXPORT =
qw ( $CP $LN $RM $MV $TOUCH $EGREP $CHOWN $CHMOD $MOUNT $UMOUNT
$NTS $NET $HOSTSFILE
$TMPASSWD $SFSSD $SFSCD $RPMCMD
os_account_cleanup os_accounts_start os_accounts_end os_accounts_sync
os_ifconfig_line os_etchosts_line
os_setup os_groupadd os_groupgid os_useradd os_userdel os_usermod os_mkdir
os_ifconfig_veth os_viface_name
os_routing_enable_forward os_routing_enable_gated
os_routing_add_manual os_routing_del_manual os_homedirdel
os_groupdel os_samba_mount os_islocaldir
os_getnfsmounts os_getnfsmountpoints os_noisycmd
os_fwconfig_line os_fwrouteconfig_line
);
sub VERSION() { return 1.0; }
# Must come after package declaration!
use English;
# Load up the paths. Its conditionalized to be compatabile with older images.
# Note this file has probably already been loaded by the caller.
BEGIN
{
if (-e "/etc/emulab/paths.pm") {
require "/etc/emulab/paths.pm";
import emulabpaths;
}
else {
my $ETCDIR = "/etc/rc.d/testbed";
my $BINDIR = "/etc/rc.d/testbed";
my $VARDIR = "/etc/rc.d/testbed";
my $BOOTDIR = "/etc/rc.d/testbed";
}
}
use librc;
#
# Various programs and things specific to CygWin on XP and that we want to export.
#
$CP = "/bin/cp";
$LN = "/bin/ln";
$RM = "/bin/rm";
$MV = "/bin/mv";
$TOUCH = "/bin/touch";
$EGREP = "/bin/egrep -q";
$CHOWN = "/bin/chown";
$CHMOD = "/bin/chmod";
$MOUNT = "/bin/mount";
$UMOUNT = "/bin/umount";
# Cygwin.
$MKPASSWD = "/bin/mkpasswd";
$MKGROUP = "/bin/mkgroup";
$AWK = "/bin/gawk";
$BASH = "/bin/bash";
# Windows under Cygwin.
$NTS = "/cygdrive/c/WINDOWS/system32";
$NET = "$NTS/net";
$NETSH = "$NTS/netsh";
$IPCONFIG = "$NTS/ipconfig";
$NTE = "$NTS/drivers/etc";
$HOSTSFILE = "$NTE/hosts";
#$HOSTSFILE = "/etc/hosts";
#
# These are not exported
#
my $ADDUSERS = "$BINDIR/addusers.exe";
my $DEVCON = "$BINDIR/devcon.exe";
my $IFCONFIGBIN = "$NETSH interface ip set address";
my $IFCONFIG = "$IFCONFIGBIN name=\"%s\" source=static addr=%s mask=%s";
my $IFC_1000MBS = "1000baseTx";
my $IFC_100MBS = "100baseTx";
my $IFC_10MBS = "10baseT";
my $IFC_FDUPLEX = "FD";
my $IFC_HDUPLEX = "HD";
my @LOCKFILES = ("/etc/group.lock", "/etc/gshadow.lock");
my $MKDIR = "/bin/mkdir";
my $RMDIR = "/bin/rmdir";
my $GATED = "/usr/sbin/gated";
my $ROUTE = "$NTS/route";
my $SHELLS = "/etc/shells";
my $DEFSHELL = "/bin/tcsh";
my $winusersfile = "$BOOTDIR/winusers";
my $usershellsfile = "$BOOTDIR/usershells";
my $XIMAP = "$BOOTDIR/xif_map";
#
# system() with error checking.
#
sub mysystem($)
{
my ($cmd) = @_;
if (system($cmd) != 0) {
warning("Failed: ($cmd), $!\n");
}
}
#
# OS dependent part of cleanup node state.
#
sub os_account_cleanup($)
{
# XXX this stuff should be lifted up into rc.accounts, sigh
my ($updatemasterpasswdfiles) = @_;
if (!defined($updatemasterpasswdfiles)) {
$updatemasterpasswdfiles = 0;
}
# Undo what rc.mounts and rc.accounts did.
# Get the users list from NT, dumped into /etc/passwd and preened by the
# os_accounts_sync function. Root and internal admin accounts should have
# homedirs under /home, while users are under /users.
my ($pwd_line, $name);
if (open(PWDHANDLE, "/etc/passwd")) {
while ($pwdline = readline(PWDHANDLE)) {
if ($pwdline !~ m|:/users/|) {
next;
}
$name = substr($pwdline, 0, index($pwdline, ":"));
print "Removing user: $name\n";
# There is always an NT account.
mysystem("$NET user $name /delete >& /dev/null");
# There will only be an NT homedir if the user has logged in sometime.
my $das = "C:/'Documents and Settings'";
if ( -d "$das/$name" ) {
print "Removing directory: $das/$name\n";
system("$CHMOD -Rf 777 $das/$name >& /dev/null");
system("$CHOWN -Rf root $das/$name >& /dev/null");
system("$RM -rf $das/$name "); # Show errors.
}
# It sometimes also makes user.PCnnn, user.PCnnn.000, etc.
if ( `ls -d $das/$name.* 2>/dev/null` ) {
print "Removing directories: $das/$name.*\n";
system("$CHMOD -Rf 777 $das/$name.* >& /dev/null");
system("$CHOWN -Rf root $das/$name.* >& /dev/null");
system("$RM -rf $das/$name.*"); # Show errors.
}
# Unmount the homedir so we can get to the mount point and remove it.
system("$UMOUNT /users/$name >& /dev/null");
system("$RMDIR /users/$name")
if ( -d "/users/$name" );
}
close(PWDHANDLE);
# Make the CygWin /etc/passwd and /etc/group files match Windows.
os_accounts_sync();
}
# Clean out the user /sshkeys directories, leaving /sshkeys/root alone.
if (opendir(DIRHANDLE, "/sshkeys")) {
while ($name = readdir(DIRHANDLE)) {
if ($name =~ m/^\.+/ || $name =~ m/^root$/) {
next;
}
# Open up an existing key dir to the root user. Even though root
# is in the Administrators group, it's locked out by permissions.
mysystem("$CHMOD 777 /sshkeys/$name");
mysystem("$CHOWN -Rf root /sshkeys/$name");
mysystem("$RM -rf /sshkeys/$name");
}
closedir(DIRHANDLE);
}
# Clean out the /proj subdirectories.
if (opendir(DIRHANDLE, "/proj")) {
while ($name = readdir(DIRHANDLE)) {
if ($name =~ m/^\.+/) {
next;
}
print "Removing project: $name\n";
# Unmount the project dir so we can get to the mount point.
mysystem("$UMOUNT /proj/$name");
mysystem("$RMDIR /proj/$name");
}
}
# Just unmount /share, everybody gets one.
mysystem("$UMOUNT /share");
}
#
# Make the CygWin /etc/passwd and /etc/group files match Windows.
#
sub os_accounts_sync()
{
unlink @LOCKFILES;
# Generate the CygWin password and group files from the registry users.
# Note that the group membership is not reported into the CygWin files.
print "Resetting the CygWin passwd and group files.\n";
my $cmd = "$MKPASSWD -l | $AWK -F: '";
$cmd .= 'BEGIN{ OFS=":"; ';
# Keep Windows admin account homedirs under /home so we know what to clean.
$cmd .= ' admin["root"]= admin["Administrator"]= admin["Guest"]= 1; ';
$cmd .= ' admin["HelpAssistant"]= admin["SUPPORT_388945a0"]= 1; }';
# Make root's UID zero.
$cmd .= '{ if ($1=="root") $3="0"; ';
# Put genuine user homedirs under /users, instead of /home.
$cmd .= ' else if ( ! admin[$1] ) sub("/home/", "/users/"); print }';
$cmd .= "'";
# Apply the users' shell preferences.
$cmd .= " | sed -f $usershellsfile"
if (-e $usershellsfile);
$cmd .= " > /etc/passwd.new";
##print "$cmd\n";
if (system("$cmd") != 0) {
warning("Could not generate /etc/password.new file: $!\n");
return -1;
}
# Work around "/etc/passwd: Device or resource busy".
$cmd = "$MV /etc/passwd /etc/passwd.prev";
##print "$cmd\n";
if (system("$cmd") != 0) {
warning("Could not $cmd $!\n");
return -1;
}
$cmd = "$MV /etc/passwd.new /etc/passwd";
##print "$cmd\n";
if (system("$cmd") != 0) {
warning("Could not $cmd $!\n");
return -1;
}
$cmd = "$MKGROUP -l | $AWK '";
# Make a duplicate group line that is a wheel alias for Administrators.
$cmd .= '/^Administrators:/{print "wheel" substr($0, index($0,":"))} {print}';
$cmd .= "' > /etc/group";
##print "$cmd\n";
if (system("$cmd") != 0) {
warning("Could not generate /etc/group file: $!\n");
return -1;
}
return 0;
}
# Import the mapping from non-control interface names, e.g. "Local Area
# Connection #4" to the Device Instance ID's used as devcon arguments, e.g.
# "@PCI\VEN_8086&DEV_1010&SUBSYS_10128086&REV_01\5&2FA58B96&0&210030".
my %dev_map = ();
sub get_dev_map()
{
if (! $dev_map) {
if (! open(DEVMAP, $XIMAP)) {
warning("Cannot open $XIMAP $!\n");
}
else {
while (my $dev_line = <DEVMAP>) {
chomp($dev_line);
my ($dev_name, $dev_inst) = split(":", $dev_line, 2);
$dev_map{$dev_name} = $dev_inst;
}
close(DEVMAP);
}
}
}
#
# Generate and return an ifconfig line that is approriate for putting
# into a shell script (invoked at bootup).
#
sub os_ifconfig_line($$$$$$$;$$%)
{
my ($iface, $inet, $mask, $speed, $duplex, $aliases, $iface_type,
$settings, $rtabid, $cookie) = @_;
my ($uplines, $downlines);
# Handle interfaces missing from ipconfig.
get_dev_map();
if ( ! defined( $dev_map{$iface} ) ) {
# Try rc.cygwin again to disable/re-enable the interface object.
system("$BINDIR/rc/rc.cygwin");
# Reboot if it still fails, in hope that the interface comes back.
#
# We dare not proceed, because using netsh to try to set the IP
# address on one of the missing addresses will blow away the IP on
# *another* interface, sometimes the control net interface. Then
# we would really be in the soup...
get_dev_map();
if ( ! defined( $dev_map{$iface} ) ) {
system("$BINDIR/rc/rc.reboot");
# Sometimes rc.reboot gets fork: Resource temporarily unavailable.
print "rc.reboot returned, trying tsshutddn.";
system("tsshutdn 1 /REBOOT /DELAY:1");
print "tsshutdn failed, sleep forever.";
sleep;
}
}
if ($inet ne "") {
# Startup.
$uplines .= qq{\n #================================\n };
$uplines .= qq{echo "Enabling $iface on $inet"\n };
#
# Re-enable device if necessary (getmac Transport is "Media disconnected".)
my $test = qq[getmac /v /fo csv | awk -F, '/^"$iface"/{print \$4}'];
$uplines .= qq{if [ \`$test\` = '"Media disconnected"' ]; then\n };
$uplines .= " $DEVCON enable '$dev_map{$iface}'\n ";
$uplines .= qq{ sleep 5\n };
$uplines .= qq{fi\n };
#
# Configure.
$uplines .= sprintf($IFCONFIG, $iface, $inet, $mask) . qq{\n };
#
# Check that the configuration took!
my $showip = qq[$NETSH interface ip show address name="$iface"];
my $ipconf = qq[$IPCONFIG /all | tr -d '\\r'];
my $ipawk = qq[/^Ethernet adapter/] .
qq[{ ifc = gensub("Ethernet adapter (.*):", "\\\\\\\\1", 1); next }] .
qq[/IP Address/ && ifc == "$iface"{print \$NF}];
my $addr1 = qq[addr1=\`$showip | awk '/IP Address:/{print \$NF}'\`];
my $addr2 = qq[addr2=\`$ipconf | awk '$ipawk'\`];
my $iptest = '[[ "$addr1" != '.$inet.' || "$addr2" != '.$inet.' ]]';
$uplines .= qq{$addr1\n $addr2\n };
$uplines .= qq{if $iptest; then\n };
#
# Re-do it if not.
$uplines .= qq{ echo " Config failed on $iface, retrying."\n };
$uplines .= " $DEVCON disable '$dev_map{$iface}'\n ";
$uplines .= qq{ sleep 5\n };
$uplines .= " $DEVCON enable '$dev_map{$iface}'\n ";
$uplines .= qq{ sleep 5\n };
$uplines .= sprintf(" " . $IFCONFIG, $iface, $inet, $mask) . qq{\n };
#
# Re-check.
$uplines .= qq{ $addr1\n $addr2\n };
$uplines .= qq{ if $iptest; then\n };
$uplines .= qq{ echo " Reconfig still failed on $iface."\n };
$uplines .= qq{ else echo " Reconfig succeeded on $iface."\n };
$uplines .= qq{ fi\n };
$uplines .= qq{fi};
# Shutdown.
$downlines .= qq{echo "Disabling $iface from $inet"\n };
$downlines .= "$DEVCON disable '$dev_map{$iface}'\n";
}
return ($uplines, $downlines);
}
#
# Specialized function for configing locally hacked veth devices.
#
sub os_ifconfig_veth($$$$$;$$$$$)
{
return "";
}
#
# Compute the name of a virtual interface device based on the
# information in ifconfig hash (as returned by getifconfig).
#
sub os_viface_name($)
{
my ($ifconfig) = @_;
my $piface = $ifconfig->{"IFACE"};
#
# Physical interfaces use their own name
#
if (!$ifconfig->{"ISVIRT"}) {
return $piface;
}
warn("CygWin does not support virtual interface type '$itype'\n");
return undef;
}
#
# Generate and return an string that is approriate for putting
# into /etc/hosts.
#
sub os_etchosts_line($$$)
{
my ($name, $ip, $aliases) = @_;
# Note: space rather than tab after the host name on Windows.
return sprintf("%s %s %s", $ip, $name, $aliases);
}
#
# On Windows NT, accumulate an input file for the addusers command.
# See "AddUsers Automates Creation of a Large Number of Users",
# http://support.microsoft.com/default.aspx?scid=kb;en-us;199878
#
# The file format is comma-delimited, as follows:
#
# [Users]
# User Name,Full name,Password,Description,HomeDrive,Homepath,Profile,Script
#
# [Global] or [Local]
# Group Name,Comment,UserName,...
#
my @groupNames;
my %groupsByGid;
my %groupMembers;
sub os_accounts_start()
{
# Remember group info to be put out at the end.
@groupNames = ();
%groupsByGid = ();
%groupMembers = ();
if (! open(WINUSERS, "> $winusersfile")) {
warning("os_accounts_start: Cannot create $winusersfile .\n");
return -1;
}
# Don't wipe out previous user shell preferences, just add new ones.
if (! open(USERSHELLS, ">> $usershellsfile")) {
warning("os_accounts_start: Cannot create or append to $usershellsfile .\n");
return -1;
}
# Users come before groups in the addusers.exe account stream.
# Notice the <CR><LF>'s! It's a Windows file.
print WINUSERS "[Users]\r\n";
return 0;
}
#
# Remember the mapping from an existing group GID to its name.
#
sub os_groupgid($$)
{
my($group, $gid) = @_;
$groupsByGid{$gid} = $group; # Remember the name associated with the gid.
return 0;
}
#
# Add a new group
#
sub os_groupadd($$)
{
my($group, $gid) = @_;
push(@groupNames, $group); # Remember all of the group names.
os_groupgid($group, $gid);
return 0;
}
#
# Delete an old group
#
sub os_groupdel($)
{
my($group) = @_;
# Unimplemented.
return -1;
}
#
# Remove a user account.
#
sub os_userdel($)
{
my($login) = @_;