One half of a Windows Sockets test

This is the client side of a Windows Sockets test in C++.

#ifndef _WINSOCK_TEST_H
#define _WINSOCK_TEST_H

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

WSADATA wsaData;

int initWinsock();

#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include "winsock_test.h"

int initWinsock()
{
	int iResult;

	puts("initWinsock()");

	if (iResult = WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		return 0;

	printf("WSAStartup(MAKRWORD(2, 2), 0x%x) returned %d\n", &wsaData, iResult);
	return 1
}
#include "winsock_test.h"

#define TCP_SOCKET_PORT 27015
#define TCP_SOCKET_ADDR "127.0.0.1"
#define BUFLEN		512

int client()
{
	int    iResult;
	int    recvbuflen       = DEFAULT_BUFLEN;
	struct addrinfo *result = NULL;
	struct addrinfo *ptr    = NULL,
	struct addrinfo hints;
	char   port[5];
	char   *sendbuf         = "this is a test";
	char   recvbuf[DEFAULT_BUFLEN];

	puts("client()");

	printf("ZeroMemory(0x%x, 0x%x)\n", &hints, sizeof (hints));
	ZeroMemory(&hints, sizeof (hints));
	hints.ai_family   = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	itoa(TCP_SOCKET_PORT, port, 10);
	printf("getaddrinfo(%s, %s, 0x%x, 0x%x)\n", TCP_SOCKET_ADDR, port, &hints, &result);
	if (iResult = getaddrinfo(TCP_SOCKET_ADDR, port, &hints, &result) != 0)
	{
		printf("getaddrinfo(%s, %s, 0x%x, 0x%x) returned %d\n", TCP_SOCKET_ADDR, port, &hints, &result, iResult);
		WSACleanup();
		return 1;
	}

	SOCKET ConnectSocket = INVALID_SOCKET;
	ptr = result;
	puts("socket(AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP)\n");
	if (ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol) == INVALID_SOCKET)
	{
		printf("Error on socket(): %ld\n", WSAGetLastError());
		freeaddrinfo(result);
		WSACleanup();
		return 1;
	}

	puts("connect(ConnectSocket, ptr->ai_addr, (int) ptr->ai_addrlen)\n");
	if (iResult = connect(ConnectSocket, ptr->ai_addr, (int) ptr->ai_addrlen) == SOCKET_ERROR)
	{
		printf("connect(ConnectSocket, ptr->ai_addr, (int) ptr->ai_addrlen) returned %d\n", iResult);
		closesocket(ConnectSocket);
		ConnectSocket = INVALID_SOCKET;
	}

	freeaddrinfo(result);

	if (ConnectSocket == INVALID_SOCKET)
	{
		puts("Socket connection failed.\n");
		WSACleanup();
		return 1;
	}

	printf("send(ConnectSocket, %s, (int) %d, 0)\n", sendbuf, (int) strlen(sendbuf));
	if (iResult = send(ConnectSocket, sendbuf, (int) strlen(sendbuf), 0) == SOCKET_ERROR)
	{
		printf("send failed: %d\n", WSAGetLastError());
		closesocket(ConnectSocket);
		WSACleanup();
		return 1;
	{

	printf("Bytes sent: %ld\n", iResult);

	puts("shutdown(ConnectSocket, SD_SEND)\n");
	if (iResult = shutdown(ConnectSocket, SD_SEND) == SOCKET_ERROR)
	{
		printf("shutdown failed: %d\n", WSAGetLastError());
		closesocket(ConnectSocket);
		WSACleanup();
		return 1;
	}

	// receive data
	do
	{
		puts("recv(ConnectSocket, recvbuf, recvbuflen, 0)\n");
		iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
		if (iResult > 0)
			printf("Bytes received: %d\n", iResult);
		else if (iResult == 0)
			puts("Connection closed"\n);
		else
			printf("recv failed: %d\n", WSAGetLastError());
	}
	while (iresult > 0);

	// no more data, shut down
	puts("shutdown(ConnectSocket, SD_SEND)\n");
	if (iResult = shutdown(ConnectSocket, SD_SEND) == SOCKET_ERROR)
	{
		printf("shutdown failed: %d\n", WSAGetLastError());
		closesocket(ConnectSocket);
		WSACleanup();
		return 1;
	}

	closesocket(ConnectSocket);
	WSACleanup();
	return 0;
}

Leave a comment

Quote Database Screen Scraper

I wanted to make fortune(6) cookie files out of the major internet quote databases. So I came up with a Bash script that uses lynx and sed to do it. It includes throttling by default because it’s not nice to suck up all the site’s bandwidth.

#!/bin/bash
# Scrapes a qdb and dumps output to a file
# and tokenizes it into a fortune cookie file
#
LYNX="/usr/bin/lynx"
DEFSLEEP="30"
PNUM_DELIM="%pnum%"

# parse command line args
# look for -s to specify sleep_int period
# look for -p to specify number of pages
# treat everything else like a URL
# %pnum% is page number delimiter
sleep_int=$DEFSLEEP
URLS=()
ARGV=("$@")
for (( thisarg = 0; thisarg < ${#ARGV[*]}; thisarg++ ))
do
	arg="${ARGV[$thisarg]}"
	if [ "$arg" = "-s" ]
	then
		thisarg=$(( $thisarg + 1 ))
		sleep_int=${ARGV[$thisarg]}
	elif [ "$arg" = "-p" ]
	then
		thisarg=$(( $thisarg + 1 ))
		pages=${ARGV[$thisarg]}
	else
		URLS=("${URLS[@]}" "$arg")
	fi
done

LYNXOPTS="-accept_all_cookies -assume_charset=iso-88591 -nolist -dump"

# debug
echo ${URLS[@]}
echo "Sleep is $sleep_int"

for url in "$URLS"
do
	name=`echo $url | cut -d / -f 3`
	mkdir "$name"

	for (( page = 1; page <= $pages; page++ ))
	do
		n_url=`echo $url | sed -e "s/$PNUM_DELIM/$page/g"`
		# debug
		echo "$LYNX $LYNXOPTS $n_url > $name/page_$page"
		$LYNX $LYNXOPTS $n_url > $name/page_$page
		sleep $sleep_int
	done

	# postprocess scraped text files
	cd "$name"

	# remove quote IDs and put in fortune delimiters
	for file in *
	do
		sed -e "s/^\s*#.*$/%/g" < "$file" >> "$name.txt"
	done

	# remove page navigation links
	sed -e "s/^.*[1-9][0-9]* of [1-9][0-9]*.*$//g" < "$name.txt" > "$name"

	# make the database
	strfile "$name"
	rm "$name.txt"

done

Leave a comment

Quick ‘n dirty anagrammer using the Internet Anagram Server

I was bored one day and noticed that the an(6) program wasn’t in Red Hat’s repos. So I wrote a Perl script to talk to the Internet Anagram Server’s HTTP interface:

#!/usr/bin/perl
use strict;
use warnings;

use HTTP::Client;
use URI::Escape;

my $client   = HTTP::Client->new();
my $string   = uri_escape(join(" ", @ARGV));
my $document = $client->get("http://www.wordsmith.org/anagram/anagram.cgi?anagram=" . $string . "&t=1000&a=n");
my $start    = index($document, "Anagrams for: $string</h3>");
my $end      = index($document, '<bottomlinks>');
my $relevant = substr($document, $start, ($end - $start));
$relevant    =~ s/<.*>//g;
print $relevant;

, , ,

Leave a comment

aliases-request.pl

A short Perl script I wrote that responds to e-mails with the excerpts of /etc/aliases relevant to the domain to which the request was addressed.

#!/usr/bin/perl
use strict;
use warnings;

# aliases-request.pl
# Returns the relevant parts of /etc/aliases (or specified file)
# Delimited by the requested domain
# ##aliases-request@<domain>
# ##aliases-end@<domain>
#

use constant ALIASES => "/etc/aliases";

# save and parse message
local $/ = undef;    # clear line-ending string
my $msg      = <>;                    # slurp in message
my $domain   = "";
my $dumpfile = "/var/tmp/dumpfile";
open( DUMPFILE, ">$dumpfile" ) or die $!;

# slurp in aliases
open( FILE, ALIASES ) or die $!;
my $aliases = <FILE>;
close FILE;

# reset line-ending string
local $/ = '\n';

for ( split /^/, $msg ) {

    # extract To: domain
    if ( $_ =~ m/^To:.*@(.*)(?:\s|$)/ ) {
        $domain = $1;
        print DUMPFILE "To: Matched " . length(@-) . " items.\n";
        print DUMPFILE "\$domain = $domain\n";
    }

    if ( $_ =~ m/^From:\s+(.*)$/ ) {
        print DUMPFILE "From: Matched " . length(@-) . " items.\n";
        $return_address = $1;
        print DUMPFILE "\$return_address = $return_address\n";
    }

    if ( $_ =~ m/^Reply-to:\s+(.*)$/ ) {
        print DUMPFILE "Reply-to: Matched " . length(@-) . " items.\n";
        $return_address = $1;
        print DUMPFILE "\$return_address = $return_address\n";
    }

    if ( $_ =~ m/^Subject:\s+(.*)$/ ) {
        print DUMPFILE "Subject: Matched " . length(@-) . " items.\n";
        $subject = $1;
        print DUMPFILE "\$subject = $subject\n";
    }
}

# find delimiters and extract relevant chunk
my $delim_string   = "##aliases-request\@$domain";
my $delim_end      = "##aliases-end\@$domain";
my $start_index    = ( index $aliases, $delim_string ) + length($delim_string);
my $end_index      = index $aliases, $delim_end;
my $offset         = $end_index - $start_index;
my $relevant_chunk = substr $aliases, $start_index, $offset;

# create return mail
my $return_address = "";
my $subject        = "";
my $sendmail       = "/usr/sbin/sendmail -t";
my $reply_to = "Reply-to: mailer-daemon\@kitesfear.lakemasoniccenter.org\n";
$subject = "Subject: RE: $subject\n";
my $from = "From: " . "mailer-daemon\@kitesfear.lakemasoniccenter.org\n";
my $to   = "To: " . "$return_address\n";

print DUMPFILE $reply_to;
print DUMPFILE $subject;
print DUMPFILE $from;
print DUMPFILE $to;
print DUMPFILE "Content-type: text/plain\n\n";    # Don't forget extra \n!
print DUMPFILE "$relevant_chunk\n\n.\n";
close(DUMPFILE);

open( SENDMAIL, "|$sendmail" ) or die $!;
print SENDMAIL $reply_to;
print SENDMAIL $subject;
print SENDMAIL $from;
print SENDMAIL $to;
print SENDMAIL "Content-type: text/plain\n\n";    # Don't forget extra \n!
print SENDMAIL "$relevant_chunk\n\n.\n";
close(SENDMAIL);

Leave a comment

Play-by-post gaming setup

Fast Requirements:

  • Grid or octagon overlay of custom image to display character positions
  • LoS and rage calculations
  • Real time OR delayed response posting
  • Round timing
  • GM-fudgable die rolls

3 Comments

Daily Archive Script

#!/usr/bin/ksh
cd ~/Pictures
for dir in `find ./ -maxdepth 1 -type d -mtime 7`
do
	tar cvjpf "${dir}.tar.bz2" "${dir}"
	rm -rf "${dir}"
done
		
ftp -v -n "ftp.lakemasoniccenter.org" <<EOF
user "user" "password"
cd /var/ftp/incoming/media/archive
lcd /home/user/Pictures
mput *.tar.bz2
quit
EOF

rm -rf *.tar.bz2

Leave a comment

Disk Space Monitor

I used to have a script copied from UNIX Hints and Hacks for monitoring disk space but that one didn’t work on my box so I deleted it.  I finally got around to finding a better one.  It was originally copied from ‘NixCraft but I modified it heavily so it’s a bit more user friendly and doesn’t break on long device names:

    #!/bin/sh
    # Shell script to monitor or watch the disk space
    # It will send an email to $ADMIN, if the (free avilable) percentage
    # of space is >= 90%
    # -------------------------------------------------------------------------
    # Copyright (c) 2005 nixCraft project <http://cyberciti.biz/fb/>
    # This script is licensed under GNU GPL version 2.0 or above
    # -------------------------------------------------------------------------
    # This script is part of nixCraft shell script collection (NSSC)
    # Visit http://bash.cyberciti.biz/ for more information.
    # ----------------------------------------------------------------------
    # Linux shell script to watch disk space (should work on other UNIX oses )
    # SEE URL: http://www.cyberciti.biz/tips/shell-script-to-watch-the-disk-space.html
    # set admin email so that you can get email
    ADMIN="operator@lakemasoniccenter.org"
    # set alert level 90% is default
    ALERT=90
    df -PH | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 " " $6 }' | while read output;
    do
            #echo $output
            usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
            partition=$(echo $output | awk '{ print $2 " mounted on " $3}' )
            if [ $usep -ge $ALERT ]; then
                    echo "Running out of space \"$partition ($usep%)\" on $(hostname) as on $(date)" |
                    mail -s "Alert: Almost out of disk space $partition" $ADMIN
            fi
    done

Leave a comment

Priorities II

Part of the reason I’ve been confused about what lenses to be looking at for my Rebel T3 is that most fora assume you’re shooting a full-frame sensor like a 1D or 5D.  Standard focal lengths for a crop sensor body are different than standard focal lengths for a full-frame body.  Because of this there are different best-use lenses at each level.  Using this new information and reviews specifically for crop sensor bodies, I’ve put together a good list for my Rebel T3 or a possible future Rebel T2i:

Strategy:  Save money by buying slow but clear zooms.  Use primes when fast lenses are needed.

Ultra-Wide Zoom (optional):  EF-S 10-22mm f/3.5-4.5 USM ($859.99)
Standard Zoom (primary):  EF-S 17-55mm f/2.8 USM ($1179.99)
Telephoto Zoom (secondary):  EF 70-200mm f/4L USM ($709.99)

Standard Telephoto (primary):  EF 50mm f/1.4 USM ($399.99)
Medium Telephoto (secondary):  EF 85mm f/1.8 USM ($419.99)
Macro and Telephoto (optional):  EF 100mm f/2.8 Macro USM ($599.99)

If I were going to build an entirely new collection from scratch, my priorities would be as follows: Standard Zoom, Standard Telephoto, Telephoto Zoom. But since I already have some lenses, my priorities are instead Standard Telephoto, Medium Telephoto, Standard Zoom, Telephoto Zoom (The only one I currently have isn’t very good).

3 Comments

How To Read Canon Lens Labels

This is a work in progress.

Canon Lens Naming

Canon Lens Naming

1 Comment

Photo Forum-style gear list

Folks in photography fora list their gear rather specifically.  Here’s my formatted list:

Canon EOS Rebel T3|EF-S 18-55mm 1:3.5-5.6 IS II|FD 50mm 1:1.4|FD 135mm 1:2.8|Vivitar 75-205mm 1:3.8 Macro Focusing Zoom

Leave a comment