Saturday, February 27, 2010

Passing by reference in bash

It is possible to mimic pass by reference in a bash shell.

The trick is to pass the name of the variable, not its expanded value.

Use

func out

instead of

func $out


In the function, set the value of the out parameter as

eval "$1=expr"

In the function, copy the value of the parameter to a local variable with

eval "L_VAR=\${$1}"

When using local variables, it is important that the name of the variable from the caller is not the same name as the local variable in the function. The local in the function is deleted when the function ends.

#!/bin/bash

#$1 is name of out param, $2 is name of out param
func () {
  local loc=8
  local diff=9
  local same=10
  eval "$1=$diff"
  eval "$2=$same"
}

loc=7
func out same
echo "loc = $loc"               #loc = 7
echo "out = $out"               #out = 9     
echo "same = $same"             #same = 

Tuesday, December 22, 2009

Jaxer in Aptana

I downloaded version 2.02 of Aptana Studio; it is supposed to have Jaxer in it. I cannot find it.

I have looked at many sites for using Jaxer, I am unable to do step 1 in any of these sites. They all refer to some button or menu in Aptana that is grayed out or that I do not have.

I found a good site at IBM that details how to install Jaxer as a stand-alone server on Windows.

It used a simple example demonstrating how to use a callback; of course, it failed. It turns out that the file that it is trying to access, http://update.aptana.com/update/jaxer/win32/version.txt, cannot be accessed.

I created a file on my own server that will report some number in the correct format: .0.9. Now the example works.

I have found the framework for Jaxer. The query string is in Jaxer.parsedUrl.queryparts.

Functions can be run on the server, client or both. A property of the Function object can be used to allow a server function to be called from the client: functionName.proxy = true. The runat property of the script can also be set to server-proxy, which sets the proxy property to true for all functions in the script block.

I have found an excellent introduction to using Jaxer.

Use Jaxer.request.currentFolder to get the absolute path to the current folder.

Use Jaxer.Dir.resolve to get an absolute path to a relative reference.
Jaxer.Dir.resolve(Jaxer.request.currentFolder + "/posts")

Unobtrusive JavaScript does not set event handlers in the HTML tags. Use JavaScript to set the handlers. If the tag is used, then it removes all other handlers.

form.submit is called when a form is submitted programatically, not by clicking a submit button.
form.addEventListener("submit", handler, bool) is called when a submit button in the form is called. The same effect as using onLoad, but onLoad can only register one event.

When overriding submit, it is good to store the old submit method. The new method will not have the default behavior of submitting the form; call the old method to submit the form. This also has an advantage of allowing the current method to be canceled without canceling the entire event. Once an event is canceled using event.preventDefault, it is not possible to enable it again.


<html>
<head>
<title>Submit Events, Handlers and Prototypes</title>
<script type="text/javascript">

function submitFromScript() {
//There is no event object, but 'this' points to the form.
alert("Submitted by calling submit from a script: this = " + this);
//call the original, if it has been set.
if (this.submitPrototype) this.submitPrototype();
}

function submitFromSubmitButton(event) {
alert("Submitted by clicking a submit button in a form");
}

function submitFromWindowSubmitButton(event) {
alert("Submitted by clicking a submit button in a form, caught by window event");
}

function submitFromHandler(event) {
alert("Submitted by clicking submit button and overriding the submit handler for the form");
if (this.submitHandler) this.submitHandler();
}

// Function to change the content of t2
function modifyText(event) {
var t2 = document.getElementById("t2");
alert("modify t2: " + t2);
t2.firstChild.nodeValue = "three";
}

// Function to add event listener to t
function load() {
alert("load")

HTMLFormElement.prototype.submitPrototype = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = submitFromScript;

var el = document.getElementById("frmPost");
el.submitHandler = el.submit;
el.submit = submitFromHandler;

el.addEventListener("submit", submitFromSubmitButton, false);
el.addEventListener("submit", modifyText, false);

}

window.addEventListener("load", load, false);

</script>
</head>
<body>
<form id="frmPost">
<input type="button" onClick="document.getElementById('frmPost').submit();" value="Submit by Script">
<input type="submit" value="Submit Button">
</form>
<table id="t">
<tr><td id="t1">one</td></tr>
<tr><td id="t2">two</td></tr>
</table>
</body>
</html>


The event handler code should always be run in the client. If it needs to run server code, then it should call a proxy on the server.

When using jQuery and Prototype, they have a conflict with $(). Use jQuery.noConflict() to allow the Prototype definition to prevail.

$(id) only works on the server. Add a function on the client that does the same thing:
function $(id) {
return window.document.getElementById(id);
}


