Programming SQL / Database

Application.FileSearch in MS Access 2007

I recently wrote a small application for someone using Microsoft Access 2003 and found the Application.FileSearch method of enumerating files is no longer available. The older “dir” function is still available so I replaced it with the following code to change the current drive and path and enumerate the files. Note this code will only work for local drive paths, not UNC style network paths.

Private Sub Form_Activate()

Dim i As Integer
Dim SearchPath As String
Dim Filename As String

SearchPath = GetPath() & "Backups"
ChDrive Mid$(SearchPath, 1, 2)
ChDir SearchPath
Filename = Dir("*.csv")
While Filename <> ""
  RestoreList.AddItem (Filename)
  Filename = Dir

End Sub
Linux Programming

POSIX threads under arm-linux-g++

Today I was changing my TomTom datalogger to use threads for GPS reception and initially had some linking problems despite including pthread.h in the C++ source code and adding -lpthread to the linker options. The thing that threw me at first was pthread_create linked fine but I was getting linker undefined reference errors to other common POSIX threading calls such as pthread_exit and pthread_join.

At first I was worried that arm-linux-g++ didn’t support POSIX threads and was only providing an unimplemented stub routine for pthread_create that satisified the linker but didn’t work. It turned out however that POSIX threading is supported by GCC for the ARM but it doesn’t sit well with static linking of the libraries. I’d only used static linking for initial convenience when I wasn’t sure what libraries would be required, once the project was converted to dynamic linking of the LGPL libraries required by the project everything worked fine.


VAX/VMS MACRO password checker

The following is come code I found I wrote many years ago in Digital VAX MACRO to check passwords for a particular username against a dictionary of words concatenated with a number.

.title    check_password


.psect    rw_data rd,wrt,noexe,noshr,long

pwdlist_fab:    $fab    fnm = <sys$library:VMS$PASSWORD_DICTIONARY.DATA>

pwdlist_rab:    $rab    fab = pwdlist_fab,-
rop = rah,-
ubf = rec_buff,-
usz = rec_size

rec_size = 32
rec_desc:    .word    rec_size
.word    0
.address rec_buff
rec_buff:    .blkb    rec_size

cur_count:    .long
max_count = 99
num_size = 2
cur_no:        .ascid    \99\

cur_pwd:    .word   rec_size+num_size
.word    0
.address 10$
10$:        .blkb    rec_size+num_size

cur_hash:    .blkb    8

username_len:    .word    12
.word    0
.address 10$
10$:        .blkb    12

pwd_list:    .word    1
.word    uai$_encrypt
.address encrypt
.address encrypt_len
.word    8
.word    uai$_pwd
.address pwd
.address pwd_len
.word    2
.word    uai$_salt
.address salt
.address salt_len
.word    0
.word    0
encrypt:    .byte
encrypt_len:    .word
pwd:        .blkb    8
pwd_len:    .word
salt:        .word
salt_len:    .word

usage_msg:    .ascid \VMS username must be specificed as a parameter\

.psect    code rd,nowrt,exe,shr,long

.entry    check_password,^m<>

; get username passed on command line - display error if not present

pushaq    username
calls    #1,g^lib$get_foreign
blbc    r0,error_exit
pushaw    username_len
pushaq    username
pushaq    username
calls    #3,g^str$trim
blbc    r0,error_exit
tstw    username_len
bnequ    get_pwd
pushaq    usage_msg
calls    #1,g^lib$put_output
brb    normal_exit

; retrieve the hashed password from the UAF file

get_pwd:    $getuai_s usrnam=username,-
blbc    r0,error_exit

; open the VMS password dictionary

open_dic:    $open    fab=pwdlist_fab
blbc    r0,error_exit
$connect rab=pwdlist_rab
blbc    r0,error_exit

; retrieve a word from the dictionary

word_loop:    $get    rab=pwdlist_rab
blbs    r0,remove_nulls
cmpl    r0,#rms$_eof
beql    normal_exit
brb    error_exit

; get rid of nulls on the end of the record and convert to uppercase

remove_nulls:    clrw    r1
movaq    rec_buff,r2
10$:        tstb    (r2)
beql    20$
incw    r1
incl    r2
brb    10$
20$:        movw    r1,rec_desc
pushaq    rec_desc
pushaq    rec_desc
calls    #2,g^str$upcase

; start back at zero for new word

clrl    cur_count

; append a number to the word

append_no:    pushl    #2
pushl    #1
pushaq    cur_no
pushal    cur_count
calls    #4,g^ots$cvt_l_tu

movw    #rec_size+num_size,cur_pwd
pushaq    cur_no
pushaq    rec_desc
pushaq    cur_pwd
calls    #3,g^str$concat
blbc    r0,error_exit

pushaw    cur_pwd
pushaq    cur_pwd
pushaq    cur_pwd
calls    #3,g^str$trim

; now we have all the info to hash a password

$hash_password_s -
blbc    r0,error_exit

; check if we have a match on the hashed password - if so display

cmpl    cur_hash,pwd
bneq    no_match
cmpl    cur_hash+4,pwd+4
bneq    no_match
pushaq    cur_pwd
calls    #1,g^lib$put_output
brb    normal_exit

; loop back 'max_count' times

no_match:    aoblss    #max_count,cur_count,append_no

; loop back for another word

brb    word_loop

normal_exit:    movl    #1,r0
error_exit:    ret

.end    check_password
Linux Programming

Linux kill process code fragment

Small C++ source code fragment to kill a certain number of instances of a process running under Linux. For example the following sends a terminate signal to the first 999 processes with the process name Tomahawk.

killproc(“Tomahawk”, “-TERM”, 999);

int killproc(const string procname, const string killcmd, const int killcnt)
	int proccnt = 0;
	const string procdir("/proc");

	DIR* dir = opendir(procdir.c_str());
	if (!dir)
		return 0;
	string searchstr = "(" + procname + ")";
	struct dirent *d;
	while ((d = readdir(dir)) &amp;&amp; proccnt &lt; killcnt)
		string dirname(d-&amp;gt;d_name);
		if( d-&gt;d_type == DT_DIR &amp;&amp; dirname != "." &amp;amp;&amp;amp; dirname != ".." &amp;amp;&amp;amp; isdigit(dirname[0]))
			string fn = procdir + "/" + dirname + "/stat";
			ifstream f(fn.c_str());
			if (f.is_open())
				string line;
			    if (getline (f, line) &amp;&amp; line.find(searchstr) != string::npos)
			    	string procid = line.substr(0, line.find(" "));
					string cmd = "kill " + killcmd + " " + procid;
	return proccnt;