Mailing Attachments from the Terminal Prompt in UNIX and Linux

UNIX logo

Transferring files from a UNIX or Linux server when FTP is not installed can be tricky. In my case, there was a set of log files that I needed to send to someone for analysis. After discovering that FTP was not set up on the server, I decided to try another route: zipping the logs into a single file and emailing the file to me.

First, I had to zip the files. The zip command was easy enough:

zip <zipped filename> <files to be zipped>

zipping files in UNIX

Next, I had to mail the zipped file. Fortunately, mailx was installed! Using this in conjunction with uuencode, and the file would be on its way.

uuencode <original filename> <final filename> | mailx -s <subject of email – put in quotes> <email address>

mailx example

Be sure to check your junk or spam folder, as email from the server could end up there.

Entering License Keys for ColdFusion 2018

ColdFusion 2018 about screen

In case you decide not to enter a license key upon installing CF 2018, or if you entered one at installation, but want to enter a different one to upgrade between versions, there doesn’t seem to be any documentation on where to do that.

The System Information screen can be accessed by clicking the “i” in a circle in the upper right-hand corner of the admin screen.

ColdFusion 2018 admin screen system information link

In the System Information screen, enter your license key into the New License box and click Submit Changes.

CF 2018 New License area

ColdFusion 11 Requires Accuracy When Naming Stored Procedure Parameters

CF 11 database activity log

In the process of finally banishing Adobe ColdFusion 8 from my application servers and completing the transition to CF 11, I came across what is apparently a little-known change in the operation of the CFPROCPARAM tag inside a CFSTOREDPROC tag.

After moving the website from CF 8 to CF 11, there were no major changes that had to be made. However, one particular action kept causing a dialog box to pop up:
generic error

I was able to trace the source of the dialog box to an error handler of sorts, but in this case, the error was quite nebulous. The error code “HANDLEDATABASEERROR” didn’t really tell me much. It appears that it may have come from Java itself.

After tracing back which function call seemed to be causing the problem, I discovered that the call to the SQL stored procedure was not using the correct parameter names – that is, names that matched the ones in the stored proc itself.

To determine if the database activity was actually the source of the error, I turned on Log Activity in the Data Source in the ColdFusion Administrator: Data Sources –> (specific Data Source Name) –> Show Advanced Settings –> Log Activity checkbox and text box showing where the log file will go. Example:

CF Log Activity info

After reloading the web page and doing the same action, the an error like the one below showed up in the dblogs.txt file:

spy(ajp-bio-8014-exec-6)(2018/09/26 12:42:30.326)>> java.sql.SQLException: [Macromedia][SQLServer JDBC Driver][SQLServer]Procedure or function 'sp_getNameSuggestion' expects parameter '@GoodParamName', which was not supplied. ErrorCode=201 SQLState=HY000
java.sql.SQLException: [Macromedia][SQLServer JDBC Driver][SQLServer]Procedure or function 'sp_storedProcName' expects parameter '@GoodParamName', which was not supplied.
	at macromedia.jdbc.sqlserverbase.ddcw.b(Unknown Source)
	at macromedia.jdbc.sqlserverbase.ddcw.a(Unknown Source)
	at macromedia.jdbc.sqlserverbase.ddcv.b(Unknown Source)
	at macromedia.jdbc.sqlserverbase.ddcv.a(Unknown Source)
	at macromedia.jdbc.sqlserver.tds.ddr.v(Unknown Source)
	at macromedia.jdbc.sqlserver.tds.ddr.a(Unknown Source)
	at macromedia.jdbc.sqlserver.tds.ddq.a(Unknown Source)
	at macromedia.jdbc.sqlserver.tds.ddr.c(Unknown Source)
	at macromedia.jdbc.sqlserver.dda3.m(Unknown Source)
	at macromedia.jdbc.sqlserverbase.dde7.e(Unknown Source)
	at macromedia.jdbc.sqlserverbase.dde7.a(Unknown Source)
	at macromedia.jdbc.sqlserverbase.ddd2.a(Unknown Source)
	at macromedia.jdbc.sqlserverbase.dde7.x(Unknown Source)
	at macromedia.jdbc.sqlserverbase.dde7.t(Unknown Source)
	at macromedia.jdbc.sqlserverbase.ddd2.execute(Unknown Source)
	at macromedia.jdbc.sqlserverbase.ddd6.execute(Unknown Source)
	at macromedia.jdbcspysqlserver.SpyPreparedStatement.execute(Unknown Source)
	at com.intergral.fusionreactor.jdbc.jdbc42.PreparedStatementSurrogate2.execute(PreparedStatementSurrogate2.java:200)
	at coldfusion.server.j2ee.sql.JRunPreparedStatement.execute(JRunPreparedStatement.java:101)
	at coldfusion.sql.Executive.executeCall(Executive.java:1087)
	at coldfusion.sql.Executive.executeCall(Executive.java:960)
	at coldfusion.sql.Executive.executeCall(Executive.java:910)
	at coldfusion.sql.SqlImpl.executeCall(SqlImpl.java:528)
	at coldfusion.tagext.sql.StoredProcTag.executeQuery(StoredProcTag.java:341)
	at coldfusion.tagext.sql.StoredProcTag.doEndTag(StoredProcTag.java:287)