The blog example from this site has errors when accessing files. Use resolve and combine to translate to a path that can be read by the native file system.
Jaxer.Dir.resolve(Jaxer.Dir.combine(Jaxer.request.documentRoot, "blog/posts"));


Here is the modified file that works on a PC.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Write Blog</title>
<script src="lib/prototype/prototype.js" runat="server" type="text/javascript">
</script>
<script src="lib/showdown/showdown.js" runat="server" type="text/javascript">
</script>

<script runat="client" type="text/javascript">

function $(id) {
return window.document.getElementById(id);
}

function onSubmit(evt) {
var newPost = $("txaPostText").value;

if (newPost.length == 0) {
alert("You haven't entered anything.");
}
else {
if (save(newPost)) {
//add the new post
formatPost(newPost);
$("txaPostText").clear();
}
else {
alert("An error occurred. Couldn't save your post.");
}
}
//stop the form from submitting
evt.preventDefault();

$("txaPostText").focus();

}

function onLoad(){
$('frmPost').addEventListener('submit', onSubmit, false);
}

if (window.addEventListener) {
window.addEventListener("load", onLoad, false);
}
</script>
<script runat="server" type="text/javascript">

function serverLoad(){
//create the main posts <DIV>

var posts_div = document.createElement('div');
posts_div.id = 'posts';
document.body.appendChild(posts_div);

var path = Jaxer.Dir.resolve(Jaxer.Dir.combine(Jaxer.request.documentRoot, "blog/posts"));
if (!Jaxer.Dir.exists(path)) {
formatPost("Path does not exist: " + path);
return;
}
var dir = new Jaxer.Dir(path);
var files = dir.readDir().map(function(file){
var post = Jaxer.File.read(Jaxer.Dir.combine(dir.path, file.leaf));
formatPost(post);
});
}

window.addEventListener("serverload", serverLoad, false);

var formatPost = (function(showdown){
return function(content){
var post_div = document.createElement('div');
Element.extend(post_div);
post_div.innerHTML = showdown.makeHtml(content);

// insert new post in the main div
$('posts').appendChild(post_div);
}
})(new Showdown.converter());

function save(text){
try {
var path = Jaxer.Dir.resolve(Jaxer.Dir.combine(Jaxer.request.documentRoot, "blog/posts"));
Jaxer.Log.info(path);
var dir = new Jaxer.Dir(path);
//get the last post number
var lastFileNo = (dir.readDir()).length;
path = Jaxer.Dir.resolve(Jaxer.Dir.combine(dir.path, (lastFileNo + 1) + ".txt"));
Jaxer.Log.info(path);
Jaxer.File.write(path, text);

return true;
}
catch (e) {
Jaxer.Log.error(e);

return false;
}
}
save.proxy = true;
</script>
</head>
<body>
<h1>The Blog Page that Writes Files</h1>
<form id="frmPost" action="">
<textarea rows="10" cols="40" id="txaPostText"></textarea>
<input id="btnPost" type="submit" value="Submit Post"/>
</form>
</body>
</html>

While exploring the Aptana resources, I found that there is a new forum site. The old site has a lot of references to Jaxer, but the new site does not. The jaxer.org site references the old forum, but there is link in the old to the new.

The new forum site has a page for forum for App Studio that has an article on manual plugins. On the link for the Jaxer plugin, I followed these instructions and was able to add Jaxer to Aptana Studio 2.0.2.

Installing this Plugin via Aptana or Eclipse

1. From the Help menu, select Install New Software... to open an Install pop-up window.
2. In the Work with: text box of the Install window, type the URL http://update15.aptana.org/jaxer/25739/ for the update site, and hit the Enter key.
3. In the populated table below, check the box next to the name of the plug-in, and click the Next button.
4. Click the Next button to go to the license page.
5. Choose the option to accept the terms of the license agreement, and click the Finish button.

More things are working now. I am writing test code to see if everything works. I now have access to the samples.

The API shows there is a data object in Jaxer, but it is called clientData.
Jaxer.Cache is Jaxer.CacheManager.
Jaxer.SendOptions does not exist.

Friday, October 30, 2009

Outer Join in MS Query

