Commit 1f159f5a authored by Rusty Myers's avatar Rusty Myers

Initial Commit

parent 2dd14ca9
#tag Class Protected Class App Inherits Application #tag Event Sub Open() Window1.IdleThread.Run Window1.Hide() End Sub #tag EndEvent #tag Constant, Name = kEditClear, Type = String, Dynamic = False, Default = \"&Delete", Scope = Public #Tag Instance, Platform = Windows, Language = Default, Definition = \"&Delete" #Tag Instance, Platform = Linux, Language = Default, Definition = \"&Delete" #tag EndConstant #tag Constant, Name = kFileQuit, Type = String, Dynamic = False, Default = \"&Quit", Scope = Public #Tag Instance, Platform = Windows, Language = Default, Definition = \"E&xit" #tag EndConstant #tag Constant, Name = kFileQuitShortcut, Type = String, Dynamic = False, Default = \"", Scope = Public #Tag Instance, Platform = Mac OS, Language = Default, Definition = \"Cmd+Q" #Tag Instance, Platform = Linux, Language = Default, Definition = \"Ctrl+Q" #tag EndConstant #tag ViewBehavior #tag EndViewBehavior End Class #tag EndClass
\ No newline at end of file
#tag BuildAutomation Begin BuildStepList Linux Begin BuildProjectStep Build End End Begin BuildStepList Mac OS X Begin BuildProjectStep Build End End Begin BuildStepList Windows Begin BuildProjectStep Build End End #tag EndBuildAutomation
\ No newline at end of file
#tag Module Protected Module Globals #tag Property, Flags = &h1 Protected gAppFolderItem As FolderItem #tag EndProperty #tag Property, Flags = &h1 Protected gDebugLoggingEnabled As Boolean = false #tag EndProperty #tag Property, Flags = &h1 Protected gIdleLogoutPrefsFile As FolderItem #tag EndProperty #tag Property, Flags = &h1 Protected gXMLprefsData As XmlDocument #tag EndProperty #tag Constant, Name = gcCPUtypeIntelStr, Type = String, Dynamic = False, Default = \"Intel", Scope = Protected #tag EndConstant #tag Constant, Name = gcCPUtypePowerPC, Type = Double, Dynamic = False, Default = \"2", Scope = Protected #tag EndConstant #tag Constant, Name = gcCPUtypePowerPCStr, Type = String, Dynamic = False, Default = \"PowerPC", Scope = Protected #tag EndConstant #tag Constant, Name = gcCPUtypeUnknown, Type = Double, Dynamic = False, Default = \"-1", Scope = Protected #tag EndConstant #tag Constant, Name = gcCPUtypeUnknownStr, Type = String, Dynamic = False, Default = \"Unknown", Scope = Protected #tag EndConstant #tag Constant, Name = gcSingleQuote, Type = String, Dynamic = False, Default = \"\'", Scope = Protected #tag EndConstant #tag Constant, Name = gcTABchar, Type = String, Dynamic = False, Default = \"\t", Scope = Protected #tag EndConstant #tag Constant, Name = kDeleteBackSpaceASCIIVal, Type = Double, Dynamic = False, Default = \"8", Scope = Protected #tag EndConstant #tag Constant, Name = kDiskVolumeIgnoreFlagFileName, Type = String, Dynamic = False, Default = \".BlastImageConfigIgnoreThisVolume", Scope = Protected #tag EndConstant #tag Constant, Name = kDoubleQuoteASCIIVal, Type = Double, Dynamic = False, Default = \"34", Scope = Protected #tag EndConstant #tag Constant, Name = kDoubleQuoteChar, Type = String, Dynamic = False, Default = \"\"", Scope = Protected #tag EndConstant #tag Constant, Name = kDownASCIIVal, Type = Double, Dynamic = False, Default = \"31", Scope = Protected #tag EndConstant #tag Constant, Name = kESC_ASCII_Val, Type = Double, Dynamic = False, Default = \"27", Scope = Protected #tag EndConstant #tag Constant, Name = kKeychainName, Type = String, Dynamic = False, Default = \"PSU Blast Image Config", Scope = Protected #tag EndConstant #tag Constant, Name = kLeftASCIIVal, Type = Double, Dynamic = False, Default = \"28", Scope = Protected #tag EndConstant #tag Constant, Name = kLogToFileDisable, Type = Boolean, Dynamic = False, Default = \"False", Scope = Protected #tag EndConstant #tag Constant, Name = kLogToFileEnable, Type = Boolean, Dynamic = False, Default = \"True", Scope = Protected #tag EndConstant #tag Constant, Name = kNullASCIIVal, Type = Double, Dynamic = False, Default = \"0", Scope = Protected #tag EndConstant #tag Constant, Name = kReturnMsgIsError, Type = Double, Dynamic = False, Default = \"2", Scope = Protected #tag EndConstant #tag Constant, Name = kReturnMsgIsStayOnCurrentStage, Type = Double, Dynamic = False, Default = \"3", Scope = Protected #tag EndConstant #tag Constant, Name = kReturnMsgIsSuccess, Type = Double, Dynamic = False, Default = \"0", Scope = Protected #tag EndConstant #tag Constant, Name = kReturnMsgIsWarning, Type = Double, Dynamic = False, Default = \"1", Scope = Protected #tag EndConstant #tag Constant, Name = kReturn_ASCII_Val, Type = Double, Dynamic = False, Default = \"13", Scope = Protected #tag EndConstant #tag Constant, Name = kRightASCIIVal, Type = Double, Dynamic = False, Default = \"29", Scope = Protected #tag EndConstant #tag Constant, Name = kSleepTimeForRectControls, Type = Double, Dynamic = False, Default = \"100", Scope = Protected #tag EndConstant #tag Constant, Name = kSleepTimeForWaitLoops, Type = Double, Dynamic = False, Default = \"250", Scope = Protected #tag EndConstant #tag Constant, Name = kSpaceASCIIVal, Type = Double, Dynamic = False, Default = \"32", Scope = Protected #tag EndConstant #tag ViewBehavior #tag ViewProperty Name="Index" Visible=true Group="ID" InitialValue="-2147483648" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Left" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Name" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Super" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Top" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag EndViewBehavior End Module #tag EndModule
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"><plist version="0.9"><dict> <key>CFBundleExecutable</key> <string>Idle Logout</string> <key>CFBundleName</key> <string>Idle Logout</string> <key>CFBundleIdentifier</key> <string>IdleLogout</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleVersion</key> <string>1.0.1.2.0</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleSignature</key> <string></string> <key>CFBundleGetInfoString</key> <string>1.0b1, Penn State University/ITS/CLC</string> <key>CFBundleShortVersionString</key> <string>1.0b1</string> <key>CFBundleIconFile</key> <string>Idle Logout.icns</string><key>LSMinimumSystemVersion</key><string>10.5.0</string> <key>CFBundleDocumentTypes</key> <array> </array></dict></plist>
\ No newline at end of file
APPL????
\ No newline at end of file
#!/bin/bash
# Written by Rusty Myers
# 2012-11-06
# postflight to tell etc/sudoers to add code
DEST_VOLUME="${3}"
TIME=`date "+%Y-%m-%d-%H-%M-%S"`
# Allow Runtime to run with root privileges without prompting for an admin password
# check sudoers for psuRebootNow.pl
RUN_AS_ROOT=`grep "psuRebootNow.pl" "${DEST_VOLUME}"/etc/sudoers`
if [ -n "${RUN_AS_ROOT}" ] # If it's there
then
# Remove it from /etc/sudoers if it exists
sed /psuRebootNow.pl/d "${DEST_VOLUME}"/etc/sudoers > "${DEST_VOLUME}"/tmp/sudoers
# Make a copy of the current version
mv "${DEST_VOLUME}"/etc/sudoers "${DEST_VOLUME}"/etc/sudoers."${TIME}"
# Replace old version with new version
mv "${DEST_VOLUME}"/tmp/sudoers "${DEST_VOLUME}"/etc/sudoers
else
# Make a copy of the current version
cp "${DEST_VOLUME}"/etc/sudoers "${DEST_VOLUME}"/etc/sudoers."${TIME}"
fi
# Add it back into /etc/sudoers
echo 'ALL ALL=NOPASSWD:/Library/CLMshared/psuRebootNow.pl' >> "${DEST_VOLUME}"/etc/sudoers
# Check permissions and reload sudoers file
chmod 440 "${DEST_VOLUME}"/etc/sudoers
chown root:wheel "${DEST_VOLUME}"/etc/sudoers
visudo -c
exit 0
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IdleLoopDelaySeconds</key>
<string>120</string>
<key>ComputerIdleAfterNumSeconds</key>
<string>600</string>
<key>WaitForUserPromptSeconds</key>
<string>90</string>
</dict>
</plist>
#!/usr/bin/perl -w
#
#--------------------------------------------------------------------------------------------------
#-- psuRebootRequested.pl
#--------------------------------------------------------------------------------------------------
# Program : psuRebootRequested.pl
#
# Purpose : Reboot computer
#
# Loaded By : launchd
# Called By : psuKioskIdleLogout.app touching file /tmp/psu_reboot_requested
#
# Author : <hkr@psu.edu> Ken Rosenberry
#
# Revisions : 2009/08/18 <hkr> Initial version
# : 2010/06/21 <hkr> no longer using /tmp/psu_reboot_now flag file
#--------------------------------------------------------------------------------------------------
# Get name of program for log records.
use File::Basename;
my ( $programName ) = basename($0);
LogData ("-->");
# psuCurrentUser.dat file contains the last logged in user.
# Remove this file, otherwise RunMaint tasks won't run because it looks like a user is logged in.
$current_user_dat_file = '/Library/PSUtemp/psuCurrentUser.dat';
if (-f $current_user_dat_file)
{
LogData("Remove current user file: $current_user_dat_file");
system "/bin/rm $current_user_dat_file";
}
LogData("Rebooting Now!");
LogData ("<--");
system '/sbin/reboot';
exit 0;
#--------------------------------------------------------------------------------------------------
#-- LogData - Print message to log file.
#--------------------------------------------------------------------------------------------------
sub LogData
{
my $text = $_[0] ;
if ( substr($text, -1, 1) ne "\n") { $text = $text . "\n"; } ### Log messages must end w/ newline.
if ( substr($text, 0, 3) eq "-->")
{
$text = substr($text, 0, 3) . $programName . ": launched..." . substr($text, 3);
}
elsif ( substr($text, 0, 3) eq "<--" )
{
$text = substr($text, 0, 3) . $programName . ": ...terminated." . substr($text, 3);
}
else
{
$text = " " . $programName . ": " . $text; ### All other log records indented.
}
$text = (scalar localtime) . " " . $text; ### Timestamp log records.
print $text;
}
#tag Class Protected Class IdleLogout Inherits Application #tag Event Sub Open() Dim debugFileName as string Dim theDate as date dim mXMLtreeToFollow(-1) as string dim mPrefKeyFoundData(-1) as string dim mTempFoundPlistData as string = "" // Local variable to use for gathering plist settings theDate = new Date Globals.gAppFolderItem = GetFolderItem("/Users/Shared/", FolderItem.PathTypeShell) // Set the name of the log debugFileName = "psuIdleLogout.RUN" + MiscMethods.PadData("0",2,str(theDate.Year),Globals.kLogToFileDisable) _ + "-" + MiscMethods.PadData("0",2,str(theDate.Month),Globals.kLogToFileDisable) + "-" debugFileName = debugFileName + MiscMethods.PadData("0",2,str(theDate.Day),Globals.kLogToFileDisable) + _ "-" + MiscMethods.PadData("0",2,str(theDate.Hour),Globals.kLogToFileDisable) + "-" debugFileName = debugFileName + MiscMethods.PadData("0",2,str(theDate.Minute),Globals.kLogToFileDisable) + _ "-" + MiscMethods.PadData("0",2,str(theDate.Second),Globals.kLogToFileDisable) + ".log" // Initilize the log, quit if we can't create the log if not (LogToFile.Initialize(debugFileName,Globals.gAppFolderItem)) then beep MsgBox "Error creating run log file! Exiting..." quit end if // Keep only the last 5 logs if ( LogToFile.DeleteOldLogs(5) ) then LogToFile("Deleted Old Logs") end if // Are there any users that we should ignore running for? if ( PlistHelper.readPlist(LogoutWarning.pDefaultPrefsFSPath, LogoutWarning.pDefaultPrefsFileName, "IgnoreUser", mTempFoundPlistData ) ) then LogoutWarning.pIgnoreUser = mTempFoundPlistData LogToFile(CurrentMethodName + ": Found the default key data, = " + str(LogoutWarning.pIgnoreUser) ) else // Failed! LogToFile(CurrentMethodName + ": Warning! Failed to find the default key 'IgnoreUser', using default of "+ str (LogoutWarning.pIgnoreUser) ) end if // Are there any groups that we should ignore running for? if ( PlistHelper.readPlist(LogoutWarning.pDefaultPrefsFSPath, LogoutWarning.pDefaultPrefsFileName, "IgnoreGroup", mTempFoundPlistData ) ) then LogoutWarning.pIgnoreGroup = mTempFoundPlistData LogToFile(CurrentMethodName + ": Found the default key data, = " + str(LogoutWarning.pIgnoreGroup) ) else // Failed! LogToFile(CurrentMethodName + ": Warning! Failed to find the default key 'IgnoreGroup', using default of "+ str (LogoutWarning.pIgnoreGroup) ) end if // Is this user macadmin? if ( MiscMethods.CurrentUsername(LogoutWarning.pIgnoreUser) ) then // It is macadmin, quit the app LogToFile("Current user is " + LogoutWarning.pIgnoreUser + ", quiting app") quit else LogToFile("User is not " + LogoutWarning.pIgnoreUser + ", continuing") end if // Is this user an admin? if ( MiscMethods.CurrentGroup(LogoutWarning.pIgnoreGroup) ) then // It is macadmin, quit the app LogToFile("Current user is an " + LogoutWarning.pIgnoreGroup + ", quiting app") quit else LogToFile("User is not an " + LogoutWarning.pIgnoreGroup + ", continuing") end if // How long should we wait before considering the Mac is idle too long? if ( PlistHelper.readPlist(LogoutWarning.pDefaultPrefsFSPath, LogoutWarning.pDefaultPrefsFileName, "ComputerIdleAfterNumSeconds", mTempFoundPlistData ) ) then LogoutWarning.pComputerIdleAfterNumSeconds = val( mTempFoundPlistData ) LogToFile(CurrentMethodName + ": Found the default key data, = " + str(LogoutWarning.pComputerIdleAfterNumSeconds) ) else // Failed! LogToFile(CurrentMethodName + ": Warning! Failed to find the default key 'ComputerIdleAfterNumSeconds', using default of "+ str (LogoutWarning.pComputerIdleAfterNumSeconds) ) end if // How often should we check to see how long the Mac has been idle? if ( PlistHelper.readPlist(LogoutWarning.pDefaultPrefsFSPath, LogoutWarning.pDefaultPrefsFileName, "IdleLoopDelaySeconds", mTempFoundPlistData ) ) then LogoutWarning.pIdleLoopDelaySeconds = val( mTempFoundPlistData ) LogToFile(CurrentMethodName + ": Found the default key data, = " + str(LogoutWarning.pIdleLoopDelaySeconds) ) else // Failed! LogToFile(CurrentMethodName + ": Warning! Failed to find the default key 'IdleLoopDelaySeconds', using default of "+ str (LogoutWarning.pIdleLoopDelaySeconds) ) end if // How long should we wait for the user to respond for More Time or to Log Out? if ( PlistHelper.readPlist(LogoutWarning.pDefaultPrefsFSPath, LogoutWarning.pDefaultPrefsFileName, "WaitForUserPromptSeconds", mTempFoundPlistData ) ) then LogoutWarning.pWaitForUserPromptSeconds = val( mTempFoundPlistData ) LogToFile(CurrentMethodName + ": Found the default key data, = " + str(LogoutWarning.pWaitForUserPromptSeconds) ) else // Failed! LogToFile(CurrentMethodName + ": Warning! Failed to find the default key 'WaitForUserPromptSeconds', using default of "+ str (LogoutWarning.pWaitForUserPromptSeconds) ) end if // Set default LogToFile(CurrentMethodName + ": Setting pMoreTimeAskedFor as True") Dim pMoreTimeAskedFor as Boolean = true LogoutWarning.Hide() LogToFile(CurrentMethodName + ": Running IdleThread") LogoutWarning.IdleThread.Run LogToFile(CurrentMethodName + ": <---") //Can't do loops in App Open event, won't give focus to window. 'do 'LogToFile("Waiting for idle time") 'LogToFile("pMoreTimeAskedFor: " + str(pMoreTimeAskedFor)) 'LogoutWarning.Show 'loop until not (LogoutWarning.pMoreTimeAskedFor) // Log the user out here or quit! // Check to see if LogoutCountdown is running End Sub #tag EndEvent #tag Note, Name = Icon Application Icon use with CC license: From http://www.flickr.com/photos/23453447@N02/5107438855/sizes/o/in/photostream/ By zyrquel http://www.flickr.com/photos/23453447@N02/ #tag EndNote #tag Constant, Name = kEditClear, Type = String, Dynamic = False, Default = \"&Delete", Scope = Public #Tag Instance, Platform = Windows, Language = Default, Definition = \"&Delete" #Tag Instance, Platform = Linux, Language = Default, Definition = \"&Delete" #tag EndConstant #tag Constant, Name = kFileQuit, Type = String, Dynamic = False, Default = \"&Quit", Scope = Public #Tag Instance, Platform = Windows, Language = Default, Definition = \"E&xit" #tag EndConstant #tag Constant, Name = kFileQuitShortcut, Type = String, Dynamic = False, Default = \"", Scope = Public #Tag Instance, Platform = Mac OS, Language = Default, Definition = \"Cmd+Q" #Tag Instance, Platform = Linux, Language = Default, Definition = \"Ctrl+Q" #tag EndConstant #tag ViewBehavior #tag EndViewBehavior End Class #tag EndClass
\ No newline at end of file
#tag Module Protected Module LogToFile #tag Method, Flags = &h1 Protected Function DeleteOldLogs(numLogFilesToKeep as integer) As Boolean dim loopVar as integer dim numLogFolderItems as integer dim logFileBaseName as string dim logItem as FolderItem dim numLogFilesFound as integer dim logFileNames() as string dim tempStr as string dim numLogFilesToDelete as integer LogToFile("LogToFile.DeleteOldLogs: ---->") if (DebugLogFolder = nil) then LogToFile("LogToFile.DeleteOldLogs: ERROR: LogFolderItem is nil, no directory to delete. Returning false.") return false end if if (numLogFilesToKeep < 2) then LogToFile("LogToFile.DeleteOldLogs: numLogFilesToKeep is less than 2, so no files to delete. Returning true.") LogToFile("LogToFile.DeleteOldLogs: <----") return true end if // Delete old log files next LogToFile("LogToFile.DeleteOldLogs: Received number of log files to keep: " + str(numLogFilesToKeep)) numLogFolderItems = DebugLogFolder.Count LogToFile("LogToFile.DeleteOldLogs: Number of items in the log folder: " + str(numLogFolderItems)) if (numLogFolderItems < numLogFilesToKeep) then LogToFile("LogToFile.DeleteOldLogs: The number of items in the log folder is less than the number of log files to keep, nothing to scan. Exiting.") LogToFile("LogToFile.DeleteOldLogs: <----") return true end if logFileBaseName = NthField(DebugLogFile.Name,".",1) // Need to get the count of the number of log files first before counting them otherwise we'll count the other items as log file counts for loopVar = 1 to numLogFolderItems logItem = DebugLogFolder.Item(loopVar) if ( left(logItem.Name,len(logFileBaseName)) = logFileBaseName ) then numLogFilesFound = numLogFilesFound + 1 logFileNames.Append logItem.Name end if next LogToFile("LogToFile.DeleteOldLogs: Number of log files found: " + str(UBound(logFileNames)+1) ) numLogFilesToDelete = UBound(logFileNames) - numLogFilesToKeep // Keep in mind that the array is zero based... // Delete log files until N are left: for loopVar = 0 to numLogFilesToDelete tempStr = logFileNames(loopVar) LogToFile("LogToFile.DeleteOldLogs: Processing log file: '" + logFileNames(loopVar) + "'") if (not(logFileNames(loopVar) = DebugLogFile.Name)) then // Check the folderitem name doesn't match the name of the active log file before deleting it LogToFile("LogToFile.DeleteOldLogs: The found log item does NOT match the current active log filed named '"+ DebugLogFile.Name + "' and WILL BE DELETED.") if (DebugLogFolder.Child(logFileNames(loopVar)).Exists) then LogToFile("LogToFile.DeleteOldLogs: Log file exists, deleting it ...") DebugLogFolder.Child(logFileNames(loopVar)).Delete else LogToFile("LogToFile.DeleteOldLogs: Log file does NOT exist, nothing to delete.") end if else LogToFile("LogToFile.DeleteOldLogs: The found log item MATCHES the current active log filed named '"+ DebugLogFile.Name + "', will NOT be deleted.") end if next LogToFile("LogToFile.DeleteOldLogs: <----") return true End Function #tag EndMethod #tag Method, Flags = &h1 Protected Function Initialize(debugFileName as string, appFolder as FolderItem) As Boolean if (debugFileName = "") then return false end if if (appFolder = nil) then return false end if DebugLogFolder = appFolder.child("IdleLogout") if (not(DebugLogFolder.Exists)) then DebugLogFolder.CreateAsFolder DebugLogFolder.Permissions = &o777 if ((DebugLogFolder.Exists) and (DebugLogFolder.Directory)) then // beep // MsgBox "Created 'Logs' folder." + EndOfLine.Macintosh + EndOfLine.Macintosh + "In order to save the run log file, I created a 'Logs' folder at the path of '" + Globals.gAppFolderItem.ShellPath + "'." else // beep // msgBox "Failed to create the 'Logs' folder for storing the run log file." return false end if end if DebugLogFile = DebugLogFolder.child(debugFileName) if not(DebugLogFile.IsWriteable) then // beep // MsgBox "Permissions prevent me from writing to the run log file in the 'Logs' folder." + EndOfLine.Macintosh + EndOfLine.Macintosh + "Created run log file in '/tmp' directory as a backup." DebugLogFile = Volume(0).Child("tmp").Child(debugFileName) end if if (not(DebugLogFile.exists)) then fileStream=TextOutputStream.Create(DebugLogFile) fileStream.Close DebugLogFile.Permissions = &o777 LogToFile("LogToFile.Initialize: New log file created.") end if return true End Function #tag EndMethod #tag Method, Flags = &h0 Sub LogToFile(logMessage as string) // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // WARNING: DO NOT CALL LogToFile in this method or you will have circular references! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Dim theTime as date theTime = new date if (DebugLogFile = NIL) then beep msgBox "LogToFile error: logFile = NIL. Unable to save to log file." return end if if (DebugLogFile.Exists) then fileStream = TextOutputStream.Append(DebugLogFile) else return end if if (fileStream <> NIL) then // Log the message if it does not contain "<DEBUG>", OR if the ENABLE_DEBUG_LOGGING config pref key is "YES" AND the logMessage contains "<DEBUG>": if ( ( (InStr(logMessage,"<DEBUG>")=0)) or ( (InStr(logMessage,"<DEBUG>")>0) and (Globals.gDebugLoggingEnabled)) ) then #if TargetWin32 then fileStream.Write (theTime.ShortDate + " " + theTime.LongTime + ": " + logMessage + EndOfLine.Windows) // Winders Line Feeds #else fileStream.Write (theTime.ShortDate + " " + theTime.LongTime + ": " + logMessage + EndOfLine.UNIX) // Unix line feeds #endif end if fileStream.Close return else beep msgBox "LogToFile error: fileStream = NIL - can't write to log file." + EndOfLine + EndOfLine + "Is the file possibly busy or open in an editor?" return end if End Sub #tag EndMethod #tag Method, Flags = &h1 Protected Function openLogFile() As Boolean DebugLogFile.launch(true) return true End Function #tag EndMethod #tag Property, Flags = &h21 Private DebugLogFile As FolderItem #tag EndProperty #tag Property, Flags = &h21 Private DebugLogFolder As FolderItem #tag EndProperty #tag Property, Flags = &h21 Private fileStream As TextOutputStream #tag EndProperty #tag ViewBehavior #tag ViewProperty Name="Index" Visible=true Group="ID" InitialValue="-2147483648" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Left" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Name" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Super" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Top" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag EndViewBehavior End Module #tag EndModule
\ No newline at end of file
#tag Window Begin Window LogoutWarning BackColor = 16777215 Backdrop = "" CloseButton = False Composite = False Frame = 7 FullScreen = False HasBackColor = False Height = 237 ImplicitInstance= True LiveResize = False MacProcID = 0 MaxHeight = 32000 MaximizeButton = False MaxWidth = 32000 MenuBar = "" MenuBarVisible = False MinHeight = 64 MinimizeButton = False MinWidth = 64 Placement = 2 Resizeable = False Title = "Idle Logout" Visible = True Width = 600 Begin PushButton BLogOut AutoDeactivate = True Bold = "" ButtonStyle = 0 Cancel = "" Caption = "Log Out" Default = False Enabled = True Height = 20 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 397 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Scope = 0 TabIndex = 1 TabPanelIndex = 0 TabStop = True TextFont = "System" TextSize = 0 TextUnit = 0 Top = 197 Underline = "" Visible = True Width = 80 End Begin PushButton BMoreTime AutoDeactivate = False Bold = "" ButtonStyle = 0 Cancel = "" Caption = "More time" Default = True Enabled = True Height = 20 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 500 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Scope = 0 TabIndex = 2 TabPanelIndex = 0 TabStop = True TextFont = "System" TextSize = 0 TextUnit = 0 Top = 197 Underline = "" Visible = True Width = 80 End Begin Label WarningTitle AutoDeactivate = True Bold = "" DataField = "" DataSource = "" Enabled = True Height = 39 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 112 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Multiline = "" Scope = 0 Selectable = False TabIndex = 3 TabPanelIndex = 0 Text = "PSU Idle Logout" TextAlign = 1 TextColor = 0 TextFont = "System" TextSize = 30 TextUnit = 0 Top = 0 Transparent = False Underline = "" Visible = True Width = 377 End Begin Label WarningMessage AutoDeactivate = True Bold = "" DataField = "" DataSource = "" Enabled = True Height = 84 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 20 LockBottom = False LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Multiline = True Scope = 0 Selectable = False TabIndex = 4 TabPanelIndex = 0 Text = "This Mac is idle.\r\rClick the ""More Time"" button to continue using the Mac.\r\rOtherwise, an automatic logout will occur and all unsaved documents will be LOST!" TextAlign = 0 TextColor = &h000000 TextFont = "System" TextSize = 0 TextUnit = 0 Top = 34 Transparent = False Underline = "" Visible = True Width = 560 End Begin Label Seconds AutoDeactivate = True Bold = "" DataField = "" DataSource = "" Enabled = True Height = 25 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 20 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Multiline = "" Scope = 0 Selectable = False TabIndex = 6 TabPanelIndex = 0 Text = "Seconds remaining before automatic logout..." TextAlign = 0 TextColor = &h000000 TextFont = "System" TextSize = 0 TextUnit = 0 Top = 127 Transparent = False Underline = "" Visible = True Width = 301 End Begin Thread IdleThread Height = 32 Index = -2147483648 Left = 13 LockedInPosition= False Priority = 5 Scope = 0 StackSize = 0 TabPanelIndex = 0 Top = 268 Width = 32 End Begin Thread CountdownThread Height = 32 Index = -2147483648 Left = 57 LockedInPosition= False Priority = 5 Scope = 0 StackSize = 0 TabPanelIndex = 0 Top = 268 Width = 32 End Begin Label TimeLabel AutoDeactivate = True Bold = "" DataField = "" DataSource = "" Enabled = True Height = 51 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 268 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Multiline = "" Scope = 0 Selectable = False TabIndex = 5 TabPanelIndex = 0 Text = "" TextAlign = 1 TextColor = &h000000 TextFont = "System" TextSize = 30 TextUnit = 0 Top = 166 Transparent = False Underline = "" Visible = True Width = 64 End End #tag EndWindow #tag WindowCode #tag Method, Flags = &h0 Function IdleSeconds() As Integer // Set up variables for idle time // Shell result Dim mIdleSecs As String // Shell exit code Dim merrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check idle time from USB input devices s.Execute "/bin/echo $((`/usr/sbin/ioreg -c IOHIDSystem | /usr/bin/sed -e '/HIDIdleTime/ !{ d' -e 't' -e '}' -e 's/.* = //g' -e 'q'` / 1000000000))" // Set results to mIdleResult mIdleSecs = s.Result // Set error code to mIdleError merrCode = s.ErrorCode // Log mIdleResult for debugging // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) Return val(mIdleSecs) End Function #tag EndMethod #tag Method, Flags = &h0 Function RemoteControlCheck() As Boolean // Set up variables for idle time Dim stablished as String = "ESTABLISHED" // Shell result Dim rccheck As String // Shell exit code Dim merrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check for connection s.Execute "/usr/sbin/netstat -n | /usr/bin/grep '.5900'| /usr/bin/awk '{print $6}'" // Set results to rccheck // Make the entire returned text uppercase in case Apple ever changes the case to CaMeL CaSe, which would break our code: rccheck = Uppercase(s.Result) //Testing line below // rccheck ="ESTABLISHED" //LogToFile("rccheck: " + rccheck) // Set error code to merrCode merrCode = s.ErrorCode // LogToFile("rccheck: "+ rccheck) // LogToFile("stablished: "+ stablished) If ( InStr( rccheck, stablished ) > 0 ) then return true else //LogToFile("rccheck: false") return false End if // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) End Function #tag EndMethod #tag Method, Flags = &h0 Function WaitForIdleTime(paramNumSecondsIdleToWait as integer) As Boolean Dim mIdleResult As Integer mIdleResult = IdleSeconds() while ( mIdleResult < paramNumSecondsIdleToWait ) // Wait pIdleLoopDelaySeconds: App.SleepCurrentThread( pIdleLoopDelaySeconds * 1000 ) // Check idle time: mIdleResult = IdleSeconds() LogToFile(CurrentMethodName + ": Idle Seconds: " + str(mIdleResult)) wend // if there is a ARD/VNC session, don't idle out // netstat -n | grep '.5900' if ( RemoteControlCheck() ) then //LogToFile("rcCheck = true") LogToFile(CurrentMethodName + ": Someone is controlling via ARD/VNC, waiting...") return false else //LogToFile("rcCheck = false") LogToFile(CurrentMethodName + ": No one is controlling via ARD/VNC, continuing...") return true end if End Function #tag EndMethod #tag Property, Flags = &h0 pComputerIdleAfterNumSeconds As Integer = 900 #tag EndProperty #tag Property, Flags = &h0 pDefaultPrefsFileName As String = "edu.psu.its.clc.IdleLogoutSettings.plist" #tag EndProperty #tag Property, Flags = &h0 pDefaultPrefsFSPath As String = "/Library/CLMadmin/Config/" #tag EndProperty #tag Property, Flags = &h0 pIdleLoopDelaySeconds As Integer = 30 #tag EndProperty #tag Property, Flags = &h0 pIgnoreGroup As String = "admin" #tag EndProperty #tag Property, Flags = &h0 pIgnoreUser As String = "macadmin" #tag EndProperty #tag Property, Flags = &h0 pMoreTimeAskedFor As Boolean = true #tag EndProperty #tag Property, Flags = &h0 pWaitForUserPromptSeconds As Integer = 90 #tag EndProperty #tag EndWindowCode #tag Events BLogOut #tag Event Sub Action() // Testing code Dim s As Shell s=New Shell s.Mode = 0 // s.execute "say logout" // Use this line to test logouts LogToFile("User chose LogOut") // No more time, please pMoreTimeAskedFor = false LogToFile("Kill open threads") CountdownThread.Kill IdleThread.Kill // Log out the user LogToFile("Quitting") s.execute "/usr/bin/sudo /Library/CLMshared/psuRebootNow.pl" // Use this line to test logouts Quit End Sub #tag EndEvent #tag EndEvents #tag Events BMoreTime #tag Event Sub Action() // Testing code Dim s As Shell s=New Shell s.Mode = 0 // s.execute "say More Time" LogToFile("More Time Requested") // Ask for more time //pMoreTimeAskedFor = true // Resume IdleThread IdleThread.Resume // Stop the current countdown CountdownThread.Kill // Get rid of the window LogoutWarning.Hide End Sub #tag EndEvent #tag EndEvents #tag Events IdleThread #tag Event Sub Run() LogToFile(CurrentMethodName + ": --->") // User has been idle 0 seconds so far Dim idleTime as Integer = 0 // How long to wait between checking idle time // Dim gLoopDelay as Integer = 30 // pIdleTime = How long to wait before considering computer abandonded pMoreTimeAskedFor = false do if ( WaitForIdleTime( pComputerIdleAfterNumSeconds ) ) then LogToFile(CurrentMethodName + ": CountdownThread Start") CountdownThread.Run else // Do Nothing... LogToFile(CurrentMethodName + ": Not Time Yet...") end if //LogToFile("pMoreTimeAskedFor = " + str(pMoreTimeAskedFor)) Loop until ( pMoreTimeAskedFor ) LogToFile(CurrentMethodName + ": <---") End Sub #tag EndEvent #tag EndEvents #tag Events CountdownThread #tag Event Sub Run() LogToFile(CurrentMethodName + ": --->") // Set how long to wait before logging out user, set from global variable for LogOutDelay Dim pLogoutDelay as Integer = pWaitForUserPromptSeconds LogoutWarning.Show() // Stop the idle thread IdleThread.Suspend // While we're waiting for the countdown to finish... While pLogoutDelay >= 0 // Set label to the time left TimeLabel.setString(str(pLogoutDelay)) // Refresh it TimeLabel.Refresh // take a second away from the time left pLogoutDelay = pLogoutDelay - 1 // do nothing for 1 second App.SleepCurrentThread( 1000 ) // sleep 1 second Wend // If we're here, the user didn't cancel or log out manaully // Testing mode, use say instead of logout Dim s As Shell s=New Shell s.Mode = 0 // s.Execute "say Logging Out" // Testing line pMoreTimeAskedFor = false LogToFile(CurrentMethodName + ": Time Out for Response. Log User Out...") LogToFile(CurrentMethodName + ": <---") s.Execute "/usr/bin/sudo /Library/CLMshared/psuRebootNow.pl" // Run script to reboot Mac // Quit app Quit End Sub #tag EndEvent #tag EndEvents
\ No newline at end of file
#tag Menu Begin Menu MenuBar1 Begin MenuItem FileMenu SpecialMenu = 0 Text = "&File" Index = -2147483648 AutoEnable = True Begin QuitMenuItem FileQuit SpecialMenu = 0 Text = "#App.kFileQuit" Index = -2147483648 ShortcutKey = "#App.kFileQuitShortcut" Shortcut = "#App.kFileQuitShortcut" AutoEnable = True End End Begin MenuItem EditMenu SpecialMenu = 0 Text = "&Edit" Index = -2147483648 AutoEnable = True Begin MenuItem EditUndo SpecialMenu = 0 Text = "&Undo" Index = -2147483648 ShortcutKey = "Z" Shortcut = "Cmd+Z" MenuModifier = True AutoEnable = True End Begin MenuItem UntitledMenu1 SpecialMenu = 0 Text = "-" Index = -2147483648 AutoEnable = True End Begin MenuItem EditCut SpecialMenu = 0 Text = "Cu&t" Index = -2147483648 ShortcutKey = "X" Shortcut = "Cmd+X" MenuModifier = True AutoEnable = True End Begin MenuItem EditCopy SpecialMenu = 0 Text = "&Copy" Index = -2147483648 ShortcutKey = "C" Shortcut = "Cmd+C" MenuModifier = True AutoEnable = True End Begin MenuItem EditPaste SpecialMenu = 0 Text = "&Paste" Index = -2147483648 ShortcutKey = "V" Shortcut = "Cmd+V" MenuModifier = True AutoEnable = True End Begin MenuItem EditClear SpecialMenu = 0 Text = "#App.kEditClear" Index = -2147483648 AutoEnable = True End Begin MenuItem UntitledMenu0 SpecialMenu = 0 Text = "-" Index = -2147483648 AutoEnable = True End Begin MenuItem EditSelectAll SpecialMenu = 0 Text = "Select &All" Index = -2147483648 ShortcutKey = "A" Shortcut = "Cmd+A" MenuModifier = True AutoEnable = True End End End #tag EndMenu
\ No newline at end of file
#tag Module Protected Module MiscMethods #tag Method, Flags = &h1 Protected Function CurrentGroup(paramGroupCheck as string) As Boolean // Set up variables for idle time // Shell result Dim mCurrentGroups As String // Shell exit code Dim mErrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check idle time from USB input devices s.Execute "/bin/echo -n `/usr/bin/groups`" // Set results to mIdleResult mCurrentGroups = s.Result // Set error code to mIdleError mErrCode = s.ErrorCode // Log mIdleResult for debugging // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) if ( InStr(mCurrentGroups, paramGroupCheck) > 0 ) then return true else return false end if End Function #tag EndMethod #tag Method, Flags = &h1 Protected Function CurrentUsername(paramUsernameCheck as string) As Boolean // Set up variables for idle time // Shell result Dim mCurrentUsername As String // Shell exit code Dim mErrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check idle time from USB input devices s.Execute "/bin/echo -n `whoami`" // Set results to mIdleResult mCurrentUsername = s.Result // Set error code to mIdleError mErrCode = s.ErrorCode // Log mIdleResult for debugging // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) if ( InStr(paramUsernameCheck, mCurrentUsername) > 0 ) then return true else return false end if End Function #tag EndMethod #tag Method, Flags = &h1 Protected Function PadData(PadChar as string, EndLength as integer, StrToPad as string, paramLogToFile as Boolean) As string dim paddedStr as string dim loopVar as integer dim NumPadChars as integer if (paramLogToFile = Globals.kLogToFileEnable) then LogToFile(CurrentMethodName + ": ---->") LogToFile(CurrentMethodName + ": String received: " + "--->" + StrToPad + "<---") LogToFile(CurrentMethodName + ": PadChar received: " + "--->" + PadChar + "<---") LogToFile(CurrentMethodName + ": EndLength received: " + "--->" + str(EndLength) + "<---") end if if (len(StrToPad) >= EndLength) then if (paramLogToFile = Globals.kLogToFileEnable) then LogToFile(CurrentMethodName + ": No padding necessary. Exiting.") LogToFile(CurrentMethodName + ": <----") end if return StrToPad end if paddedStr = StrToPad NumPadChars = EndLength - len(StrToPad) for loopVar = 1 to NumPadChars paddedStr = PadChar + paddedStr next if (paramLogToFile = Globals.kLogToFileEnable) then LogToFile(CurrentMethodName + ": <----") end if return paddedStr End Function #tag EndMethod #tag ViewBehavior #tag ViewProperty Name="Index" Visible=true Group="ID" InitialValue="-2147483648" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Left" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Name" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Super" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Top" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag EndViewBehavior End Module #tag EndModule
\ No newline at end of file
#tag Module Protected Module PlistHelper #tag Method, Flags = &h0 Function readPlist(paramPathToPlist as String, paramNameofPlist as String, paramPlistKey as String, byRef paramFoundDataString as String) As Boolean dim mXMLtreeToFollow(-1) as string dim mPrefKeyFoundData(-1) as string LogToFile(CurrentMethodName + ": --->") // LogToFile("paramPathToPlist: " + paramPathToPlist) // LogToFile("paramPlistKey: " + paramPlistKey) // Read the default values to start with Globals.gXMLprefsData = new XmlDocument // paramPathToPlist = "/Library/CLMadmin/Config/" Globals.gIdleLogoutPrefsFile = GetFolderItem( paramPathToPlist + paramNameofPlist, FolderItem.PathTypeShell ) if ( Globals.gIdleLogoutPrefsFile = nil ) then // The folder path does not exist, so set the bare minimium defaults... LogToFile(CurrentMethodName + ": ERROR! The file variable is NIL.") LogToFile(CurrentMethodName + ": <----") return false elseif ( not ( Globals.gIdleLogoutPrefsFile.IsReadable ) ) then LogToFile(CurrentMethodName + ": ERROR! The file is not readable, or does not exist!") LogToFile(CurrentMethodName + ": <----") return false else // Read the XML data next: LogToFile (CurrentMethodName + ": Found the plist data file. Reading it next...") Globals.gXMLprefsData.LoadXml(Globals.gIdleLogoutPrefsFile) redim mXMLtreeToFollow(-1) mXMLtreeToFollow.Append("<plist>") mXMLtreeToFollow.Append("<dict>") mXMLtreeToFollow.Append("<key>" + paramPlistKey + "</key>") mXMLtreeToFollow.Append("<string>") if ( myXMLTools.getXMLPlistData( Globals.gXMLprefsData.ToString ,mXMLtreeToFollow,mPrefKeyFoundData) ) then if ( UBound (mPrefKeyFoundData) > -1 ) then LogToFile(CurrentMethodName + ": Success! " + paramPlistKey + " = '" + mPrefKeyFoundData(0) + "'") paramFoundDataString = mPrefKeyFoundData(0) LogToFile(CurrentMethodName + ": <----") return true else LogToFile(CurrentMethodName + ": ERROR: Returned data is EMPTY! Returning FALSE.") LogToFile(CurrentMethodName + ": <----") return false end if else LogToFile(CurrentMethodName + ": ERROR! Returning FALSE.") LogToFile(CurrentMethodName + ": <----") return false end if end if End Function #tag EndMethod #tag ViewBehavior #tag ViewProperty Name="Index" Visible=true Group="ID" InitialValue="-2147483648" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Left" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Name" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Super" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Top" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag EndViewBehavior End Module #tag EndModule
\ No newline at end of file
IdleLogout.app
==============
Application to log out users after a specified period of time.
\ No newline at end of file
Description
------------
Application to log out users after a specified period of time. The user will see a prompt with a countdown asking them if they wish to log out or continue working ("More Time").
Background
------------
Idle Logout.app was written in RealStudio 2012 R2. It uses the ioreg command to determine how long USB devices have been idle. Once the idle limit is meet, the computer is forcibly restarted to log out any users.
The terminal command we use to check idle seconds on USB devices is:
> /bin/echo $((`/usr/sbin/ioreg -c IOHIDSystem | /usr/bin/sed -e '/HIDIdleTime/ !{ d' -e 't' -e '}' -e 's/.* = //g' -e 'q'` / 1000000000))"
Important Notes
-------------
Idle Logout.app can be run at login with a LaunchAgent under the users context. **In order for the application to work, the /etc/sudoers file needs to be edited to allow all users to run the "psuRebootNow.pl" script (included in the repo under 'IdleLogout app' folder).** View the "IdleLogoutSudoers.sh" script (included in the repo under 'IdleLogout app' folder) to see what changes are made to the /etc/sudoers file. The script can be used as a postflight script in a package while deploying the app.
Preferences
-------------
The Idle Logout.app looks for a preference file in /Library/CLMadmin/Config named "edu.psu.its.clc.IdleLogoutSettings.plist" (included in the repo under 'IdleLogout app' folder). It looks for the following key/string pairs in the plist. If they are missing, it will use the defaults:
* IgnoreUser = Ignore the username, don't force logout.
* IgnoreGroup = Ignore anyone in this group, don't force logout.
* ComputerIdleAfterNumSeconds = Number of seconds before considering the computer abandoned.
* IdleLoopDelaySeconds = Number of seconds to wait between checking the usb idle seconds.
* WaitForUserPromptSeconds = Number of seconds to wait for user to respond to logout prompt.
Default Values if plist is not installed:
* IgnoreUser = "macadmin"
* IgnoreGroup = "admin"
* ComputerIdleAfterNumSeconds = "600"
* IdleLoopDelaySeconds = "30"
* WaitForUserPromptSeconds = "90"
\ No newline at end of file
#tag Module Protected Module SystemEventsMod #tag Method, Flags = &h1 Protected Function ShutdownOrRestartThisMac(paramRestartOrShutdown as string, byRef paramErrMsg as string, byRef paramErrCodeInt as integer) As Boolean dim mShell as Shell dim mShellResult as string dim mShellErrInt as integer LogToFile(CurrentMethodName + ": ---->") mShell = new Shell mShell.Mode = 0 if ( paramRestartOrShutdown = "" ) then LogToFile(CurrentMethodName + ": ERROR: Received paramRestartOrShutdown is EMPTY.") LogToFile(CurrentMethodName + ": <----") return false end if // Restart: /usr/bin/osascript -e "Tell application \"Finder\" to restart" // Shutdown: /usr/bin/osascript -e "Tell application \"Finder\" to shut down" mShell.Execute("/usr/bin/osascript -e " + Globals.kDoubleQuoteChar _ + "Tell application \" + Globals.kDoubleQuoteChar + "Finder\" + Globals.kDoubleQuoteChar + " to " + paramRestartOrShutdown + Globals.kDoubleQuoteChar) mShellResult = mShell.Result mShellErrInt = mShell.ErrorCode paramErrMsg = mShellResult LogToFile(CurrentMethodName + ": Result of shell command to " + paramRestartOrShutdown + ": '" + mShellResult + "'") LogToFile(CurrentMethodName + ": Shell exit error code = " + str(mShellErrInt) ) if ( mShellErrInt <> 0 ) then LogToFile(CurrentMethodName + ": ERROR: Shell execute failed!") paramErrCodeInt = Globals.kReturnMsgIsError LogToFile(CurrentMethodName + ": <----") return false end if paramErrCodeInt = Globals.kReturnMsgIsSuccess LogToFile(CurrentMethodName + ": <----") return true End Function #tag EndMethod #tag Constant, Name = kRestart, Type = String, Dynamic = False, Default = \"restart", Scope = Protected #tag EndConstant #tag Constant, Name = kShutDown, Type = String, Dynamic = False, Default = \"shut down", Scope = Protected #tag EndConstant #tag ViewBehavior #tag ViewProperty Name="Index" Visible=true Group="ID" InitialValue="-2147483648" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Left" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Name" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Super" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Top" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag EndViewBehavior End Module #tag EndModule
\ No newline at end of file
#tag Window Begin Window Window1 BackColor = 16777215 Backdrop = "" CloseButton = True Composite = False Frame = 0 FullScreen = False HasBackColor = False Height = 237 ImplicitInstance= True LiveResize = True MacProcID = 0 MaxHeight = 32000 MaximizeButton = False MaxWidth = 32000 MenuBar = 1665256176 MenuBarVisible = True MinHeight = 64 MinimizeButton = False MinWidth = 64 Placement = 2 Resizeable = False Title = "Idle Logout" Visible = True Width = 600 Begin PushButton BLogOut AutoDeactivate = True Bold = "" ButtonStyle = 0 Cancel = "" Caption = "Log Out" Default = False Enabled = True Height = 20 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 337 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Scope = 0 TabIndex = 1 TabPanelIndex = 0 TabStop = True TextFont = "System" TextSize = 0 TextUnit = 0 Top = 197 Underline = "" Visible = True Width = 80 End Begin PushButton BMoreTime AutoDeactivate = False Bold = "" ButtonStyle = 0 Cancel = "" Caption = "More time" Default = True Enabled = True Height = 20 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 191 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Scope = 0 TabIndex = 2 TabPanelIndex = 0 TabStop = True TextFont = "System" TextSize = 0 TextUnit = 0 Top = 197 Underline = "" Visible = True Width = 80 End Begin Label WarningTitle AutoDeactivate = True Bold = "" DataField = "" DataSource = "" Enabled = True Height = 54 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 112 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Multiline = "" Scope = 0 Selectable = False TabIndex = 3 TabPanelIndex = 0 Text = "PSU Idle Logout" TextAlign = 1 TextColor = 0 TextFont = "System" TextSize = 30 TextUnit = 0 Top = 14 Transparent = False Underline = "" Visible = True Width = 377 End Begin Label WarningMessage AutoDeactivate = True Bold = "" DataField = "" DataSource = "" Enabled = True Height = 41 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 57 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Multiline = "" Scope = 0 Selectable = False TabIndex = 4 TabPanelIndex = 0 Text = "The computer will log out out and close any unsaved work in:" TextAlign = 1 TextColor = &h000000 TextFont = "System" TextSize = 0 TextUnit = 0 Top = 70 Transparent = False Underline = "" Visible = True Width = 486 End Begin Label TimeLabel AutoDeactivate = True Bold = "" DataField = "" DataSource = "" Enabled = True Height = 51 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 268 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Multiline = "" Scope = 0 Selectable = False TabIndex = 5 TabPanelIndex = 0 Text = "" TextAlign = 1 TextColor = &h000000 TextFont = "System" TextSize = 30 TextUnit = 0 Top = 121 Transparent = False Underline = "" Visible = True Width = 64 End Begin Label Seconds AutoDeactivate = True Bold = "" DataField = "" DataSource = "" Enabled = True Height = 14 HelpTag = "" Index = -2147483648 InitialParent = "" Italic = "" Left = 331 LockBottom = "" LockedInPosition= False LockLeft = True LockRight = "" LockTop = True Multiline = "" Scope = 0 Selectable = False TabIndex = 6 TabPanelIndex = 0 Text = "seconds..." TextAlign = 0 TextColor = &h000000 TextFont = "System" TextSize = 0 TextUnit = 0 Top = 146 Transparent = False Underline = "" Visible = True Width = 104 End Begin Thread IdleThread Height = 32 Index = -2147483648 Left = 13 LockedInPosition= False Priority = 5 Scope = 0 StackSize = 0 TabPanelIndex = 0 Top = 268 Width = 32 End Begin Thread CountdownThread Height = 32 Index = -2147483648 Left = 57 LockedInPosition= False Priority = 5 Scope = 0 StackSize = 0 TabPanelIndex = 0 Top = 268 Width = 32 End End #tag EndWindow #tag WindowCode #tag Method, Flags = &h0 Sub Untitled() End Sub #tag EndMethod #tag Property, Flags = &h0 gLogoutDelay As Integer #tag EndProperty #tag Property, Flags = &h0 mIdleResult As Double #tag EndProperty #tag EndWindowCode #tag Events BLogOut #tag Event Sub Action() // Testing code Dim s As Shell s=New Shell s.Mode = 0 s.execute "say logout" // Log out the user Quit End Sub #tag EndEvent #tag EndEvents #tag Events BMoreTime #tag Event Sub Action() // Testing code Dim s As Shell s=New Shell s.Mode = 0 s.execute "say More Time" // Reset time user has been idel to 0 Dim idleTime as Integer = 0 // Stop the current countdown CountdownThread.Kill // Get rid of the window Window1.Hide // Start the idle thread again IdleThread.Run End Sub #tag EndEvent #tag EndEvents #tag Events IdleThread #tag Event Sub Run() // User has been idle 0 seconds so far Dim idleTime as Integer = 0 // How long to wait between checking idle time Dim gLoopDelay as Integer = 30 // How long to wait before considering computer abandonded Dim gIdleTooLong as Integer = 5 // Set up variables for idle time // Shell result Dim mIdleResult As String // Shell exit code Dim mIdleError As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 Do // Check idle time //s.Execute code to check idle time from USB input devices s.Execute "echo $((`ioreg -c IOHIDSystem | sed -e '/HIDIdleTime/ !{ d' -e 't' -e '}' -e 's/.* = //g' -e 'q'` / 1000000000))" // Set results to mIdleResult mIdleResult = s.Result // Set error code to mIdleError mIdleError = s.ErrorCode // Log mIdleResult for debugging // System.Log(System.LogLevelError, mIdleResult) // Create a value that holds the current "time" (Ticks) and add the time in gLoopDelay you want to wait. Dim waitUntil As Integer = Ticks + gLoopDelay // Wait until Ticks has reached the new value While Ticks < waitUntil Wend // Keep looping until you're considered abandonded. Loop Until val(mIdleResult) >= gIdleTooLong // Show Window1 and start the countdown to logout. Window1.Show() CountdownThread.Run End Sub #tag EndEvent #tag EndEvents #tag Events CountdownThread #tag Event Sub Run() // Set how long to wait before logging out user Dim gLogoutDelay as Integer = 20 // Stop the idle thread IdleThread.Kill // While we're waiting for the countdown to finish... While gLogoutDelay >= 0 // Set label to the time left TimeLabel.setString(str(gLogoutDelay)) // Refresh it TimeLabel.Refresh // take a second away from the time left gLogoutDelay = gLogoutDelay - 1 // do nothing for 1 second Dim waitUntil As Integer = Ticks + 60 While Ticks < waitUntil Wend Wend // If we're here, the user didn't cancel or log out manaully // Testing mode, use say instead of logout Dim s As Shell s=New Shell s.Mode = 0 s.Execute "say Logging Out" // Quit app Quit End Sub #tag EndEvent #tag EndEvents
\ No newline at end of file
#tag Module Protected Module myXMLTools #tag Method, Flags = &h21 Private Function getXMLkeyString(paramXMLkey as string) As string dim mXMLkeyStr as string //LogToFile(CurrentMethodName + ": ---->") //LogToFile(CurrentMethodName + ": paramXMLkey received = '" + paramXMLkey + "'") mXMLkeyStr = NthField(paramXMLkey,">",1) mXMLkeyStr = ReplaceAll(mXMLkeyStr,"<","") // Remove the < and >'s if found mXMLkeyStr = ReplaceAll(mXMLkeyStr,">","") //LogToFile(CurrentMethodName + ": Returning string = '" + mXMLkeyStr + "'") //LogToFile(CurrentMethodName + ": <----") return mXMLkeyStr End Function #tag EndMethod #tag Method, Flags = &h1 Protected Function getXMLPlistData(paramXMLdataString as string, paramXMLtreeArrayToFollow() as string, byRef paramDataArrayToFill() as string) As Boolean // This method assumes that we're dealing with plist files. // paramXMLtreeArrayToFollow = {"<plist>","<dict>","<key>VolumesFromDisks</key>","<array>") // Sample data: paramXMLdataString = // <?xml version="1.0" encoding="UTF-8"?> // <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> // <plist version="1.0"> // <dict> // <key>AllDisks</key> // <array> // <string>disk0</string> // <string>disk0s1</string> // <string>disk0s2</string> // <string>disk1</string> // <string>disk1s1</string> // <string>disk1s2</string> // </array> // <key>VolumesFromDisks</key> // <array> // <string>Boot</string> // <string>keys</string> // </array> // <key>WholeDisks</key> // <array> // <string>disk0</string> // <string>disk1</string> // </array> // </dict> // </plist> // Result (paramDataArrayToFill) should be: {"<string>Boot</string>","<string>keys</string>"} dim mXMLdoc as XmlDocument dim mXMLroot, mPrefNode, mChildNode as XMLNode dim mXMLtreeToFollowIndex as integer dim mPrefNodeLocalName as string dim mXMLtreeSearchElement as string dim mXMLtreeSearchElementValue as string dim mXMLkeyName as string dim mFoundXMLdata as Boolean dim mTempStr as string // LogToFile(CurrentMethodName + ": ---->") if (paramXMLdataString = "") then LogToFile(CurrentMethodName + ": ERROR: paramXMLdataString received is empty. Returning FALSE.") LogToFile(CurrentMethodName + ": <----") return false else // LogToFile(CurrentMethodName + ": paramXMLdataString =" + EndOfLine + paramXMLdataString + EndOfLine) end if if ( (paramXMLtreeArrayToFollow = nil) or (UBound(paramXMLtreeArrayToFollow)<=0) ) then LogToFile(CurrentMethodName + ": ERROR: paramXMLtreeArrayToFollow received is nil or contains no elements. Returning FALSE.") LogToFile(CurrentMethodName + ": <----") return false else // LogToFile(CurrentMethodName + ": paramXMLtreeArrayToFollow = {" + join(paramXMLtreeArrayToFollow,",") + "}" ) end if if (paramDataArrayToFill = nil) then LogToFile(CurrentMethodName + ": ERROR: paramDataArrayToFill received is nil. Returning FALSE.") LogToFile(CurrentMethodName + ": <----") return false end if redim paramDataArrayToFill(-1) // Erase all data, we're going to refill it next... mFoundXMLdata = false mXMLdoc = new XmlDocument #pragma BreakOnExceptions off // Don't BreakOnExceptions in the IDE on this, just log it and return FALSE try mXMLdoc.LoadXml paramXMLdataString catch LogToFile(CurrentMethodName + ": ERROR: Failed to .loadXML received XML string data (paramXMLdataString). Is it correctly formed XML?") LogToFile(CurrentMethodName + ": <----") return false end #pragma BreakOnExceptions on mXMLroot = mXMLdoc mPrefNode = mXMLroot.FirstChild mXMLtreeToFollowIndex = 0 mXMLkeyName = "" while (mPrefNode <> nil) mPrefNodeLocalName = mPrefNode.LocalName //LogToFile(CurrentMethodName + ": XML Data: mPrefNodeLocalName = '" + mPrefNodeLocalName + "'") if (mPrefNode.FirstChild = nil) then // ie, '<dict>' versus '<dict>AllDisks</dict>' //LogToFile(CurrentMethodName + ": XML Data: mXMLkeyName is NIL. Setting to an empty string.") else // '<dict>AllDisks</dict>' mXMLkeyName = mPrefNode.FirstChild.Value //LogToFile(CurrentMethodName + ": XML Data: mXMLkeyName = '" + mXMLkeyName + "'") end if mXMLtreeSearchElement = getXMLkeyString(paramXMLtreeArrayToFollow(mXMLtreeToFollowIndex)) //LogToFile(CurrentMethodName + ": mXMLtreeSearchElement = '" + mXMLtreeSearchElement + "'") mXMLtreeSearchElementValue = paramXMLtreeArrayToFollow(mXMLtreeToFollowIndex) mXMLtreeSearchElementValue = ReplaceAll(mXMLtreeSearchElementValue,("<" + mXMLtreeSearchElement + ">"),"") mXMLtreeSearchElementValue = ReplaceAll(mXMLtreeSearchElementValue,("</" + mXMLtreeSearchElement + ">"),"") //LogToFile(CurrentMethodName + ": mXMLtreeSearchElementValue = '" + mXMLtreeSearchElementValue + "'") if (mXMLtreeSearchElement = "plist") then if ( InStr(mPrefNodeLocalName,mXMLtreeSearchElement)>0 ) then //catches all versions of the plist format, ie: "<plist version="1.0">" could be "<plist version="1.1">, etc. //LogToFile(CurrentMethodName + ": XML Data: Found plist node, going to first child node next...") mPrefNode = mPrefNode.FirstChild mXMLtreeToFollowIndex = mXMLtreeToFollowIndex + 1 Continue // Skip the rest of the code below, go to the next while loop interation end if end if // Check if the found XML tree item is a match and if so, go in one level: select case mPrefNodeLocalName case mXMLtreeSearchElement //LogToFile(CurrentMethodName + ": XML Data: Found matching XML tree node to search element (<" + mXMLtreeSearchElement + ">)") // Found the matching XML key node. if (mXMLtreeToFollowIndex = (ubound(paramXMLtreeArrayToFollow)-1) ) then // We're on the last key element in the paramXMLdataString, but need to check that it's the right key next... //LogToFile(CurrentMethodName + ": XML Data: Checking key value mXMLtreeSearchElementValue next ...") if ( (mXMLkeyName<>"") and (mXMLtreeSearchElementValue<>"") and (mXMLkeyName = mXMLtreeSearchElementValue) ) then // LogToFile(CurrentMethodName + ": XML Data: Found a matching key! (<" + mXMLkeyName + ">) Next obtaining the child data elements...") mPrefNode = mPrefNode.NextSibling mXMLtreeToFollowIndex = mXMLtreeToFollowIndex + 1 mXMLtreeSearchElement = getXMLkeyString(paramXMLtreeArrayToFollow(mXMLtreeToFollowIndex)) // mXMLtreeSearchElement = "junkTest" // Debugging only if (mXMLtreeSearchElement = "boolean") then mTempStr = mPrefNode.LocalName //LogToFile(CurrentMethodName + ": Boolean value found. Value = '" + mTempStr + "'") paramDataArrayToFill.Append mTempStr mFoundXMLdata = true exit end if if (mPrefNode.LocalName = mXMLtreeSearchElement) then // We have what we need! //LogToFile(CurrentMethodName + ": XML Data: SUCCESS! Found last XML data item. (<" + mXMLtreeSearchElement + _ //">) Adding data elements to the input array next ...") if ( mPrefNode.FirstChild = nil) then // Try the next sibling instead // LogToFile(CurrentMethodName + ": mPrefNode.FirstChild is nil, so trying mPrefNode.NextSibling next ... could be an empty string key value?") mPrefNode = mPrefNode.NextSibling if ( mPrefNode <> nil ) then mTempStr = mPrefNode.Value // LogToFile(CurrentMethodName + ": mPrefNode is NOT nil, data to append = '" + mTempStr + "'") paramDataArrayToFill.Append mTempStr else // LogToFile(CurrentMethodName + ": ERROR: mPrefNode IS nil, nothing found!") end if else mPrefNode = mPrefNode.FirstChild while (mPrefNode <> nil) if (mPrefNode.ToString = "") then mTempStr = mPrefNode.Value // ie, "disk0" (no tags.) else mTempStr = removeXMLtags(mPrefNode.ToString) // ie, "<string>disk0</string>" (with tags!) end if paramDataArrayToFill.Append mTempStr //LogToFile(CurrentMethodName + ": XML Data: Added XML data element '" + mTempStr + "' to the paramDataArrayToFill array.") mPrefNode = mPrefNode.NextSibling wend end if mFoundXMLdata = true exit // exit the loop, we're done else LogToFile(CurrentMethodName + ": ERROR: Unable to locate last XML element data item! (" + mXMLtreeSearchElement + ")") exit // exit the loop, we're done end if exit // exit the loop, we're done else // the next sibling might not have a key name if (mPrefNode.NextSibling <> nil) then //LogToFile(CurrentMethodName + ": mPrefNode.NextSibling exists, moving to it next...") mPrefNode = mPrefNode.NextSibling else //LogToFile(CurrentMethodName + ": ERROR: mPrefNode.NextSibling is NIL! Can't go any further to search for data, exiting search loop.") exit // exit the loop, we're done end if end if else // ELSE, continue on to the next child node... mPrefNode = mPrefNode.FirstChild mXMLtreeToFollowIndex = mXMLtreeToFollowIndex + 1 end if else //LogToFile(CurrentMethodName + ": XML Data: Current XML node local name (<" + mPrefNodeLocalName + ">) does NOT match search element (<" + mXMLtreeSearchElement + ">). Checking next XML sibling...") mPrefNode = mPrefNode.NextSibling end select wend // LogToFile(CurrentMethodName + ": <----") return mFoundXMLdata End Function #tag EndMethod #tag Method, Flags = &h21 Private Function removeXMLtags(paramXMLelement as string) As string dim mKeyName as string dim mReturnString as string LogToFile(CurrentMethodName + ": ---->") LogToFile(CurrentMethodName + ": Received XML string = '" + paramXMLelement + "'") if (paramXMLelement = "") then LogToFile(CurrentMethodName + ": The received string is empty, nothing to do, returning ''.") LogToFile(CurrentMethodName + ": <----") return "" end if // Determine what the key title is first... mKeyName = NthField(paramXMLelement,">",1) // ie, "<string" mKeyName = NthField(mKeyName,"<",2) // ie, "string" mReturnString = paramXMLelement // ie, <string>disk0s2</string> mReturnString = ReplaceAll( mReturnString,("<" + mKeyName + ">","") ) // ie, disk0s2</string> mReturnString = ReplaceAll( mReturnString,("</" + mKeyName + ">","") ) // ie, disk0s2 LogToFile(CurrentMethodName + ": Returning string = '" + mReturnString + "'") LogToFile(CurrentMethodName + ": <----") return mReturnString End Function #tag EndMethod #tag Constant, Name = kIndentXML, Type = String, Dynamic = False, Default = \"<\?xml version\x3D\"1.0\" encoding\x3D\"UTF-8\"\?><xsl:transform version\x3D\"1.0\" xmlns:xsl\x3D\"http://www.w3.org/1999/XSL/Transform\"><xsl:output method\x3D\"xml\" indent\x3D\"yes\" /><xsl:template match\x3D\"/\"><xsl:copy-of select\x3D\"/\" /></xsl:template></xsl:transform>", Scope = Protected #tag EndConstant #tag ViewBehavior #tag ViewProperty Name="Index" Visible=true Group="ID" InitialValue="-2147483648" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Left" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Name" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Super" Visible=true Group="ID" InheritedFrom="Object" #tag EndViewProperty #tag ViewProperty Name="Top" Visible=true Group="Position" InitialValue="0" InheritedFrom="Object" #tag EndViewProperty #tag EndViewBehavior End Module #tag EndModule
\ No newline at end of file
Type=Desktop RBProjectVersion=2012.02 MinIDEVersion=20070100 Class=IdleLogout;IdleLogout.rbbas;&h3007783E;&h0;false Window=LogoutWarning;LogoutWarning.rbfrm;&h3A6788BA;&h0;false MenuBar=MenuBar1;MenuBar1.rbmnu;&h6341CAF0;&h0;false BuildSteps=Build Automation;Build Automation.rbbas;&h2A7E2380;&h0;false Module=LogToFile;LogToFile.rbbas;&h236DD59E;&h0;false Module=Globals;Globals.rbbas;&h7FE3CBE3;&h0;false Module=MiscMethods;MiscMethods.rbbas;&h445F2753;&h0;false Module=myXMLTools;myXMLTools.rbbas;&h6DD0A4A2;&h0;false Module=PlistHelper;PlistHelper.rbbas;&h4AA6652A;&h0;false AppMenuBar=MenuBar1 MajorVersion=1 MinorVersion=0 SubVersion=1 NonRelease=0 Release=2 InfoVersion= LongVersion=1.0b1, Penn State University/ITS/CLC ShortVersion=1.0b1 WinCompanyName= WinInternalName= WinProductName= AutoIncrementVersionInformation=False BuildFlags=&h4000 BuildLanguage=&h0 DebugLanguage=&h0 Region= WindowsName=My Application.exe MacCarbonMachName=Idle Logout LinuxX86Name=MyApplication MacCreator= MDI=0 MDICaption= DefaultEncoding=&h0 AppIcon=psuIdleLogout.rbres;&h0 OSXBundleID=IdleLogout DebuggerCommandLine= UseGDIPlus=True UseBuildsFolder=True IsWebProject=False
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment