[quote]
The paste utility concatenates the corresponding lines of the given input
files, replacing all but the last file's newline characters with a single
tab character,
[/quote]
tab
Oh.
Name:
Anonymous2012-04-13 19:49
Why should I use Plan 9 if I have Haiku?
Name:
Anonymous2012-04-13 20:13
I'm using open genera, a LISP OS made for programming
>>19
That doesn't matter. The language and the programs either performs its job at controlling the computer or it doesn't. Limbo works and Inferno works.
It's running on top of the Android Loonix kernel because of PROPRIETARY DRIVERS THAT DO NOT RESPECT YOUR FREEDOM, but Inferno was always meant to run virtually on many different platforms.
Name:
Anonymous2012-04-14 5:33
The GUI is simple and beautiful
Ha-ha. No. It's uglier than xterm. Also it lacks software.
Because Plan 9 is a great environment for programmers to learn and explore, and is not diluted by attempts to make it practical for or popular with lay users.
Name:
surrealdeal2012-04-15 20:30
It's benefits aren't all that compelling, and anyone that would be interested in it is already fluent enough in *nix not to give a fuck about it
The GUI is a good idea, it's just too much of a paradigm shift from the WIMP stuff we're all used to. And that's a bad thing.
It is kind of cool as an historic interest though, much like the Blit.
Name:
Anonymous2012-04-16 5:57
>>28
Literally any resource you can access in a Plan 9 system is a file. Network resources can be easily accessed by mounting the remote system into an empty directory. These two powerful features means that Plan 9 systems are very flexible and yet, easy to use for a huge number of modern use cases.
>>32 Literally any resource you can access in a Plan 9 system is a file. Network resources can be easily accessed by mounting the remote system into an empty directory.
So how do I mount /prague/ somewhere?
Name:
Anonymous2012-04-16 10:50
>>34
Actually, I don't know how to do that. I'll need to look into that.
Name:
Anonymous2012-04-16 11:04
Because I can install GNU/Linux on any computer on the side of the road too.
webfs[1] already exists; writing a progfs on top of it would be trivial.
One might use it like this:
% progfs
% ls /mnt/prog/frontpage
free programming classes
why arent you using plan 9
sepples
jews enslave us
aaa penis
excel function
multithreading for fagstorms
anus
% ls '/mnt/prog/frontpage/why arent you using plan 9'
date
count
posts
% cat '/mnt/prog/frontpage/why arent you using plan 9/count'
39
% cat '/mnt/prog/frontpage/why arent you using plan 9/posts/38'
38 Name: Anonymous : 2012-04-16 19:31
>>37
Doing it the Plan 9 way is a matter of implementing a progscrape filesystem (or a more general httpfs).
%
Now that I wrote all this I think I want to go implement it!
Not really what we were talking about, but here's a FUSE progfs. You'll need http://code.google.com/p/fusepy/.
It's twice as slow as balls and it doesn't properly set mtime/ctime/atime because it does very little caching and I don't want getattr to instigate a web request every time, but it kind of works. Someone else can figure out how to export it over 9P.
#!/usr/bin/python
import argparse
import errno
import json
import os
import re
import stat
import sys
import time
import urllib2
def parse_path(path):
"""
Paths are at most three levels deep. This always returns a three-member
list and fills the blanks with None.
"""
path = filter(None, path.split('/'))
if len(path) > 3:
raise fuse.FuseOSError(errno.ENOENT)
while len(path) < 3:
path.append(None)
return path
def parse_name(name):
"""
Takes the contents of the name field and returns ['name!trip', 'email'].
"""
m = re.match(name,
'^([^<]*)<a href="mailto:([^"]*)">([^<]*)</a>(.*)$',
re.DOTALL)
if m is None:
return '', ''
else:
return ''.join(m.group(1), m.group(3), m.group(4)), m.group(2)
class HeadRequest(urllib2.Request):
"""Makes a HEAD request rather than GET."""
get_method = lambda self: 'HEAD'
def _get_subject_txt(self):
"""
Checks if subject.txt has changed, and if so, fetches the new file
and updates the threads table.
"""
r = urllib2.urlopen(HeadRequest(self.subject_url))
if self.last_modified >= unix_time(r.headers.getheader('last-modified')):
# No change. Stop now.
r.close()
return
r.close()
r = urllib2.urlopen(self.subject_url)
self.last_modified = unix_time(r.headers.getheader('last-modified'))
regex = re.compile(u"""
^(?P<subject>.*) # Subject
<>
.*? # Creator's name
<>
.*? # Thread icon
<>
(?P<id>-?\d*) # Time posted/thread ID
<>
(?P<replies>\d*) # Number of replies
<>
.*? # ???
<>
(?P<last_post>\d*) # Time of last post
\\n$""", re.VERBOSE)
for line in r.readlines():
# FIXME this loop is slow as balls
# Replacing the regex with split('<>') is faster, but Shiichan is
# full of corner cases and that loses /prog/ threads.
thread = regex.match(line).groupdict()
if thread['id'] not in self.threads:
self.threads[thread['id']] = {}
self.threads[thread['id']]['title'] = thread['subject']
self.threads[thread['id']]['last_modified'] = \
float(thread['last_post'])
self.threads[thread['id']]['posts'] = \
int(thread['replies'])
r.close()
if path[1] == 'title' and not path[2]:
# Thread title file
return {'st_mode': (stat.S_IFREG | 0444),
'st_ctime': float(path[0]),
'st_mtime': float(path[0]),
'st_atime': float(path[0]),
'st_size': 1024,
'st_uid': os.getuid(),
'st_gid': os.getgid()}
try:
path[1] = int(path[1])
except ValueError:
# Not a post folder
raise fuse.FuseOSError(errno.ENOENT)
if path[1] < 1 or path[1] > self.threads[path[0]]['posts']:
# Post index out of range
raise fuse.FuseOSError(errno.ENOENT)
if not path[2]:
# Post folder
# TODO fetch post for accurate times
return {'st_mode': (stat.S_IFDIR | 0555),
'st_ctime': self.threads[path[0]]['last_modified'],
'st_mtime': self.threads[path[0]]['last_modified'],
'st_atime': self.threads[path[0]]['last_modified'],
'st_uid': os.getuid(),
'st_gid': os.getgid()}
if path[2] not in ('poster', 'email', 'body'):
raise fuse.FuseOSError(errno.ENOENT)
# Post data file
# TODO fetch post for accurate times
return {'st_mode': (stat.S_IFREG | 0444),
'st_ctime': self.threads[path[0]]['last_modified'],
'st_mtime': self.threads[path[0]]['last_modified'],
'st_atime': self.threads[path[0]]['last_modified'],
'st_size': 1024 * 1024,
'st_uid': os.getuid(),
'st_gid': os.getgid()}