SELECT UffMacBen.`FIRST NAME`, UffMacBen.`LAST NAME`, UffMacBen.MAC_EMPLID, UffMacBen_Original.`FIRST NAME`, UffMacBen_Original.`LAST NAME`, UffMacBen_Original.MAC_EMPLID, UffMacBen.`FIRST NAME` FROM {oj `U:\uweb\members\2009\UFFmacBEN_09032009_copy`.UffMacBen UffMacBen LEFT OUTER JOIN `U:\uweb\members\2009\UFFmacBEN_09032009_copy`.UffMacBen_Original UffMacBen_Original ON UffMacBen.MAC_EMPLID = UffMacBen_Original.MAC_EMPLID} WHERE (UffMacBen_Original.MAC_EMPLID Is Null) UNION SELECT UffMacBen.`FIRST NAME`, UffMacBen.`LAST NAME`, UffMacBen.MAC_EMPLID, UffMacBen_Original.`FIRST NAME`, UffMacBen_Original.`LAST NAME`, UffMacBen_Original.MAC_EMPLID, UffMacBen.`FIRST NAME` FROM {oj `U:\uweb\members\2009\UFFmacBEN_09032009_copy`.UffMacBen_Original UffMacBen_Original LEFT OUTER JOIN `U:\uweb\members\2009\UFFmacBEN_09032009_copy`.UffMacBen UffMacBen ON UffMacBen_Original.MAC_EMPLID = UffMacBen.MAC_EMPLID} WHERE (UffMacBen.MAC_EMPLID Is Null)

Wednesday, October 14, 2009

Reading Excel Files from JDBC

Reading Excel Files from JDBC


I followed this example from JavaWorld and it worked. The instructions were good, except for the explanation of why qas was used as the name of the worksheet. The file was named qa.xls, the connection was qa-list; it took me a few minutes to realize that the name on the worksheet tab was qas.

Next step is to read my own file and do a query. It worked.

Next step is to perform an outer join between two sheets in the same file.

I have created the outer join with the following syntax (from ibm):

query = "SELECT * FROM {oj [09032009$] LEFT OUTER JOIN [09172009$] ON ([09032009$].MAC_EMPLID=[09172009$].MAC_EMPLID)}";

The names of my sheets in the file are 09032009 and 09172009.

I have determined the number of columns in the result set (from devdaily):

    //------------------------------------------------------//
   //  Here's the code to determine the number of columns  //
   //  in the ResultSet.                                   //
   //------------------------------------------------------//
   Statement st = conn.createStatement();
   ResultSet rs = st.executeQuery("SELECT * from Customer");
   ResultSetMetaData rsmd = rs.getMetaData();

   int numCols = rsmd.getColumnCount();
This can also be used to retrieve a column name.

Saturday, September 19, 2009

Replacing the Hard Drive on a Vista Machine

I dropped my HP tx2-1950dx Touchsmart laptop the other day. Since then, the hard drive has been making clicking sounds. After doing a disk check, it seems that the area from 11% to 14% on the hard disk is in bad shape.

I ordered a replacement disk from HP and it arrived the next day.

The first thing that needs to be done is to create a recovery disk that can be used to boot the system from the CD. In Vista, type Recovery in the start box and select Create Recovery Disks. This uses the recovery partition on the hard drive to create disks that will restore the system to its original factory state. Please note, this should have been done BEFORE the drive was damaged!!!

I have also created a current backup of the drive using the Windows Recovery option. I hope that I can use these disks to restore the disk instead of using the original state disks.

I also used DriveImageXML to create a compressed backup of the disk, but I will need to figure out a way to run the software before the main partition is installed.

I will follow the instructions on http://www.bleepingcomputer.com/tutorials/tutorial144.html
, once I have my recovery disks created.

After running the recovery disk, it seems that I will need to reinstall the factory state and then restore the later recovery that was created in Vista.

There is no way to load an image of the disk, except for the original factory state. The HP recovery disk does not allow access to the Repair Computer utility that is normally accessed after pressing F8 during boot. The only way to load another image is to buy a piece of hardware that will add the new drive to the computer through USB. I have ordered such a device.

I borrowed the hardware from a friend, but it didn't work on Vista. I bought the hardware for Vista. It still didn't work. Some of the partitions could be restored but not the boot partition. After several attempts, I surmised that the boot partition was corrupt, since I made it after the crash.

I ran the "restore to factory state" disks and reinstalled additional software and updates. All is well now.

Wednesday, August 26, 2009

Modifying the boot loader in Vista

I miss boot.ini. Why isn't there a GUI version of bcdedit?

I could run bcdedit, but I could not read the boot loader store without admin permission. I found a useful link that had the secret to running cmd with admin permission: type cmd in the search window in the start menu and hit CTRL-SHIFT-ENTER. So obvious.

bcdedit /? will show all the options.

bcdedit /v will show all the boot choices, including the annoying ID.

bcdedit /delete ID /cleanup will delete a choice from the list, as long as you get the ID correct.

If the partition has already been deleted, then this will not work!!!

bcdedit /deletevalue ID type will remove the entry, if you know the type.

bcdedit /? /TYPES will tell you more about the types.

bcdedit /deletevalue ID DESCRIPTION desc should remove the entry, but it doesn't, of course.

