tag:blogger.com,1999:blog-41685690033219007312024-03-13T11:29:16.114-07:00Gregory Masseau((lambda (x) (x x)) (lambda (x) (x x)))gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.comBlogger32125tag:blogger.com,1999:blog-4168569003321900731.post-31222359327743003362009-03-28T16:50:00.001-07:002009-03-28T17:01:39.692-07:00Fedora NTFS initrd maker, first release.<span class="Apple-style-span" style="font-size:medium;"> The first prototype of the code that will be used to produce an initrd image capable of booting off of an NTFS file system is finally ready.</span><div><span class="Apple-style-span" style="font-size:medium;"><br /></span></div><div><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-size:large;">What This Code Is Supposed To Do:</span></span><span class="Apple-style-span" style="font-size:large;"><br /></span></div><div><span class="Apple-style-span" style=" ;font-size:12px;"><br /></span></div><div><span class="Apple-style-span" style=" ;font-size:12px;"> This code is intended to take a standard Fedora initrd image and transform it into one capable of mounting it's root filesystem from a file located on an NTFS filesystem.</span></div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-size:large;">What This Code Does Today:</span></span></div><div><span class="Apple-style-span" style=" ;font-size:9px;"><br /></span></div><div><span class="Apple-style-span" style=" ;font-size:12px;"> Right now, the code is not complete, and does not actually produce the desired initrd image as it's final output. Rather, what is produced at this point is an environment that can be chrooted into to simulate the capabilities that will be available within the confines of the initrd image during the bootup process. This environment can be used for debugging while determining what further changes are needed to achieve our final goal.</span></div><div><span class="Apple-style-span" style=" font-weight: bold;font-size:12px;"><br /></span></div><div><span class="Apple-style-span" style="font-weight: bold; "><span class="Apple-style-span" style="font-size:large;">How to Test This Code Out:</span></span></div><div><span class="Apple-style-span" style=" ;font-size:9px;"> </span></div><div><span class="Apple-style-span" style=" ;font-size:9px;"> To test this code out, you'll need to run it as root on a Fedora system. It should run with the standard packages provided by a base install, but you may have to add some additional entries to your path environment variable so the program can locate certain executables it needs: if a desired executable is not in your path, the program will halt and warn you of this. Simply add the directory in which it is located to your path and try again. Directions on how to test out the capabilities of the chroot environment will be provided by the program when executed. You should be able to mount the NTFS filesystem, though the ext2 filesystem cannot yet be mounted via bash as the normal mount command has not been placed in the chroot environment yet.</span></div><div><span class="Apple-style-span" style=" ;font-size:9px;"><br /></span></div><div><span class="Apple-style-span" style=" ;font-size:9px;"> The syntax you should use to invoke this code is simple: as it's first, and only argument, it expects the path of an already existing initrd image.</span></div><div><span class="Apple-style-span" style=" font-weight: bold;font-size:9px;"><br /></span></div><div><span class="Apple-style-span" style="font-size:large;"><span class="Apple-style-span" style="font-weight: bold;">Get The Code:</span></span></div><div><span class="Apple-style-span" style=" ;font-size:12px;"><br /></span></div><div><span class="Apple-style-span" style=" ;font-size:9px;"> The current version of this program is available for download at: http://matrix.senecac.on.ca/~gjmasseau/ntfsboot/.</span></div>gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-24095822769772146762009-02-18T20:27:00.001-08:002009-02-18T21:49:32.175-08:00More Higher Order Python: CPS based pure I/O in Python<span style="font-family:courier new;"><span style="font-family:times new roman;"><span class="Apple-style-span" style="font-size: small;">Continuing with my quest to achieve the purest possible I/O and state handling possible in Python, here's another experiment. This one takes a somewhat different approach than the last one, and is based on continuation passing style. The portions of the code actually written in this implementation of CPS end up looking very Lisp-ish due to the abundance of brackets, though the semantics are quite different. Anyway, on with the code...</span></span><span class="Apple-style-span" style="font-size: small;"><br /><br />#!/usr/bin/python</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#######################################################################################################################</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Continuation passing based, functionally pure I/O in python!</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Author: Gregory Masseau.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#######################################################################################################################</span></span><span class="Apple-style-span" style="font-size: small;"><br /><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># This is the main program we're going to run, stored as a thunk so we don't have to worry about what's defined. Skim </span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># it, and you might get some idea what we're going to do.</span></span><span class="Apple-style-span" style="font-size: small;"><br /><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">main = lambda:chain( (inject("Hi. Enter a string, I will repeat it twice in uppercase.\n\nEntry: ")) (prntc)(discard) </span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"> , (input) (mul(2))(uc) (interject((prntc("Result:"))(discard))) (prnt) (discard) </span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"> , (inject("\nBye.\n"))(prnt) (end("Success."))</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"> )</span></span><span class="Apple-style-span" style="font-size: small;"><br /><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Now lets define all the functions we need to handle this sort of code.</span></span><span class="Apple-style-span" style="font-size: small;"><br /><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#######################################################################################################################</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># These functions are combinators which transform a function into a curried version of itself. This means a function that</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># was previously called using syntax line 'func(x,y)' must now be called using the syntax 'func(x)(y)' to achieve the </span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># same effect. The advantage is that it can also be called like 'func(x)' to partially apply it, returning a function</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># that recieves the remaining variables.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def curried_2args(f): return lambda x:lambda y: f(x,y)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def curried_3args(f): return lambda x:lambda y:lambda z: f(x,y,z)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def curried_4args(f): return lambda x:lambda y:lambda z:lambda w: f(x,y,z,w)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># These functions are combinators that modify a function (which should already be curried) to behave in a continuation</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># passing style, taking the continuation as an additional argument and continuing with it (passing what would ordinarily</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># be the return value) to it instaed of returning it as they ordinarily would -- remember, in this style of programming</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># only the last function ever returns.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def continuationpasser_thunk(f): return lambda c: c(f())</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def continuationpasser_1arg(f): return lambda x:lambda c: c(f(x))</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def continuationpasser_2args(f): return lambda x:lambda y:lambda c: c(f(x)(y))</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def continuationpasser_3args(f): return lambda x:lambda y:lambda z:lambda c: c(f(x)(y)(z))</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def continuationpasser_4args(f): return lambda x:lambda y:lambda z:lambda w:lambda c: c(f(x)(y)(z)(w))</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># This turns a value into a value expecting a continuation.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def inject(x): return lambda c: c(x)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># This evaluates it's argument and calls it's continuation without it.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def discard(x): return lambda c: c</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># This is basically shortand for (discard)(inject x).</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def restart(x): return lambda y:lambda c: c(x)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># This is fun. This takes another sequence of commands in CPS format, and runs those, before passing it's argument to</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># it's continuation.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def interject(f): return lambda x:lambda c: c(x) if f else c(x)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># This just ends with the exit status/message 'v', expecting no continuation.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def end(v): return lambda x: (inject(v))(id)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Since inject just passes it's argument to it's continuation, it can be used as a no op in CPS code blocks.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def noop(x): return inject(x)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># This is kind of like (but not quite, I don't think) a monadic bind, taking a thunk and a function and returning a thunk that does the first function to the result of the thunk</span></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">, returning the result of the second.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def chained(x,y): return lambda: y(x())</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># This is just the previous function extended to operate on n thunks, where 1 <><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def chain(*fs): return reduce(chained,fs)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># The identity function. End a CPS function sequence with it to return a value into normal code.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def id(x): return x</span></span></span><div><span style="font-family:courier new;"><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#######################################################################################################################</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># These are some trivial math and I/O functions, appropriately curried and lifted to work in our CPS model.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Adds two objects implementing +.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">@continuationpasser_2args</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">@curried_2args</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def add(x,y): return y+x</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Multiplies two objects implementing *.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">@continuationpasser_2args</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">@curried_2args</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def mul(x,y): return y*x</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Increments a number.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">@continuationpasser_1arg</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def inc(x): return 1+x</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Takes input from stdin.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">@continuationpasser_thunk</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def input(): return raw_input()</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">@continuationpasser_1arg</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Prints a value to stdout.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def prnt(s):</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"> print str(s)</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"> return True</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Prints a value to stdout, printing no newline after.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">@continuationpasser_1arg</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def prntc(s):</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"> print str(s),</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"> return True</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#----------------------------------------------------------------------------------------------------------------------</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Returns a string in uppercase.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">@continuationpasser_1arg</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">def uc(s): return s.upper()</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#######################################################################################################################</span></span><span class="Apple-style-span" style="font-size: small;"><br /><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Now we call main, executing our program.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">main()</span></span><span class="Apple-style-span" style="font-size: small;"><br /><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># Instead of calling main as above, just uncommenting this will also have a similar effect, though it's a little less </span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># pure since it is techincally three statements when used that way. </span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#(inject("Hi. Enter a string, I will repeat it twice in uppercase.\n\nEntry: "))(prntc)(discard) </span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#(input)(mul(2))(uc)(interject((prntc("Result:"))(discard)))(prnt)(discard) </span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#(inject("\nBye.\n"))(prnt)(end("Success."))</span></span><span class="Apple-style-span" style="font-size: small;"><br /><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;"># The following is equally valid, if somewhat less readable, as well as about as pure as this gets right now.</span></span><span class="Apple-style-span" style="font-size: small;"><br /></span><span style="font-family:courier new;"><span class="Apple-style-span" style="font-size: small;">#(inject("Hi. Enter a string, I will repeat it twice in uppercase.\n\nEntry:"))(prntc)(discard)(input)(mul(2))(uc)(interject((prntc("Result:"))(discard)))(prnt)(discard) (inject("\nBye.\n"))(prnt)(end("Success."))</span></span></span></div>gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-72126351242397308852009-02-16T22:16:00.000-08:002009-02-16T22:38:59.832-08:00Higher Order PythonJust for fun, here's an example of how one can completely ignore the bias towards a statement oriented programming style that's usually prevalent in Python and handle use I/O in a purely functional manner.<br /><span class="Apple-style-span" style="font-family:'courier new';"><br />def appliedto(x): return lambda y:y(x())<br />def adder(x): return lambda y:int(x)+int(y)<br />def l_msg(s): return lambda:prnt(s)<br />def l_msgc(s): return lambda:prntc(s)<br />def l_v(v): return lambda:v<br />def ife(p,t,e): return lambda x: t() if p(x) else e()<br />def input(): return raw_input()<br />def seqe(*a): return reduce(binde,a)<br />def seq(*a): return reduce(bind,a)<br />def binde(x,y): return lambda:y(x())<br /> <br />def bind(x,y):<br /> def actionpair(*a):<br /> x(*a)<br /> return y()<br /> return actionpair<br /><br />def passahead(x,y):<br /> def actionpair(*a):<br /> x()<br /> return y(*a)<br /> return actionpair<br /><br />def prnt(s):<br /> print s<br /> return True<br /><br />def prntc(s):<br /> print s,<br /> return True<br /><br />hello = l_msg("Hello!")<br />goodbye = l_msg("Goodbye.")<br />question1 = l_msgc("Enter the first addend: ")<br />question2 = l_msgc("Enter the second addend:")<br />desc = l_msg("Enter two numbers, and I will add them.")<br />smsg = l_msgc("The sum of the numbers is ")<br />printnl = l_msg("")<br /><br />seq(hello<br /> ,printnl<br /> ,desc<br /> ,printnl<br /> ,question1<br /> ,seqe(input<br /> ,adder<br /> ,appliedto(seq(question2<br /> ,input))<br /> ,passahead(seq(printnl<br /> ,smsg)<br /> ,prnt))<br /> ,printnl<br /> ,goodbye<br /> ,printnl)()<br /><br /></span>gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-42921837251135338052009-02-13T19:57:00.000-08:002009-02-13T20:00:16.765-08:00Func Users Module version 0.5 is released.Release 0.5, released today, consists a final polishing of the Users & Groups module before it's initial release.<br /><br />Changes in this version included:<br /><br /> - register_method_args has been implemented in users.py<br /> - unit tests for the methods in user.py have been added to test_client.py<br /><br />As of this release, all features intended for the release version of this module are present and working, and it appears to be ready for merging.<br /><br />The code is linked off the project page <a href="http://zenit.senecac.on.ca/wiki/index.php/Func_-_Users_And_Groups_Module">here</a>.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-53823242350013334942009-01-30T19:55:00.000-08:002009-01-30T19:59:28.122-08:00Func Users Module v0.4 is released!A new version of the func users & groups management module has been released for public use, testing or review. The updated module can be found here: <a href="http://matrix.senecac.on.ca/~gjmasseau/func/0.4/users.py">Func Users Module v0.4</a>.<br /><br /><br />New Features:<br /><br />- Password alteration method added.<br />- Pluralized methods for all applicable singular methods.<br /><br /><br />Other Changes:<br /><br />- General API cleanup.<br /><br /><br />Planned for version 0.5: <br /><br />As nearly all core functionality for day to day user and group management is at this point complete, release 0.5 is expected to be a candidate for final release and integration with the project's main branch.<br /><br />One feature remains: GECOS field manipulation methods: Currently, the GECOS field can only be manipulated as a single unit. Version 0.5 will fill in this remaining gap in functionality by providing getter/setter methods for all subfields of the GECOS field.<br /><br /><br />The updated project page is <a href="http://zenit.senecac.on.ca/wiki/index.php/Func_-_Users_And_Groups_Module">here</a>.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-32832487619054425962009-01-22T00:57:00.001-08:002009-01-22T07:56:51.518-08:00Getting the hang of Python.So, I've been practicing a little more with Python, and kind of think I'm getting the hang of it.<br /><br />But as far as the language's supposed 'readability', I offer the following counterexample...<br /><br /><span class="Apple-style-span" style="font-family: 'courier new';">AccessTable.py<br /></span><div><span class="Apple-style-span" style="font-family: 'courier new';"># Usage: head -60 /var/log/apache2/access.log | python AccessTable.py<br /># Effect: Produces a spiffy HTML page containing the contents of your Apache access log in a table.</span><div><span class="Apple-style-span" style="font-family: 'courier new';"><br />from fileinput import input as OO<br />O=[(lambda o,oo,ooo:[o]if(oo=="")else[o+oo[0],oo[1:]]if(oo[0]==ooo)else(O[0](o+oo[0],oo[1:],ooo))),(lambda o,oo:[o]if(((O[0]("",o,oo[0])if(not(o==""or(oo==[])))else[o,""])[0]and(not(O[0]("",o,oo[0])if(not(o==""or(oo==[])))else[o,""])[1]))or(o==""))else[(O[0]("",o,oo[0])if(not(o==""or(oo==[])))else[o,""])[0]]+[(O[0]("",o,oo[0])if(not(o==""or(oo==[])))else[o,""])[1]]if(not(oo[1:]))else[(O[0]("",o,oo[0])if(not(o==""or(oo==[])))else[o,""])[0]]+O[1]((O[0]("",o,oo[0])if(not(o==""or(oo==[])))else[o,""])[1],oo[1:])),""+chr(60)+"/b"+chr(62)+""+chr(60)+"/u"+chr(62)+"",(lambda o,oo:""if(oo=="")else(oo[0])if((oo[0]!=o)and(not(oo[1:])))else(oo)if(oo[0]!=o)else(O[3](o,oo[1:]))),(lambda o,oo:""if(oo=="")else(oo[0])if((not(oo[1:])))else(O[3](o,(oo)if(oo[-1]!=o)else(O[4](o,oo[:-1]))))),["IP Address","Date","Time","Method","URL","Protocol Version","Error Code","Bytes","URL 2","Client"],(lambda o:""+chr(60)+"html"+chr(62)+"\n\t"+chr(60)+"body"+chr(62)+"\n"+'\t\t'+chr(60)+'table border="1"'+chr(62)+"\n"+"\n".join(["\t\t\t"+chr(60)+"tr"+chr(62)+"\n"+line+"\t\t\t"+chr(60)+"/tr"+chr(62)+""for(line)in[''.join(o)for(o)in[["\t\t\t\t"+chr(60)+"td"+chr(62)+""+word+""+chr(60)+"/td"+chr(62)+"\n"for(word)in(line)]for(line)in(o)]]])+"\n\t\t"+chr(60)+"/table"+chr(62)+"\n"+"\t"+chr(60)+"/body"+chr(62)+"\n"+chr(60)+"/html"+chr(62)+""),""+chr(60)+"b"+chr(62)+""+chr(60)+"u"+chr(62)+"",(lambda s:[(o)for(o)in[(lambda o:O[4]("\n",O[4](":",O[4]("]",O[4]('"',O[4](" ",o))))))(o)for(o)in(O[1](s,[" ","[",":","]",'"'," "," ",'"'," "," "," "," "]))]if(o)not in[" ",'"',"","- - ["]])]<br />print(O[6]([[O[7]+o+O[2]for(o)in(O[5])]]+[O[8](o)for(o)in(OO())]))<br /></span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><br /></span><br /></div></div><br /><br />Just a little something I came up with this evening. Feel free to try it out - it works with the default log format in the version of Apache installed on my (somewhat outdated) Ubuntu 6.06 webserver. If the format gets messed up in the blog, a copy is on the web at 'http://matrix.senecac.on.ca/~gjmasseau/AccessTable.py'.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com2tag:blogger.com,1999:blog-4168569003321900731.post-80959495246263975212009-01-20T20:46:00.001-08:002009-01-20T20:46:40.665-08:00Observations on the installation of FreeBSDDifferences in installation between FreeBSD and Linux:<br /><br /> During installation the differences between FreeBSD and Linux are not particularily pronounced: the installer's interface and usage bear quite a significant resemblence to those used in many Linux distributions, Debian and Slackware being two particularly notable examples. While the overall experience is quite similar to installing one of these distributions of Linux, there are a few particular areas that are clearly a little bit different.<br /><br /> The first difference one is likely to notice is that the FreeBSD version of the fdisk utility uses some terminology that may be unfamiliar - instead of referring to primary partitions, it refers to slices - in fact, they are the same thing, and merely the terminology has been changed. FreeBSD requires one slice on which to be installed. Meanwhile, after the boot manager has been installed, the FreeBSD DiskLabel Editor will launch, and you may notice that the word 'parititons' has been repurposed - in FreeBSD, the word 'partition' is used not to refer to physical disk partitions , but rather refers to an additional layer of storage abstraction implemented on top of the physical slices on may create on their storage devices (e.g., harddrives, flash media, etc). Many configuration files found in /etc look quite similar to their Linux counterparts, such as fstab, while a few, such as freebsd-update.conf, are clearly new. Additionally, the structure of the rc files is significantly different, with all startup script code contained in a small set of rc.* files located in the /etc/ directory itself, rather than a distinct folder for each level -- indeed, runlevels themselves are absent!<br /><br />Things I liked about the FreeBSD installer:<br /><br /> The installation experience was simple, to the point, and straightforwards, while providing a fairly wide set of options to customize your installation. The straightforwards, simple user interface was refreshingly uncluttered compared to the GUI installers that have grown popular in some distributions, and I must confess it elicited some nostalgia with the memory of installing Slackware many times (though never more than once on a given machine! How's that for stable?) back in the good old days.<br /><br />Things I did not like about the FreeBSD installer:<br /><br /> So far, I haven't really found anything to dislike - maybe something will come up later on, during use, but I have no issues with the installer.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-16040395789960540152008-12-05T08:57:00.000-08:002008-12-05T09:03:50.803-08:00Func Users Module v0.3 is released!A new version of the func users & groups management module has been released for public user and/or review. The updated module can be found here: <a href="http://matrix.senecac.on.ca/~gjmasseau/func/0.3/users.py">Func Users Module v0.3</a>.<br /><br />This release includes some coding style alterations to the already extant informational methods, as well as a boatload of new methods that will allow you to:<br /><br />- Create, delete, and modify groups.<br />- Create, delete, and modify users.<br />- Manage the memberships of users within groups<br /><br />To do:<br /><br />The current implementation of user_add has very few options, and incorporating these options is most of what's on the feature list for v0.4. In the mean time, most sorts of users you would like to create can be created by first creating a user with relatively default settings using user_add, and subsequently modifying any properties you'd like changed. It would be nice if these additional steps could be cut out and the user be instantiated with the desired options with one method call.<br /><br />Enjoy!gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-74034119752781018402008-12-02T16:23:00.001-08:002008-12-02T16:27:05.365-08:00LPT730 Assignment #2<b>LPT Assignment 2: Converting a DV video to distribution formats using open source tools on Linux</b><br /><br /><br /><b>Step 1: Exporting the video from Quicktime to DVD:</b><br /><br /><img src="http://matrix.senecac.on.ca/~gjmasseau/lptasn2/1_Exporting_to_DV.png"><br /><br />First, I took the provided file and converted it to DV. This was accomplished by loading the file in Kino and selecting 'export' on the vertical tab bar, followed by 'DV file' on the horizontal tab bar, and then proceeding to hit the 'export' button and select the desired output filename.<br /><br /><br /><b>Step 2: Improving the audio quality:</b><br /><br /><img src="http://matrix.senecac.on.ca/~gjmasseau/lptasn2/2_The_Original_Audio.png"><br /><br />The provided audio file had several problems - it was recorded in stereo, but it appears to actually be two mics, one worn by the speaker, and one worn by an announcer who speaks only briefly at the beginning. To correct this, I used Kino to export the audio track from the DV file and loaded it up in Audacity. In eh editor, I amplified the brief period of conversation from the announcer, mixed it over the speaker's track in the other channel, and then copied that channel over both, creating a mono mix where both speakers are clearly visible. Noise reduction was then applied to reduce some of the ambient noise, after which the file was normalized to 0 db.<br /><br /><img src="http://matrix.senecac.on.ca/~gjmasseau/lptasn2/3_The_Editted_Audio.png"><br /><br /><br /><b>Step 3: Replacing the audio in the original DV file with the corrected audio</b><br /><br /><img src="http://matrix.senecac.on.ca/~gjmasseau/lptasn2/4_Adding_the_New_Audio_to_the_DV_with_Cinelerra.png"><br /><br />To replace the audio with our new, cleaned up version of the track, I launched Cinelerra, imported both the video from the DV file and the audio file produced by audacity and selected the 'render' option from the file menu to produce a new DV file with the new audio.<br /><br /><br /><b>Step 4: Transcoding to Theora</b><br /><br /><img src="http://matrix.senecac.on.ca/~gjmasseau/lptasn2/5_Transcoding_to_Theora_with_ffmpeg2theora.png"><br /><br />To transcode the DV file to theora, I install the ffmpeg2theora package and it's dependencies and, after reading the man page to determine the syntax, ran the script shown above. This actually produces many more files than we need at a variety of quality settings. To select the final files, each produced file was checked with the 'ogginfo' command and those with bitrates closest to the desired bitrates were selected.<br /><br /><br /><b>Step 5: Transcoding to MPEG2</b><br /><br /><img src="http://matrix.senecac.on.ca/~gjmasseau/lptasn2/7_Transcoding_to_MPEG2_with_Transcode.png"><br /><br />To transcode the video to MPEG2, the following commands are saved to a file, 'trans', and then executed:<br /><br />transcode -i Out.dv -o out.avi -V -J smartyuv,hqdn3d,msharpen -Z 640x480 -y null -w 1800 -b 256 -R 1;<br />transcode -i Out.dv -o out.avi -V -J smartyuv,hqdn3d,msharpen -Z 640x480 -y -w 1800 -b 256 -R 2<br /><br /><br /><b>Step 6: Transcoding to H264</b><br /><br /><img src="http://matrix.senecac.on.ca/~gjmasseau/lptasn2/6_Transcoding_to_H264_with_Podencode.png"><br /><br />To transcode the video to H264, I installed Mark Pilgrim's podencode python script and ran it on the AVI file (unfortunately, I could find no working tool to convert this directly from the DV file).gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-88158802604509042222008-11-22T18:46:00.001-08:002008-11-22T18:51:08.605-08:00Virt-manager LabSo, I was finally able to find some time to complete the FreeBSD virtual machine lab for SYA710. I wasn't able to do it in the lab, as I wasn't able to get it done while on campus, so ended up doing the lab using our China machine remotely. This didn't really require much serious modification to the lab - the only change was the use of a regular file for the main disk rather than a physical disk, as there weren't any partitions to spare on China.<br /><br />After a few initial failed attempts to install the ports collection from an FTP server, I ended up redownloading the ISO images and using those to get the ports collection installed. Getting X and a copy of the emacs text editor running was relatively simple, though compiling emacs on FreeBSD turned out to be a startlingly lengthy process.<br /><br /><img src="http://matrix.senecac.on.ca/~gjmasseau/fbsdvm.png"><br /><br />I'm quite impressed with the capabilities of the virsh and virt-manager pairing alongside KVM. The ability to have virtual machines start on boot certainly is a handy one to have around.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-25518531880325857412008-11-18T13:08:00.000-08:002008-11-18T13:11:00.098-08:00SPR720 Number Game LabSo, I just finished the number guessing game for SPR720... most of the conceptual material was pretty old hat, but it provided a convenient excuse to familiarize myself with a little bit more of the Python syntax surrounding classes, initialization of objects, custom exceptions, etc.<br /><br />Without further ado, here's the code...<br /><br /><a href="http://matrix.senecac.on.ca/~gjmasseau/spr720/NumberGame.py">Clicky</a>gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-44782487476159437562008-11-18T13:03:00.000-08:002008-11-18T13:04:19.413-08:00LPT730 Lab #7 -- Magnet Links vs. TorrentsMagnet Links vs. Torrents<br /><br /> A torrent file is a small file which can be downloaded and, by providing the torrent to a compatible client (Azureus, uTorrent, Transmission, etc.), then used to download the file described by the torrent file in question. In the scheme used by torrents, the file to be distributed is segmented into a number of pieces, to each of which is applied the SHA1 hashing algorithm. The hash value for each piece is stored within the torrent file, and it is this series of hash values that is used to identify, recover, and reassemble the segments described.<br /><br /> Magnet links are an open standard for a URI scheme accomplishing a similar goal through slightly different means. In this case, the user is offered a specially formatted URI containing a hash value that will be used to identify the correct file. The idea behind a magnet link is that some external P2P program (such as Vuze, Bearshare, or DC++, among others) will be used to locate the file whose hash corresponds with that in the URI. Magnet links may use a variety of hash algorithms, but unlike torrent files, the file is not segmented before being hashed, and it is the entirety of the file that is used in the production of the hash value used.<br /><br /> Even before any technical factors are considered, the advantage rests solidly with the BitTorrent protocol, due largely to it's popularity among the general public: the use of torrent files to acquire a variety of forms of media has become popular even among non-technical users, and as such, the chances of a given reciever having the required software installed to handle a torrent file are higher than the chances of them having software compatible with the magnet link scheme.<br /><br /> When technical aspects are considered, the advantages posessed by the BitTorrent profile become even more apparent. The technique used by BitTorrent of segmenting files before hashing them means that a peer node need not possess the entirety of the desired file to begin providing it to a requesting client: posessing only some segments of the file in question, the peer node will nonetheless register a match when the hash of the requested file is presented to it, and can immediately begin transfer of the segment it posesses to the requesting client.<br /> <br /> Secondly, the use of BitTorrent continues to make things simpler for the distributer as it can be guaranteed that clients seeking to access their file will be making use of a particular protocol (specifically, BitTorrent), unlike in the magnet link scheme (in which a client may be using any of a number of protocols to transfer the file in question). For the distributor, that makes it easier to reinforce the group of seeders with nodes under their own control simply by configuring them to seed the file over the BitTorrent protocol: there is no need to create a set of seed nodes for each of the possible protocols a client may turn out to be using.<br /><br /> To conlcude, I believe this one to be a clear win for BitTorrent.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-57550681638443468912008-11-14T07:56:00.000-08:002008-11-14T08:21:33.809-08:00Write Perl? You want this module.The other day, I discovered a great, easy-to-use profiling tool that anyone who writes Perl is bound to love. The tool is called Devel::NYTProf, and you'd definately be doing yourself a favour by checking it out. It'll provide you with beautifully readable, comprehensive reports (in a variety of formats - I haven't tried them all yet, but so far I like HTML) on Perl programs of your choice, in which you'll find all sorts of useful information about what your program actually spends it's time doing.<br /><br /><br /> To get ahold of it, just run the following command:<br /><br /> 'perl -MCPAN -e 'install Devel::NYTProf''<br /><br /><br /> To try it out on a Perl program of your own (let's say it's called 'example.pl'), just run...<br /><br /> 'perl -d:NYTProf example.pl'<br /><br /><br /> This will result in the creation of a file called 'nytprof.out' in your current directory. You can output a human readable HTML version of the report using a command like:<br /><br /> 'nytprofhtml nytprof.out'<br /><br /><br /> The 'nytprofhtml' command will have produced a directory called 'nytprof' in your current directory containing the report in an HTML format. You can open the report in your web browser of choice with the following command:<br /><br /> 'xdg-open nytprof/index.html'<br /><br /><br /> If you'd like to see an example of the sort of output it produces, you can check out the output it gave while profiling some of my code here:<br /><br /> 'http://matrix.senecac.on.ca/~gjmasseau/nytprof-example/index.html'<br /><br /><br /> From here, you can navigate through the report to view all sorts of useful information to help you optimize your program.<br /><br /><br /> Until next we speak, happy profiling!gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-1195846885027335052008-11-10T13:56:00.001-08:002008-11-10T14:00:34.161-08:00Func Users Module v0.2 is released.So, after some brief discussion with alikens and showing him the work that has been done so far, I've decided that version 0.2 of the Func users and groups module is now released. It's been mailed to the project lead, submitted on the mailing list and is available for general download <a href="http://matrix.senecac.on.ca/~gjmasseau/func/0.2/users.py">here</a><br /><br />Features on the list for version 0.3:<br />- User creation.<br />- Group creation.<br />- Deletion of either of the above.<br />- Managing group membership of users.<br /><br />Possible for v0.3, but maybe in 0.4 depending on time:<br />- Implementation of the remainder of the possibilities offered by usermod and groupmod.<br /><br />At this rate, the users and groups module should probably be completed well before the end of the year - in that case, I'm going to take a look at what other holes remain in the module selection and see what looks most interesting. Maybe the crontab module, as it'd give me an opportunity to fiddle with mangling files from Python in more detail.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-13992368523903494052008-10-19T19:40:00.000-07:002008-10-19T19:49:45.798-07:00SYA 710 Kernel Compile LabIt's a week or two late - I've been busy with the Func project, to the exclusion of much else - but after a few attempts the kernel compilation lab is done. I grabbed the freshest 2.6.27 off kernel.org, grabbed the required packages, and off I went to spin up a new kernel. There were some initial problems with one step in the compilation of some particular component ('no rule to make target 'n/n' on a file 'ngen.so''), but a bit of Googling quickly turned up a solution. The solution (which involved simple answering a single question about external firmware loaders differently during 'make menuconfig') was also from a Fedora Core 9 user, so perhaps there's a bug somewhere there that neds to be worked out. One of the later commands in the course notes regarding kernel compilation, the syntax offered for 'mkinitrd' in particular, did not work for me, and I've added a note with the syntax that did to this page of the wiki.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-90997568690065035252008-10-09T07:55:00.000-07:002008-10-09T07:56:20.160-07:00Byebye badware.Woot. Just finished removing everything related to Mono from my main Ubuntu system. Feels good.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com2tag:blogger.com,1999:blog-4168569003321900731.post-38063792679569873392008-10-08T17:05:00.000-07:002008-10-08T17:19:59.351-07:00Func Project Report 1So, after some time of thought, high-level study, and waiting for decisions to be made regarding exactly who's writing exactly what, real work on actually getting things done with <a href="http://fedorahosted.org/func/">Func</a> seems to have begun in earnest.<br /><br />Chris Tyler cooked up and cloned a small handful of Fedora VMs to use for our development and testing network, and so tonight I've taken to setting them up and trying to get all the pieces in place for a working Func environment - luckily, there don't seem to be too many. Installing Func itself was a breeze, but upon moving to actually setting them up to interact with one another it seems they expect a working DNS system around them - so, my current task is setting up bind. Luckily, that's something I've done a few times, so doing it again should only be a brief distraction from setting up Func itself.<br /><br />I'm still trying to get a firmer grasp on the Python language itself; while most of the concepts are familiar ones, I'm finding the actual syntax to be somewhat unappealing - to my eye, at least, it just doesn't read very well, and the flow seems somewhat unnatural to me. Nevertheless, while it seems unlikely that Python will become my language of choice, it's nothing a bit more time and practice won't solve. <br /><br />I've been skimming the actual Func code, the modules in particular, and while I haven't quite attained complete understanding of all the intricacies yet, my grasp is growing better the more I read.<br /><br />Back to bind.conf for me.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-45537399617778471452008-10-05T19:25:00.000-07:002008-10-05T19:33:15.085-07:00SPR720 Packaging LabSo I've just completed the SPR720 packaging lab. For my package, I'd chosen <a href="http://www.csounds.com/">Csound</a>, a C-like language for audio synthesis. The .spec file required some modification to be suitable, as Csound uses a Python-based build system called 'scons' and an accompanying 'install.py' script rather than the usual './configure && make' routine, but this part was fairly minor. Some additional modifications were required to compensate for Csound's tendency to, by default, place several of it's executables in '/bin' instead of '/usr/bin'. <br /><br />All in all, the process wasn't unusually dificult, but it might be nice if the documentation were given a bit more polish - maybe a seperate, more rudimentary tutorial on the procedures with more examples to accompany the main document.<br /><br />The RPM files produced can be found here <a href="http://matrix.senecac.on.ca/~gjmasseau/csound-rpms/">here</a>.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-38982136138116277472008-09-29T20:16:00.000-07:002008-09-29T20:19:09.171-07:00SPR Build Lab NotesFor the build lab, I downloaded the latest version of Csound (a C-like language for musical composition and synthesis in which source files compile to either audio or MIDI output files).<br /><br />Building the package was a little unusual, but not to dificult: rather than the standard configure and make set, the package had to be build using a system called 'scons'. After resolving this dependency, as well as acquiring the development headers for libsndfile, the build and install proceeded flawlessly.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-38141670357808222922008-09-29T14:58:00.000-07:002008-09-29T15:02:44.236-07:00LPT730 Lab #4 Reflections.The chart creation tools provided in OpenOffice.org's Calc application, are, to be frank, terrible. The interface is unintuitive and the output is unattractive at best. While the OpenOffice.org suite is certainly strong in other areas, in my opinion this particular feature is one that could use quite a bit of work.<br /><br />The creation of man pages is, as usual, a fairly straight forwards procedure, so nothing really new there. The only item of interest is what appears to be a slight bug in the software for which the man page was being written, which has been noted in the resulting man page and will hopefully be corrected.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-12444971609063566632008-09-22T13:51:00.000-07:002008-09-22T13:52:08.503-07:00Phishing and the Robots Exclusion StandardPhishing:<br /><br /> 'Phishing' is a term used to describe a variety of techniques for perpetuating criminal activities via the Internet by means of techniques revolving around the core mechanism of producing content intended to first decieve the consumer of said content into believing the content creator to be a trusted party and then proceeding to create a plausible motivation for the content consumer to take a course of action resulting in private information belonging to the content consumer being transmitted to the content creator. The type of personal information sought most often is banking or financial information such as bank account or credit card numbers. Common trusted parties that a phishing content creator may try to impersonate will often include (but are certainly not limited to) banks, insurance agencies or other financial institutions. The most common means of delivering the deceptive conent to content consumers is usually by means of an email message inviting the user to either reply to the email with one containing personal information, or to click on a link bringing them to a similarily deceptive website into which personal information may be entered. These are not the only means used, however, and email is not always involved - another popular technique is to purchase domain names closely resembling that of a trusted entity but with single letter typos, in the hopes of decieving unwary web surfers who may accidentally input the incorrect address into their browser and thereby come across the false site.<br /><br /> The best defense an individual user may take to avoid falling prey to such a scheme is unfortunately not a technical one that can be simply installed on their computer and trusted to do it's work, but simply perceptiveness on the part of the user. A user should take a critical eye towards any online communications with institutions likely to be impersonated. The deceptive content produced by phishers is often of less than sterling quality, and a careful observer is likely to take note of many minor errors in the text of the deceptive content. If the user has any suspicions regarding the veracity of the communication, they should immediately contact the trusted party by another channel, using contact information acquired previousl and known to be correct, and seek confirmation of whether the communication recieved was authentic.<br /><br /> Numerous technical measures exist with the goal of making it easier for users to determine whether a suspect email message or website is legitimate, but the problem is at it's core not a technical one, and as such no purely technical solution is truly able to solve the problem. Educating users as to how to identify false communications is the only method likely to have any impact.<br /><br /><br />Robot Exclusion Standard:<br /><br /> The Robot Exclusion Standard is an informal convention that has been adopted by many webmasters and search engine operators to allow webmasters to determine which pages on a particular website web robots - tools used by search providers to discover and index pages on the World Wide Web - will be allowed to index. This convention states that by including a specially formatted text file named robots.txt in the top directory of a web site, files and directories specified in this file will not be indexed by web robots complying with the standard.<br /><br /> The biggest weakness is that as this is an informal convention there is no particular requirement that any given piece of web robot software obey the standard, and providers who wish to disobey the standard are as such able to do so largely at their leisure, with no particular legal countermeasure possible to discourage such behaviour.<br /><br /> An example robots.txt configuration, taken from my personal home web server, is as follows:<br /><br /> User-agent: *<br /> Disallow: /<br /><br /> When the robots.txt file is configured as above, all cooperating web robots will refrain from indexing any content on the web site in question.<br /><br /><br />References: <br /> (This section left blank as no published articles or other sources of information were referenced during the writing of this article.)gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-87080469018956769532008-09-22T12:50:00.000-07:002008-09-22T12:56:55.110-07:00SPR720 Lab #3Most of the material in this particular lab was already familiar to me - most of it, from personal experience and usage, and a little that I picked up in OPS435. I'm honestly pretty confident in my bash scripting skills, and while it's definitely not my language of choice for most purposes these days it can still be useful for creating quick and dirty, usually temporary solutions to small obstacles blocking the route to a solution to some larger problem. For review, I completed the following scripts from the list of suggestions accompanying the lab: <br /><br />Count the number of users with user IDs between 500 and 10000 on the system (user IDs are the third field in /etc/passwd).<br />Count the number of files in the user's home directory which are not readable.<br />For each directory in the $PATH, display the number of executable files in that directory.<br /><br />The programs solving these problems can be found <a href="http://bombshelter13.dyndns.org/stuff/spr720lab/">here</a>.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-89921295009647628962008-09-16T06:01:00.000-07:002008-09-16T06:07:42.389-07:00NAD710 Lab #2 ReflectionsLab two for this course was at least a little more interesting, as I got to encounter at least one new tool this time. While a lot of the tools used, like ifconfig, the arp commands, etc., were already familiar to me due to either personal use or previous experience in other courses, the 'ip' tool for configuring the network card was something I hadn't used before. The 'ip' tool's syntax reminds me of the style of syntax used for configuring network interfaces on Cisco router's, though it's not quite identical in a few places. 'tcpdump' was also new - I've used tools with similar functionality from the GUI, but it's always preferable to have a command-line version if possible, so I'll probably be playing with this tool a bit more in my spare time.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-10059999358633449972008-09-12T12:56:00.000-07:002008-09-12T13:03:02.719-07:00SYA710 Lab 01 ThoughtsSYA710 Lab 01 has been submitted, and mostly felt like review for me. A lot of the material covered in this particular lab bears a good resemblence to things I've done in some other classes, and I'd encountered most of the more basic file and disk utilities shown for several years on my home systems even before then. While I don't have quite as much experience with LVM as with the other tools listed, I'm pretty confident with that toolset as well -- it's always good to review though. Most of my multi-disk setups at home revolve around the md raid system rather than LVM, and learning alternative/complimentary tools is always useful -- maybe next time one of the home servers gets rebuilt I'll layer LVM with md, just for fun.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0tag:blogger.com,1999:blog-4168569003321900731.post-91534326258194707302008-09-12T08:12:00.000-07:002008-09-12T08:15:36.555-07:00LPT730 Lab01<u>Software Patents</u><br /><br /> I do not believe that software patents are a good idea in general, at least not in the form in which they currently exist in most countries. <br /><br /> A large part of the dificulty comes from the fact that software patents are dificult for usual patent office employees to evaluate effectively, and as such a disturbingly high number of approved patents have been granted that, most likely, should not have been. When evaluating a patent application for a software practice, patent reviewers do not have time to learn an entire new discipline, and patent reviewers are typically not software developers and are unlikely to fully understand the material contained within the patent application. As such, many 'bad' software patents exist. Usually, the element making these patents 'bad' is that many times patents have been granted for broadly defined techniques or strategies, rather than merely for a particular specific implementation -- and, as per normal practices in the granting of patents, patents are intended to apply only to particular implementations or methods of accomplishing a goal.<br /><br /> While I don't necessarily see anything wrong with patenting a particular, specific implementation for achieving a particular goal in software, the cost of the patent office retaining evaluators knowledgeable enough to effectively evaluate these patens is one that most governments are unlikely to be willing to pay. Needless to say, if the patent office was handling the granting of software patents in an effective manner, these patents would become far less valuable to companies, as the chances of recieving a broad patent that one could use to litigate their way to riches would be far less likely.<br /><br /><u>Bill C-61</u><br /><br /> While the odds of Bill C-61 becoming law in Canada currently appear to be low, I would still be in favour of such a law, if not for the reasons one might think. <br /><br /> Bill C-61 would, if passed, imply many onerous new restrictions on how an end user may make use of copyrighted content they own, mostly in the area of making the circumvention of technical measures intended to prevent the copying of data an illegal act.<br /><br /> Many in the open source community are up in arms over the restrictions on users' freedom that this bill would imply, being as usual all for the freedom to do what they wish with information in their posesssion. I would suggesst, however, that they look at things in a different light: what Bill C-61 really does is make using, posessing, or acquiring copyrighted content distributed under a proprietary liscence far less attractive than it was previously. The more careful the user has to be with handling the information, the more they have to worry about accidentally doing something illegal with it and not realizing it until it is too late, the less they will want to have anything to do with this dangerous, legally risky proprietary media.gregorymasseauhttp://www.blogger.com/profile/01711476479063422079noreply@blogger.com0