
So here I was, all set to start getting all of my notes into one place on bash scripting, when I came across an obscure note in my pile of paper. Something I had actually scribbled in there some time ago, but either a) forgot I wrote it there, and as such never referenced it, or b) glanced down at the note and couldn't immediately make out what it said. See, some of my note taking occurs at 3AM, or thereabouts, under the influence of a tremendous amount of coffee and tea, making my notes a bit un readable by most humans in this particular plane of existance.
The original note said: LDP - bash programming howto.
This was crossed out in green crayon, and written directly below was: LDP - ABS.
Intuitive.
LDP - bash programming howto: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html
LDP - ABS (Advanced Bash Scripting) : http://tldp.org/LDP/abs/html/index.html
The latter actually has everything that is in my notes, with the exception of my notes pertaining to whatever problem I was attempting to solve at the time, and the examples in teh ABS are generic, and thus "More gooderer"(tm) than my notes.
Why did I bother writing all this drivel if my intent was to merely point the reader to those two resources? Only so I could use the term "Giant Monkey Robot Ninja Pirate Viking" in a sentence. And also, so there was a place for me to go look in the event I ever need to find these resources again.
Saturday, July 4, 2009
Bash Scripting
Posted by
Rick
at
9:23 AM
0
comments
Thursday, January 15, 2009
Update to "The Best Hotdogs on Planet Earth"
The original blog post here: http://lifeoncastro.blogspot.com/2008/01/best-hot-dogs-on-planet-earth.html
So, a couple of folks wanted to know exactly where it was - my childhood hot dog stand, the ultimate in what makes a dog a dog.. hot dog mecca.
View Larger Map
There it is - in all of it's glory. If you have business in Newark, or live in the tri-state area (really, it's that worth it!) go. For the sake of your soul, go.
Plus - you can pick up an "Eat Me" t-shirt while you are there. Oh.. and you should also fedex me a dozen or so of those bad boys.
Posted by
Rick
at
7:54 AM
0
comments
Friday, January 9, 2009
Linux Interview - Just when you thought you knew it all.