The problem that I have is that I have already deleted the Windows 7 partition, so none of the commands work. If I use the current OS, then they work. For instance,

bcdedit /set description "Vista Sucks"

works beautifully. I can even use the ID as

bcdedit /set ID description "Vista Really Sucks"

According to several posts, the /delete command should work but it doesn't.

The solution was to download easybcd

Wednesday, June 24, 2009

Fedora 11 Installing Samba

yum install samba
version 3.3.2-0.33.fc11

cd /etc/samba
mv smb.conf smb.conf.backup
vi smb.conf
[global]
workgroup = wrkgrp
netbios name = smbserver
security = SHARE
load printers = No
default service = global
path = /home
available = No
encrypt passwords = yes
[share]
writeable = yes
admin users = smbuser
path = /home/share
force user = root
valid users = smbuser
public = yes
available = yes

save and exit

add user smbuser to local and smb
useradd smbuser
passwd smbuser
smbpasswd -a smbuser

/etc/init.d/smb restart

new use z: \\ip\share passwd username

I could not connect from Windows.

I changed security to user: it still didn't work.

I am now reading an online Samba book.
http://us1.samba.org/samba/docs/man/Samba-HOWTO-Collection/


testparm is a command that will test the configuration of the samba conf file.
testparm /etc/samba/smb.conf

The file passes the test.

Optimize the file and strip all comments with
testparm -s source dest

SWAT is a web-based config tool. I will look into that after I get the conf file working.

Display all shares that are defined on a host:
smbclient -L hostname

This asks for a password for the current user. Even if I am logged in as the smb user, I am unable to connect.

Do an anonymous login by addeng -N to the command. I am able to see the share that I created.

Connect to home dir:
smbclient //host/user
This also requires password and fails.

/etc/sysconfig/network contains nameservers and hostname.
Where is the alias for eth0 and wlan0 defined? There is no /etc/modprobe.conf

Name resolution of DHCP addresses needs to be hardcoded, which defeats DHCP. I found a link,
http://www.cameratim.com/computing/linux/using-bind-as-a-local-dns-server, that indicates how to get around this. I will investigate later; for now I am hardcoding the DHCP address.

I failed to start nmb. Both the nmb and smb services must be running.
service smb start
service nmb start

Test if all the appropriate services are running (from http://troy.jdmz.net/samba/fw/):
# service smb stop
# netstat -ln > netstat-ln-smb.before
# service smb start
# netstat -ln > netstat-ln-smb.after
# diff netstat-ln-smb.*

Open firewall for udp and tcp in the /etc/sysconfig/iptables file:
-A INPUT -p udp -m udp --dport 137 -j ACCEPT
-A INPUT -p udp -m udp --dport 138 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 139 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 445 -j ACCEPT

Then restart the firewall
service iptables restart

The smbserver is now visible from the Window machine. I am still unable to connect to a share.

Tried a simple config from http://us6.samba.org/samba/docs/man/Samba-Guide/simple.html#draft-smbconf
[global]
workgroup = MIDEARTH
security = SHARE

[Plans]
path = /plans
read only = Yes
guest ok = Yes

When I tried smbclient -L server -Uroot%passwd, I got an error about LANMAN authorization. I fixed it by adding the following to the global section of the conf file and restarted smb:
client lanman auth = Yes
lanman auth = Yes

I can now see the server and the share (though I changed the name of the workgroup, but windows still sees the old one); however, when I try to access the share, my Linux security warns me that someone is trying to access my home directory. I placed the share in my home directory, so the error is correct. I will move the share. I just noticed that on Linux, the new workgroup name is not recognized, either.

I seem to being editing the wrong smb.conf file. The changes that I am making are not being implemented. I am editing /etc/samba/smb.conf ... No, I am editing the correct file, but the workgroup command in the global section is changing the domain, but not the workgroup.

I tried following the advice of the AVC warning: setsebool -P samba_enable_home_dirs=1, it did not resolve the problem.

I am still getting the home dir error; eventhough I moved the directory to the root. I will try moving it to /tmp ... Did not work.

I have added the following share
[homes]
browseable = ok
guest ok = yes


I can now access homes, but it opens my root directory.

I am able to mount a windows share with
mount.cifs //ip/path /mnt
It asks for a password.

I found a page on printing from linux to a windows printer: http://www.math.colostate.edu/~reinholz/freebsd/smb_print_client.html

In the original smb.conf, there are comments about SELinux for home directories and domains.
setsebool -P samba-domain-controller on
setsebool -P samba-enable-home-dirs on

There is also a comment about setting samba-share-t for new directories, for allowing SELinux to write to a dir.

Use the command ls -ldZ to see the context for a directory.

I used the original smb.conf file and I can access home directories.

More Blogs

Followers