...

The CFML source code calling this stored procedure was revealing:

<cfstoredproc procedure="dbo.sp_storedProcName" datasource="#getDSN()#">
	<cfprocparam cfsqltype="cf_sql_varchar" type="in" dbvarname="@BadParamName" value="#arguments.GoodParamData#" null="no" />
	<cfprocparam cfsqltype="cf_sql_integer" type="in" dbvarname="@OtherParam" value="#arguments.OtherParamData#" null="no" />
	<cfprocresult name="qResultSet" />
</cfstoredproc>

In some older versions of ColdFusion (at least as recently as version 8, perhaps all the way through 10), if the name of the parameter stored in the dbvarname attribute of the cfprocparam tag wasn’t correct, no error was thrown as long as the data types of the parameters matched in the correct order for both the cfstoredproc tag and the database stored procedure. This dbvarname attribute was essentially ignored in those versions. Version 11 changed all that.

By changing the source code to reflect the correct name, the bug was fixed.

<cfstoredproc procedure="dbo.sp_storedProcName" datasource="#getDSN()#">
	<cfprocparam cfsqltype="cf_sql_varchar" type="in" dbvarname="@GoodParamName" value="#arguments.GoodParamData#" null="no" />
	<cfprocparam cfsqltype="cf_sql_integer" type="in" dbvarname="@OtherParam" value="#arguments.OtherParamData#" null="no" />
	<cfprocresult name="qResultSet" />
</cfstoredproc>

Copying Windows Registry Keys from One User to Another

Windows Registry - regedit.exe

After switching the logged on user on a Windows Service, I found out that the original user had some printers set up that were not present in the new user’s profile.

While I could have manually set up the necessary printers on the new user, it seemed that there must be a way to do this that would ensure that all of the printers were set up correctly on the new user.

Printer information for each user is stored in the HKEY_CURRENT_USER\Printers registry key.

However, the HKEY_CURRENT_USER hive only shows registry information for whatever user you’re logged on as. What if you wanted to copy from one user (other than you), to some other user?

The HKEY_CURRENT_USER key for each user is found in the registry under the HKEY_USERS hive, under each user’s SID. If you don’t have an easy way to find out what a user’s SID is, what then?

There is a solution! The information that is displayed in the HKEY_CURRENT_USER hive is stored in the NTUSER.DAT file in each user’s profile.

Each user’s hive can be loaded either from the Registry Editor or the command line. Both of these must be started as an Administrator to have the privileges to do this.

The example below shows how to do this from a command line. If the user whose hive to be copied is called OLDUSER, the following command (reg load) should attach the OLDUSER hive as HKEY_USERS\OLDUSER. This can be run from Command Prompt or PowerShell.

reg load C:\Users\OLDUSER\NTUSER.DAT

Do the same thing with the new user (NEWUSER):

reg load C:\Users\NEWUSER\NTUSER.DAT

Note: If either of these users is currently logged on or running a service, they must first be logged off or the service stopped.

In the Registry Editor, export (in this case) the Printers key from HKEY_USERS\OLDUSER into a .reg file.

Open the .reg file with an editor and replace all instances of OLDUSER with NEWUSER. Save the file. Execute the file by double-clicking on it. Confirm the dialog box to add the information to NEWUSER’s hive.

confirm registry change

To unload both users’ hives, execute the following commands:

reg unload OLDUSER
reg unload NEWUSER

(Remember to restart any Services that were stopped before loading!)

To verify that the information was copied correctly, you can log on as the new user and examine its HKEY_CURRENT_USER hive.