I have recently found myself in a search for the perfect job. What might that be? Well, I would say a job where I get to operate 200 foot tall giant robots in some cool inter-galactic robo-monkey-gladiator-swordfight type sport. I'm reasonably sure that I won't be running into one of those anytime soon. So, failing that, I think the perfect job is a Linux Systems Administration gig, working for a company that is doing something really cool, really needed, and really open. I would want to be surrounded by a group of people who are there for the same reason I am: make those systems run at peak performance, find new ways of achieving those goals, and scaling them out as needed. I need the people around me to have ideas to share, and be happy to hear mine.
Well, that's enough of the "What I want in a perfect world". The meat of this article is really to list out some of the most common questions I have been asked along this journey (which I am still on as of this writing). There are things we, as Linux Administrators, do every day. Using ls, ps, df, du, who, w, last, top, vmstat, cat, blah blah blah... but there are things that we know, we just get caught offguard having to describe them to people who ask. Hopefully this list will help you along with your search.
Warning: If you do not know a certain level of Linux, Unix, BSD, or shell scripting, this is not a cheatsheet for you. I make a lot of assumptions here, and hope that you will go off and research how to write scripts on your own.
Standard questions/exercises:
- What is an inode? An inode is a data structure holding information about filesin a file system. There is an inode for each file, and a file is uniquely identified by the file system on which it resides and its inode number on that system.
- Write a script that does "X". Using the shell you are most familiar with will help you here. We all execute oneliners every day, several times a day. Simply string those commands together in a most unelegant manner - it should not matter to the interviewer; obviously you know what you are doing. Example - a script that counts up to 10 without using count:
ten=0
while [ $ten -le 10 ]
do
echo $ten
ten=$((ten+1))
done
- What tool would you use to detect the OS of a remote machine, and what is the command line to do it? Tricky. Could use rsh in an insecure environment and do: rsh -l username hostname "uname -r" ... or, the equivelent in ssh, assuming ssh keys are in place; ssh hostname uname -r ... or, and this would be my first try - install nmap and do a sudo nmap -O -v hostname
- Show the failed attempts to login via ssh. It's dirty, but it's a first pass that gives an indication of who tried to pop the top off your box: sudo grep Failed /var/log/messages
- What system call signals are available in linux? If you can memorize and ramble off 64 available signals, and their names.. maybe you should get out more. I rely on "man kill" and "kill -l" (thats a lowercase "L", not a ONE)
- How do I find what network connections are active, and what program is using them? netstat -ap -or- netstat -anp (if there is a problem with name resolution, the "n" will use the ip rather than perform a hostname lookup)
- What are setuid/setgid in relation to file permissions? Yikes. I love the short questions with the long answers. Don't stumble, mutter, or ramble here - it's easy to do. setuid on an executable file allows a user to run that program with the permissions of the owner of the file rather than the person who executed it. setguid is the same thing; only with the permission of the group the file is a member of.
- What is init? Init is the program that runs after the kernel loads that spawns all other processes. It runs as PID 1, and on RH, CentOS, Fedora, looks to the rc#.d/* files for stuff to launch. The # is the current runlevel, and the * is anything executable that is in there - either symlinked by hand or using something like chkconfig --level ##### PROGRAM on/off
- What are the standard runlevels? This is totally tricky, there's only 3 runlevels that are the same across all UNIXs/Linux's/BSD's - 0(Halt), 1(Single user), and 6(Reboot). Typical of the newish modified systems (Redhat and its derivitives), standard runlevels 3 (no X), and 5 (X) are default - set in inittab.
Posted by
Rick
at
7:18 AM
0
comments
Friday, December 12, 2008
Trapping in bash
Scenario: You are running a code deployment to a small server farm of maybe 10-15 servers. Too small for something like tentakal, but too big to just ssh and deploy, logout, wash - rinse - repeat.
So you write a simple while; do loop and roll your stuff out that way.
The problem comes up when you realize that the deployment is hanging on a particular function, and you want to exit from that session, but want to continue your deployment on the rest of the machines - or whatever...
Enter my friend "trap".
Trap can pick up a variety of signals, and act on those in whatever way you wish.
Example: You want to stop someone from hitting ^C:
#!/bin/bash
trap "echo 'tsk tsk - no ^cing!'" 2
while true; do
echo "I dare you to press ^C"
echo ""
sleep 15
done
So - this will wait for the signal 2 (INTerrupt), and print tsk tsk - no ^cing! to the screen everytime you hit ^C.
Now, how do you stick this into a script so that it will execute that portion until it gets a ^C?
#!/bin/bash
# some code.. do what you want here...
#Trap code:
# First trap - if ctl-c is hit, it will go to the next function:
while [ trap -ne 2 ] ; do
# your commandline/script code here
done
# The next function:
while [ trap -ne 2 ] ; do
# your commandline/script code here
done
...and so on...
Posted by
Rick
at
3:57 PM
0
comments
Thursday, December 4, 2008
PCLinuxOS on the Dell Inspiron 1526
The Dell Inspiron 1526 was too inexpensive for the power to pass up.. but I did not want to run Windows on it, and I didn't want to run Ubuntu (nothing against it, just not my cup of tea). I also didn't want to force my favorite linux (Slackware) to work on it, since this was to be used for everyday work.
PCLinuxOS seemed to offer exactly what I wanted.
I installed it and it just worked. That is, except the wireless. If there was anything that I would have be an issue, it is the wireless - since there are so many ways to hack that to work.
Step-by-Step (as root, to avoid having to sudo every time):
1) echo -e 'blacklist bcm43xx\nblacklist wl' | sudo tee -a /etc/modprobe.d/blacklist
2) wget ftp://ftp.us.dell.com/network/R174291.exe
3) mkdir bcm-drivers
4) cd bcm-drivers
5) unzip ../R174291.exe
6) ndiswrapper -i bcmwl5.inf
7) depmod -a
8) modprobe ndiswrapper
9) echo 'ndiswrapper' | sudo tee -a /etc/module
10) Click Control Center -> Network -> Set up a new network interface -> Wireless
11) Follow the prompts, and use the Broadcom driver that now shows up (or should)
12) You should be taken through the process of configuring the wireless network.
13) In your terminal window, as root, type: ndiswrapper -ma
14) in your terminal window, open /etc/rc.d/rc.local and add:
depmod -a
modprobe ndiswrapper
ndiswrapper -ma
15) All done. Now when you reboot, your wireless interface will be there.
Posted by
Rick
at
2:50 PM
0
comments
Labels: inspiron 1526, linux, pclinuxos, wireless
Monday, June 2, 2008
Five favorite tools
Everyone has their lists. Here's my list of "top 5 tools every linux admin needs to know intimately":
5) screen ( http://www.gnu.org/software/screen/ ) I love the ability to log in to a box, work a bit, detach my screen, go home, re-attach to the screen, and it's like I never left the session (technically, I didn't)
4) lsof ( http://people.freebsd.org/~abe/ ) - gives info about all open files. This is one of the standard troubleshooting tools for finding network issues, "why cant I rm that file?", and a host of other annoyances.
4) strace ( http://sourceforge.net/projects/strace/ ) - need to find out why a running process is hanging? strace -p [PID] that bad boy. Like lsof, I cannot live without this.
3) splitvt ( http://www.devolution.com/~slouken/projects/splitvt/ ) - I am always needing to compare two files side by side, and sometimes I just don't want to go through the series of logins to get to a specific machine to do it. SplitVT will give you multiple usable windows to work in inside of a single VT. Very cool.
2) awk ( http://www.gnu.org/manual/gawk/ ) - when im in a situation where I want to grab specific data from something, this is my best friend. Like when I need to grab the MAC address of my eth0 device: /sbin/ifconfig eth0 | grep HWadd | awk '{ print $5 }'
and finally - Rick's number one.. the single most oft used utility I have.. and the one that is going to get me branded as being on "THAT SIDE" -
1) vim ( http://www.vim.org/ ) - vi .. improved.. :) it's a tool; it's my preferred tool for editing nearly anything (except this blog, cause the web interface is also a tool - and handy) I can't expand on this any further.. either you use it or you don't..
:wq
Posted by
Rick
at
3:11 PM
0
comments
Saturday, May 17, 2008
Locking down a RedHat based box
It has been a long time since I wrote anything here - I've been extremely busy. We're doing some pretty darn cool stuff at work technology-wise, which keeps me excited (it helps when a fellas boss is a tech junkie, and like to see your ideas and then add to em..). So, yesterday I had to harden a box for an undisclosed purpose, and it made me think "Hey! I can stick this on the blog!"
This should work with any RPM based (redhat, fedora, centos, whitebox, etc) Linux distro.
Here's a not so brief overview: First, we need the local (non-root) account created, make sure we're booting to runlevel 3, drop the number of tty's to 2, lock the filesystem, remove unimportant services, fixup (not in that special IOS way, but in the southern phrase way) a few of the etc/* files, lock down some not-so-secure services, make ssh a little more secure, removing a metric good lot of un-used RPM's, locking down the services we do use, perform a little tcp hardening, some IPTables Rules.. eh.. a lot of stuff.
UPDATE: 06/02/2008: ... I wrote that about 2 weeks ago - since then, I've whipped this up: http://freshmeat.net/projects/lockdown/
It needs some outside eyes, a little TLC, and some good ol' community contribution to be worthy...
Posted by
Rick
at
7:33 AM
0
comments
Wednesday, February 6, 2008
In the midst of Tornadoes and Super Tuesday.. the Cat Rules.

It's good to have things in perspective. All applaud Surfing Cat.
We have tornadoes, we have the primaries, we have death and destruction, global warming, and new technology. What rates top 3 news stories for CNN?
I have no idea why this is so funny to me. It just is.
The linkie to the surfing cat is here (with commercial - yay!)
Posted by
Rick
at
9:00 AM
1 comments
Friday, January 25, 2008
Monday, January 21, 2008
Postgres Replication: Elvis is not dead.
Much like the cat, there has been some speculation on the death of the king. He is alive and well in the Postgres SQL Replication mechanism called ELVIS.
https://sourceforge.net/projects/bruce/
Keep an eye on this, the code will be uploaded, the binaries made available, and "it will be a good thing."(tm)
Posted by
Rick
at
7:46 AM
0
comments
Thursday, January 17, 2008
Tuesday, January 15, 2008
A.M.I.S. Source code.
Seriously, I don't know why I'm posting this; but I think it is awesome to see how we had to juggle stuff in the 80's to make something like this. This is the source code for the AMIS BBS written for the atari 8-bit line of computers. I ran mine on an Atari 800. The code for my BBS was heavily modified to do things like not crash (woot!), use 4 character passwords and have a real users database, it had 26 message bases, and 10 file areas. All this ran from a pair of 126K (Yes, K.. as in KILO byte) floppy disks.
---------------BEGIN CODE--------------------
5 GOTO 29000:REM AMIS.BBS 07-01-83 FLAGCITY VERSION #2.2
8 STATUS #MODEM,X:IF PEEK(749)>C0 THEN GOTO C8
9 IF PEEK(INK)=C255 THEN IF NOT PEEK(INM) OR LOCAL THEN RETURN
10 GOSUB GETCHR:IF X<>19 THEN RETURN
12 GOSUB GETCHR:RETURN
20 TOUT=C0:IF LOCAL THEN GET #C3,X:RETURN
25 STATUS #MODEM,X:IF PEEK(INM) THEN GET #MODEM,X:? CHR$(X);:RETURN
30 IF PEEK(INK)1000 THEN GOSUB OPM
50 GOTO 25
70 L$="":IF PEEK(CON)=C5 THEN POP :GOTO 13000:REM GLINE
80 GOSUB GETCHR:X$=CHR$(X)
90 IF ((X$=BS$) OR (X$=CHR$(C127) AND AMODE=C0)) AND L$<>"" THEN ? #MODEM;BS$;" ";BS$;:L$(LEN(L$))="":GOTO 80
100 IF X$=DEL$ AND L$<>"" THEN FOR X=C1 TO LEN(L$):? #MODEM;BS$;" ";BS$;:NEXT X:L$="":GOTO 80
110 IF X$=CR$ THEN ? #MODEM:RETURN
120 ? #MODEM;X$;:L$(LEN(L$)+C1)=X$:IF LEN(L$)=L THEN ? #MODEM;BUFFER$(F,L);:RETURN
210 ? #MODEM;BUFFER$(F,T);:F=F+C8:GOSUB C8:IF X=C24 OR X=152 THEN ? #MODEM;CR$;"+++ Interrupted +++";CR$:RETURN
220 GOTO 200
250 TRAP ERR:IF PEEK(864)=C255 OR LOCAL THEN RETURN
260 STATUS #MODEM,X:IF PEEK(749)>C0 THEN 260
270 X=C1^C1:CLOSE #MODEM:RETURN
300 POKE 77,C0:GOSUB CLM:IF LOCAL THEN RETURN :REM OPM
310 OPEN #MODEM,13,0,"R:":XIO C36,#MODEM,C0,C1,"R:":XIO C34,#MODEM,240,C0,"R:":XIO C38,#MODEM,AMODE+LMODE,C0,"R:"
320 TOUT=C0:STATUS #MODEM,X:IF PEEK(747)";:GOSUB GETCHR:IF X>96 THEN X=X-C32
360 IF X=89 OR X=C121 THEN X=C1:? #MODEM;"Yes":RETURN
370 IF X=78 OR X=110 THEN X=C0:? #MODEM;"No":RETURN
380 GOSUB OPM:GOTO YN
900 GOSUB RFILE
910 GOSUB SEND
920 IF X=24 OR X=152 THEN CAP=C0:GOTO 950
930 IF CAP THEN CAP=C0:GOSUB GETCHR
950 ? #MODEM
1000 TRAP ERR:GOSUB OPM:? #MODEM;CR$;PROMPT$;:IF NOT LOCAL THEN ? :? PROMPT$;
1010 IL=C40:GOSUB GETCHR:L$=CHR$(X):? #MODEM;L$;CR$:? :IF X=33 THEN ? #MODEM;">";:? ">":GOSUB GLINE:GOTO MAIN
1020 IL=C40:IF X=13 OR X=155 THEN 9810
1030 IF X>95 THEN X=X-C32
1040 X=X-C64:IF X<11 x="X-C10:IF" x="X-C10:IF" x="C10" xmode=" NOT">":GOTO MAIN
1510 ? #MODEM;"NORMAL USER MODE":GOSUB 1520:GOTO MAIN
1520 PROMPT$="A,B,C,D,F,G,H,I,L,M,N,O,P,T,U,W,X,Y"
1530 PROMPT$(LEN(PROMPT$)+C1)=CR$:PROMPT$(LEN(PROMPT$)+C1)="or":RETURN
1900 GOSUB 2000:X=TIMEON:GOSUB 2100:REM T
1910 ? #MODEM;CR$;" On at ";TIME$;:X=ABS(A-TIMEON):GOSUB 2100:? #MODEM;" ";TIME$;" On Sys.":GOTO MAIN
2000 GOSUB TIME:? #MODEM;DAY$;" ";TODAY$;" ";TIME$;" CST":RETURN
2010 T=PEEK(20):X=((PEEK(18)*256+PEEK(19))*256+PEEK(20)):IF T>PEEK(20) THEN 2010
2020 IF X<5184000 x="X-5177000:F="INT(X/65536):X="X-(F*65536):T="INT(X/256):X="X-(T*256):POKE" dow="DOW+C1:IF">7 THEN DOW=C1
2050 IF TODAY$(5,5)>"9" THEN TODAY$(5,5)="0":TODAY$(4,4)=CHR$(ASC(TODAY$(4))+C1)
2060 LI=VAL(TODAY$)*2:IF TODAY$(4,5)<=MTH$(LI-C1,LI) THEN 2010 2070 IF TODAY$(4,5)="29" AND VAL(TODAY$(7))/4=INT(VAL(TODAY$(7))/4) THEN 2010 2080 TODAY$(4,5)="01":TODAY$(2,2)=CHR$(ASC(TODAY$(2))+C1):GOTO 2010 2090 X=X/60:A=X:DAY$=DAYS$(DOW*9-8,DOW*9) 2100 T=X:X=INT(T/3600):F=INT(T/60)-X*60:T=T-X*3600-F*60 2110 TIME$=STR$(X+100):TIME$=TIME$(2,3) 2120 TIME$(3,5)=STR$(F+100):TIME$(6,8)=STR$(T+100) 2130 TIME$(3,3)=":":TIME$(6,6)=":":RETURN 3600 ? #MODEM;CALLNO;" Callers.":GOSUB CLM:CLOSE #FILE:OPEN #FILE,C4,C0,CDF$:NOTE #FILE,A,I:REM C 3605 POINT #FILE,CSECT,CBYTE:INPUT #FILE,PAS$:TRAP 3606:GOTO 3607 3606 POINT #FILE,A,I 3607 INPUT #FILE,PAS$:IF PAS$<>"+" THEN 3607
3608 INPUT #FILE,TEMP$,A$,DATE$,TIME$
3610 GOSUB OPM:? #MODEM;"First Date:";DATE$;"-Last Date:";TODAY$;CR$;"ENTER Starting Date";
3612 GOSUB GLINE:IF LEN(L$)<>8 THEN GOTO MAIN
3616 IF L$(C3,C3)<>"/" OR L$(C6,C6)<>"/" THEN 3610
3617 IF L$>=DATE$ AND L$<=TODAY$ THEN 3619 3618 GOTO 3610 3619 ? #MODEM;"SEARCHING CALLERS...":IF XMODE THEN ? #MODEM 3620 IF L$<>DATE$ THEN GOSUB 3680:GOTO 3620
3622 IF NOT XMODE THEN GOSUB OPM:? #MODEM;CTRL$:? #MODEM
3625 GOSUB OPM
3630 ? #MODEM;"CALLER: ";TEMP$;CR$;"FROM: ";A$;CR$;"AT: ";TIME$;" ON: ";DATE$;CR$
3640 GOSUB C8:IF X=C24 THEN GOTO MAIN
3650 GOSUB 3680:GOTO 3625
3670 POINT #FILE,A,I
3680 GOSUB CLM:TRAP 3670:INPUT #FILE,PAS$,TEMP$,A$,DATE$,TIME$:TRAP ERR:IF PAS$<>"*" THEN RETURN
3690 POP :CLOSE #FILE:GOSUB OPM:GOTO 950
5000 GOSUB 5100:L=X:GOSUB CLM:CLOSE #FILE:TRAP 5800:OPEN #FILE,C4,C0,FILE$:CLOSE #FILE
5010 TRAP ERR:GOSUB TIME:IF L THEN 6000
5020 LPRINT "DL ";FILE$;" ";TIME$
5030 GOSUB 5900:GOSUB OPM:? #MODEM;"FILE: ";FILE$:CAP=C1:GOSUB SEND
5040 IF BFLAG OR X=C24 OR X=152 THEN 920
5050 GOSUB CLM:BUFFER$="":GOSUB 5920:GOSUB OPM:GOSUB 170:GOTO 5040
5100 FILE$="D2:":? #MODEM;"RETURN=Exit, File Name >";:IF LEN(L$)>1 THEN IF L$(2,2)="1" THEN FILE$(2,2)="2"
5110 GOSUB GLINE:IF L$="" THEN POP :GOTO MAIN
5120 IF LEN(L$)>C8 THEN L$(9)=""
5130 FOR X=C1 TO LEN(L$):IF L$(X,X)>"Z" THEN L$(X,X)=CHR$(ASC(L$(X,X))-C32)
5140 IF L$(X,X)>="A" AND L$(X,X)<="Z" THEN FILE$(LEN(FILE$)+C1)=L$(X,X) 5150 IF L$(X,X)>="0" AND L$(X,X)<="9" THEN FILE$(LEN(FILE$)+C1)=L$(X,X) 5160 NEXT X:FILE$(LEN(FILE$)+C1)=".UDL":IF FILE$(C4,C4)<"A" THEN POP :GOTO MAIN 5170 IF LEN(FILE$)<>" F" THEN 5220
5230 BUFFER$(LEN(BUFFER$)+C1)=CR$:CLOSE #FILE:GOSUB OPM:? #MODEM;BUFFER$:GOSUB 5100:L=X
5240 GOSUB CLM:GOSUB TIME:CLOSE #FILE:FILE$(2,2)="2":IF L THEN LPRINT "XUP ";FILE$;" ";TIME$:GOTO 5260
5250 LPRINT "UP ";FILE$;" ";TIME$
5260 TRAP 5290:OPEN #FILE,C4,C0,FILE$:TRAP ERR
5270 CLOSE #FILE:GOSUB OPM:? #MODEM;CR$;BEL$;"FILE ALREADY EXISTS!!!"
5280 GOTO MAIN
5290 CLOSE #FILE:GOSUB OPM:TRAP ERR:BUFFER$="":IF L THEN 6500
5300 GOSUB CLM:OPEN #FILE,C8,C0,FILE$:GOSUB OPM
5310 ? #MODEM;"Upload --- Enter file=Exit "
5320 ? #MODEM;">";:IL=C120:GOSUB GLINE
5330 IF L$="" THEN GOSUB CLM:CLOSE #FILE:GOTO MAIN
5340 GOSUB CLM:? #FILE;L$:GOSUB OPM:GOTO 5320
5400 GOSUB CLM:CLOSE #FILE:FILE$="D2:*.UDL":IF LEN(L$)>C1 THEN IF L$(2,2)="1" THEN FILE$(2,2)="2"
5410 OPEN #FILE,C6,C0,FILE$:BUFFER$="":TEMP$="FILE DIRECTORY---":GOTO 5440
5420 INPUT #FILE,TEMP$:IF TEMP$(C4,C5)=" F" THEN 5470
5430 TEMP$(11,C13)=" -"
5440 BUFFER$(LEN(BUFFER$)+C1)=TEMP$
5450 BUFFER$(LEN(BUFFER$)+C1)=CR$
5460 GOTO 5420
5470 BUFFER$(LEN(BUFFER$)+C1)=CR$
5471 BUFFER$(LEN(BUFFER$)+C1)="* = BINARY FILE"
5472 BUFFER$(LEN(BUFFER$)+C1)=CR$
5475 BUFFER$(LEN(BUFFER$)+C1)=CR$
5480 CLOSE #FILE:GOSUB OPM:GOSUB SEND:GOTO MAIN
5800 TRAP ERR:GOSUB OPM:? #MODEM
5810 ? #MODEM;"Can't find that file"
5820 GOTO MAIN
5900 GOSUB CLM:CLOSE #FILE:OPEN #FILE,C4,C0,FILE$:REM INF. BUFF
5910 POKE 195,C0:A$(C255)=" ":BUFFER$=""
5920 TRAP 5930:FOR I=C1 TO C4:XIO 7,#FILE,C4,C0,A$:BUFFER$(LEN(BUFFER$)+C1)=A$:NEXT I:BFLAG=C0:RETURN
5930 IF PEEK(856) THEN BUFFER$(LEN(BUFFER$)+C1)=A$(C1,PEEK(856))
5940 BFLAG=PEEK(C195):RETURN
5950 T=LEN(BUFFER$):F=((T/C128)-INT(T/C128))*C128
5960 FOR I=F+1 TO C128:BUFFER$(LEN(BUFFER$)+1)=CHR$(F):NEXT I
5970 RETURN
6000 CLOSE #FILE
6010 LPRINT "XDL ";FILE$;" ";TIME$
6020 GOSUB 5900:IF BFLAG THEN GOSUB 5950
6030 GOSUB OPM:? #MODEM;"FILE: ";FILE$;" Ready to Send":? #MODEM;"^X to cancel"
6040 BLOCK=C1:GOSUB GETCHR:IF X<>21 THEN GOTO MAIN
6050 AM=AMODE:LM=LMODE:AMODE=C32:LMODE=C0:GOSUB OPM
6060 DIR=C0
6070 FOR T=C1 TO C10:PUT #MODEM,C1:PUT #MODEM,BLOCK:PUT #MODEM,C255-BLOCK:F=C0
6080 A=DIR*C128+ADR(BUFFER$)
6090 FOR I=C0 TO C127:X=PEEK(A+I):PUT #MODEM,X:F=F+X:NEXT I
6100 F=ASC(CHR$(F)):PUT #MODEM,F:GOSUB GETCHR:IF X=21 THEN 6120
6110 T=C10
6120 NEXT T:DIR=DIR+C1:BLOCK=BLOCK+C1
6130 IF X<>6 THEN 6300
6140 F=(DIR+C1)*C128:T=LEN(BUFFER$):IF F<=T THEN 6070 6150 IF BFLAG THEN 6200 6160 IF F=T THEN BUFFER$="":GOTO 6180 6170 BUFFER$=BUFFER$(DIR*C128+C1,T) 6180 GOSUB CLM:GOSUB 5920:IF BFLAG THEN GOSUB 5950 6190 GOSUB OPM:GOTO 6060 6200 PUT #MODEM,C4:GOTO 6350 6300 ? #MODEM:? #MODEM;"* ABORTED *" 6350 DIR=C0:AMODE=AM:LMODE=LM:GOTO MAIN 6500 AM=AMODE:LM=LMODE:AMODE=C32:LMODE=C64:L=21:NSEC=C0 6510 TRAP 6700:A$(131)=" ":A=ADR(A$):GOSUB CLM:OPEN #FILE,C8,C0,FILE$ 6520 GOSUB OPM:? #MODEM;"FILE: ";FILE$;" Ready to Receive,":? #MODEM;"^X to Cancel" 6530 FOR T=C1 TO C10:TOUT=C0:? CHR$(L); 6540 STATUS #MODEM,X:IF PEEK(INM) THEN GET #MODEM,X:GOTO 6540 6550 PUT #MODEM,L:L=6:GET #MODEM,SOH:F=SOH:IF SOH<>C1 THEN 6620
6560 FOR I=C0 TO 130
6570 STATUS #MODEM,X:IF PEEK(INM) THEN GET #MODEM,X:POKE A+I,X:F=F+X:NEXT I:GOTO 6600
6580 TOUT=TOUT+C1:IF TOUT<100 f="F-X:F="ASC(CHR$(F)):IF" x="F" nsec="NSEC+C1:GOTO" l="C1" l="21:TRAP" t="C10" soh="C1" l="6" 6640="" nsec="NUMSECT" 6530="" 6650="" soh="C4" and="" l="C6" 6700="" aborted="" 6710="" 6800="" put="" saving="" file="" 6810="" trap="" gosub="" then="" close="" goto="" 6890="" 6820="" x="ASC(X$)" 6830="" for="" i="LEN(BUFFER$)-C127+X" to="" if=""><>X$ THEN X=C128
6840 NEXT I
6860 ? #FILE;BUFFER$(C1,LEN(BUFFER$)-C128+X);:CLOSE #FILE
6890 I=C1:T=C1:AMODE=AM:LMODE=LM:GOTO MAIN
7000 MSGNO$="0000":MSGNO$(5-LEN(STR$(FROM)))=STR$(FROM):REM SEARCH
7020 T=INT(LEN(BUFFER$)/C40):F=INT(T*0.5+0.5):Y=F
7040 FOR X=C1 TO CLOG(T+2)/CLOG(2)
7060 TSS=F*C40:Y=INT(Y*0.5+0.5)
7070 IF MSGNO$>BUFFER$(TSS-C39,TSS-C36) THEN F=F+Y+Y
7080 F=F-Y:IF FT THEN F=T
7120 NEXT X:TSS=F*C40
7130 IF MSGNO$>BUFFER$(TSS-C39,TSS-C36) AND DIR=C1 THEN F=F+C1
7140 IF MSGNO$LEN(L$) THEN 7300
7230 IF L$(X,X)>="0" AND L$(X,X)<="9" THEN FROM=FROM*C10+VAL(L$(X,X)):GOTO 7220 7240 IF L$(X,X)<>"-" THEN 7300
7250 X=X+C1:IF X>LEN(L$) THEN 7310
7260 IF L$(X,X)>="0" AND L$(X,X)<="9" THEN TU=TU*C10+VAL(L$(X,X)):GOTO 7250 7270 GOTO 7310 7300 TU=FROM:DIR=C1:GOTO 7320 7310 DIR=C1:IF TU";
7550 ? #MODEM;"(Q)uick scan, (R)etrieve, (S)ummary";CR$;"?>";:L$=" ":GOSUB GETCHR:L$=CHR$(X):IF X>90 THEN X=X-C32
7555 ? #MODEM;L$;CR$
7560 MC=X:IF MC=69 THEN 9000
7570 IF MC=77 THEN GOTO MAIN
7580 IF MC=75 OR MC=81 OR MC=82 OR MC=83 THEN 7610
7590 GOTO 7510
7610 ? #MODEM;"First Msg ";F;" - Last Msg ";T
7620 ? #MODEM;"Enter Msg# (From-To)>";:GOSUB GLINE:? #MODEM:IF L$="" THEN GOTO 7510
7630 GOSUB 7200:IF DIR=C0 THEN 7620
7640 GOSUB 7000
7645 IF FLEN(BUFFER$) THEN 7630
7650 MSGNO$=BUFFER$(F*C40-C39):T=VAL(MSGNO$):IF DIR=C1 THEN IF TTU THEN 7630
7660 IF DIR=-C1 THEN IF TFROM THEN 7630
7670 IF MC=81 THEN ? #MODEM;T;". ";BUFFER$(F*C40-35,F*C40-C4):GOSUB C8:GOTO 7690
7680 GOSUB CLM:CLOSE #FILE:OPEN #FILE,C4,C0,MDF$:GOSUB 7700:IF MC=75 THEN 7900
7690 IF X=C24 THEN 7620
7695 F=F+DIR:GOTO 7645
7700 BYTE=ASC(BUFFER$(F*C40)):SECT=ASC(BUFFER$(F*C40-C2))*C256+ASC(BUFFER$(F*C40-C1))
7710 POINT #FILE,SECT,BYTE:INPUT #FILE,MSGNO$,SUBJ$,PAS$,DATE$,TIME$,FROM$,FR$,LI
7720 MSG$="MSG# ":MSG$(C6)=MSGNO$:MSG$(C10)=" DATE:":MSG$(16)=DATE$:MSG$(24)=" TIME:":MSG$(30)=TIME$:MSG$(38)=CR$
7730 MSG$(C39)="FROM: ":MSG$(45)=FROM$:MSG$(LEN(MSG$)+C1)=CR$:MSG$(LEN(MSG$)+C1)=" TO: ":MSG$(LEN(MSG$)+C1)=FR$
7740 MSG$(LEN(MSG$)+C1)=CR$:MSG$(LEN(MSG$)+C1)="SUBJ: ":MSG$(LEN(MSG$)+C1)=SUBJ$:MSG$(LEN(MSG$)+C1)=CR$
7750 IF MC=75 OR MC=83 THEN MSG$(LEN(MSG$)+C1)="=========":GOTO 7770
7760 FOR X=C1 TO LI:INPUT #FILE,TEMP$:MSG$(LEN(MSG$)+C1)=TEMP$:MSG$(LEN(MSG$)+C1)=CR$:NEXT X
7770 L=LEN(MSG$):GOSUB OPM:Y=C1:T=C0
7771 IF FR$="ALL" OR LOCAL THEN 7780
7773 IF FR$<>NAME$ AND FROM$<>NAME$ THEN ? #MODEM;" MESSAGE #";MSGNO$;" IS PRIVATE";CR$:RETURN
7780 T=T+C8:IF T>=L THEN ? #MODEM;MSG$(Y,L);:GOTO 7810
7790 ? #MODEM;MSG$(Y,T);:Y=Y+C8:GOSUB C8:IF X=C14 OR X=C24 OR X=152 THEN ? #MODEM;CR$:RETURN
7795 IF X=3 THEN ? #MODEM;CR$;CR$;"+++ Canceled +++";CR$;CR$:RETURN
7800 GOTO 7780
7810 ? #MODEM;" ":IF LOCAL THEN ? "PRINT":GET #C3,X:? :IF X=89 THEN LPRINT MSG$
7820 RETURN
7900 ? #MODEM;"ENTER Password >";
7910 GOSUB GLINE:IF LOCAL AND L$="KILL" THEN 7930
7920 IF L$<>PAS$ THEN ? #MODEM;"INVALID PASSWORD";BEL$:GOTO 7510
7930 IF F*C40+C1>LEN(BUFFER$) THEN BUFFER$(F*C40-C39)="":GOTO 7950
7940 BUFFER$(F*C40-C39)=BUFFER$(F*C40+C1)
7950 GOSUB CLM:CLOSE #FILE:OPEN #FILE,C8,C0,MIF$
7960 ? #FILE;BUFFER$:CLOSE #FILE:GOSUB 28100
7970 LPRINT "KILLED MSG ";MSGNO$:GOSUB OPM:? #MODEM;"MESSAGE DELETED":GOTO 7510
8000 GOSUB CLM:CLOSE #FILE:OPEN #FILE,C4,C0,FILE$:REM RFILE
8010 TRAP 8070:A$(C255)=" ":BUFFER$=""
8020 XIO 7,#FILE,C4,C0,A$:BUFFER$(LEN(BUFFER$)+C1)=A$:GOTO 8020
8070 TRAP ERR:IF PEEK(856) THEN BUFFER$(LEN(BUFFER$)+C1)=A$(C1,PEEK(856))
8080 IF PEEK(C195)<>136 AND PEEK(C195)<>139 THEN 8120
8085 TRAP ERR:IF PEEK(C195)=139 THEN POP :POP :POP :POP :POKE C195,C1:GOTO WAITRING
8100 GOTO OPM
8120 ERROR=PEEK(C195):GOSUB CLM:CLOSE #FILE
8130 LPRINT "Error- ";ERROR;" LINE # ";C256*PEEK(187)+PEEK(186)
8140 GOSUB OPM
8150 ? #MODEM;CR$;"SYSTEM ERROR --- TRY AGAIN."
8160 POP :POP :POP :GOTO MAIN
9000 FROM$=NAME$:? #MODEM;"Enter Message:":? #MODEM;"SUBJECT: ";:GOSUB GLINE:IF L$="" THEN GOTO 7510:REM ENTER
9010 SUBJ$=L$:? #MODEM;"TO:=All ";:GOSUB GLINE:IF L$="" THEN L$="ALL":? #MODEM;"TO: ";L$;CR$
9020 FR$=L$:? #MODEM;"Enter PASSWORD Required to Kill Msg:":GOSUB GLINE:PAS$=L$
9030 LI=C0:? #MODEM;"Enter Message, Twos when done"
9040 IL=C80:LI=LI+C1:IF LI>C16 THEN 9080
9050 IF LI>C13 THEN ? #MODEM;"Only ";17-LI;" Lines left"
9060 ? #MODEM;LI:GOSUB GLINE:IF L$="" THEN 9080
9070 MSG$(LI*C121-C120)=CHR$(LEN(L$)):MSG$(LI*C121-C119)=L$:GOTO 9040
9080 LI=LI-C1
9100 GOSUB OPM:? #MODEM;CR$;"(A)dd, (E)dit, (L)ist,";CR$;"(Q)uit, (R)ead, (S)ave ?";:GOSUB GETCHR
9105 IF X>96 THEN X=X-C32
9110 ? #MODEM;CHR$(X);CR$:IF X=65 THEN 9040
9120 IF X=69 THEN 9200
9130 IF X=76 OR X=82 THEN 9300
9140 IF X=81 THEN ? #MODEM;"MESSAGE ABORTED":GOTO 7510
9150 IF X=83 THEN 9400
9160 GOTO 9100
9200 IF NOT LI THEN 9100
9210 ? #MODEM;"EDIT WHICH LINE 1-";LI;" ?";:GOSUB GLINE:IF L$="" THEN 9100
9220 TRAP 9210:Z=INT(VAL(L$)):TRAP ERR
9230 IF ZLI THEN 9210
9240 ? #MODEM;"OLD LINE ";Z;" READS:";CR$:? #MODEM;Z;" ";MSG$(C121*Z-C119,C121*Z-C120+ASC(MSG$(Z*C121-C120)))
9250 ? #MODEM;"CHANGE TO:=NO CHANGE";CR$;Z;" ";:GOSUB GLINE
9260 IF L$<>"" THEN MSG$(Z*C121-C120,Z*C121-C120)=CHR$(LEN(L$)):MSG$(Z*C121-C119,Z*C121)=L$
9270 GOTO 9210
9300 MC=X:IF NOT LI THEN 9100
9310 FOR I=C1 TO LI:IF MC=76 THEN ? #MODEM;I;" ";
9320 ? #MODEM;MSG$(I*C121-C119,I*C121-C120+ASC(MSG$(I*C121-C120))):GOSUB C8:IF X=C24 THEN I=C24
9330 NEXT I:GOTO 9100
9400 IF NOT LI THEN 9100
9410 HMSG=HMSG+C1:MSGNO$="0000":MSGNO$(5-LEN(STR$(HMSG)))=STR$(HMSG):? #MODEM;"SAVING MESSAGE...."
9420 GOSUB CLM:GOSUB TIME:CLOSE #FILE:OPEN #FILE,12,C0,MDF$:NOTE #FILE,A,I:POINT #FILE,MSECT,MBYTE
9430 SECT=MSECT:BYTE=MBYTE
9440 ? #FILE;MSGNO$;CR$;SUBJ$;CR$;PAS$;CR$;TODAY$;CR$;TIME$;CR$;FROM$;CR$;FR$;CR$;LI
9450 FOR X=C1 TO LI:? #FILE;MSG$(X*C121-C119,X*C121-C120+ASC(MSG$(X*C121-C120))):NEXT X:NOTE #FILE,MSECT,MBYTE
9460 CLOSE #FILE:FILE$=MIF$:GOSUB RFILE:GOSUB CLM
9470 TEMP$=" ":TEMP$=MSGNO$:TEMP$(5)=SUBJ$
9480 T=INT(SECT/C256):SECT=SECT-T*C256
9490 TEMP$(C38)=CHR$(T):TEMP$(C39)=CHR$(SECT):TEMP$(C40)=CHR$(BYTE)
9500 BUFFER$(INT(LEN(BUFFER$)/C40)*C40+C1)=TEMP$:CLOSE #FILE
9510 OPEN #FILE,C8,C0,FILE$:? #FILE;BUFFER$;:CLOSE #FILE:GOSUB 28100
9512 IF FR$<>"ALL" THEN OPEN #FILE,C9,C0,"D:M":? #FILE;" ";FR$;"MSG#";MSGNO$:CLOSE #FILE
9520 LPRINT "MESSAGE ";MSGNO$;" ";MSECT-A:GOSUB OPM:MSGS=MSGS+C1
9530 ? #MODEM;"SAVED AS MSG#";MSGNO$
9540 GOTO 7510
9800 FILE$="D1:BULL":GOTO JMPT
9810 FILE$="D1:FUNC":GOTO JMPT
9820 FILE$="D1:HELP":GOTO JMPT
9830 FILE$="D1:INDX":GOTO JMPT
9840 FILE$="D1:NEWU":GOTO JMPT
9850 FILE$="D1:OBBS":GOTO JMPT
9860 FILE$="D1:WELC":GOTO JMPT
9900 ? #MODEM;"Any Comments or Suggestions?";:GOSUB YN:IF NOT X THEN 9940
9910 ? #MODEM;"Please, what are they?":GOTO 9920
9915 ? #MODEM;"Enter PRIVATE Message to SYSOP":DEW=C1
9920 ? #MODEM;">";:GOSUB GLINE:IF L$="" THEN 9935
9930 GOSUB CLM:LPRINT L$:GOSUB OPM:GOTO 9920
9935 IF DEW THEN DEW=C0:GOSUB CLM:GOTO MAIN
9940 ? #MODEM;"Log-Off now?";:GOSUB YN:IF NOT X THEN GOTO MAIN
9950 GOSUB CLM:GOSUB TIME:LPRINT "LOG-OFF ";TIME$:GOSUB OPM:X=ABS(A-TIMEON):GOSUB 2100:? #MODEM;"On for ";TIME$
9960 ? #MODEM;"Thanks for calling ";NAME$;CR$;"Please call again soon..."
9970 ? #MODEM;CR$;"Log-Off: Hang up your phone now.":GOSUB 2000:? #MODEM
10000 LOCAL=C0:REM WAITRING
10010 GOSUB CLM
10020 WAITRUNG=WAITRUNG+1:IF WAITRUNG>21 THEN XIO C34,#MODEM,C128,C0,"R1:":WAITRUNG=19
10030 XIO C38,#MODEM,C0,C0,"R:"
10040 XIO C34,#MODEM,C128,C0,"R1:"
10050 GRAPHICS C0:GOSUB TIME:LPRINT "====== ";TODAY$;" ====== ";TIME$;" ======"
10060 XIO C34,#MODEM,192,C0,"R1:"
10070 XIO C36,#MODEM,C0,C0,"R1:"
10080 OPEN #MODEM,C13,C0,"R1:"
10090 XIO C40,#MODEM,C0,C0,"R1:":GOSUB 10900:FOR X=1 TO 50:NEXT X
10100 ? #MODEM;"ATZ":LOCAL=C0:AMODE=C32:LMODE=C0:XMODE=C0:GOSUB 1520:GOSUB 10980:X=C8^C8:GOSUB 10800
10110 POKE 752,C1:X=C8^C8:? #MODEM;"ATE0 S2=255 S4=24 S7=15":GOSUB 10800
10120 ? MSGS;" MESSAGES, LAST MESSAGE # ";HMSG;" ";CALLNO
10150 GOSUB TIME:POSITION C2,C9:? "TIME: ";TIME$;" DATE: ";TODAY$:I=PEEK(CON):IF I=C3 THEN 28000
10160 IF I=C5 OR I=C6 THEN ? #MODEM;"AT H1 M0":GOSUB CLM:LOCAL=C1:OPEN #MODEM,C13,C0,"E:":GOTO 10999
10165 IF I=4 THEN 10500
10170 STATUS #MODEM,X:IF PEEK(INM) THEN GOSUB 10900:GOSUB 10910:GOTO 10500
10180 GOTO 10150
10500 ? "ANSWERING CALL"
10510 ? #MODEM;"ATA"
10520 STATUS #MODEM,X:IF NOT PEEK(INM) THEN 10520
10530 STATUS #MODEM,X:IF PEEK(INM)=C0 THEN TRAP ERR:GOSUB OPM:GOTO 11000
10540 GOSUB GETCHR:IF X=73 THEN GOTO WAITRING
10550 GOTO 10530
10800 STATUS #MODEM,X:IF PEEK(INM) THEN GOSUB GETCHR:GOTO 10800
10810 RETURN
10900 STATUS #MODEM,X:IF PEEK(INM) THEN GOSUB GETCHR:GOTO 10900
10910 IF TIME$(C1,C2)>"07" AND TIME$(C1,C2)<"22" THEN ? CHR$(C253); 10920 RETURN 10940 AMODE=C32:GOSUB OPM:GOSUB 10950:GOTO MAIN:REM A 10950 ? #MODEM;"A.S.I.A. B.B.S. HIT";:GOSUB GETCHR:IF X=13 OR X=141 THEN AMODE=C0:GOTO 10960
10955 IF X<>155 THEN 10950
10960 GOSUB 10980:GOSUB OPM:IF AMODE THEN ? #MODEM;CR$;"ÁÔÁÒÉ Íïäå":RETURN
10970 ? #MODEM;CR$;"ASCII Mode":RETURN
10980 IF AMODE THEN BEL$=CHR$(C253):DEL$=CHR$(156):BS$=CHR$(C126):RETURN
10990 BEL$=CHR$(7):DEL$=CHR$(C24):BS$=CHR$(C8):RETURN
10999 IF I=6 THEN NAME$="SYSOP":GOTO MAIN
11000 GOSUB 10950:IF AMODE THEN 11025
11010 ? #MODEM;CR$;"Do you require Line Feeds";:GOSUB YN
11020 IF X THEN LMODE=C64:GOSUB OPM
11025 FILE$="D:LOGO":GOSUB RFILE:GOSUB 170
11026 ? #MODEM;CR$;"If you are a frequent caller and wish";CR$;"to skip the intros hit (Y) ";:FR$="":SKIP=C0
11027 ? #MODEM;"==> ";:GOSUB GETCHR:? #MODEM;CHR$(X);CR$:IF X=89 THEN SKIP=C1:FR$="SKIP":GOTO 11040
11030 ? #MODEM;CR$;"Please enter your computer or";CR$;"terminal type for my records!":FR$=""
11035 ? #MODEM;"==> ";:GOSUB GLINE:? #MODEM;CR$;"Thank you!":FR$=L$
11040 GOSUB TIME:TIMEON=A
11042 ? #MODEM;CR$;SAY$;CR$
11045 IF TIME$(C1,C2)<"11" THEN PERIOD$="Morning" 11050 IF TIME$(C1,C2)>"16" THEN PERIOD$="Evening"
11055 IF TIME$(C1,C2)>"10" AND TIME$(C1,C2)<"17" THEN PERIOD$="Afternoon" 11060 ? #MODEM;CR$;"Good ";PERIOD$;"!" 11065 ? #MODEM;"Logged on:":GOSUB 2000:? #MODEM 11100 IF SKIP THEN 11110 11105 FILE$="D:WELC":GOSUB RFILE:GOSUB 170 11110 IL=C40:? #MODEM;CR$;"Enter your Name >";:GOSUB GLINE:IF LEN(L$)";:GOSUB GLINE:IF LEN(L$) ";:GET #C3,X:? CHR$(X):? :TRAP 27000
27070 IF X=68 THEN I=33:? "DELETE; ";:GOTO 27900
27080 IF X=76 THEN I=35:? "LOCK; ";:GOTO 27900
27090 IF X=82 THEN I=C32:? "RENAME; ";:GOTO 27900
27100 IF X=85 THEN I=C36:? "UNLOCK; ";:GOTO 27900
27110 IF X=84 THEN GOTO 27600
27120 IF X<49>52 THEN GOTO MAIN
27500 TRAP 27530:FILE$="D1:*.* ":FILE$(2,2)=CHR$(X):OPEN #FILE,C6,C0,FILE$
27510 TRAP 27520:INPUT #FILE,L$:? L$:GOTO 27510
27520 ? "PRESS RETURN FOR MENU ";:GET #C3,X
27530 TRAP 27540:CLOSE #FILE
27540 GOTO 27000
27600 ? "Enter file name";:INPUT FILE$:? "On Printer? ";:GET #C3,X:IF X<>89 THEN GOTO JMPT
27610 GOSUB RFILE:LPRINT BUFFER$:GOTO 27000
27900 ? "Enter Filespec ";:INPUT FILE$:XIO I,#FILE,C0,C0,FILE$:? "DONE":GOTO 27000
28000 ? #MODEM;"AT H1 M0":GOSUB 28100:POKE 752,C0
28020 END
28100 GOSUB CLM:CLOSE #FILE:OPEN #FILE,C8,C0,"D:CONFIG"
28110 ? #FILE;CSECT;CR$;CBYTE;CR$;CALLNO;CR$;MSECT;CR$;MBYTE;CR$;MSGS;CR$;HMSG:CLOSE #FILE
28120 RETURN
29000 C0=0:C1=1:C2=2:C3=3:C4=4:C5=5:C6=6:C7=7:C8=8:C9=9:C10=10:C13=13:C14=14:C16=16:C24=24:C32=32:C34=34
29010 C36=36:C38=38:C39=39:C40=40:C64=64:C80=80:C119=119:C120=120:C121=121:C126=126:C127=127:C128=128
29020 C195=195:C253=253:C255=255:C256=256
29030 FILE=C1:MODEM=C2:LET GETCHR=20:GLINE=70:SEND=160:CLM=250:OPM=300:YN=350:INM=747:INK=764:JMPT=900:MAIN=1000
29040 CLK=1030:TIME=2010:RFILE=8000:ERR=8080:WAITRING=10000:CON=53279
29050 DIM L$(C120),FILE$(C16),NAME$(C40),ADDRES$(C40),CTRL$(C40)
29060 DIM MSG$(2100),PROMPT$(60),FROM$(C40),FR$(C40),MSGNO$(C4),SUBJ$(33),TEMP$(C120),PAS$(C40),SAY$(C80),A$(C255)
29070 DIM SCIO$(C7):SCIO$="hhhªLVä"
29080 DIM CR$(C1),BEL$(C1),DEL$(C1),BS$(C1),X$(C1),TODAY$(C8),DATE$(C8),TIME$(C8),PERIOD$(C9)
29090 DIM MIF$(C14),MDF$(C14),CDF$(C14):MIF$="D1:MESSAGE.ISM":MDF$="D1:MESSAGE.DAT":CDF$="D1:CALLERS.DAT"
29100 DIM DAYS$(63),DAY$(9):DAYS$=" Monday TuesdayWednesday Thursday Friday Saturday Sunday"
29105 DIM MTH$(24):MTH$="312831303130313130313031"
29110 CTRL$="(^=CTRL ^S PAUSE, ^Q RESUME, ^X QUIT":CR$=CHR$(155):? CHR$(125);" AMIS.BBS, 5/20/83 FLAGCITY Ver."
29120 TRAP 29120:? :? "Enter day of week (1-7)";:INPUT DOW
29130 TRAP 29130:? "Enter date as: mm/dd/yy ";:INPUT TODAY$:? "Enter time as: hh:mm:ss ";:INPUT TIME$
29135 TODAY$(6,8)="/85":TIME$(6,8)=":00"
29137 ? "Enter saying of the day>":INPUT PAS$
29138 SAY$=" Saying of the day: ":SAY$(39)=PAS$
29139 IF PAS$="" THEN SAY$(39)=" If you can't be good, Be Careful!"
29140 X=((VAL(TIME$(C1,C2))*60+VAL(TIME$(C4,C5)))*60+VAL(TIME$(C7,C8)))*60:F=INT(X/65536):T=INT(X/256)-F*256
29150 X=X-F*65536-T*256:POKE 20,X:POKE 19,T:POKE 18,F
29155 ? "Put WORK disk in drive!!!":INPUT PAS$:TRAP 40000:CLOSE #FILE
29160 TRAP 29155:OPEN #FILE,C4,C0,"D:CONFIG":INPUT #FILE,CSECT,CBYTE,CALLNO,MSECT,MBYTE,MSGS,HMSG:CLOSE #FILE
29170 X=FRE(C0)-100:LPRINT "BUFF = ";X:DIM BUFFER$(X):NUMSECT=C8:REM INT(X/C128)-C1
29180 OPEN #C3,C4,C0,"K:":GOTO WAITRING
Posted by
Rick
at
8:56 AM
1 comments
Labels: a.m.i.s., amis, atari, bbs, bulletin board system, retro
Monday, January 14, 2008
Collection of stupif UNIX tricks
(some people just don't get the silliness of stupif and dumf stuff...)
I'm a user of bash and linux/bsd. YMMV with this stuff.
Copy files to a bunch of boxes:
BOXEN="box1 box2 box3"
for b in $BOXEN
do
scp FILENAME OTHERFILENAME username@${s}:/path
done
Saturday, January 12, 2008
Everex Cloudbook: $399.00 USD At Walmart

Mmm.. this looks like a lot of fun. Someone needs to buy me one to play with. Touted as a GREEN notebook - I'm kind of excited about this one...
9 Inches, 2 pounds, 5 hours of battery life. Surf, email, blog, IM, Skype, compute. Cloud computing makes it simple and easy for everyone.
Based on the latest gOS Rocket operating system, the ultra-mobile Everex PC comes with popular applications from Google, Mozilla, Skype, OpenOffice.org and more.
From the website:
Additional Preinstalled and Linked Software
Mozilla Firefox, gMail, Meebo, Skype, Wikipedia, GIMP, Blogger, YouTube, Xing Movie Player, RythemBox, Faqly, Facebook and OpenOffice.org 2.3 (includes WRITER, IMPRESS, DRAW, CALC, BASE)
Posted by
Rick
at
11:39 PM
0
comments
Not too tech - but dang cool
I wish I'd thought of something as simple as this when I lived there.
Beautiful...
Posted by
Rick
at
10:00 AM
0
comments
Tuesday, January 8, 2008
E-Mail Deliverability Using Postfix + DKIMProxy Part I: Getting the stuff
Notes: I am using a CentOS 4.3 testbox.
This isn't a tutorial, it's just an account of what I'm doing so I don't lose my place as I go.
Install the following stuff:
postfix
openssl-devel
Installing the required perl modules was a little bit of a pain, since the VMWare install I had didn't have vmware tools or X running.. so not cut&paste from the webpage for me... but, feh.. I needed the finger exercise.
Crypt::OpenSSL::RSAThere were lots of dependencies that will auto-resolve just by saying "yes".
Mail::Address
MIME::Base64
Net::DNS
Net::Server
Test::More
Error
Digest::SHA
Digest::SHA1
...to be continued..
Posted by
Rick
at
1:22 PM
0
comments
Monday, January 7, 2008
New Firewall for Rick: Part II - Options, Options, Options
We're now on day 2 of the pfSense Firewall/Router. So far I've rebuilt it once - probably because I can't quit screwing with things.
There are a few items I'd like to have in my little device that most people don't give a rats hiney about. First thing I'd like is to explain that I have not got unlimited room for the projects I once had room for. Gone is the day of having a rack or two of goodies in the house. No more room all to myself where lie an assortment of hardware goodness from the likes of Sun, SGI, Apple, and several other vendors.
Now I need to cram as much crap onto a single box as I can.
So, I'd really like to have a BBS on the little pfSense machine.
No; not phpBB or something like that - we're talkin' Synchronet ( http://synchro.net ) here. But to do that, and some other stuff, I need a dev environment on the little box. DANGER DANGER DANGER!! Yeah.. whatever.. this ain't no corporation I'm protectin' here. It's a couple of boxes I use to play Everquest II on, or ssh out to work, or .. well.. write this ether-poo.
I installed the dev package (hey.. it was right there in packages..).. and then something occured to me: I had not rebooted the thing since it was configured. I had better stop now, before I actually do anything with it and reboot for sanity's sake.
Reboot - no web interface. Eep!
Ok.. so I rebuild the thing again - this time I decide to use the config wizard.. which works without a hitch.
Now.. until I figure out what killed the web interface, I think I'll wait on the BBS. Bummer.. well.. actually, I do have a license for APE and a spare Atari 130XE lying around.. maybe I'll make use of the port forwarding, and setup my BBS on my Atari 8-bit.. it's a way more fun hack anyway...
Posted by
Rick
at
10:15 PM
0
comments
E-Mail Deliverability : SPF and SenderID
First, the links:
http://www.openspf.org/
This relies entirely on DNS being set up correctly. You must have your MX records correct, you must have reverse lookups working right (ie: pointed to your mail server).
It's all about the text records.
Here might be an example forward zone for your domain, which has a few dns servers, a mail server, and a web server:
$ORIGIN mydomain.com.
@ IN SOA dns1.mydomain.com. primary.mydomain.com. (
2008010900 ; serial
1800 ; refresh
3600 ; retry
604800 ; expire
86400 ; minimum
)
; DNS SERVERS
mydomain.com. 300 IN NS dns2.mydomain.com.
mydomain.com. 300 IN NS dns3.mydomain.com.
mydomain.com. 300 IN NS dns4.mydomain.com.
;MX RECORDS
mydomain.com. 300 IN MX 5 mail.mydomain.com.
mail.mydomain.com. 300 IN MX 5 mail.mydomain.com.
;A RECORDS
mail.mydomain.com. 300 IN A 10.1.1.10
dns1.mydomain.com. 300 IN A 192.168.1.2
mydomain.com 300 IN A 10.1.1.2
;CNAME RECORDS
primary.mydomain.com. 300 IN CNAME dns1.mydomain.com.
www.mydomain.com. 300 IN CNAME mydomain.com.
; TEXT RECORDS
mail.mydomain.com. 300 IN TXT "v=spf1 a -all"
mydomain.com. 300 IN TXT "v=spf1 ipv4:10.1.1.10 mx -all"
...continued...
Posted by
Rick
at
11:36 AM
0
comments
Sunday, January 6, 2008
New Firewall for Rick: Part I - Selection
ARGH! My Linksys WRT54GS keeps randomly breaking. By breaking I mean "my wired net connections stop working as advertised". This is a royal pain when you are trying to complete things for work... or you happen to be on call and watching your Nagios monitoring stop refreshing (yay!).
The entire reason I went to the WRT is because I just didn't have room for a whole computer dedicated to firewalling. Well; I now officially give up. After some careful browsing and comparison (in between losing internet access, that is), I've settled on either pfSense again or UnTangle. I had run m0n0wall, then pfSense when it was an openbsd based system, and pfSense as based on freebsd. It's super simple to setup, it's easy to maintain, and it "just works".
The one drawback for me though, is that it has to be connected to the live network during installation (correct me if I'm wrong). This is a real drag for folks like me who tend to pop online regularly to check a setting or fail to print out the notes on installation/configuration.
Untangle is a relatively new one, that has application modules that plug right in - the only thing about this one that I fear is the slowness associated with this many filters applied.
We shall see.
Posted by
Rick
at
10:09 AM
3
comments
Friday, January 4, 2008
scripting mailq output for error handling
So, I was in need of a way to parse mailq on a postfix box and remove all mail that was sitting there waiting indefinately because of an error. Since setting a timeout is not good when email deliverability is king, I had to do this manually.
I'm not a user of 'tr'.. or rather I wasn't. I so am now...
Here's the script:
mailq | tr '\n' '|' | sed "s/MYDOMAIN.COM|/MYDOMAIN.COM/g" | tr '|' '\n' | grep error | awk {'print $1'} | postsuper -d -
Here's what it does:
take the output of mailq and pipe it to tr
strip all newline chars and replace with pipes
hand this output to sed, and do a regex search and replace on MYDOMAIN.COM| and replace with MYDOMAIN.COM
handoff to tr again, and remove the remaining pipes, and replace those with newlines.
find the error
grab the first "word" in each line (the message id in this case) and pass the output to postsuper
postsuper will then delete the messages based on the message id.
The internet is held together with pipe and tubes. It's absolutely true.
Posted by
Rick
at
2:08 PM
0
comments
