diff options
author | Tim Peters <tim.peters@gmail.com> | 2004-07-18 05:56:09 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2004-07-18 05:56:09 (GMT) |
commit | e6ddc8b20b493fef2e7cffb2e1351fe1d238857e (patch) | |
tree | 3b3d8fcd92e1d8f0cad44297d5c2ae8522bb984c /Demo | |
parent | 4fba4521e836e0cab08316592392b1e4d06eb6ef (diff) | |
download | cpython-e6ddc8b20b493fef2e7cffb2e1351fe1d238857e.zip cpython-e6ddc8b20b493fef2e7cffb2e1351fe1d238857e.tar.gz cpython-e6ddc8b20b493fef2e7cffb2e1351fe1d238857e.tar.bz2 |
Whitespace normalization. Ran reindent.py over the entire source tree.
Diffstat (limited to 'Demo')
61 files changed, 5242 insertions, 5253 deletions
diff --git a/Demo/curses/life.py b/Demo/curses/life.py index 4ce09d2..a787e26 100755 --- a/Demo/curses/life.py +++ b/Demo/curses/life.py @@ -11,7 +11,7 @@ # Cursor keys : Move the cursor around the board # Space or Enter : Toggle the contents of the cursor's position # -# TODO : +# TODO : # Support the mouse # Use colour if available # Make board updates faster @@ -26,11 +26,11 @@ class LifeBoard: Attributes: X,Y : horizontal and vertical size of the board state : dictionary mapping (x,y) to 0 or 1 - + Methods: - display(update_board) -- If update_board is true, compute the + display(update_board) -- If update_board is true, compute the next generation. Then display the state - of the board and refresh the screen. + of the board and refresh the screen. erase() -- clear the entire board makeRandom() -- fill the board randomly set(y,x) -- set the given cell to Live; doesn't refresh the screen @@ -39,90 +39,90 @@ class LifeBoard: """ def __init__(self, scr, char=ord('*')): - """Create a new LifeBoard instance. - - scr -- curses screen object to use for display - char -- character used to render live cells (default: '*') - """ - self.state={} ; self.scr=scr - Y, X = self.scr.getmaxyx() - self.X, self.Y = X-2, Y-2-1 - self.char = char - self.scr.clear() - - # Draw a border around the board - border_line='+'+(self.X*'-')+'+' - self.scr.addstr(0, 0, border_line) - self.scr.addstr(self.Y+1,0, border_line) - for y in range(0, self.Y): - self.scr.addstr(1+y, 0, '|') - self.scr.addstr(1+y, self.X+1, '|') - self.scr.refresh() - - def set(self, y, x): - """Set a cell to the live state""" - if x<0 or self.X<=x or y<0 or self.Y<=y: - raise ValueError, "Coordinates out of range %i,%i"% (y,x) - self.state[x,y] = 1 - - def toggle(self, y, x): - """Toggle a cell's state between live and dead""" - if x<0 or self.X<=x or y<0 or self.Y<=y: - raise ValueError, "Coordinates out of range %i,%i"% (y,x) - if self.state.has_key( (x,y) ): - del self.state[x,y] - self.scr.addch(y+1, x+1, ' ') - else: - self.state[x,y]=1 - self.scr.addch(y+1, x+1, self.char) - self.scr.refresh() + """Create a new LifeBoard instance. + + scr -- curses screen object to use for display + char -- character used to render live cells (default: '*') + """ + self.state={} ; self.scr=scr + Y, X = self.scr.getmaxyx() + self.X, self.Y = X-2, Y-2-1 + self.char = char + self.scr.clear() + + # Draw a border around the board + border_line='+'+(self.X*'-')+'+' + self.scr.addstr(0, 0, border_line) + self.scr.addstr(self.Y+1,0, border_line) + for y in range(0, self.Y): + self.scr.addstr(1+y, 0, '|') + self.scr.addstr(1+y, self.X+1, '|') + self.scr.refresh() + + def set(self, y, x): + """Set a cell to the live state""" + if x<0 or self.X<=x or y<0 or self.Y<=y: + raise ValueError, "Coordinates out of range %i,%i"% (y,x) + self.state[x,y] = 1 + + def toggle(self, y, x): + """Toggle a cell's state between live and dead""" + if x<0 or self.X<=x or y<0 or self.Y<=y: + raise ValueError, "Coordinates out of range %i,%i"% (y,x) + if self.state.has_key( (x,y) ): + del self.state[x,y] + self.scr.addch(y+1, x+1, ' ') + else: + self.state[x,y]=1 + self.scr.addch(y+1, x+1, self.char) + self.scr.refresh() def erase(self): - """Clear the entire board and update the board display""" - self.state={} - self.display(update_board=0) + """Clear the entire board and update the board display""" + self.state={} + self.display(update_board=0) def display(self, update_board=1): - """Display the whole board, optionally computing one generation""" - M,N = self.X, self.Y - if not update_board: - for i in range(0, M): - for j in range(0, N): - if self.state.has_key( (i,j) ): - self.scr.addch(j+1, i+1, self.char) - else: - self.scr.addch(j+1, i+1, ' ') - self.scr.refresh() - return - - d={} ; self.boring=1 - for i in range(0, M): - L=range( max(0, i-1), min(M, i+2) ) - for j in range(0, N): - s=0 - live=self.state.has_key( (i,j) ) - for k in range( max(0, j-1), min(N, j+2) ): - for l in L: - if self.state.has_key( (l,k) ): - s=s+1 - s=s-live - if s==3: - # Birth - d[i,j]=1 - self.scr.addch(j+1, i+1, self.char) - if not live: self.boring=0 - elif s==2 and live: d[i,j]=1 # Survival - elif live: - # Death - self.scr.addch(j+1, i+1, ' ') - self.boring=0 - self.state=d - self.scr.refresh() + """Display the whole board, optionally computing one generation""" + M,N = self.X, self.Y + if not update_board: + for i in range(0, M): + for j in range(0, N): + if self.state.has_key( (i,j) ): + self.scr.addch(j+1, i+1, self.char) + else: + self.scr.addch(j+1, i+1, ' ') + self.scr.refresh() + return + + d={} ; self.boring=1 + for i in range(0, M): + L=range( max(0, i-1), min(M, i+2) ) + for j in range(0, N): + s=0 + live=self.state.has_key( (i,j) ) + for k in range( max(0, j-1), min(N, j+2) ): + for l in L: + if self.state.has_key( (l,k) ): + s=s+1 + s=s-live + if s==3: + # Birth + d[i,j]=1 + self.scr.addch(j+1, i+1, self.char) + if not live: self.boring=0 + elif s==2 and live: d[i,j]=1 # Survival + elif live: + # Death + self.scr.addch(j+1, i+1, ' ') + self.boring=0 + self.state=d + self.scr.refresh() def makeRandom(self): - "Fill the board with a random pattern" - self.state={} - for i in range(0, self.X): + "Fill the board with a random pattern" + self.state={} + for i in range(0, self.X): for j in range(0, self.Y): if random.random() > 0.5: self.set(j,i) @@ -149,7 +149,7 @@ def main(stdscr): display_menu(stdscr, menu_y) # Allocate a subwindow for the Life board and create the board object - subwin=stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0) + subwin=stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0) board=LifeBoard(subwin, char=ord('*')) board.display(update_board=0) @@ -158,66 +158,65 @@ def main(stdscr): # Main loop: while (1): - stdscr.move(1+ypos, 1+xpos) # Move the cursor - c=stdscr.getch() # Get a keystroke - if 0<c<256: - c=chr(c) - if c in ' \n': - board.toggle(ypos, xpos) - elif c in 'Cc': - erase_menu(stdscr, menu_y) - stdscr.addstr(menu_y, 6, ' Hit any key to stop continuously ' - 'updating the screen.') - stdscr.refresh() - # Activate nodelay mode; getch() will return -1 - # if no keystroke is available, instead of waiting. - stdscr.nodelay(1) - while (1): - c=stdscr.getch() - if c!=-1: break - stdscr.addstr(0,0, '/'); stdscr.refresh() - board.display() - stdscr.addstr(0,0, '+'); stdscr.refresh() - - stdscr.nodelay(0) # Disable nodelay mode - display_menu(stdscr, menu_y) - - elif c in 'Ee': board.erase() - elif c in 'Qq': break - elif c in 'Rr': - board.makeRandom() - board.display(update_board=0) - elif c in 'Ss': - board.display() - else: pass # Ignore incorrect keys - elif c==curses.KEY_UP and ypos>0: ypos=ypos-1 - elif c==curses.KEY_DOWN and ypos<board.Y-1: ypos=ypos+1 - elif c==curses.KEY_LEFT and xpos>0: xpos=xpos-1 - elif c==curses.KEY_RIGHT and xpos<board.X-1: xpos=xpos+1 - else: pass # Ignore incorrect keys + stdscr.move(1+ypos, 1+xpos) # Move the cursor + c=stdscr.getch() # Get a keystroke + if 0<c<256: + c=chr(c) + if c in ' \n': + board.toggle(ypos, xpos) + elif c in 'Cc': + erase_menu(stdscr, menu_y) + stdscr.addstr(menu_y, 6, ' Hit any key to stop continuously ' + 'updating the screen.') + stdscr.refresh() + # Activate nodelay mode; getch() will return -1 + # if no keystroke is available, instead of waiting. + stdscr.nodelay(1) + while (1): + c=stdscr.getch() + if c!=-1: break + stdscr.addstr(0,0, '/'); stdscr.refresh() + board.display() + stdscr.addstr(0,0, '+'); stdscr.refresh() + + stdscr.nodelay(0) # Disable nodelay mode + display_menu(stdscr, menu_y) + + elif c in 'Ee': board.erase() + elif c in 'Qq': break + elif c in 'Rr': + board.makeRandom() + board.display(update_board=0) + elif c in 'Ss': + board.display() + else: pass # Ignore incorrect keys + elif c==curses.KEY_UP and ypos>0: ypos=ypos-1 + elif c==curses.KEY_DOWN and ypos<board.Y-1: ypos=ypos+1 + elif c==curses.KEY_LEFT and xpos>0: xpos=xpos-1 + elif c==curses.KEY_RIGHT and xpos<board.X-1: xpos=xpos+1 + else: pass # Ignore incorrect keys if __name__=='__main__': try: - # Initialize curses - stdscr=curses.initscr() - # Turn off echoing of keys, and enter cbreak mode, - # where no buffering is performed on keyboard input - curses.noecho() ; curses.cbreak() - - # In keypad mode, escape sequences for special keys - # (like the cursor keys) will be interpreted and - # a special value like curses.KEY_LEFT will be returned - stdscr.keypad(1) - main(stdscr) # Enter the main loop - # Set everything back to normal - stdscr.keypad(0) - curses.echo() ; curses.nocbreak() - curses.endwin() # Terminate curses + # Initialize curses + stdscr=curses.initscr() + # Turn off echoing of keys, and enter cbreak mode, + # where no buffering is performed on keyboard input + curses.noecho() ; curses.cbreak() + + # In keypad mode, escape sequences for special keys + # (like the cursor keys) will be interpreted and + # a special value like curses.KEY_LEFT will be returned + stdscr.keypad(1) + main(stdscr) # Enter the main loop + # Set everything back to normal + stdscr.keypad(0) + curses.echo() ; curses.nocbreak() + curses.endwin() # Terminate curses except: # In the event of an error, restore the terminal - # to a sane state. - stdscr.keypad(0) - curses.echo() ; curses.nocbreak() - curses.endwin() - traceback.print_exc() # Print the exception - + # to a sane state. + stdscr.keypad(0) + curses.echo() ; curses.nocbreak() + curses.endwin() + traceback.print_exc() # Print the exception diff --git a/Demo/curses/ncurses.py b/Demo/curses/ncurses.py index 96aa142..c9394d0 100644 --- a/Demo/curses/ncurses.py +++ b/Demo/curses/ncurses.py @@ -209,7 +209,7 @@ def demo_panels(win): w5.addstr(mod[itmp]) pflush() wait_a_while() - + saywhat("m5; press any key to continue") w4.move(curses.LINES / 6, 1) w4.addstr(mod[itmp]) @@ -218,7 +218,7 @@ def demo_panels(win): w5.addstr(mod[itmp]) pflush() wait_a_while() - + saywhat("m4; press any key to continue") p4.move(curses.LINES / 6, (itmp + 1) * curses.COLS / 8) pflush() diff --git a/Demo/curses/rain.py b/Demo/curses/rain.py index 2399d7f..69794b3 100644 --- a/Demo/curses/rain.py +++ b/Demo/curses/rain.py @@ -27,18 +27,18 @@ def main(win): # Initialize it globally for convenience. global stdscr stdscr = win - + if curses.has_colors(): bg = curses.COLOR_BLACK curses.init_pair(1, curses.COLOR_BLUE, bg) curses.init_pair(2, curses.COLOR_CYAN, bg) - + curses.nl() curses.noecho() # XXX curs_set() always returns ERR # curses.curs_set(0) stdscr.timeout(0) - + c = curses.COLS - 4 r = curses.LINES - 4 xpos = [0] * c @@ -46,38 +46,38 @@ def main(win): for j in range(4, -1, -1): xpos[j] = randrange(0, c) + 2 ypos[j] = randrange(0, r) + 2 - + j = 0 while 1: x = randrange(0, c) + 2 y = randrange(0, r) + 2 - + stdscr.addch(y, x, ord('.')) - + stdscr.addch(ypos[j], xpos[j], ord('o')) - + j = next_j(j) stdscr.addch(ypos[j], xpos[j], ord('O')) - + j = next_j(j) stdscr.addch( ypos[j] - 1, xpos[j], ord('-')) stdscr.addstr(ypos[j], xpos[j] - 1, "|.|") stdscr.addch( ypos[j] + 1, xpos[j], ord('-')) - + j = next_j(j) stdscr.addch( ypos[j] - 2, xpos[j], ord('-')) stdscr.addstr(ypos[j] - 1, xpos[j] - 1, "/ \\") stdscr.addstr(ypos[j], xpos[j] - 2, "| O |") stdscr.addstr(ypos[j] + 1, xpos[j] - 1, "\\ /") stdscr.addch( ypos[j] + 2, xpos[j], ord('-')) - + j = next_j(j) stdscr.addch( ypos[j] - 2, xpos[j], ord(' ')) stdscr.addstr(ypos[j] - 1, xpos[j] - 1, " ") stdscr.addstr(ypos[j], xpos[j] - 2, " ") stdscr.addstr(ypos[j] + 1, xpos[j] - 1, " ") stdscr.addch( ypos[j] + 2, xpos[j], ord(' ')) - + xpos[j] = x ypos[j] = y @@ -90,5 +90,5 @@ def main(win): stdscr.nodelay(1) curses.napms(50) - + curses.wrapper(main) diff --git a/Demo/curses/tclock.py b/Demo/curses/tclock.py index f423e9a..1950043 100644 --- a/Demo/curses/tclock.py +++ b/Demo/curses/tclock.py @@ -66,7 +66,7 @@ def dline(pair, from_x, from_y, x2, y2, ch): def main(win): global stdscr stdscr = win - + lastbeep = -1 my_bg = curses.COLOR_BLACK @@ -80,7 +80,7 @@ def main(win): cx = (curses.COLS - 1) / 2 cy = curses.LINES / 2 - ch = min( cy-1, int(cx / ASPECT) - 1) + ch = min( cy-1, int(cx / ASPECT) - 1) mradius = (3 * ch) / 4 hradius = ch / 2 sradius = 5 * ch / 6 @@ -95,7 +95,7 @@ def main(win): "ASCII Clock by Howard Jones <ha.jones@ic.ac.uk>, 1994") sradius = max(sradius-4, 8) - + while 1: curses.napms(1000) @@ -125,7 +125,7 @@ def main(win): stdscr.attrset(curses.color_pair(1)) plot(cx + sdx, cy - sdy, ord('O')) - + if curses.has_colors(): stdscr.attrset(curses.color_pair(0)) diff --git a/Demo/curses/xmas.py b/Demo/curses/xmas.py index 99c7087..e51bc5f 100644 --- a/Demo/curses/xmas.py +++ b/Demo/curses/xmas.py @@ -66,9 +66,9 @@ def seas(): stdscr.addch(14, 1, ord('N')) stdscr.addch(16, 1, ord("'")) stdscr.addch(18, 1, ord('S')) - + return - + def greet(): stdscr.addch(3, 5, ord('G')) stdscr.addch(5, 5, ord('R')) @@ -300,7 +300,7 @@ def blinkit(): break treescrn8.touchwin() - + # ALL ON treescrn.overlay(treescrn8) treescrn8.refresh() @@ -347,10 +347,10 @@ def reindeer(): else: dotdeer0.addch(y_pos, x_pos, ord('*')) dotdeer0.refresh() - w_del_msg.refresh() - dotdeer0.erase() - dotdeer0.refresh() - w_del_msg.refresh() + w_del_msg.refresh() + dotdeer0.erase() + dotdeer0.refresh() + w_del_msg.refresh() x_pos = 58 @@ -360,76 +360,76 @@ def reindeer(): w_del_msg.refresh() for looper in range(0, 4): - deer_step(lildeer3, y_pos, x_pos) - deer_step(lildeer2, y_pos, x_pos) - deer_step(lildeer1, y_pos, x_pos) - deer_step(lildeer2, y_pos, x_pos) - deer_step(lildeer3, y_pos, x_pos) - - lildeer0.touchwin() - lildeer0.refresh() - w_del_msg.refresh() + deer_step(lildeer3, y_pos, x_pos) + deer_step(lildeer2, y_pos, x_pos) + deer_step(lildeer1, y_pos, x_pos) + deer_step(lildeer2, y_pos, x_pos) + deer_step(lildeer3, y_pos, x_pos) + + lildeer0.touchwin() + lildeer0.refresh() + w_del_msg.refresh() - x_pos -= 2 + x_pos -= 2 x_pos = 35 for y_pos in range(5, 10): - middeer0.touchwin() - middeer0.refresh() - w_del_msg.refresh() + middeer0.touchwin() + middeer0.refresh() + w_del_msg.refresh() for looper in range(0, 2): - deer_step(middeer3, y_pos, x_pos) - deer_step(middeer2, y_pos, x_pos) - deer_step(middeer1, y_pos, x_pos) - deer_step(middeer2, y_pos, x_pos) - deer_step(middeer3, y_pos, x_pos) - - middeer0.touchwin() - middeer0.refresh() - w_del_msg.refresh() + deer_step(middeer3, y_pos, x_pos) + deer_step(middeer2, y_pos, x_pos) + deer_step(middeer1, y_pos, x_pos) + deer_step(middeer2, y_pos, x_pos) + deer_step(middeer3, y_pos, x_pos) + + middeer0.touchwin() + middeer0.refresh() + w_del_msg.refresh() - x_pos -= 3 + x_pos -= 3 look_out(300) y_pos = 1 for x_pos in range(8, 16): - deer_step(bigdeer4, y_pos, x_pos) - deer_step(bigdeer3, y_pos, x_pos) - deer_step(bigdeer2, y_pos, x_pos) - deer_step(bigdeer1, y_pos, x_pos) - deer_step(bigdeer2, y_pos, x_pos) - deer_step(bigdeer3, y_pos, x_pos) - deer_step(bigdeer4, y_pos, x_pos) - deer_step(bigdeer0, y_pos, x_pos) + deer_step(bigdeer4, y_pos, x_pos) + deer_step(bigdeer3, y_pos, x_pos) + deer_step(bigdeer2, y_pos, x_pos) + deer_step(bigdeer1, y_pos, x_pos) + deer_step(bigdeer2, y_pos, x_pos) + deer_step(bigdeer3, y_pos, x_pos) + deer_step(bigdeer4, y_pos, x_pos) + deer_step(bigdeer0, y_pos, x_pos) x_pos -= 1 for looper in range(0, 6): - deer_step(lookdeer4, y_pos, x_pos) - deer_step(lookdeer3, y_pos, x_pos) - deer_step(lookdeer2, y_pos, x_pos) - deer_step(lookdeer1, y_pos, x_pos) - deer_step(lookdeer2, y_pos, x_pos) - deer_step(lookdeer3, y_pos, x_pos) - deer_step(lookdeer4, y_pos, x_pos) + deer_step(lookdeer4, y_pos, x_pos) + deer_step(lookdeer3, y_pos, x_pos) + deer_step(lookdeer2, y_pos, x_pos) + deer_step(lookdeer1, y_pos, x_pos) + deer_step(lookdeer2, y_pos, x_pos) + deer_step(lookdeer3, y_pos, x_pos) + deer_step(lookdeer4, y_pos, x_pos) deer_step(lookdeer0, y_pos, x_pos) for y_pos in range(y_pos, 10): for looper in range(0, 2): - deer_step(bigdeer4, y_pos, x_pos) - deer_step(bigdeer3, y_pos, x_pos) - deer_step(bigdeer2, y_pos, x_pos) - deer_step(bigdeer1, y_pos, x_pos) - deer_step(bigdeer2, y_pos, x_pos) - deer_step(bigdeer3, y_pos, x_pos) - deer_step(bigdeer4, y_pos, x_pos) - deer_step(bigdeer0, y_pos, x_pos) + deer_step(bigdeer4, y_pos, x_pos) + deer_step(bigdeer3, y_pos, x_pos) + deer_step(bigdeer2, y_pos, x_pos) + deer_step(bigdeer1, y_pos, x_pos) + deer_step(bigdeer2, y_pos, x_pos) + deer_step(bigdeer3, y_pos, x_pos) + deer_step(bigdeer4, y_pos, x_pos) + deer_step(bigdeer0, y_pos, x_pos) y_pos -= 1 @@ -439,7 +439,7 @@ def reindeer(): def main(win): global stdscr stdscr = win - + global my_bg, y_pos, x_pos global treescrn, treescrn2, treescrn3, treescrn4 global treescrn5, treescrn6, treescrn7, treescrn8 @@ -452,7 +452,7 @@ def main(win): my_bg = curses.COLOR_BLACK # curses.curs_set(0) - + treescrn = curses.newwin(16, 27, 3, 53) treescrn2 = curses.newwin(16, 27, 3, 53) treescrn3 = curses.newwin(16, 27, 3, 53) @@ -461,37 +461,37 @@ def main(win): treescrn6 = curses.newwin(16, 27, 3, 53) treescrn7 = curses.newwin(16, 27, 3, 53) treescrn8 = curses.newwin(16, 27, 3, 53) - + dotdeer0 = curses.newwin(3, 71, 0, 8) - + stardeer0 = curses.newwin(4, 56, 0, 8) - + lildeer0 = curses.newwin(7, 53, 0, 8) lildeer1 = curses.newwin(2, 4, 0, 0) lildeer2 = curses.newwin(2, 4, 0, 0) lildeer3 = curses.newwin(2, 4, 0, 0) - + middeer0 = curses.newwin(15, 42, 0, 8) middeer1 = curses.newwin(3, 7, 0, 0) middeer2 = curses.newwin(3, 7, 0, 0) middeer3 = curses.newwin(3, 7, 0, 0) - + bigdeer0 = curses.newwin(10, 23, 0, 0) bigdeer1 = curses.newwin(10, 23, 0, 0) bigdeer2 = curses.newwin(10, 23, 0, 0) bigdeer3 = curses.newwin(10, 23, 0, 0) bigdeer4 = curses.newwin(10, 23, 0, 0) - + lookdeer0 = curses.newwin(10, 25, 0, 0) lookdeer1 = curses.newwin(10, 25, 0, 0) lookdeer2 = curses.newwin(10, 25, 0, 0) lookdeer3 = curses.newwin(10, 25, 0, 0) lookdeer4 = curses.newwin(10, 25, 0, 0) - + w_holiday = curses.newwin(1, 27, 3, 27) - + w_del_msg = curses.newwin(1, 20, 23, 60) - + try: w_del_msg.addstr(0, 0, "Hit any key to quit") except curses.error: @@ -501,7 +501,7 @@ def main(win): w_holiday.addstr(0, 0, "H A P P Y H O L I D A Y S") except curses.error: pass - + # set up the windows for our various reindeer lildeer1.addch(0, 0, ord('V')) lildeer1.addch(1, 0, ord('@')) @@ -511,7 +511,7 @@ def main(win): lildeer1.addch(1, 3, ord('~')) except curses.error: pass - + lildeer2.addch(0, 0, ord('V')) lildeer2.addch(1, 0, ord('@')) lildeer2.addch(1, 1, ord('|')) @@ -520,16 +520,16 @@ def main(win): lildeer2.addch(1, 3, ord('~')) except curses.error: pass - + lildeer3.addch(0, 0, ord('V')) lildeer3.addch(1, 0, ord('@')) lildeer3.addch(1, 1, ord('>')) lildeer3.addch(1, 2, ord('<')) try: - lildeer2.addch(1, 3, ord('~')) # XXX + lildeer2.addch(1, 3, ord('~')) # XXX except curses.error: pass - + middeer1.addch(0, 2, ord('y')) middeer1.addch(0, 3, ord('y')) middeer1.addch(1, 2, ord('0')) @@ -539,7 +539,7 @@ def main(win): middeer1.addch(1, 6, ord('~')) middeer1.addch(2, 3, ord('\\')) middeer1.addch(2, 5, ord('/')) - + middeer2.addch(0, 2, ord('y')) middeer2.addch(0, 3, ord('y')) middeer2.addch(1, 2, ord('0')) @@ -549,7 +549,7 @@ def main(win): middeer2.addch(1, 6, ord('~')) middeer2.addch(2, 3, ord('|')) middeer2.addch(2, 5, ord('|')) - + middeer3.addch(0, 2, ord('y')) middeer3.addch(0, 3, ord('y')) middeer3.addch(1, 2, ord('0')) @@ -577,11 +577,11 @@ def main(win): bigdeer1.addch(4, 19, ord('\\')) bigdeer1.addch(4, 22, ord('\\')) bigdeer1.addstr(5, 7, "^~~~~~~~~// ~~U") - bigdeer1.addstr(6, 7, "( \\_____( /") # )) + bigdeer1.addstr(6, 7, "( \\_____( /") # )) bigdeer1.addstr(7, 8, "( ) /") bigdeer1.addstr(8, 9, "\\\\ /") bigdeer1.addstr(9, 11, "\\>/>") - + bigdeer2.addch(0, 17, ord('\\')) bigdeer2.addch(0, 18, ord('/')) bigdeer2.addch(0, 19, ord('\\')) @@ -599,11 +599,11 @@ def main(win): bigdeer2.addch(4, 19, ord('\\')) bigdeer2.addch(4, 22, ord('\\')) bigdeer2.addstr(5, 7, "^~~~~~~~~// ~~U") - bigdeer2.addstr(6, 7, "(( )____( /") # )) + bigdeer2.addstr(6, 7, "(( )____( /") # )) bigdeer2.addstr(7, 7, "( / |") bigdeer2.addstr(8, 8, "\\/ |") bigdeer2.addstr(9, 9, "|> |>") - + bigdeer3.addch(0, 17, ord('\\')) bigdeer3.addch(0, 18, ord('/')) bigdeer3.addch(0, 19, ord('\\')) @@ -621,11 +621,11 @@ def main(win): bigdeer3.addch(4, 19, ord('\\')) bigdeer3.addch(4, 22, ord('\\')) bigdeer3.addstr(5, 7, "^~~~~~~~~// ~~U") - bigdeer3.addstr(6, 6, "( ()_____( /") # )) + bigdeer3.addstr(6, 6, "( ()_____( /") # )) bigdeer3.addstr(7, 6, "/ / /") bigdeer3.addstr(8, 5, "|/ \\") bigdeer3.addstr(9, 5, "/> \\>") - + bigdeer4.addch(0, 17, ord('\\')) bigdeer4.addch(0, 18, ord('/')) bigdeer4.addch(0, 19, ord('\\')) @@ -643,51 +643,51 @@ def main(win): bigdeer4.addch(4, 19, ord('\\')) bigdeer4.addch(4, 22, ord('\\')) bigdeer4.addstr(5, 7, "^~~~~~~~~// ~~U") - bigdeer4.addstr(6, 6, "( )______( /") # ) - bigdeer4.addstr(7, 5, "(/ \\") # ) + bigdeer4.addstr(6, 6, "( )______( /") # ) + bigdeer4.addstr(7, 5, "(/ \\") # ) bigdeer4.addstr(8, 0, "v___= ----^") - + lookdeer1.addstr(0, 16, "\\/ \\/") lookdeer1.addstr(1, 17, "\\Y/ \\Y/") lookdeer1.addstr(2, 19, "\\=/") lookdeer1.addstr(3, 17, "^\\o o/^") lookdeer1.addstr(4, 17, "//( )") lookdeer1.addstr(5, 7, "^~~~~~~~~// \\O/") - lookdeer1.addstr(6, 7, "( \\_____( /") # )) + lookdeer1.addstr(6, 7, "( \\_____( /") # )) lookdeer1.addstr(7, 8, "( ) /") lookdeer1.addstr(8, 9, "\\\\ /") lookdeer1.addstr(9, 11, "\\>/>") - + lookdeer2.addstr(0, 16, "\\/ \\/") lookdeer2.addstr(1, 17, "\\Y/ \\Y/") lookdeer2.addstr(2, 19, "\\=/") lookdeer2.addstr(3, 17, "^\\o o/^") lookdeer2.addstr(4, 17, "//( )") lookdeer2.addstr(5, 7, "^~~~~~~~~// \\O/") - lookdeer2.addstr(6, 7, "(( )____( /") # )) + lookdeer2.addstr(6, 7, "(( )____( /") # )) lookdeer2.addstr(7, 7, "( / |") lookdeer2.addstr(8, 8, "\\/ |") lookdeer2.addstr(9, 9, "|> |>") - + lookdeer3.addstr(0, 16, "\\/ \\/") lookdeer3.addstr(1, 17, "\\Y/ \\Y/") lookdeer3.addstr(2, 19, "\\=/") lookdeer3.addstr(3, 17, "^\\o o/^") lookdeer3.addstr(4, 17, "//( )") lookdeer3.addstr(5, 7, "^~~~~~~~~// \\O/") - lookdeer3.addstr(6, 6, "( ()_____( /") # )) + lookdeer3.addstr(6, 6, "( ()_____( /") # )) lookdeer3.addstr(7, 6, "/ / /") lookdeer3.addstr(8, 5, "|/ \\") lookdeer3.addstr(9, 5, "/> \\>") - + lookdeer4.addstr(0, 16, "\\/ \\/") lookdeer4.addstr(1, 17, "\\Y/ \\Y/") lookdeer4.addstr(2, 19, "\\=/") lookdeer4.addstr(3, 17, "^\\o o/^") lookdeer4.addstr(4, 17, "//( )") lookdeer4.addstr(5, 7, "^~~~~~~~~// \\O/") - lookdeer4.addstr(6, 6, "( )______( /") # ) - lookdeer4.addstr(7, 5, "(/ \\") # ) + lookdeer4.addstr(6, 6, "( )______( /") # ) + lookdeer4.addstr(7, 5, "(/ \\") # ) lookdeer4.addstr(8, 0, "v___= ----^") ############################################### @@ -780,9 +780,9 @@ def main(win): # strng1 treescrn4.addch(3, 13, ord(' ')) - + # strng2 - + # strng3 treescrn4.addch(7, 15, ord(' ')) treescrn4.addch(8, 11, ord(' ')) @@ -830,67 +830,67 @@ def main(win): treescrn.overlay(treescrn6) # balls - treescrn6.addch(6, 7, ord(' ')) - treescrn6.addch(7, 18, ord(' ')) - treescrn6.addch(10, 4, ord(' ')) - treescrn6.addch(11, 23, ord(' ')) + treescrn6.addch(6, 7, ord(' ')) + treescrn6.addch(7, 18, ord(' ')) + treescrn6.addch(10, 4, ord(' ')) + treescrn6.addch(11, 23, ord(' ')) - # star - treescrn6.standout() - treescrn6.addch(0, 12, ord('*')) - treescrn6.standend() + # star + treescrn6.standout() + treescrn6.addch(0, 12, ord('*')) + treescrn6.standend() - # strng1 + # strng1 - # strng2 - treescrn6.addch(5, 11, ord(' ')) + # strng2 + treescrn6.addch(5, 11, ord(' ')) - # strng3 - treescrn6.addch(7, 13, ord(' ')) - treescrn6.addch(8, 9, ord(' ')) + # strng3 + treescrn6.addch(7, 13, ord(' ')) + treescrn6.addch(8, 9, ord(' ')) - # strng4 - treescrn6.addch(9, 14, ord(' ')) - treescrn6.addch(10, 10, ord(' ')) - treescrn6.addch(11, 6, ord(' ')) + # strng4 + treescrn6.addch(9, 14, ord(' ')) + treescrn6.addch(10, 10, ord(' ')) + treescrn6.addch(11, 6, ord(' ')) - # strng5 - treescrn6.addch(11, 16, ord(' ')) - treescrn6.addch(12, 12, ord(' ')) + # strng5 + treescrn6.addch(11, 16, ord(' ')) + treescrn6.addch(12, 12, ord(' ')) - # treescrn7 + # treescrn7 - treescrn.overlay(treescrn7) + treescrn.overlay(treescrn7) - # balls - treescrn7.addch(3, 15, ord(' ')) - treescrn7.addch(6, 7, ord(' ')) - treescrn7.addch(7, 18, ord(' ')) - treescrn7.addch(10, 4, ord(' ')) - treescrn7.addch(11, 22, ord(' ')) + # balls + treescrn7.addch(3, 15, ord(' ')) + treescrn7.addch(6, 7, ord(' ')) + treescrn7.addch(7, 18, ord(' ')) + treescrn7.addch(10, 4, ord(' ')) + treescrn7.addch(11, 22, ord(' ')) - # star - treescrn7.addch(0, 12, ord('*')) + # star + treescrn7.addch(0, 12, ord('*')) - # strng1 - treescrn7.addch(3, 12, ord(' ')) + # strng1 + treescrn7.addch(3, 12, ord(' ')) - # strng2 - treescrn7.addch(5, 13, ord(' ')) - treescrn7.addch(6, 9, ord(' ')) + # strng2 + treescrn7.addch(5, 13, ord(' ')) + treescrn7.addch(6, 9, ord(' ')) - # strng3 - treescrn7.addch(7, 15, ord(' ')) - treescrn7.addch(8, 11, ord(' ')) + # strng3 + treescrn7.addch(7, 15, ord(' ')) + treescrn7.addch(8, 11, ord(' ')) - # strng4 - treescrn7.addch(9, 16, ord(' ')) - treescrn7.addch(10, 12, ord(' ')) - treescrn7.addch(11, 8, ord(' ')) + # strng4 + treescrn7.addch(9, 16, ord(' ')) + treescrn7.addch(10, 12, ord(' ')) + treescrn7.addch(11, 8, ord(' ')) - # strng5 - treescrn7.addch(11, 18, ord(' ')) - treescrn7.addch(12, 14, ord(' ')) + # strng5 + treescrn7.addch(11, 18, ord(' ')) + treescrn7.addch(12, 14, ord(' ')) look_out(150) reindeer() @@ -902,5 +902,5 @@ def main(win): look_out(500) for i in range(0, 20): blinkit() - + curses.wrapper(main) diff --git a/Demo/md5test/md5driver.py b/Demo/md5test/md5driver.py index bbd6130..4c7cfcb 100755 --- a/Demo/md5test/md5driver.py +++ b/Demo/md5test/md5driver.py @@ -6,8 +6,8 @@ def MDPrint(str): outstr = '' for i in str: o = ord(i) - outstr = (outstr - + string.hexdigits[(o >> 4) & 0xF] + outstr = (outstr + + string.hexdigits[(o >> 4) & 0xF] + string.hexdigits[o & 0xF]) print outstr, @@ -97,8 +97,8 @@ def MDTestSuite(): MDString('abc') MDString('message digest') MDString(makestr(ord('a'), ord('z'))) - MDString(makestr(ord('A'), ord('Z')) - + makestr(ord('a'), ord('z')) + MDString(makestr(ord('A'), ord('Z')) + + makestr(ord('a'), ord('z')) + makestr(ord('0'), ord('9'))) MDString((makestr(ord('1'), ord('9')) + '0') * 8) diff --git a/Demo/metaclasses/Eiffel.py b/Demo/metaclasses/Eiffel.py index 68eb1cd..24fac14 100644 --- a/Demo/metaclasses/Eiffel.py +++ b/Demo/metaclasses/Eiffel.py @@ -87,7 +87,7 @@ class EiffelMethodWrapper(MetaMethodWrapper): if self.post: apply(self.post, (Result,) + args, kw) return Result - + class EiffelHelper(MetaHelper): __methodwrapper__ = EiffelMethodWrapper diff --git a/Demo/metaclasses/Meta.py b/Demo/metaclasses/Meta.py index 5534074..580f582 100644 --- a/Demo/metaclasses/Meta.py +++ b/Demo/metaclasses/Meta.py @@ -88,7 +88,7 @@ class MetaClass: init = lambda: None apply(init, args, kw) return inst - + Meta = MetaClass('Meta', (), {}) @@ -116,5 +116,3 @@ def _test(): if __name__ == '__main__': _test() - - diff --git a/Demo/metaclasses/Synch.py b/Demo/metaclasses/Synch.py index df70337..80e52d9 100644 --- a/Demo/metaclasses/Synch.py +++ b/Demo/metaclasses/Synch.py @@ -125,7 +125,7 @@ def _testLock(): lock.release() lock.acquire() - + thread.start_new_thread(f1, (lock,)) # Adds 2 thread.start_new_thread(f1, (lock, f1)) # Adds 3 thread.start_new_thread(f2, (lock,)) # Adds 1 diff --git a/Demo/metaclasses/Trace.py b/Demo/metaclasses/Trace.py index ea12cd9..69b9fab 100644 --- a/Demo/metaclasses/Trace.py +++ b/Demo/metaclasses/Trace.py @@ -142,4 +142,3 @@ def _test(): if __name__ == '__main__': _test() - diff --git a/Demo/newmetaclasses/Eiffel.py b/Demo/newmetaclasses/Eiffel.py index 1dd7e6c..78a8bb5 100644 --- a/Demo/newmetaclasses/Eiffel.py +++ b/Demo/newmetaclasses/Eiffel.py @@ -48,7 +48,7 @@ class EiffelMetaClass1(EiffelBaseMetaClass): method.__doc__ = func.__doc__ return method - + make_eiffel_method = staticmethod(make_eiffel_method) class EiffelMethodWrapper: @@ -66,7 +66,7 @@ class EiffelDescriptor(object): self._func = func self._pre = pre self._post = post - + self.__name__ = func.__name__ self.__doc__ = func.__doc__ @@ -141,4 +141,3 @@ def _test(metaclass): if __name__ == "__main__": _test(EiffelMetaClass1) _test(EiffelMetaClass2) - diff --git a/Demo/newmetaclasses/Enum.py b/Demo/newmetaclasses/Enum.py index 5d490a9..2a5823b 100644 --- a/Demo/newmetaclasses/Enum.py +++ b/Demo/newmetaclasses/Enum.py @@ -175,4 +175,3 @@ def _test2(): if __name__ == '__main__': _test() _test2() - diff --git a/Demo/pdist/FSProxy.py b/Demo/pdist/FSProxy.py index 7510d1e..a1ab635 100755 --- a/Demo/pdist/FSProxy.py +++ b/Demo/pdist/FSProxy.py @@ -24,299 +24,299 @@ import time import fnmatch if os.name == 'mac': - import macfs - maxnamelen = 31 + import macfs + maxnamelen = 31 else: - macfs = None - maxnamelen = 255 + macfs = None + maxnamelen = 255 skipnames = (os.curdir, os.pardir) class FSProxyLocal: - - def __init__(self): - self._dirstack = [] - self._ignore = ['*.pyc'] + self._readignore() - - def _close(self): - while self._dirstack: - self.back() - - def _readignore(self): - file = self._hide('ignore') - try: - f = open(file) - except IOError: - file = self._hide('synctree.ignorefiles') - try: - f = open(file) - except IOError: - return [] - ignore = [] - while 1: - line = f.readline() - if not line: break - if line[-1] == '\n': line = line[:-1] - ignore.append(line) - f.close() - return ignore - - def _hidden(self, name): - if os.name == 'mac': - return name[0] == '(' and name[-1] == ')' - else: - return name[0] == '.' - - def _hide(self, name): - if os.name == 'mac': - return '(%s)' % name - else: - return '.%s' % name - - def visible(self, name): - if len(name) > maxnamelen: return 0 - if name[-1] == '~': return 0 - if name in skipnames: return 0 - if self._hidden(name): return 0 - head, tail = os.path.split(name) - if head or not tail: return 0 - if macfs: - if os.path.exists(name) and not os.path.isdir(name): - try: - fs = macfs.FSSpec(name) - c, t = fs.GetCreatorType() - if t != 'TEXT': return 0 - except macfs.error, msg: - print "***", name, msg - return 0 - else: - if os.path.islink(name): return 0 - if '\0' in open(name, 'rb').read(512): return 0 - for ign in self._ignore: - if fnmatch.fnmatch(name, ign): return 0 - return 1 - - def check(self, name): - if not self.visible(name): - raise os.error, "protected name %s" % repr(name) - - def checkfile(self, name): - self.check(name) - if not os.path.isfile(name): - raise os.error, "not a plain file %s" % repr(name) - - def pwd(self): - return os.getcwd() - - def cd(self, name): - self.check(name) - save = os.getcwd(), self._ignore - os.chdir(name) - self._dirstack.append(save) - self._ignore = self._ignore + self._readignore() - - def back(self): - if not self._dirstack: - raise os.error, "empty directory stack" - dir, ignore = self._dirstack[-1] - os.chdir(dir) - del self._dirstack[-1] - self._ignore = ignore - - def _filter(self, files, pat = None): - if pat: - def keep(name, pat = pat): - return fnmatch.fnmatch(name, pat) - files = filter(keep, files) - files = filter(self.visible, files) - files.sort() - return files - - def list(self, pat = None): - files = os.listdir(os.curdir) - return self._filter(files, pat) - - def listfiles(self, pat = None): - files = os.listdir(os.curdir) - files = filter(os.path.isfile, files) - return self._filter(files, pat) - - def listsubdirs(self, pat = None): - files = os.listdir(os.curdir) - files = filter(os.path.isdir, files) - return self._filter(files, pat) - - def exists(self, name): - return self.visible(name) and os.path.exists(name) - - def isdir(self, name): - return self.visible(name) and os.path.isdir(name) - - def islink(self, name): - return self.visible(name) and os.path.islink(name) - - def isfile(self, name): - return self.visible(name) and os.path.isfile(name) - - def sum(self, name): - self.checkfile(name) - BUFFERSIZE = 1024*8 - f = open(name) - sum = md5.new() - while 1: - buffer = f.read(BUFFERSIZE) - if not buffer: - break - sum.update(buffer) - return sum.digest() - - def size(self, name): - self.checkfile(name) - return os.stat(name)[ST_SIZE] - - def mtime(self, name): - self.checkfile(name) - return time.localtime(os.stat(name)[ST_MTIME]) - - def stat(self, name): - self.checkfile(name) - size = os.stat(name)[ST_SIZE] - mtime = time.localtime(os.stat(name)[ST_MTIME]) - return size, mtime - - def info(self, name): - sum = self.sum(name) - size = os.stat(name)[ST_SIZE] - mtime = time.localtime(os.stat(name)[ST_MTIME]) - return sum, size, mtime - - def _list(self, function, list): - if list is None: - list = self.listfiles() - res = [] - for name in list: - try: - res.append((name, function(name))) - except (os.error, IOError): - res.append((name, None)) - return res - - def sumlist(self, list = None): - return self._list(self.sum, list) - - def statlist(self, list = None): - return self._list(self.stat, list) - - def mtimelist(self, list = None): - return self._list(self.mtime, list) - - def sizelist(self, list = None): - return self._list(self.size, list) - - def infolist(self, list = None): - return self._list(self.info, list) - - def _dict(self, function, list): - if list is None: - list = self.listfiles() - dict = {} - for name in list: - try: - dict[name] = function(name) - except (os.error, IOError): - pass - return dict - - def sumdict(self, list = None): - return self.dict(self.sum, list) - - def sizedict(self, list = None): - return self.dict(self.size, list) - - def mtimedict(self, list = None): - return self.dict(self.mtime, list) - - def statdict(self, list = None): - return self.dict(self.stat, list) - - def infodict(self, list = None): - return self._dict(self.info, list) - - def read(self, name, offset = 0, length = -1): - self.checkfile(name) - f = open(name) - f.seek(offset) - if length == 0: - data = '' - elif length < 0: - data = f.read() - else: - data = f.read(length) - f.close() - return data - - def create(self, name): - self.check(name) - if os.path.exists(name): - self.checkfile(name) - bname = name + '~' - try: - os.unlink(bname) - except os.error: - pass - os.rename(name, bname) - f = open(name, 'w') - f.close() - - def write(self, name, data, offset = 0): - self.checkfile(name) - f = open(name, 'r+') - f.seek(offset) - f.write(data) - f.close() - - def mkdir(self, name): - self.check(name) - os.mkdir(name, 0777) - - def rmdir(self, name): - self.check(name) - os.rmdir(name) + + def __init__(self): + self._dirstack = [] + self._ignore = ['*.pyc'] + self._readignore() + + def _close(self): + while self._dirstack: + self.back() + + def _readignore(self): + file = self._hide('ignore') + try: + f = open(file) + except IOError: + file = self._hide('synctree.ignorefiles') + try: + f = open(file) + except IOError: + return [] + ignore = [] + while 1: + line = f.readline() + if not line: break + if line[-1] == '\n': line = line[:-1] + ignore.append(line) + f.close() + return ignore + + def _hidden(self, name): + if os.name == 'mac': + return name[0] == '(' and name[-1] == ')' + else: + return name[0] == '.' + + def _hide(self, name): + if os.name == 'mac': + return '(%s)' % name + else: + return '.%s' % name + + def visible(self, name): + if len(name) > maxnamelen: return 0 + if name[-1] == '~': return 0 + if name in skipnames: return 0 + if self._hidden(name): return 0 + head, tail = os.path.split(name) + if head or not tail: return 0 + if macfs: + if os.path.exists(name) and not os.path.isdir(name): + try: + fs = macfs.FSSpec(name) + c, t = fs.GetCreatorType() + if t != 'TEXT': return 0 + except macfs.error, msg: + print "***", name, msg + return 0 + else: + if os.path.islink(name): return 0 + if '\0' in open(name, 'rb').read(512): return 0 + for ign in self._ignore: + if fnmatch.fnmatch(name, ign): return 0 + return 1 + + def check(self, name): + if not self.visible(name): + raise os.error, "protected name %s" % repr(name) + + def checkfile(self, name): + self.check(name) + if not os.path.isfile(name): + raise os.error, "not a plain file %s" % repr(name) + + def pwd(self): + return os.getcwd() + + def cd(self, name): + self.check(name) + save = os.getcwd(), self._ignore + os.chdir(name) + self._dirstack.append(save) + self._ignore = self._ignore + self._readignore() + + def back(self): + if not self._dirstack: + raise os.error, "empty directory stack" + dir, ignore = self._dirstack[-1] + os.chdir(dir) + del self._dirstack[-1] + self._ignore = ignore + + def _filter(self, files, pat = None): + if pat: + def keep(name, pat = pat): + return fnmatch.fnmatch(name, pat) + files = filter(keep, files) + files = filter(self.visible, files) + files.sort() + return files + + def list(self, pat = None): + files = os.listdir(os.curdir) + return self._filter(files, pat) + + def listfiles(self, pat = None): + files = os.listdir(os.curdir) + files = filter(os.path.isfile, files) + return self._filter(files, pat) + + def listsubdirs(self, pat = None): + files = os.listdir(os.curdir) + files = filter(os.path.isdir, files) + return self._filter(files, pat) + + def exists(self, name): + return self.visible(name) and os.path.exists(name) + + def isdir(self, name): + return self.visible(name) and os.path.isdir(name) + + def islink(self, name): + return self.visible(name) and os.path.islink(name) + + def isfile(self, name): + return self.visible(name) and os.path.isfile(name) + + def sum(self, name): + self.checkfile(name) + BUFFERSIZE = 1024*8 + f = open(name) + sum = md5.new() + while 1: + buffer = f.read(BUFFERSIZE) + if not buffer: + break + sum.update(buffer) + return sum.digest() + + def size(self, name): + self.checkfile(name) + return os.stat(name)[ST_SIZE] + + def mtime(self, name): + self.checkfile(name) + return time.localtime(os.stat(name)[ST_MTIME]) + + def stat(self, name): + self.checkfile(name) + size = os.stat(name)[ST_SIZE] + mtime = time.localtime(os.stat(name)[ST_MTIME]) + return size, mtime + + def info(self, name): + sum = self.sum(name) + size = os.stat(name)[ST_SIZE] + mtime = time.localtime(os.stat(name)[ST_MTIME]) + return sum, size, mtime + + def _list(self, function, list): + if list is None: + list = self.listfiles() + res = [] + for name in list: + try: + res.append((name, function(name))) + except (os.error, IOError): + res.append((name, None)) + return res + + def sumlist(self, list = None): + return self._list(self.sum, list) + + def statlist(self, list = None): + return self._list(self.stat, list) + + def mtimelist(self, list = None): + return self._list(self.mtime, list) + + def sizelist(self, list = None): + return self._list(self.size, list) + + def infolist(self, list = None): + return self._list(self.info, list) + + def _dict(self, function, list): + if list is None: + list = self.listfiles() + dict = {} + for name in list: + try: + dict[name] = function(name) + except (os.error, IOError): + pass + return dict + + def sumdict(self, list = None): + return self.dict(self.sum, list) + + def sizedict(self, list = None): + return self.dict(self.size, list) + + def mtimedict(self, list = None): + return self.dict(self.mtime, list) + + def statdict(self, list = None): + return self.dict(self.stat, list) + + def infodict(self, list = None): + return self._dict(self.info, list) + + def read(self, name, offset = 0, length = -1): + self.checkfile(name) + f = open(name) + f.seek(offset) + if length == 0: + data = '' + elif length < 0: + data = f.read() + else: + data = f.read(length) + f.close() + return data + + def create(self, name): + self.check(name) + if os.path.exists(name): + self.checkfile(name) + bname = name + '~' + try: + os.unlink(bname) + except os.error: + pass + os.rename(name, bname) + f = open(name, 'w') + f.close() + + def write(self, name, data, offset = 0): + self.checkfile(name) + f = open(name, 'r+') + f.seek(offset) + f.write(data) + f.close() + + def mkdir(self, name): + self.check(name) + os.mkdir(name, 0777) + + def rmdir(self, name): + self.check(name) + os.rmdir(name) class FSProxyServer(FSProxyLocal, server.Server): - - def __init__(self, address, verbose = server.VERBOSE): - FSProxyLocal.__init__(self) - server.Server.__init__(self, address, verbose) - - def _close(self): - server.Server._close(self) - FSProxyLocal._close(self) - - def _serve(self): - server.Server._serve(self) - # Retreat into start directory - while self._dirstack: self.back() + + def __init__(self, address, verbose = server.VERBOSE): + FSProxyLocal.__init__(self) + server.Server.__init__(self, address, verbose) + + def _close(self): + server.Server._close(self) + FSProxyLocal._close(self) + + def _serve(self): + server.Server._serve(self) + # Retreat into start directory + while self._dirstack: self.back() class FSProxyClient(client.Client): - - def __init__(self, address, verbose = client.VERBOSE): - client.Client.__init__(self, address, verbose) + + def __init__(self, address, verbose = client.VERBOSE): + client.Client.__init__(self, address, verbose) def test(): - import string - import sys - if sys.argv[1:]: - port = string.atoi(sys.argv[1]) - else: - port = 4127 - proxy = FSProxyServer(('', port)) - proxy._serverloop() + import string + import sys + if sys.argv[1:]: + port = string.atoi(sys.argv[1]) + else: + port = 4127 + proxy = FSProxyServer(('', port)) + proxy._serverloop() if __name__ == '__main__': - test() + test() diff --git a/Demo/pdist/client.py b/Demo/pdist/client.py index a00f005..3e97d84 100755 --- a/Demo/pdist/client.py +++ b/Demo/pdist/client.py @@ -12,118 +12,118 @@ VERBOSE = 1 class Client: - - """RPC Client class. No need to derive a class -- it's fully generic.""" - - def __init__(self, address, verbose = VERBOSE): - self._pre_init(address, verbose) - self._post_init() - - def _pre_init(self, address, verbose = VERBOSE): - if type(address) == type(0): - address = ('', address) - self._address = address - self._verbose = verbose - if self._verbose: print "Connecting to %s ..." % repr(address) - self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._socket.connect(address) - if self._verbose: print "Connected." - self._lastid = 0 # Last id for which a reply has been received - self._nextid = 1 # Id of next request - self._replies = {} # Unprocessed replies - self._rf = self._socket.makefile('r') - self._wf = self._socket.makefile('w') - - def _post_init(self): - self._methods = self._call('.methods') - - def __del__(self): - self._close() - - def _close(self): - if self._rf: self._rf.close() - self._rf = None - if self._wf: self._wf.close() - self._wf = None - if self._socket: self._socket.close() - self._socket = None - - def __getattr__(self, name): - if name in self._methods: - method = _stub(self, name) - setattr(self, name, method) # XXX circular reference - return method - raise AttributeError, name - - def _setverbose(self, verbose): - self._verbose = verbose - - def _call(self, name, *args): - return self._vcall(name, args) - - def _vcall(self, name, args): - return self._recv(self._vsend(name, args)) - - def _send(self, name, *args): - return self._vsend(name, args) - - def _send_noreply(self, name, *args): - return self._vsend(name, args, 0) - - def _vsend_noreply(self, name, args): - return self._vsend(name, args, 0) - - def _vsend(self, name, args, wantreply = 1): - id = self._nextid - self._nextid = id+1 - if not wantreply: id = -id - request = (name, args, id) - if self._verbose > 1: print "sending request: %s" % repr(request) - wp = pickle.Pickler(self._wf) - wp.dump(request) - return id - - def _recv(self, id): - exception, value, rid = self._vrecv(id) - if rid != id: - raise RuntimeError, "request/reply id mismatch: %d/%d" % (id, rid) - if exception is None: - return value - x = exception - if hasattr(__builtin__, exception): - x = getattr(__builtin__, exception) - elif exception in ('posix.error', 'mac.error'): - x = os.error - if x == exception: - exception = x - raise exception, value - - def _vrecv(self, id): - self._flush() - if self._replies.has_key(id): - if self._verbose > 1: print "retrieving previous reply, id = %d" % id - reply = self._replies[id] - del self._replies[id] - return reply - aid = abs(id) - while 1: - if self._verbose > 1: print "waiting for reply, id = %d" % id - rp = pickle.Unpickler(self._rf) - reply = rp.load() - del rp - if self._verbose > 1: print "got reply: %s" % repr(reply) - rid = reply[2] - arid = abs(rid) - if arid == aid: - if self._verbose > 1: print "got it" - return reply - self._replies[rid] = reply - if arid > aid: - if self._verbose > 1: print "got higher id, assume all ok" - return (None, None, id) - - def _flush(self): - self._wf.flush() + + """RPC Client class. No need to derive a class -- it's fully generic.""" + + def __init__(self, address, verbose = VERBOSE): + self._pre_init(address, verbose) + self._post_init() + + def _pre_init(self, address, verbose = VERBOSE): + if type(address) == type(0): + address = ('', address) + self._address = address + self._verbose = verbose + if self._verbose: print "Connecting to %s ..." % repr(address) + self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._socket.connect(address) + if self._verbose: print "Connected." + self._lastid = 0 # Last id for which a reply has been received + self._nextid = 1 # Id of next request + self._replies = {} # Unprocessed replies + self._rf = self._socket.makefile('r') + self._wf = self._socket.makefile('w') + + def _post_init(self): + self._methods = self._call('.methods') + + def __del__(self): + self._close() + + def _close(self): + if self._rf: self._rf.close() + self._rf = None + if self._wf: self._wf.close() + self._wf = None + if self._socket: self._socket.close() + self._socket = None + + def __getattr__(self, name): + if name in self._methods: + method = _stub(self, name) + setattr(self, name, method) # XXX circular reference + return method + raise AttributeError, name + + def _setverbose(self, verbose): + self._verbose = verbose + + def _call(self, name, *args): + return self._vcall(name, args) + + def _vcall(self, name, args): + return self._recv(self._vsend(name, args)) + + def _send(self, name, *args): + return self._vsend(name, args) + + def _send_noreply(self, name, *args): + return self._vsend(name, args, 0) + + def _vsend_noreply(self, name, args): + return self._vsend(name, args, 0) + + def _vsend(self, name, args, wantreply = 1): + id = self._nextid + self._nextid = id+1 + if not wantreply: id = -id + request = (name, args, id) + if self._verbose > 1: print "sending request: %s" % repr(request) + wp = pickle.Pickler(self._wf) + wp.dump(request) + return id + + def _recv(self, id): + exception, value, rid = self._vrecv(id) + if rid != id: + raise RuntimeError, "request/reply id mismatch: %d/%d" % (id, rid) + if exception is None: + return value + x = exception + if hasattr(__builtin__, exception): + x = getattr(__builtin__, exception) + elif exception in ('posix.error', 'mac.error'): + x = os.error + if x == exception: + exception = x + raise exception, value + + def _vrecv(self, id): + self._flush() + if self._replies.has_key(id): + if self._verbose > 1: print "retrieving previous reply, id = %d" % id + reply = self._replies[id] + del self._replies[id] + return reply + aid = abs(id) + while 1: + if self._verbose > 1: print "waiting for reply, id = %d" % id + rp = pickle.Unpickler(self._rf) + reply = rp.load() + del rp + if self._verbose > 1: print "got reply: %s" % repr(reply) + rid = reply[2] + arid = abs(rid) + if arid == aid: + if self._verbose > 1: print "got it" + return reply + self._replies[rid] = reply + if arid > aid: + if self._verbose > 1: print "got higher id, assume all ok" + return (None, None, id) + + def _flush(self): + self._wf.flush() from security import Security @@ -131,28 +131,27 @@ from security import Security class SecureClient(Client, Security): - def __init__(self, *args): - import string - apply(self._pre_init, args) - Security.__init__(self) - self._wf.flush() - line = self._rf.readline() - challenge = string.atoi(string.strip(line)) - response = self._encode_challenge(challenge) - line = repr(long(response)) - if line[-1] in 'Ll': line = line[:-1] - self._wf.write(line + '\n') - self._wf.flush() - self._post_init() + def __init__(self, *args): + import string + apply(self._pre_init, args) + Security.__init__(self) + self._wf.flush() + line = self._rf.readline() + challenge = string.atoi(string.strip(line)) + response = self._encode_challenge(challenge) + line = repr(long(response)) + if line[-1] in 'Ll': line = line[:-1] + self._wf.write(line + '\n') + self._wf.flush() + self._post_init() class _stub: - - """Helper class for Client -- each instance serves as a method of the client.""" - - def __init__(self, client, name): - self._client = client - self._name = name - - def __call__(self, *args): - return self._client._vcall(self._name, args) + """Helper class for Client -- each instance serves as a method of the client.""" + + def __init__(self, client, name): + self._client = client + self._name = name + + def __call__(self, *args): + return self._client._vcall(self._name, args) diff --git a/Demo/pdist/cmdfw.py b/Demo/pdist/cmdfw.py index 25584b7..e2edd0a 100755 --- a/Demo/pdist/cmdfw.py +++ b/Demo/pdist/cmdfw.py @@ -3,142 +3,142 @@ class CommandFrameWork: - """Framework class for command line interfaces like CVS. - - The general command line structure is - - command [flags] subcommand [subflags] [argument] ... - - There's a class variable GlobalFlags which specifies the - global flags options. Subcommands are defined by defining - methods named do_<subcommand>. Flags for the subcommand are - defined by defining class or instance variables named - flags_<subcommand>. If there's no command, method default() - is called. The __doc__ strings for the do_ methods are used - for the usage message, printed after the general usage message - which is the class variable UsageMessage. The class variable - PostUsageMessage is printed after all the do_ methods' __doc__ - strings. The method's return value can be a suggested exit - status. [XXX Need to rewrite this to clarify it.] - - Common usage is to derive a class, instantiate it, and then call its - run() method; by default this takes its arguments from sys.argv[1:]. - """ - - UsageMessage = \ - "usage: (name)s [flags] subcommand [subflags] [argument] ..." - - PostUsageMessage = None - - GlobalFlags = '' - - def __init__(self): - """Constructor, present for completeness.""" - pass - - def run(self, args = None): - """Process flags, subcommand and options, then run it.""" - import getopt, sys - if args is None: args = sys.argv[1:] - try: - opts, args = getopt.getopt(args, self.GlobalFlags) - except getopt.error, msg: - return self.usage(msg) - self.options(opts) - if not args: - self.ready() - return self.default() - else: - cmd = args[0] - mname = 'do_' + cmd - fname = 'flags_' + cmd - try: - method = getattr(self, mname) - except AttributeError: - return self.usage("command %r unknown" % (cmd,)) - try: - flags = getattr(self, fname) - except AttributeError: - flags = '' - try: - opts, args = getopt.getopt(args[1:], flags) - except getopt.error, msg: - return self.usage( - "subcommand %s: " % cmd + str(msg)) - self.ready() - return method(opts, args) - - def options(self, opts): - """Process the options retrieved by getopt. - Override this if you have any options.""" - if opts: - print "-"*40 - print "Options:" - for o, a in opts: - print 'option', o, 'value', repr(a) - print "-"*40 - - def ready(self): - """Called just before calling the subcommand.""" - pass - - def usage(self, msg = None): - """Print usage message. Return suitable exit code (2).""" - if msg: print msg - print self.UsageMessage % {'name': self.__class__.__name__} - docstrings = {} - c = self.__class__ - while 1: - for name in dir(c): - if name[:3] == 'do_': - if docstrings.has_key(name): - continue - try: - doc = getattr(c, name).__doc__ - except: - doc = None - if doc: - docstrings[name] = doc - if not c.__bases__: - break - c = c.__bases__[0] - if docstrings: - print "where subcommand can be:" - names = docstrings.keys() - names.sort() - for name in names: - print docstrings[name] - if self.PostUsageMessage: - print self.PostUsageMessage - return 2 - - def default(self): - """Default method, called when no subcommand is given. - You should always override this.""" - print "Nobody expects the Spanish Inquisition!" + """Framework class for command line interfaces like CVS. + + The general command line structure is + + command [flags] subcommand [subflags] [argument] ... + + There's a class variable GlobalFlags which specifies the + global flags options. Subcommands are defined by defining + methods named do_<subcommand>. Flags for the subcommand are + defined by defining class or instance variables named + flags_<subcommand>. If there's no command, method default() + is called. The __doc__ strings for the do_ methods are used + for the usage message, printed after the general usage message + which is the class variable UsageMessage. The class variable + PostUsageMessage is printed after all the do_ methods' __doc__ + strings. The method's return value can be a suggested exit + status. [XXX Need to rewrite this to clarify it.] + + Common usage is to derive a class, instantiate it, and then call its + run() method; by default this takes its arguments from sys.argv[1:]. + """ + + UsageMessage = \ + "usage: (name)s [flags] subcommand [subflags] [argument] ..." + + PostUsageMessage = None + + GlobalFlags = '' + + def __init__(self): + """Constructor, present for completeness.""" + pass + + def run(self, args = None): + """Process flags, subcommand and options, then run it.""" + import getopt, sys + if args is None: args = sys.argv[1:] + try: + opts, args = getopt.getopt(args, self.GlobalFlags) + except getopt.error, msg: + return self.usage(msg) + self.options(opts) + if not args: + self.ready() + return self.default() + else: + cmd = args[0] + mname = 'do_' + cmd + fname = 'flags_' + cmd + try: + method = getattr(self, mname) + except AttributeError: + return self.usage("command %r unknown" % (cmd,)) + try: + flags = getattr(self, fname) + except AttributeError: + flags = '' + try: + opts, args = getopt.getopt(args[1:], flags) + except getopt.error, msg: + return self.usage( + "subcommand %s: " % cmd + str(msg)) + self.ready() + return method(opts, args) + + def options(self, opts): + """Process the options retrieved by getopt. + Override this if you have any options.""" + if opts: + print "-"*40 + print "Options:" + for o, a in opts: + print 'option', o, 'value', repr(a) + print "-"*40 + + def ready(self): + """Called just before calling the subcommand.""" + pass + + def usage(self, msg = None): + """Print usage message. Return suitable exit code (2).""" + if msg: print msg + print self.UsageMessage % {'name': self.__class__.__name__} + docstrings = {} + c = self.__class__ + while 1: + for name in dir(c): + if name[:3] == 'do_': + if docstrings.has_key(name): + continue + try: + doc = getattr(c, name).__doc__ + except: + doc = None + if doc: + docstrings[name] = doc + if not c.__bases__: + break + c = c.__bases__[0] + if docstrings: + print "where subcommand can be:" + names = docstrings.keys() + names.sort() + for name in names: + print docstrings[name] + if self.PostUsageMessage: + print self.PostUsageMessage + return 2 + + def default(self): + """Default method, called when no subcommand is given. + You should always override this.""" + print "Nobody expects the Spanish Inquisition!" def test(): - """Test script -- called when this module is run as a script.""" - import sys - class Hello(CommandFrameWork): - def do_hello(self, opts, args): - "hello -- print 'hello world', needs no arguments" - print "Hello, world" - x = Hello() - tests = [ - [], - ['hello'], - ['spam'], - ['-x'], - ['hello', '-x'], - None, - ] - for t in tests: - print '-'*10, t, '-'*10 - sts = x.run(t) - print "Exit status:", repr(sts) + """Test script -- called when this module is run as a script.""" + import sys + class Hello(CommandFrameWork): + def do_hello(self, opts, args): + "hello -- print 'hello world', needs no arguments" + print "Hello, world" + x = Hello() + tests = [ + [], + ['hello'], + ['spam'], + ['-x'], + ['hello', '-x'], + None, + ] + for t in tests: + print '-'*10, t, '-'*10 + sts = x.run(t) + print "Exit status:", repr(sts) if __name__ == '__main__': - test() + test() diff --git a/Demo/pdist/cmptree.py b/Demo/pdist/cmptree.py index 8a34f3f..f6c611f 100755 --- a/Demo/pdist/cmptree.py +++ b/Demo/pdist/cmptree.py @@ -7,202 +7,202 @@ import time import os def main(): - pwd = os.getcwd() - s = raw_input("chdir [%s] " % pwd) - if s: - os.chdir(s) - pwd = os.getcwd() - host = ask("host", 'voorn.cwi.nl') - port = 4127 - verbose = 1 - mode = '' - print """\ + pwd = os.getcwd() + s = raw_input("chdir [%s] " % pwd) + if s: + os.chdir(s) + pwd = os.getcwd() + host = ask("host", 'voorn.cwi.nl') + port = 4127 + verbose = 1 + mode = '' + print """\ Mode should be a string of characters, indicating what to do with differences. r - read different files to local file system w - write different files to remote file system c - create new files, either remote or local d - delete disappearing files, either remote or local """ - s = raw_input("mode [%s] " % mode) - if s: mode = s - address = (host, port) - t1 = time.time() - local = FSProxy.FSProxyLocal() - remote = FSProxy.FSProxyClient(address, verbose) - compare(local, remote, mode) - remote._close() - local._close() - t2 = time.time() - dt = t2-t1 - mins, secs = divmod(dt, 60) - print mins, "minutes and", round(secs), "seconds" - raw_input("[Return to exit] ") + s = raw_input("mode [%s] " % mode) + if s: mode = s + address = (host, port) + t1 = time.time() + local = FSProxy.FSProxyLocal() + remote = FSProxy.FSProxyClient(address, verbose) + compare(local, remote, mode) + remote._close() + local._close() + t2 = time.time() + dt = t2-t1 + mins, secs = divmod(dt, 60) + print mins, "minutes and", round(secs), "seconds" + raw_input("[Return to exit] ") def ask(prompt, default): - s = raw_input("%s [%s] " % (prompt, default)) - return s or default + s = raw_input("%s [%s] " % (prompt, default)) + return s or default def askint(prompt, default): - s = raw_input("%s [%s] " % (prompt, str(default))) - if s: return string.atoi(s) - return default + s = raw_input("%s [%s] " % (prompt, str(default))) + if s: return string.atoi(s) + return default def compare(local, remote, mode): - print - print "PWD =", repr(os.getcwd()) - sums_id = remote._send('sumlist') - subdirs_id = remote._send('listsubdirs') - remote._flush() - print "calculating local sums ..." - lsumdict = {} - for name, info in local.sumlist(): - lsumdict[name] = info - print "getting remote sums ..." - sums = remote._recv(sums_id) - print "got", len(sums) - rsumdict = {} - for name, rsum in sums: - rsumdict[name] = rsum - if not lsumdict.has_key(name): - print repr(name), "only remote" - if 'r' in mode and 'c' in mode: - recvfile(local, remote, name) - else: - lsum = lsumdict[name] - if lsum != rsum: - print repr(name), - rmtime = remote.mtime(name) - lmtime = local.mtime(name) - if rmtime > lmtime: - print "remote newer", - if 'r' in mode: - recvfile(local, remote, name) - elif lmtime > rmtime: - print "local newer", - if 'w' in mode: - sendfile(local, remote, name) - else: - print "same mtime but different sum?!?!", - print - for name in lsumdict.keys(): - if not rsumdict.keys(): - print repr(name), "only locally", - fl() - if 'w' in mode and 'c' in mode: - sendfile(local, remote, name) - elif 'r' in mode and 'd' in mode: - os.unlink(name) - print "removed." - print - print "gettin subdirs ..." - subdirs = remote._recv(subdirs_id) - common = [] - for name in subdirs: - if local.isdir(name): - print "Common subdirectory", repr(name) - common.append(name) - else: - print "Remote subdirectory", repr(name), "not found locally" - if 'r' in mode and 'c' in mode: - pr = "Create local subdirectory %s? [y] " % \ - repr(name) - if 'y' in mode: - ok = 'y' - else: - ok = ask(pr, "y") - if ok[:1] in ('y', 'Y'): - local.mkdir(name) - print "Subdirectory %s made" % \ - repr(name) - common.append(name) - lsubdirs = local.listsubdirs() - for name in lsubdirs: - if name not in subdirs: - print "Local subdirectory", repr(name), "not found remotely" - for name in common: - print "Entering subdirectory", repr(name) - local.cd(name) - remote.cd(name) - compare(local, remote, mode) - remote.back() - local.back() + print + print "PWD =", repr(os.getcwd()) + sums_id = remote._send('sumlist') + subdirs_id = remote._send('listsubdirs') + remote._flush() + print "calculating local sums ..." + lsumdict = {} + for name, info in local.sumlist(): + lsumdict[name] = info + print "getting remote sums ..." + sums = remote._recv(sums_id) + print "got", len(sums) + rsumdict = {} + for name, rsum in sums: + rsumdict[name] = rsum + if not lsumdict.has_key(name): + print repr(name), "only remote" + if 'r' in mode and 'c' in mode: + recvfile(local, remote, name) + else: + lsum = lsumdict[name] + if lsum != rsum: + print repr(name), + rmtime = remote.mtime(name) + lmtime = local.mtime(name) + if rmtime > lmtime: + print "remote newer", + if 'r' in mode: + recvfile(local, remote, name) + elif lmtime > rmtime: + print "local newer", + if 'w' in mode: + sendfile(local, remote, name) + else: + print "same mtime but different sum?!?!", + print + for name in lsumdict.keys(): + if not rsumdict.keys(): + print repr(name), "only locally", + fl() + if 'w' in mode and 'c' in mode: + sendfile(local, remote, name) + elif 'r' in mode and 'd' in mode: + os.unlink(name) + print "removed." + print + print "gettin subdirs ..." + subdirs = remote._recv(subdirs_id) + common = [] + for name in subdirs: + if local.isdir(name): + print "Common subdirectory", repr(name) + common.append(name) + else: + print "Remote subdirectory", repr(name), "not found locally" + if 'r' in mode and 'c' in mode: + pr = "Create local subdirectory %s? [y] " % \ + repr(name) + if 'y' in mode: + ok = 'y' + else: + ok = ask(pr, "y") + if ok[:1] in ('y', 'Y'): + local.mkdir(name) + print "Subdirectory %s made" % \ + repr(name) + common.append(name) + lsubdirs = local.listsubdirs() + for name in lsubdirs: + if name not in subdirs: + print "Local subdirectory", repr(name), "not found remotely" + for name in common: + print "Entering subdirectory", repr(name) + local.cd(name) + remote.cd(name) + compare(local, remote, mode) + remote.back() + local.back() def sendfile(local, remote, name): - try: - remote.create(name) - except (IOError, os.error), msg: - print "cannot create:", msg - return - - print "sending ...", - fl() - - data = open(name).read() - - t1 = time.time() - - remote._send_noreply('write', name, data) - remote._flush() - - t2 = time.time() - - dt = t2-t1 - print len(data), "bytes in", round(dt), "seconds", - if dt: - print "i.e.", round(len(data)/dt), "bytes/sec", - print + try: + remote.create(name) + except (IOError, os.error), msg: + print "cannot create:", msg + return + + print "sending ...", + fl() + + data = open(name).read() + + t1 = time.time() + + remote._send_noreply('write', name, data) + remote._flush() + + t2 = time.time() + + dt = t2-t1 + print len(data), "bytes in", round(dt), "seconds", + if dt: + print "i.e.", round(len(data)/dt), "bytes/sec", + print def recvfile(local, remote, name): - ok = 0 - try: - rv = recvfile_real(local, remote, name) - ok = 1 - return rv - finally: - if not ok: - print "*** recvfile of %r failed, deleting" % (name,) - local.delete(name) + ok = 0 + try: + rv = recvfile_real(local, remote, name) + ok = 1 + return rv + finally: + if not ok: + print "*** recvfile of %r failed, deleting" % (name,) + local.delete(name) def recvfile_real(local, remote, name): - try: - local.create(name) - except (IOError, os.error), msg: - print "cannot create:", msg - return - - print "receiving ...", - fl() - - f = open(name, 'w') - t1 = time.time() - - length = 4*1024 - offset = 0 - id = remote._send('read', name, offset, length) - remote._flush() - while 1: - newoffset = offset + length - newid = remote._send('read', name, newoffset, length) - data = remote._recv(id) - id = newid - if not data: break - f.seek(offset) - f.write(data) - offset = newoffset - size = f.tell() - - t2 = time.time() - f.close() - - dt = t2-t1 - print size, "bytes in", round(dt), "seconds", - if dt: - print "i.e.", int(size/dt), "bytes/sec", - print - remote._recv(id) # ignored + try: + local.create(name) + except (IOError, os.error), msg: + print "cannot create:", msg + return + + print "receiving ...", + fl() + + f = open(name, 'w') + t1 = time.time() + + length = 4*1024 + offset = 0 + id = remote._send('read', name, offset, length) + remote._flush() + while 1: + newoffset = offset + length + newid = remote._send('read', name, newoffset, length) + data = remote._recv(id) + id = newid + if not data: break + f.seek(offset) + f.write(data) + offset = newoffset + size = f.tell() + + t2 = time.time() + f.close() + + dt = t2-t1 + print size, "bytes in", round(dt), "seconds", + if dt: + print "i.e.", int(size/dt), "bytes/sec", + print + remote._recv(id) # ignored def fl(): - sys.stdout.flush() + sys.stdout.flush() if __name__ == '__main__': - main() + main() diff --git a/Demo/pdist/cvslib.py b/Demo/pdist/cvslib.py index 0f689c4..ebcc697 100755 --- a/Demo/pdist/cvslib.py +++ b/Demo/pdist/cvslib.py @@ -7,358 +7,358 @@ import md5 import fnmatch if not hasattr(time, 'timezone'): - time.timezone = 0 + time.timezone = 0 class File: - """Represent a file's status. - - Instance variables: - - file -- the filename (no slashes), None if uninitialized - lseen -- true if the data for the local file is up to date - eseen -- true if the data from the CVS/Entries entry is up to date - (this implies that the entry must be written back) - rseen -- true if the data for the remote file is up to date - proxy -- RCSProxy instance used to contact the server, or None - - Note that lseen and rseen don't necessary mean that a local - or remote file *exists* -- they indicate that we've checked it. - However, eseen means that this instance corresponds to an - entry in the CVS/Entries file. - - If lseen is true: - - lsum -- checksum of the local file, None if no local file - lctime -- ctime of the local file, None if no local file - lmtime -- mtime of the local file, None if no local file - - If eseen is true: - - erev -- revision, None if this is a no revision (not '0') - enew -- true if this is an uncommitted added file - edeleted -- true if this is an uncommitted removed file - ectime -- ctime of last local file corresponding to erev - emtime -- mtime of last local file corresponding to erev - extra -- 5th string from CVS/Entries file - - If rseen is true: - - rrev -- revision of head, None if non-existent - rsum -- checksum of that revision, Non if non-existent - - If eseen and rseen are both true: - - esum -- checksum of revision erev, None if no revision - - Note - """ - - def __init__(self, file = None): - if file and '/' in file: - raise ValueError, "no slash allowed in file" - self.file = file - self.lseen = self.eseen = self.rseen = 0 - self.proxy = None - - def __cmp__(self, other): - return cmp(self.file, other.file) - - def getlocal(self): - try: - self.lmtime, self.lctime = os.stat(self.file)[-2:] - except os.error: - self.lmtime = self.lctime = self.lsum = None - else: - self.lsum = md5.new(open(self.file).read()).digest() - self.lseen = 1 - - def getentry(self, line): - words = string.splitfields(line, '/') - if self.file and words[1] != self.file: - raise ValueError, "file name mismatch" - self.file = words[1] - self.erev = words[2] - self.edeleted = 0 - self.enew = 0 - self.ectime = self.emtime = None - if self.erev[:1] == '-': - self.edeleted = 1 - self.erev = self.erev[1:] - if self.erev == '0': - self.erev = None - self.enew = 1 - else: - dates = words[3] - self.ectime = unctime(dates[:24]) - self.emtime = unctime(dates[25:]) - self.extra = words[4] - if self.rseen: - self.getesum() - self.eseen = 1 - - def getremote(self, proxy = None): - if proxy: - self.proxy = proxy - try: - self.rrev = self.proxy.head(self.file) - except (os.error, IOError): - self.rrev = None - if self.rrev: - self.rsum = self.proxy.sum(self.file) - else: - self.rsum = None - if self.eseen: - self.getesum() - self.rseen = 1 - - def getesum(self): - if self.erev == self.rrev: - self.esum = self.rsum - elif self.erev: - name = (self.file, self.erev) - self.esum = self.proxy.sum(name) - else: - self.esum = None - - def putentry(self): - """Return a line suitable for inclusion in CVS/Entries. - - The returned line is terminated by a newline. - If no entry should be written for this file, - return "". - """ - if not self.eseen: - return "" - - rev = self.erev or '0' - if self.edeleted: - rev = '-' + rev - if self.enew: - dates = 'Initial ' + self.file - else: - dates = gmctime(self.ectime) + ' ' + \ - gmctime(self.emtime) - return "/%s/%s/%s/%s/\n" % ( - self.file, - rev, - dates, - self.extra) - - def report(self): - print '-'*50 - def r(key, repr=repr, self=self): - try: - value = repr(getattr(self, key)) - except AttributeError: - value = "?" - print "%-15s:" % key, value - r("file") - if self.lseen: - r("lsum", hexify) - r("lctime", gmctime) - r("lmtime", gmctime) - if self.eseen: - r("erev") - r("enew") - r("edeleted") - r("ectime", gmctime) - r("emtime", gmctime) - if self.rseen: - r("rrev") - r("rsum", hexify) - if self.eseen: - r("esum", hexify) + """Represent a file's status. + + Instance variables: + + file -- the filename (no slashes), None if uninitialized + lseen -- true if the data for the local file is up to date + eseen -- true if the data from the CVS/Entries entry is up to date + (this implies that the entry must be written back) + rseen -- true if the data for the remote file is up to date + proxy -- RCSProxy instance used to contact the server, or None + + Note that lseen and rseen don't necessary mean that a local + or remote file *exists* -- they indicate that we've checked it. + However, eseen means that this instance corresponds to an + entry in the CVS/Entries file. + + If lseen is true: + + lsum -- checksum of the local file, None if no local file + lctime -- ctime of the local file, None if no local file + lmtime -- mtime of the local file, None if no local file + + If eseen is true: + + erev -- revision, None if this is a no revision (not '0') + enew -- true if this is an uncommitted added file + edeleted -- true if this is an uncommitted removed file + ectime -- ctime of last local file corresponding to erev + emtime -- mtime of last local file corresponding to erev + extra -- 5th string from CVS/Entries file + + If rseen is true: + + rrev -- revision of head, None if non-existent + rsum -- checksum of that revision, Non if non-existent + + If eseen and rseen are both true: + + esum -- checksum of revision erev, None if no revision + + Note + """ + + def __init__(self, file = None): + if file and '/' in file: + raise ValueError, "no slash allowed in file" + self.file = file + self.lseen = self.eseen = self.rseen = 0 + self.proxy = None + + def __cmp__(self, other): + return cmp(self.file, other.file) + + def getlocal(self): + try: + self.lmtime, self.lctime = os.stat(self.file)[-2:] + except os.error: + self.lmtime = self.lctime = self.lsum = None + else: + self.lsum = md5.new(open(self.file).read()).digest() + self.lseen = 1 + + def getentry(self, line): + words = string.splitfields(line, '/') + if self.file and words[1] != self.file: + raise ValueError, "file name mismatch" + self.file = words[1] + self.erev = words[2] + self.edeleted = 0 + self.enew = 0 + self.ectime = self.emtime = None + if self.erev[:1] == '-': + self.edeleted = 1 + self.erev = self.erev[1:] + if self.erev == '0': + self.erev = None + self.enew = 1 + else: + dates = words[3] + self.ectime = unctime(dates[:24]) + self.emtime = unctime(dates[25:]) + self.extra = words[4] + if self.rseen: + self.getesum() + self.eseen = 1 + + def getremote(self, proxy = None): + if proxy: + self.proxy = proxy + try: + self.rrev = self.proxy.head(self.file) + except (os.error, IOError): + self.rrev = None + if self.rrev: + self.rsum = self.proxy.sum(self.file) + else: + self.rsum = None + if self.eseen: + self.getesum() + self.rseen = 1 + + def getesum(self): + if self.erev == self.rrev: + self.esum = self.rsum + elif self.erev: + name = (self.file, self.erev) + self.esum = self.proxy.sum(name) + else: + self.esum = None + + def putentry(self): + """Return a line suitable for inclusion in CVS/Entries. + + The returned line is terminated by a newline. + If no entry should be written for this file, + return "". + """ + if not self.eseen: + return "" + + rev = self.erev or '0' + if self.edeleted: + rev = '-' + rev + if self.enew: + dates = 'Initial ' + self.file + else: + dates = gmctime(self.ectime) + ' ' + \ + gmctime(self.emtime) + return "/%s/%s/%s/%s/\n" % ( + self.file, + rev, + dates, + self.extra) + + def report(self): + print '-'*50 + def r(key, repr=repr, self=self): + try: + value = repr(getattr(self, key)) + except AttributeError: + value = "?" + print "%-15s:" % key, value + r("file") + if self.lseen: + r("lsum", hexify) + r("lctime", gmctime) + r("lmtime", gmctime) + if self.eseen: + r("erev") + r("enew") + r("edeleted") + r("ectime", gmctime) + r("emtime", gmctime) + if self.rseen: + r("rrev") + r("rsum", hexify) + if self.eseen: + r("esum", hexify) class CVS: - - """Represent the contents of a CVS admin file (and more). - - Class variables: - - FileClass -- the class to be instantiated for entries - (this should be derived from class File above) - IgnoreList -- shell patterns for local files to be ignored - - Instance variables: - - entries -- a dictionary containing File instances keyed by - their file name - proxy -- an RCSProxy instance, or None - """ - - FileClass = File - - IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc'] - - def __init__(self): - self.entries = {} - self.proxy = None - - def setproxy(self, proxy): - if proxy is self.proxy: - return - self.proxy = proxy - for e in self.entries.values(): - e.rseen = 0 - - def getentries(self): - """Read the contents of CVS/Entries""" - self.entries = {} - f = self.cvsopen("Entries") - while 1: - line = f.readline() - if not line: break - e = self.FileClass() - e.getentry(line) - self.entries[e.file] = e - f.close() - - def putentries(self): - """Write CVS/Entries back""" - f = self.cvsopen("Entries", 'w') - for e in self.values(): - f.write(e.putentry()) - f.close() - - def getlocalfiles(self): - list = self.entries.keys() - addlist = os.listdir(os.curdir) - for name in addlist: - if name in list: - continue - if not self.ignored(name): - list.append(name) - list.sort() - for file in list: - try: - e = self.entries[file] - except KeyError: - e = self.entries[file] = self.FileClass(file) - e.getlocal() - - def getremotefiles(self, proxy = None): - if proxy: - self.proxy = proxy - if not self.proxy: - raise RuntimeError, "no RCS proxy" - addlist = self.proxy.listfiles() - for file in addlist: - try: - e = self.entries[file] - except KeyError: - e = self.entries[file] = self.FileClass(file) - e.getremote(self.proxy) - - def report(self): - for e in self.values(): - e.report() - print '-'*50 - - def keys(self): - keys = self.entries.keys() - keys.sort() - return keys - - def values(self): - def value(key, self=self): - return self.entries[key] - return map(value, self.keys()) - - def items(self): - def item(key, self=self): - return (key, self.entries[key]) - return map(item, self.keys()) - - def cvsexists(self, file): - file = os.path.join("CVS", file) - return os.path.exists(file) - - def cvsopen(self, file, mode = 'r'): - file = os.path.join("CVS", file) - if 'r' not in mode: - self.backup(file) - return open(file, mode) - - def backup(self, file): - if os.path.isfile(file): - bfile = file + '~' - try: os.unlink(bfile) - except os.error: pass - os.rename(file, bfile) - - def ignored(self, file): - if os.path.isdir(file): return True - for pat in self.IgnoreList: - if fnmatch.fnmatch(file, pat): return True - return False + + """Represent the contents of a CVS admin file (and more). + + Class variables: + + FileClass -- the class to be instantiated for entries + (this should be derived from class File above) + IgnoreList -- shell patterns for local files to be ignored + + Instance variables: + + entries -- a dictionary containing File instances keyed by + their file name + proxy -- an RCSProxy instance, or None + """ + + FileClass = File + + IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc'] + + def __init__(self): + self.entries = {} + self.proxy = None + + def setproxy(self, proxy): + if proxy is self.proxy: + return + self.proxy = proxy + for e in self.entries.values(): + e.rseen = 0 + + def getentries(self): + """Read the contents of CVS/Entries""" + self.entries = {} + f = self.cvsopen("Entries") + while 1: + line = f.readline() + if not line: break + e = self.FileClass() + e.getentry(line) + self.entries[e.file] = e + f.close() + + def putentries(self): + """Write CVS/Entries back""" + f = self.cvsopen("Entries", 'w') + for e in self.values(): + f.write(e.putentry()) + f.close() + + def getlocalfiles(self): + list = self.entries.keys() + addlist = os.listdir(os.curdir) + for name in addlist: + if name in list: + continue + if not self.ignored(name): + list.append(name) + list.sort() + for file in list: + try: + e = self.entries[file] + except KeyError: + e = self.entries[file] = self.FileClass(file) + e.getlocal() + + def getremotefiles(self, proxy = None): + if proxy: + self.proxy = proxy + if not self.proxy: + raise RuntimeError, "no RCS proxy" + addlist = self.proxy.listfiles() + for file in addlist: + try: + e = self.entries[file] + except KeyError: + e = self.entries[file] = self.FileClass(file) + e.getremote(self.proxy) + + def report(self): + for e in self.values(): + e.report() + print '-'*50 + + def keys(self): + keys = self.entries.keys() + keys.sort() + return keys + + def values(self): + def value(key, self=self): + return self.entries[key] + return map(value, self.keys()) + + def items(self): + def item(key, self=self): + return (key, self.entries[key]) + return map(item, self.keys()) + + def cvsexists(self, file): + file = os.path.join("CVS", file) + return os.path.exists(file) + + def cvsopen(self, file, mode = 'r'): + file = os.path.join("CVS", file) + if 'r' not in mode: + self.backup(file) + return open(file, mode) + + def backup(self, file): + if os.path.isfile(file): + bfile = file + '~' + try: os.unlink(bfile) + except os.error: pass + os.rename(file, bfile) + + def ignored(self, file): + if os.path.isdir(file): return True + for pat in self.IgnoreList: + if fnmatch.fnmatch(file, pat): return True + return False # hexify and unhexify are useful to print MD5 checksums in hex format hexify_format = '%02x' * 16 def hexify(sum): - "Return a hex representation of a 16-byte string (e.g. an MD5 digest)" - if sum is None: - return "None" - return hexify_format % tuple(map(ord, sum)) + "Return a hex representation of a 16-byte string (e.g. an MD5 digest)" + if sum is None: + return "None" + return hexify_format % tuple(map(ord, sum)) def unhexify(hexsum): - "Return the original from a hexified string" - if hexsum == "None": - return None - sum = '' - for i in range(0, len(hexsum), 2): - sum = sum + chr(string.atoi(hexsum[i:i+2], 16)) - return sum + "Return the original from a hexified string" + if hexsum == "None": + return None + sum = '' + for i in range(0, len(hexsum), 2): + sum = sum + chr(string.atoi(hexsum[i:i+2], 16)) + return sum unctime_monthmap = {} def unctime(date): - if date == "None": return None - if not unctime_monthmap: - months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - i = 0 - for m in months: - i = i+1 - unctime_monthmap[m] = i - words = string.split(date) # Day Mon DD HH:MM:SS YEAR - year = string.atoi(words[4]) - month = unctime_monthmap[words[1]] - day = string.atoi(words[2]) - [hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':')) - ss = ss - time.timezone - return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0)) + if date == "None": return None + if not unctime_monthmap: + months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + i = 0 + for m in months: + i = i+1 + unctime_monthmap[m] = i + words = string.split(date) # Day Mon DD HH:MM:SS YEAR + year = string.atoi(words[4]) + month = unctime_monthmap[words[1]] + day = string.atoi(words[2]) + [hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':')) + ss = ss - time.timezone + return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0)) def gmctime(t): - if t is None: return "None" - return time.asctime(time.gmtime(t)) + if t is None: return "None" + return time.asctime(time.gmtime(t)) def test_unctime(): - now = int(time.time()) - t = time.gmtime(now) - at = time.asctime(t) - print 'GMT', now, at - print 'timezone', time.timezone - print 'local', time.ctime(now) - u = unctime(at) - print 'unctime()', u - gu = time.gmtime(u) - print '->', gu - print time.asctime(gu) + now = int(time.time()) + t = time.gmtime(now) + at = time.asctime(t) + print 'GMT', now, at + print 'timezone', time.timezone + print 'local', time.ctime(now) + u = unctime(at) + print 'unctime()', u + gu = time.gmtime(u) + print '->', gu + print time.asctime(gu) def test(): - x = CVS() - x.getentries() - x.getlocalfiles() -## x.report() - import rcsclient - proxy = rcsclient.openrcsclient() - x.getremotefiles(proxy) - x.report() + x = CVS() + x.getentries() + x.getlocalfiles() +## x.report() + import rcsclient + proxy = rcsclient.openrcsclient() + x.getremotefiles(proxy) + x.report() if __name__ == "__main__": - test() + test() diff --git a/Demo/pdist/cvslock.py b/Demo/pdist/cvslock.py index 75f866e..8f6d008 100755 --- a/Demo/pdist/cvslock.py +++ b/Demo/pdist/cvslock.py @@ -22,25 +22,25 @@ a write lock is held. - To set a read lock: - - acquire the meta-lock - - create the file "#cvs.rfl.<pid>" - - release the meta-lock + - acquire the meta-lock + - create the file "#cvs.rfl.<pid>" + - release the meta-lock - To set a write lock: - - acquire the meta-lock - - check that there are no files called "#cvs.rfl.*" - - if there are, release the meta-lock, sleep, try again - - create the file "#cvs.wfl.<pid>" + - acquire the meta-lock + - check that there are no files called "#cvs.rfl.*" + - if there are, release the meta-lock, sleep, try again + - create the file "#cvs.wfl.<pid>" - To release a write lock: - - remove the file "#cvs.wfl.<pid>" - - rmdir the meta-lock + - remove the file "#cvs.wfl.<pid>" + - rmdir the meta-lock - To release a read lock: - - remove the file "#cvs.rfl.<pid>" + - remove the file "#cvs.rfl.<pid>" Additional notes @@ -93,188 +93,188 @@ CVSWFL = "#cvs.wfl." class Error: - def __init__(self, msg): - self.msg = msg + def __init__(self, msg): + self.msg = msg - def __repr__(self): - return repr(self.msg) + def __repr__(self): + return repr(self.msg) - def __str__(self): - return str(self.msg) + def __str__(self): + return str(self.msg) class Locked(Error): - pass + pass class Lock: - def __init__(self, repository = ".", delay = DELAY): - self.repository = repository - self.delay = delay - self.lockdir = None - self.lockfile = None - pid = repr(os.getpid()) - self.cvslck = self.join(CVSLCK) - self.cvsrfl = self.join(CVSRFL + pid) - self.cvswfl = self.join(CVSWFL + pid) - - def __del__(self): - print "__del__" - self.unlock() - - def setlockdir(self): - while 1: - try: - self.lockdir = self.cvslck - os.mkdir(self.cvslck, 0777) - return - except os.error, msg: - self.lockdir = None - if msg[0] == EEXIST: - try: - st = os.stat(self.cvslck) - except os.error: - continue - self.sleep(st) - continue - raise Error("failed to lock %s: %s" % ( - self.repository, msg)) - - def unlock(self): - self.unlockfile() - self.unlockdir() - - def unlockfile(self): - if self.lockfile: - print "unlink", self.lockfile - try: - os.unlink(self.lockfile) - except os.error: - pass - self.lockfile = None - - def unlockdir(self): - if self.lockdir: - print "rmdir", self.lockdir - try: - os.rmdir(self.lockdir) - except os.error: - pass - self.lockdir = None - - def sleep(self, st): - sleep(st, self.repository, self.delay) - - def join(self, name): - return os.path.join(self.repository, name) + def __init__(self, repository = ".", delay = DELAY): + self.repository = repository + self.delay = delay + self.lockdir = None + self.lockfile = None + pid = repr(os.getpid()) + self.cvslck = self.join(CVSLCK) + self.cvsrfl = self.join(CVSRFL + pid) + self.cvswfl = self.join(CVSWFL + pid) + + def __del__(self): + print "__del__" + self.unlock() + + def setlockdir(self): + while 1: + try: + self.lockdir = self.cvslck + os.mkdir(self.cvslck, 0777) + return + except os.error, msg: + self.lockdir = None + if msg[0] == EEXIST: + try: + st = os.stat(self.cvslck) + except os.error: + continue + self.sleep(st) + continue + raise Error("failed to lock %s: %s" % ( + self.repository, msg)) + + def unlock(self): + self.unlockfile() + self.unlockdir() + + def unlockfile(self): + if self.lockfile: + print "unlink", self.lockfile + try: + os.unlink(self.lockfile) + except os.error: + pass + self.lockfile = None + + def unlockdir(self): + if self.lockdir: + print "rmdir", self.lockdir + try: + os.rmdir(self.lockdir) + except os.error: + pass + self.lockdir = None + + def sleep(self, st): + sleep(st, self.repository, self.delay) + + def join(self, name): + return os.path.join(self.repository, name) def sleep(st, repository, delay): - if delay <= 0: - raise Locked(st) - uid = st[stat.ST_UID] - try: - pwent = pwd.getpwuid(uid) - user = pwent[0] - except KeyError: - user = "uid %d" % uid - print "[%s]" % time.ctime(time.time())[11:19], - print "Waiting for %s's lock in" % user, repository - time.sleep(delay) + if delay <= 0: + raise Locked(st) + uid = st[stat.ST_UID] + try: + pwent = pwd.getpwuid(uid) + user = pwent[0] + except KeyError: + user = "uid %d" % uid + print "[%s]" % time.ctime(time.time())[11:19], + print "Waiting for %s's lock in" % user, repository + time.sleep(delay) class ReadLock(Lock): - def __init__(self, repository, delay = DELAY): - Lock.__init__(self, repository, delay) - ok = 0 - try: - self.setlockdir() - self.lockfile = self.cvsrfl - fp = open(self.lockfile, 'w') - fp.close() - ok = 1 - finally: - if not ok: - self.unlockfile() - self.unlockdir() + def __init__(self, repository, delay = DELAY): + Lock.__init__(self, repository, delay) + ok = 0 + try: + self.setlockdir() + self.lockfile = self.cvsrfl + fp = open(self.lockfile, 'w') + fp.close() + ok = 1 + finally: + if not ok: + self.unlockfile() + self.unlockdir() class WriteLock(Lock): - def __init__(self, repository, delay = DELAY): - Lock.__init__(self, repository, delay) - self.setlockdir() - while 1: - uid = self.readers_exist() - if not uid: - break - self.unlockdir() - self.sleep(uid) - self.lockfile = self.cvswfl - fp = open(self.lockfile, 'w') - fp.close() - - def readers_exist(self): - n = len(CVSRFL) - for name in os.listdir(self.repository): - if name[:n] == CVSRFL: - try: - st = os.stat(self.join(name)) - except os.error: - continue - return st - return None + def __init__(self, repository, delay = DELAY): + Lock.__init__(self, repository, delay) + self.setlockdir() + while 1: + uid = self.readers_exist() + if not uid: + break + self.unlockdir() + self.sleep(uid) + self.lockfile = self.cvswfl + fp = open(self.lockfile, 'w') + fp.close() + + def readers_exist(self): + n = len(CVSRFL) + for name in os.listdir(self.repository): + if name[:n] == CVSRFL: + try: + st = os.stat(self.join(name)) + except os.error: + continue + return st + return None def MultipleWriteLock(repositories, delay = DELAY): - while 1: - locks = [] - for r in repositories: - try: - locks.append(WriteLock(r, 0)) - except Locked, instance: - del locks - break - else: - break - sleep(instance.msg, r, delay) - return list + while 1: + locks = [] + for r in repositories: + try: + locks.append(WriteLock(r, 0)) + except Locked, instance: + del locks + break + else: + break + sleep(instance.msg, r, delay) + return list def test(): - import sys - if sys.argv[1:]: - repository = sys.argv[1] - else: - repository = "." - rl = None - wl = None - try: - print "attempting write lock ..." - wl = WriteLock(repository) - print "got it." - wl.unlock() - print "attempting read lock ..." - rl = ReadLock(repository) - print "got it." - rl.unlock() - finally: - print [1] - sys.exc_traceback = None - print [2] - if rl: - rl.unlock() - print [3] - if wl: - wl.unlock() - print [4] - rl = None - print [5] - wl = None - print [6] + import sys + if sys.argv[1:]: + repository = sys.argv[1] + else: + repository = "." + rl = None + wl = None + try: + print "attempting write lock ..." + wl = WriteLock(repository) + print "got it." + wl.unlock() + print "attempting read lock ..." + rl = ReadLock(repository) + print "got it." + rl.unlock() + finally: + print [1] + sys.exc_traceback = None + print [2] + if rl: + rl.unlock() + print [3] + if wl: + wl.unlock() + print [4] + rl = None + print [5] + wl = None + print [6] if __name__ == '__main__': - test() + test() diff --git a/Demo/pdist/mac.py b/Demo/pdist/mac.py index 516ee15..107113c 100755 --- a/Demo/pdist/mac.py +++ b/Demo/pdist/mac.py @@ -3,17 +3,17 @@ import string import rcvs def main(): - while 1: - try: - line = raw_input('$ ') - except EOFError: - break - words = string.split(line) - if not words: - continue - if words[0] != 'rcvs': - words.insert(0, 'rcvs') - sys.argv = words - rcvs.main() + while 1: + try: + line = raw_input('$ ') + except EOFError: + break + words = string.split(line) + if not words: + continue + if words[0] != 'rcvs': + words.insert(0, 'rcvs') + sys.argv = words + rcvs.main() main() diff --git a/Demo/pdist/rcsclient.py b/Demo/pdist/rcsclient.py index 5d88a57..d8cb004 100755 --- a/Demo/pdist/rcsclient.py +++ b/Demo/pdist/rcsclient.py @@ -21,51 +21,51 @@ import client class RCSProxyClient(client.SecureClient): - - def __init__(self, address, verbose = client.VERBOSE): - client.SecureClient.__init__(self, address, verbose) + + def __init__(self, address, verbose = client.VERBOSE): + client.SecureClient.__init__(self, address, verbose) def openrcsclient(opts = []): - "open an RCSProxy client based on a list of options returned by getopt" - import RCSProxy - host = HOST - port = PORT - verbose = VERBOSE - local = LOCAL - directory = None - for o, a in opts: - if o == '-h': - host = a - if ':' in host: - i = string.find(host, ':') - host, p = host[:i], host[i+1:] - if p: - port = string.atoi(p) - if o == '-p': - port = string.atoi(a) - if o == '-d': - directory = a - if o == '-v': - verbose = verbose + 1 - if o == '-q': - verbose = 0 - if o == '-L': - local = 1 - if local: - import RCSProxy - x = RCSProxy.RCSProxyLocal() - else: - address = (host, port) - x = RCSProxyClient(address, verbose) - if not directory: - try: - directory = open(os.path.join("CVS", "Repository")).readline() - except IOError: - pass - else: - if directory[-1] == '\n': - directory = directory[:-1] - if directory: - x.cd(directory) - return x + "open an RCSProxy client based on a list of options returned by getopt" + import RCSProxy + host = HOST + port = PORT + verbose = VERBOSE + local = LOCAL + directory = None + for o, a in opts: + if o == '-h': + host = a + if ':' in host: + i = string.find(host, ':') + host, p = host[:i], host[i+1:] + if p: + port = string.atoi(p) + if o == '-p': + port = string.atoi(a) + if o == '-d': + directory = a + if o == '-v': + verbose = verbose + 1 + if o == '-q': + verbose = 0 + if o == '-L': + local = 1 + if local: + import RCSProxy + x = RCSProxy.RCSProxyLocal() + else: + address = (host, port) + x = RCSProxyClient(address, verbose) + if not directory: + try: + directory = open(os.path.join("CVS", "Repository")).readline() + except IOError: + pass + else: + if directory[-1] == '\n': + directory = directory[:-1] + if directory: + x.cd(directory) + return x diff --git a/Demo/pdist/rcslib.py b/Demo/pdist/rcslib.py index 78de111..d5f7b65 100755 --- a/Demo/pdist/rcslib.py +++ b/Demo/pdist/rcslib.py @@ -83,7 +83,7 @@ class RCS: if line[0] == '\t': # XXX could be a lock or symbolic name # Anything else? - continue + continue i = string.find(line, ':') if i > 0: key, value = line[:i], string.strip(line[i+1:]) @@ -287,7 +287,7 @@ class RCS: if reason&0x80: code = code + '(coredump)' return code, signal - + def _system(self, cmd): """INTERNAL: run COMMAND in a subshell. @@ -311,7 +311,7 @@ class RCS: If a second PATTERN argument is given, only files matching it are kept. No check for valid filenames is made. - + """ if pat: def keep(name, pat = pat): diff --git a/Demo/pdist/rcvs.py b/Demo/pdist/rcvs.py index 24036c7..8b8bae6 100755 --- a/Demo/pdist/rcvs.py +++ b/Demo/pdist/rcvs.py @@ -40,188 +40,188 @@ import sys from cmdfw import CommandFrameWork -DEF_LOCAL = 1 # Default -l +DEF_LOCAL = 1 # Default -l class MyFile(File): - def action(self): - """Return a code indicating the update status of this file. - - The possible return values are: - - '=' -- everything's fine - '0' -- file doesn't exist anywhere - '?' -- exists locally only - 'A' -- new locally - 'R' -- deleted locally - 'U' -- changed remotely, no changes locally - (includes new remotely or deleted remotely) - 'M' -- changed locally, no changes remotely - 'C' -- conflict: changed locally as well as remotely - (includes cases where the file has been added - or removed locally and remotely) - 'D' -- deleted remotely - 'N' -- new remotely - 'r' -- get rid of entry - 'c' -- create entry - 'u' -- update entry - - (and probably others :-) - """ - if not self.lseen: - self.getlocal() - if not self.rseen: - self.getremote() - if not self.eseen: - if not self.lsum: - if not self.rsum: return '0' # Never heard of - else: - return 'N' # New remotely - else: # self.lsum - if not self.rsum: return '?' # Local only - # Local and remote, but no entry - if self.lsum == self.rsum: - return 'c' # Restore entry only - else: return 'C' # Real conflict - else: # self.eseen - if not self.lsum: - if self.edeleted: - if self.rsum: return 'R' # Removed - else: return 'r' # Get rid of entry - else: # not self.edeleted - if self.rsum: - print "warning:", - print self.file, - print "was lost" - return 'U' - else: return 'r' # Get rid of entry - else: # self.lsum - if not self.rsum: - if self.enew: return 'A' # New locally - else: return 'D' # Deleted remotely - else: # self.rsum - if self.enew: - if self.lsum == self.rsum: - return 'u' - else: - return 'C' - if self.lsum == self.esum: - if self.esum == self.rsum: - return '=' - else: - return 'U' - elif self.esum == self.rsum: - return 'M' - elif self.lsum == self.rsum: - return 'u' - else: - return 'C' - - def update(self): - code = self.action() - if code == '=': return - print code, self.file - if code in ('U', 'N'): - self.get() - elif code == 'C': - print "%s: conflict resolution not yet implemented" % \ - self.file - elif code == 'D': - remove(self.file) - self.eseen = 0 - elif code == 'r': - self.eseen = 0 - elif code in ('c', 'u'): - self.eseen = 1 - self.erev = self.rrev - self.enew = 0 - self.edeleted = 0 - self.esum = self.rsum - self.emtime, self.ectime = os.stat(self.file)[-2:] - self.extra = '' - - def commit(self, message = ""): - code = self.action() - if code in ('A', 'M'): - self.put(message) - return 1 - elif code == 'R': - print "%s: committing removes not yet implemented" % \ - self.file - elif code == 'C': - print "%s: conflict resolution not yet implemented" % \ - self.file - - def diff(self, opts = []): - self.action() # To update lseen, rseen - flags = '' - rev = self.rrev - # XXX should support two rev options too! - for o, a in opts: - if o == '-r': - rev = a - else: - flags = flags + ' ' + o + a - if rev == self.rrev and self.lsum == self.rsum: - return - flags = flags[1:] - fn = self.file - data = self.proxy.get((fn, rev)) - sum = md5.new(data).digest() - if self.lsum == sum: - return - import tempfile - tf = tempfile.NamedTemporaryFile() - tf.write(data) - tf.flush() - print 'diff %s -r%s %s' % (flags, rev, fn) - sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) - if sts: - print '='*70 - - def commitcheck(self): - return self.action() != 'C' - - def put(self, message = ""): - print "Checking in", self.file, "..." - data = open(self.file).read() - if not self.enew: - self.proxy.lock(self.file) - messages = self.proxy.put(self.file, data, message) - if messages: - print messages - self.setentry(self.proxy.head(self.file), self.lsum) - - def get(self): - data = self.proxy.get(self.file) - f = open(self.file, 'w') - f.write(data) - f.close() - self.setentry(self.rrev, self.rsum) - - def log(self, otherflags): - print self.proxy.log(self.file, otherflags) - - def add(self): - self.eseen = 0 # While we're hacking... - self.esum = self.lsum - self.emtime, self.ectime = 0, 0 - self.erev = '' - self.enew = 1 - self.edeleted = 0 - self.eseen = 1 # Done - self.extra = '' - - def setentry(self, erev, esum): - self.eseen = 0 # While we're hacking... - self.esum = esum - self.emtime, self.ectime = os.stat(self.file)[-2:] - self.erev = erev - self.enew = 0 - self.edeleted = 0 - self.eseen = 1 # Done - self.extra = '' + def action(self): + """Return a code indicating the update status of this file. + + The possible return values are: + + '=' -- everything's fine + '0' -- file doesn't exist anywhere + '?' -- exists locally only + 'A' -- new locally + 'R' -- deleted locally + 'U' -- changed remotely, no changes locally + (includes new remotely or deleted remotely) + 'M' -- changed locally, no changes remotely + 'C' -- conflict: changed locally as well as remotely + (includes cases where the file has been added + or removed locally and remotely) + 'D' -- deleted remotely + 'N' -- new remotely + 'r' -- get rid of entry + 'c' -- create entry + 'u' -- update entry + + (and probably others :-) + """ + if not self.lseen: + self.getlocal() + if not self.rseen: + self.getremote() + if not self.eseen: + if not self.lsum: + if not self.rsum: return '0' # Never heard of + else: + return 'N' # New remotely + else: # self.lsum + if not self.rsum: return '?' # Local only + # Local and remote, but no entry + if self.lsum == self.rsum: + return 'c' # Restore entry only + else: return 'C' # Real conflict + else: # self.eseen + if not self.lsum: + if self.edeleted: + if self.rsum: return 'R' # Removed + else: return 'r' # Get rid of entry + else: # not self.edeleted + if self.rsum: + print "warning:", + print self.file, + print "was lost" + return 'U' + else: return 'r' # Get rid of entry + else: # self.lsum + if not self.rsum: + if self.enew: return 'A' # New locally + else: return 'D' # Deleted remotely + else: # self.rsum + if self.enew: + if self.lsum == self.rsum: + return 'u' + else: + return 'C' + if self.lsum == self.esum: + if self.esum == self.rsum: + return '=' + else: + return 'U' + elif self.esum == self.rsum: + return 'M' + elif self.lsum == self.rsum: + return 'u' + else: + return 'C' + + def update(self): + code = self.action() + if code == '=': return + print code, self.file + if code in ('U', 'N'): + self.get() + elif code == 'C': + print "%s: conflict resolution not yet implemented" % \ + self.file + elif code == 'D': + remove(self.file) + self.eseen = 0 + elif code == 'r': + self.eseen = 0 + elif code in ('c', 'u'): + self.eseen = 1 + self.erev = self.rrev + self.enew = 0 + self.edeleted = 0 + self.esum = self.rsum + self.emtime, self.ectime = os.stat(self.file)[-2:] + self.extra = '' + + def commit(self, message = ""): + code = self.action() + if code in ('A', 'M'): + self.put(message) + return 1 + elif code == 'R': + print "%s: committing removes not yet implemented" % \ + self.file + elif code == 'C': + print "%s: conflict resolution not yet implemented" % \ + self.file + + def diff(self, opts = []): + self.action() # To update lseen, rseen + flags = '' + rev = self.rrev + # XXX should support two rev options too! + for o, a in opts: + if o == '-r': + rev = a + else: + flags = flags + ' ' + o + a + if rev == self.rrev and self.lsum == self.rsum: + return + flags = flags[1:] + fn = self.file + data = self.proxy.get((fn, rev)) + sum = md5.new(data).digest() + if self.lsum == sum: + return + import tempfile + tf = tempfile.NamedTemporaryFile() + tf.write(data) + tf.flush() + print 'diff %s -r%s %s' % (flags, rev, fn) + sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) + if sts: + print '='*70 + + def commitcheck(self): + return self.action() != 'C' + + def put(self, message = ""): + print "Checking in", self.file, "..." + data = open(self.file).read() + if not self.enew: + self.proxy.lock(self.file) + messages = self.proxy.put(self.file, data, message) + if messages: + print messages + self.setentry(self.proxy.head(self.file), self.lsum) + + def get(self): + data = self.proxy.get(self.file) + f = open(self.file, 'w') + f.write(data) + f.close() + self.setentry(self.rrev, self.rsum) + + def log(self, otherflags): + print self.proxy.log(self.file, otherflags) + + def add(self): + self.eseen = 0 # While we're hacking... + self.esum = self.lsum + self.emtime, self.ectime = 0, 0 + self.erev = '' + self.enew = 1 + self.edeleted = 0 + self.eseen = 1 # Done + self.extra = '' + + def setentry(self, erev, esum): + self.eseen = 0 # While we're hacking... + self.esum = esum + self.emtime, self.ectime = os.stat(self.file)[-2:] + self.erev = erev + self.enew = 0 + self.edeleted = 0 + self.eseen = 1 # Done + self.extra = '' SENDMAIL = "/usr/lib/sendmail -t" @@ -231,247 +231,247 @@ Subject: CVS changes: %s ...Message from rcvs... Committed files: - %s + %s Log message: - %s + %s """ class RCVS(CVS): - FileClass = MyFile - - def __init__(self): - CVS.__init__(self) - - def update(self, files): - for e in self.whichentries(files, 1): - e.update() - - def commit(self, files, message = ""): - list = self.whichentries(files) - if not list: return - ok = 1 - for e in list: - if not e.commitcheck(): - ok = 0 - if not ok: - print "correct above errors first" - return - if not message: - message = raw_input("One-liner: ") - committed = [] - for e in list: - if e.commit(message): - committed.append(e.file) - self.mailinfo(committed, message) - - def mailinfo(self, files, message = ""): - towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX - mailtext = MAILFORM % (towhom, string.join(files), - string.join(files), message) - print '-'*70 - print mailtext - print '-'*70 - ok = raw_input("OK to mail to %s? " % towhom) - if string.lower(string.strip(ok)) in ('y', 'ye', 'yes'): - p = os.popen(SENDMAIL, "w") - p.write(mailtext) - sts = p.close() - if sts: - print "Sendmail exit status %s" % str(sts) - else: - print "Mail sent." - else: - print "No mail sent." - - def report(self, files): - for e in self.whichentries(files): - e.report() - - def diff(self, files, opts): - for e in self.whichentries(files): - e.diff(opts) - - def add(self, files): - if not files: - raise RuntimeError, "'cvs add' needs at least one file" - list = [] - for e in self.whichentries(files, 1): - e.add() - - def rm(self, files): - if not files: - raise RuntimeError, "'cvs rm' needs at least one file" - raise RuntimeError, "'cvs rm' not yet imlemented" - - def log(self, files, opts): - flags = '' - for o, a in opts: - flags = flags + ' ' + o + a - for e in self.whichentries(files): - e.log(flags) - - def whichentries(self, files, localfilestoo = 0): - if files: - list = [] - for file in files: - if self.entries.has_key(file): - e = self.entries[file] - else: - e = self.FileClass(file) - self.entries[file] = e - list.append(e) - else: - list = self.entries.values() - for file in self.proxy.listfiles(): - if self.entries.has_key(file): - continue - e = self.FileClass(file) - self.entries[file] = e - list.append(e) - if localfilestoo: - for file in os.listdir(os.curdir): - if not self.entries.has_key(file) \ - and not self.ignored(file): - e = self.FileClass(file) - self.entries[file] = e - list.append(e) - list.sort() - if self.proxy: - for e in list: - if e.proxy is None: - e.proxy = self.proxy - return list + FileClass = MyFile + + def __init__(self): + CVS.__init__(self) + + def update(self, files): + for e in self.whichentries(files, 1): + e.update() + + def commit(self, files, message = ""): + list = self.whichentries(files) + if not list: return + ok = 1 + for e in list: + if not e.commitcheck(): + ok = 0 + if not ok: + print "correct above errors first" + return + if not message: + message = raw_input("One-liner: ") + committed = [] + for e in list: + if e.commit(message): + committed.append(e.file) + self.mailinfo(committed, message) + + def mailinfo(self, files, message = ""): + towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX + mailtext = MAILFORM % (towhom, string.join(files), + string.join(files), message) + print '-'*70 + print mailtext + print '-'*70 + ok = raw_input("OK to mail to %s? " % towhom) + if string.lower(string.strip(ok)) in ('y', 'ye', 'yes'): + p = os.popen(SENDMAIL, "w") + p.write(mailtext) + sts = p.close() + if sts: + print "Sendmail exit status %s" % str(sts) + else: + print "Mail sent." + else: + print "No mail sent." + + def report(self, files): + for e in self.whichentries(files): + e.report() + + def diff(self, files, opts): + for e in self.whichentries(files): + e.diff(opts) + + def add(self, files): + if not files: + raise RuntimeError, "'cvs add' needs at least one file" + list = [] + for e in self.whichentries(files, 1): + e.add() + + def rm(self, files): + if not files: + raise RuntimeError, "'cvs rm' needs at least one file" + raise RuntimeError, "'cvs rm' not yet imlemented" + + def log(self, files, opts): + flags = '' + for o, a in opts: + flags = flags + ' ' + o + a + for e in self.whichentries(files): + e.log(flags) + + def whichentries(self, files, localfilestoo = 0): + if files: + list = [] + for file in files: + if self.entries.has_key(file): + e = self.entries[file] + else: + e = self.FileClass(file) + self.entries[file] = e + list.append(e) + else: + list = self.entries.values() + for file in self.proxy.listfiles(): + if self.entries.has_key(file): + continue + e = self.FileClass(file) + self.entries[file] = e + list.append(e) + if localfilestoo: + for file in os.listdir(os.curdir): + if not self.entries.has_key(file) \ + and not self.ignored(file): + e = self.FileClass(file) + self.entries[file] = e + list.append(e) + list.sort() + if self.proxy: + for e in list: + if e.proxy is None: + e.proxy = self.proxy + return list class rcvs(CommandFrameWork): - GlobalFlags = 'd:h:p:qvL' - UsageMessage = \ + GlobalFlags = 'd:h:p:qvL' + UsageMessage = \ "usage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]" - PostUsageMessage = \ - "If no subcommand is given, the status of all files is listed" - - def __init__(self): - """Constructor.""" - CommandFrameWork.__init__(self) - self.proxy = None - self.cvs = RCVS() - - def close(self): - if self.proxy: - self.proxy._close() - self.proxy = None - - def recurse(self): - self.close() - names = os.listdir(os.curdir) - for name in names: - if name == os.curdir or name == os.pardir: - continue - if name == "CVS": - continue - if not os.path.isdir(name): - continue - if os.path.islink(name): - continue - print "--- entering subdirectory", name, "---" - os.chdir(name) - try: - if os.path.isdir("CVS"): - self.__class__().run() - else: - self.recurse() - finally: - os.chdir(os.pardir) - print "--- left subdirectory", name, "---" - - def options(self, opts): - self.opts = opts - - def ready(self): - import rcsclient - self.proxy = rcsclient.openrcsclient(self.opts) - self.cvs.setproxy(self.proxy) - self.cvs.getentries() - - def default(self): - self.cvs.report([]) - - def do_report(self, opts, files): - self.cvs.report(files) - - def do_update(self, opts, files): - """update [-l] [-R] [file] ...""" - local = DEF_LOCAL - for o, a in opts: - if o == '-l': local = 1 - if o == '-R': local = 0 - self.cvs.update(files) - self.cvs.putentries() - if not local and not files: - self.recurse() - flags_update = '-lR' - do_up = do_update - flags_up = flags_update - - def do_commit(self, opts, files): - """commit [-m message] [file] ...""" - message = "" - for o, a in opts: - if o == '-m': message = a - self.cvs.commit(files, message) - self.cvs.putentries() - flags_commit = 'm:' - do_com = do_commit - flags_com = flags_commit - - def do_diff(self, opts, files): - """diff [difflags] [file] ...""" - self.cvs.diff(files, opts) - flags_diff = 'cbitwcefhnlr:sD:S:' - do_dif = do_diff - flags_dif = flags_diff - - def do_add(self, opts, files): - """add file ...""" - if not files: - print "'rcvs add' requires at least one file" - return - self.cvs.add(files) - self.cvs.putentries() - - def do_remove(self, opts, files): - """remove file ...""" - if not files: - print "'rcvs remove' requires at least one file" - return - self.cvs.remove(files) - self.cvs.putentries() - do_rm = do_remove - - def do_log(self, opts, files): - """log [rlog-options] [file] ...""" - self.cvs.log(files, opts) - flags_log = 'bhLNRtd:s:V:r:' + PostUsageMessage = \ + "If no subcommand is given, the status of all files is listed" + + def __init__(self): + """Constructor.""" + CommandFrameWork.__init__(self) + self.proxy = None + self.cvs = RCVS() + + def close(self): + if self.proxy: + self.proxy._close() + self.proxy = None + + def recurse(self): + self.close() + names = os.listdir(os.curdir) + for name in names: + if name == os.curdir or name == os.pardir: + continue + if name == "CVS": + continue + if not os.path.isdir(name): + continue + if os.path.islink(name): + continue + print "--- entering subdirectory", name, "---" + os.chdir(name) + try: + if os.path.isdir("CVS"): + self.__class__().run() + else: + self.recurse() + finally: + os.chdir(os.pardir) + print "--- left subdirectory", name, "---" + + def options(self, opts): + self.opts = opts + + def ready(self): + import rcsclient + self.proxy = rcsclient.openrcsclient(self.opts) + self.cvs.setproxy(self.proxy) + self.cvs.getentries() + + def default(self): + self.cvs.report([]) + + def do_report(self, opts, files): + self.cvs.report(files) + + def do_update(self, opts, files): + """update [-l] [-R] [file] ...""" + local = DEF_LOCAL + for o, a in opts: + if o == '-l': local = 1 + if o == '-R': local = 0 + self.cvs.update(files) + self.cvs.putentries() + if not local and not files: + self.recurse() + flags_update = '-lR' + do_up = do_update + flags_up = flags_update + + def do_commit(self, opts, files): + """commit [-m message] [file] ...""" + message = "" + for o, a in opts: + if o == '-m': message = a + self.cvs.commit(files, message) + self.cvs.putentries() + flags_commit = 'm:' + do_com = do_commit + flags_com = flags_commit + + def do_diff(self, opts, files): + """diff [difflags] [file] ...""" + self.cvs.diff(files, opts) + flags_diff = 'cbitwcefhnlr:sD:S:' + do_dif = do_diff + flags_dif = flags_diff + + def do_add(self, opts, files): + """add file ...""" + if not files: + print "'rcvs add' requires at least one file" + return + self.cvs.add(files) + self.cvs.putentries() + + def do_remove(self, opts, files): + """remove file ...""" + if not files: + print "'rcvs remove' requires at least one file" + return + self.cvs.remove(files) + self.cvs.putentries() + do_rm = do_remove + + def do_log(self, opts, files): + """log [rlog-options] [file] ...""" + self.cvs.log(files, opts) + flags_log = 'bhLNRtd:s:V:r:' def remove(fn): - try: - os.unlink(fn) - except os.error: - pass + try: + os.unlink(fn) + except os.error: + pass def main(): - r = rcvs() - try: - r.run() - finally: - r.close() + r = rcvs() + try: + r.run() + finally: + r.close() if __name__ == "__main__": - main() + main() diff --git a/Demo/pdist/rrcs.py b/Demo/pdist/rrcs.py index a07260c..4d23e6c 100755 --- a/Demo/pdist/rrcs.py +++ b/Demo/pdist/rrcs.py @@ -11,150 +11,150 @@ import tempfile from rcsclient import openrcsclient def main(): - sys.stdout = sys.stderr - try: - opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL') - if not rest: - cmd = 'head' - else: - cmd, rest = rest[0], rest[1:] - if not commands.has_key(cmd): - raise getopt.error, "unknown command" - coptset, func = commands[cmd] - copts, files = getopt.getopt(rest, coptset) - except getopt.error, msg: - print msg - print "usage: rrcs [options] command [options] [file] ..." - print "where command can be:" - print " ci|put # checkin the given files" - print " co|get # checkout" - print " info # print header info" - print " head # print revision of head branch" - print " list # list filename if valid" - print " log # print full log" - print " diff # diff rcs file and work file" - print "if no files are given, all remote rcs files are assumed" - sys.exit(2) - x = openrcsclient(opts) - if not files: - files = x.listfiles() - for fn in files: - try: - func(x, copts, fn) - except (IOError, os.error), msg: - print "%s: %s" % (fn, msg) + sys.stdout = sys.stderr + try: + opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL') + if not rest: + cmd = 'head' + else: + cmd, rest = rest[0], rest[1:] + if not commands.has_key(cmd): + raise getopt.error, "unknown command" + coptset, func = commands[cmd] + copts, files = getopt.getopt(rest, coptset) + except getopt.error, msg: + print msg + print "usage: rrcs [options] command [options] [file] ..." + print "where command can be:" + print " ci|put # checkin the given files" + print " co|get # checkout" + print " info # print header info" + print " head # print revision of head branch" + print " list # list filename if valid" + print " log # print full log" + print " diff # diff rcs file and work file" + print "if no files are given, all remote rcs files are assumed" + sys.exit(2) + x = openrcsclient(opts) + if not files: + files = x.listfiles() + for fn in files: + try: + func(x, copts, fn) + except (IOError, os.error), msg: + print "%s: %s" % (fn, msg) def checkin(x, copts, fn): - f = open(fn) - data = f.read() - f.close() - new = not x.isvalid(fn) - if not new and same(x, copts, fn, data): - print "%s: unchanged since last checkin" % fn - return - print "Checking in", fn, "..." - message = asklogmessage(new) - messages = x.put(fn, data, message) - if messages: - print messages + f = open(fn) + data = f.read() + f.close() + new = not x.isvalid(fn) + if not new and same(x, copts, fn, data): + print "%s: unchanged since last checkin" % fn + return + print "Checking in", fn, "..." + message = asklogmessage(new) + messages = x.put(fn, data, message) + if messages: + print messages def checkout(x, copts, fn): - data = x.get(fn) - f = open(fn, 'w') - f.write(data) - f.close() + data = x.get(fn) + f = open(fn, 'w') + f.write(data) + f.close() def lock(x, copts, fn): - x.lock(fn) + x.lock(fn) def unlock(x, copts, fn): - x.unlock(fn) + x.unlock(fn) def info(x, copts, fn): - dict = x.info(fn) - keys = dict.keys() - keys.sort() - for key in keys: - print key + ':', dict[key] - print '='*70 + dict = x.info(fn) + keys = dict.keys() + keys.sort() + for key in keys: + print key + ':', dict[key] + print '='*70 def head(x, copts, fn): - head = x.head(fn) - print fn, head + head = x.head(fn) + print fn, head def list(x, copts, fn): - if x.isvalid(fn): - print fn + if x.isvalid(fn): + print fn def log(x, copts, fn): - flags = '' - for o, a in copts: - flags = flags + ' ' + o + a - flags = flags[1:] - messages = x.log(fn, flags) - print messages + flags = '' + for o, a in copts: + flags = flags + ' ' + o + a + flags = flags[1:] + messages = x.log(fn, flags) + print messages def diff(x, copts, fn): - if same(x, copts, fn): - return - flags = '' - for o, a in copts: - flags = flags + ' ' + o + a - flags = flags[1:] - data = x.get(fn) - tf = tempfile.NamedTemporaryFile() - tf.write(data) - tf.flush() - print 'diff %s -r%s %s' % (flags, x.head(fn), fn) - sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) - if sts: - print '='*70 + if same(x, copts, fn): + return + flags = '' + for o, a in copts: + flags = flags + ' ' + o + a + flags = flags[1:] + data = x.get(fn) + tf = tempfile.NamedTemporaryFile() + tf.write(data) + tf.flush() + print 'diff %s -r%s %s' % (flags, x.head(fn), fn) + sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) + if sts: + print '='*70 def same(x, copts, fn, data = None): - if data is None: - f = open(fn) - data = f.read() - f.close() - lsum = md5.new(data).digest() - rsum = x.sum(fn) - return lsum == rsum + if data is None: + f = open(fn) + data = f.read() + f.close() + lsum = md5.new(data).digest() + rsum = x.sum(fn) + return lsum == rsum def asklogmessage(new): - if new: - print "enter description,", - else: - print "enter log message,", - print "terminate with single '.' or end of file:" - if new: - print "NOTE: This is NOT the log message!" - message = "" - while 1: - sys.stderr.write(">> ") - sys.stderr.flush() - line = sys.stdin.readline() - if not line or line == '.\n': break - message = message + line - return message + if new: + print "enter description,", + else: + print "enter log message,", + print "terminate with single '.' or end of file:" + if new: + print "NOTE: This is NOT the log message!" + message = "" + while 1: + sys.stderr.write(">> ") + sys.stderr.flush() + line = sys.stdin.readline() + if not line or line == '.\n': break + message = message + line + return message def remove(fn): - try: - os.unlink(fn) - except os.error: - pass + try: + os.unlink(fn) + except os.error: + pass commands = { - 'ci': ('', checkin), - 'put': ('', checkin), - 'co': ('', checkout), - 'get': ('', checkout), - 'info': ('', info), - 'head': ('', head), - 'list': ('', list), - 'lock': ('', lock), - 'unlock': ('', unlock), - 'log': ('bhLRtd:l:r:s:w:V:', log), - 'diff': ('c', diff), - } + 'ci': ('', checkin), + 'put': ('', checkin), + 'co': ('', checkout), + 'get': ('', checkout), + 'info': ('', info), + 'head': ('', head), + 'list': ('', list), + 'lock': ('', lock), + 'unlock': ('', unlock), + 'log': ('bhLRtd:l:r:s:w:V:', log), + 'diff': ('c', diff), + } if __name__ == '__main__': - main() + main() diff --git a/Demo/pdist/security.py b/Demo/pdist/security.py index 0ffd511..b63081e 100755 --- a/Demo/pdist/security.py +++ b/Demo/pdist/security.py @@ -1,33 +1,33 @@ class Security: - def __init__(self): - import os - env = os.environ - if env.has_key('PYTHON_KEYFILE'): - keyfile = env['PYTHON_KEYFILE'] - else: - keyfile = '.python_keyfile' - if env.has_key('HOME'): - keyfile = os.path.join(env['HOME'], keyfile) - if not os.path.exists(keyfile): - import sys - for dir in sys.path: - kf = os.path.join(dir, keyfile) - if os.path.exists(kf): - keyfile = kf - break - try: - self._key = eval(open(keyfile).readline()) - except IOError: - raise IOError, "python keyfile %s: cannot open" % keyfile + def __init__(self): + import os + env = os.environ + if env.has_key('PYTHON_KEYFILE'): + keyfile = env['PYTHON_KEYFILE'] + else: + keyfile = '.python_keyfile' + if env.has_key('HOME'): + keyfile = os.path.join(env['HOME'], keyfile) + if not os.path.exists(keyfile): + import sys + for dir in sys.path: + kf = os.path.join(dir, keyfile) + if os.path.exists(kf): + keyfile = kf + break + try: + self._key = eval(open(keyfile).readline()) + except IOError: + raise IOError, "python keyfile %s: cannot open" % keyfile - def _generate_challenge(self): - import random - return random.randint(100, 100000) + def _generate_challenge(self): + import random + return random.randint(100, 100000) - def _compare_challenge_response(self, challenge, response): - return self._encode_challenge(challenge) == response + def _compare_challenge_response(self, challenge, response): + return self._encode_challenge(challenge) == response - def _encode_challenge(self, challenge): - p, m = self._key - return pow(long(challenge), p, m) + def _encode_challenge(self, challenge): + p, m = self._key + return pow(long(challenge), p, m) diff --git a/Demo/pdist/server.py b/Demo/pdist/server.py index 4e4ab0d..e692eea 100755 --- a/Demo/pdist/server.py +++ b/Demo/pdist/server.py @@ -12,103 +12,103 @@ VERBOSE = 1 class Server: - - """RPC Server class. Derive a class to implement a particular service.""" - - def __init__(self, address, verbose = VERBOSE): - if type(address) == type(0): - address = ('', address) - self._address = address - self._verbose = verbose - self._socket = None - self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._socket.bind(address) - self._socket.listen(1) - self._listening = 1 - - def _setverbose(self, verbose): - self._verbose = verbose - - def __del__(self): - self._close() - - def _close(self): - self._listening = 0 - if self._socket: - self._socket.close() - self._socket = None - - def _serverloop(self): - while self._listening: - self._serve() - - def _serve(self): - if self._verbose: print "Wait for connection ..." - conn, address = self._socket.accept() - if self._verbose: print "Accepted connection from %s" % repr(address) - if not self._verify(conn, address): - print "*** Connection from %s refused" % repr(address) - conn.close() - return - rf = conn.makefile('r') - wf = conn.makefile('w') - ok = 1 - while ok: - wf.flush() - if self._verbose > 1: print "Wait for next request ..." - ok = self._dorequest(rf, wf) - - _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*'] - - def _verify(self, conn, address): - host, port = address - for pat in self._valid: - if fnmatch(host, pat): return 1 - return 0 - - def _dorequest(self, rf, wf): - rp = pickle.Unpickler(rf) - try: - request = rp.load() - except EOFError: - return 0 - if self._verbose > 1: print "Got request: %s" % repr(request) - try: - methodname, args, id = request - if '.' in methodname: - reply = (None, self._special(methodname, args), id) - elif methodname[0] == '_': - raise NameError, "illegal method name %s" % repr(methodname) - else: - method = getattr(self, methodname) - reply = (None, apply(method, args), id) - except: - reply = (sys.exc_type, sys.exc_value, id) - if id < 0 and reply[:2] == (None, None): - if self._verbose > 1: print "Suppress reply" - return 1 - if self._verbose > 1: print "Send reply: %s" % repr(reply) - wp = pickle.Pickler(wf) - wp.dump(reply) - return 1 - - def _special(self, methodname, args): - if methodname == '.methods': - if not hasattr(self, '_methods'): - self._methods = tuple(self._listmethods()) - return self._methods - raise NameError, "unrecognized special method name %s" % repr(methodname) - - def _listmethods(self, cl=None): - if not cl: cl = self.__class__ - names = cl.__dict__.keys() - names = filter(lambda x: x[0] != '_', names) - names.sort() - for base in cl.__bases__: - basenames = self._listmethods(base) - basenames = filter(lambda x, names=names: x not in names, basenames) - names[len(names):] = basenames - return names + + """RPC Server class. Derive a class to implement a particular service.""" + + def __init__(self, address, verbose = VERBOSE): + if type(address) == type(0): + address = ('', address) + self._address = address + self._verbose = verbose + self._socket = None + self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._socket.bind(address) + self._socket.listen(1) + self._listening = 1 + + def _setverbose(self, verbose): + self._verbose = verbose + + def __del__(self): + self._close() + + def _close(self): + self._listening = 0 + if self._socket: + self._socket.close() + self._socket = None + + def _serverloop(self): + while self._listening: + self._serve() + + def _serve(self): + if self._verbose: print "Wait for connection ..." + conn, address = self._socket.accept() + if self._verbose: print "Accepted connection from %s" % repr(address) + if not self._verify(conn, address): + print "*** Connection from %s refused" % repr(address) + conn.close() + return + rf = conn.makefile('r') + wf = conn.makefile('w') + ok = 1 + while ok: + wf.flush() + if self._verbose > 1: print "Wait for next request ..." + ok = self._dorequest(rf, wf) + + _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*'] + + def _verify(self, conn, address): + host, port = address + for pat in self._valid: + if fnmatch(host, pat): return 1 + return 0 + + def _dorequest(self, rf, wf): + rp = pickle.Unpickler(rf) + try: + request = rp.load() + except EOFError: + return 0 + if self._verbose > 1: print "Got request: %s" % repr(request) + try: + methodname, args, id = request + if '.' in methodname: + reply = (None, self._special(methodname, args), id) + elif methodname[0] == '_': + raise NameError, "illegal method name %s" % repr(methodname) + else: + method = getattr(self, methodname) + reply = (None, apply(method, args), id) + except: + reply = (sys.exc_type, sys.exc_value, id) + if id < 0 and reply[:2] == (None, None): + if self._verbose > 1: print "Suppress reply" + return 1 + if self._verbose > 1: print "Send reply: %s" % repr(reply) + wp = pickle.Pickler(wf) + wp.dump(reply) + return 1 + + def _special(self, methodname, args): + if methodname == '.methods': + if not hasattr(self, '_methods'): + self._methods = tuple(self._listmethods()) + return self._methods + raise NameError, "unrecognized special method name %s" % repr(methodname) + + def _listmethods(self, cl=None): + if not cl: cl = self.__class__ + names = cl.__dict__.keys() + names = filter(lambda x: x[0] != '_', names) + names.sort() + for base in cl.__bases__: + basenames = self._listmethods(base) + basenames = filter(lambda x, names=names: x not in names, basenames) + names[len(names):] = basenames + return names from security import Security @@ -116,30 +116,30 @@ from security import Security class SecureServer(Server, Security): - def __init__(self, *args): - apply(Server.__init__, (self,) + args) - Security.__init__(self) - - def _verify(self, conn, address): - import string - challenge = self._generate_challenge() - conn.send("%d\n" % challenge) - response = "" - while "\n" not in response and len(response) < 100: - data = conn.recv(100) - if not data: - break - response = response + data - try: - response = string.atol(string.strip(response)) - except string.atol_error: - if self._verbose > 0: - print "Invalid response syntax", repr(response) - return 0 - if not self._compare_challenge_response(challenge, response): - if self._verbose > 0: - print "Invalid response value", repr(response) - return 0 - if self._verbose > 1: - print "Response matches challenge. Go ahead!" - return 1 + def __init__(self, *args): + apply(Server.__init__, (self,) + args) + Security.__init__(self) + + def _verify(self, conn, address): + import string + challenge = self._generate_challenge() + conn.send("%d\n" % challenge) + response = "" + while "\n" not in response and len(response) < 100: + data = conn.recv(100) + if not data: + break + response = response + data + try: + response = string.atol(string.strip(response)) + except string.atol_error: + if self._verbose > 0: + print "Invalid response syntax", repr(response) + return 0 + if not self._compare_challenge_response(challenge, response): + if self._verbose > 0: + print "Invalid response value", repr(response) + return 0 + if self._verbose > 1: + print "Response matches challenge. Go ahead!" + return 1 diff --git a/Demo/pdist/sumtree.py b/Demo/pdist/sumtree.py index 92c1fd0..9291a56 100755 --- a/Demo/pdist/sumtree.py +++ b/Demo/pdist/sumtree.py @@ -2,23 +2,23 @@ import time import FSProxy def main(): - t1 = time.time() - #proxy = FSProxy.FSProxyClient(('voorn.cwi.nl', 4127)) - proxy = FSProxy.FSProxyLocal() - sumtree(proxy) - proxy._close() - t2 = time.time() - print t2-t1, "seconds" - raw_input("[Return to exit] ") + t1 = time.time() + #proxy = FSProxy.FSProxyClient(('voorn.cwi.nl', 4127)) + proxy = FSProxy.FSProxyLocal() + sumtree(proxy) + proxy._close() + t2 = time.time() + print t2-t1, "seconds" + raw_input("[Return to exit] ") def sumtree(proxy): - print "PWD =", proxy.pwd() - files = proxy.listfiles() - proxy.infolist(files) - subdirs = proxy.listsubdirs() - for name in subdirs: - proxy.cd(name) - sumtree(proxy) - proxy.back() + print "PWD =", proxy.pwd() + files = proxy.listfiles() + proxy.infolist(files) + subdirs = proxy.listsubdirs() + for name in subdirs: + proxy.cd(name) + sumtree(proxy) + proxy.back() main() diff --git a/Demo/rpc/T.py b/Demo/rpc/T.py index 2adf486..3325507 100644 --- a/Demo/rpc/T.py +++ b/Demo/rpc/T.py @@ -4,19 +4,19 @@ import sys, os, time def TSTART(): - global t0, t1 - u, s, cu, cs = os.times() - t0 = u+cu, s+cs, time.time() + global t0, t1 + u, s, cu, cs = os.times() + t0 = u+cu, s+cs, time.time() def TSTOP(*label): - global t0, t1 - u, s, cu, cs = os.times() - t1 = u+cu, s+cs, time.time() - tt = [] - for i in range(3): - tt.append(t1[i] - t0[i]) - [u, s, r] = tt - msg = '' - for x in label: msg = msg + (x + ' ') - msg = msg + '%r user, %r sys, %r real\n' % (u, s, r) - sys.stderr.write(msg) + global t0, t1 + u, s, cu, cs = os.times() + t1 = u+cu, s+cs, time.time() + tt = [] + for i in range(3): + tt.append(t1[i] - t0[i]) + [u, s, r] = tt + msg = '' + for x in label: msg = msg + (x + ' ') + msg = msg + '%r user, %r sys, %r real\n' % (u, s, r) + sys.stderr.write(msg) diff --git a/Demo/rpc/mountclient.py b/Demo/rpc/mountclient.py index 8a4b1b6..318a9d9 100644 --- a/Demo/rpc/mountclient.py +++ b/Demo/rpc/mountclient.py @@ -26,8 +26,8 @@ FHSIZE = 32 class MountPacker(Packer): - def pack_fhandle(self, fhandle): - self.pack_fopaque(FHSIZE, fhandle) + def pack_fhandle(self, fhandle): + self.pack_fopaque(FHSIZE, fhandle) # Unpacker derived class for Mount protocol clients. @@ -39,35 +39,35 @@ class MountPacker(Packer): class MountUnpacker(Unpacker): - def unpack_fhandle(self): - return self.unpack_fopaque(FHSIZE) + def unpack_fhandle(self): + return self.unpack_fopaque(FHSIZE) - def unpack_fhstatus(self): - status = self.unpack_uint() - if status == 0: - fh = self.unpack_fhandle() - else: - fh = None - return status, fh + def unpack_fhstatus(self): + status = self.unpack_uint() + if status == 0: + fh = self.unpack_fhandle() + else: + fh = None + return status, fh - def unpack_mountlist(self): - return self.unpack_list(self.unpack_mountstruct) + def unpack_mountlist(self): + return self.unpack_list(self.unpack_mountstruct) - def unpack_mountstruct(self): - hostname = self.unpack_string() - directory = self.unpack_string() - return (hostname, directory) + def unpack_mountstruct(self): + hostname = self.unpack_string() + directory = self.unpack_string() + return (hostname, directory) - def unpack_exportlist(self): - return self.unpack_list(self.unpack_exportstruct) + def unpack_exportlist(self): + return self.unpack_list(self.unpack_exportstruct) - def unpack_exportstruct(self): - filesys = self.unpack_string() - groups = self.unpack_groups() - return (filesys, groups) + def unpack_exportstruct(self): + filesys = self.unpack_string() + groups = self.unpack_groups() + return (filesys, groups) - def unpack_groups(self): - return self.unpack_list(self.unpack_string) + def unpack_groups(self): + return self.unpack_list(self.unpack_string) # These are the procedures specific to the Mount client class. @@ -75,84 +75,84 @@ class MountUnpacker(Unpacker): class PartialMountClient: - # This method is called by Client.__init__ to initialize - # self.packer and self.unpacker - def addpackers(self): - self.packer = MountPacker() - self.unpacker = MountUnpacker('') - - # This method is called by Client.__init__ to bind the socket - # to a particular network interface and port. We use the - # default network interface, but if we're running as root, - # we want to bind to a reserved port - def bindsocket(self): - import os - try: - uid = os.getuid() - except AttributeError: - uid = 1 - if uid == 0: - port = rpc.bindresvport(self.sock, '') - # 'port' is not used - else: - self.sock.bind(('', 0)) - - # This function is called to cough up a suitable - # authentication object for a call to procedure 'proc'. - def mkcred(self): - if self.cred == None: - self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default() - return self.cred - - # The methods Mnt, Dump etc. each implement one Remote - # Procedure Call. This is done by calling self.make_call() - # with as arguments: - # - # - the procedure number - # - the arguments (or None) - # - the "packer" function for the arguments (or None) - # - the "unpacker" function for the return value (or None) - # - # The packer and unpacker function, if not None, *must* be - # methods of self.packer and self.unpacker, respectively. - # A value of None means that there are no arguments or is no - # return value, respectively. - # - # The return value from make_call() is the return value from - # the remote procedure call, as unpacked by the "unpacker" - # function, or None if the unpacker function is None. - # - # (Even if you expect a result of None, you should still - # return the return value from make_call(), since this may be - # needed by a broadcasting version of the class.) - # - # If the call fails, make_call() raises an exception - # (this includes time-outs and invalid results). - # - # Note that (at least with the UDP protocol) there is no - # guarantee that a call is executed at most once. When you do - # get a reply, you know it has been executed at least once; - # when you don't get a reply, you know nothing. - - def Mnt(self, directory): - return self.make_call(1, directory, \ - self.packer.pack_string, \ - self.unpacker.unpack_fhstatus) - - def Dump(self): - return self.make_call(2, None, \ - None, self.unpacker.unpack_mountlist) - - def Umnt(self, directory): - return self.make_call(3, directory, \ - self.packer.pack_string, None) - - def Umntall(self): - return self.make_call(4, None, None, None) - - def Export(self): - return self.make_call(5, None, \ - None, self.unpacker.unpack_exportlist) + # This method is called by Client.__init__ to initialize + # self.packer and self.unpacker + def addpackers(self): + self.packer = MountPacker() + self.unpacker = MountUnpacker('') + + # This method is called by Client.__init__ to bind the socket + # to a particular network interface and port. We use the + # default network interface, but if we're running as root, + # we want to bind to a reserved port + def bindsocket(self): + import os + try: + uid = os.getuid() + except AttributeError: + uid = 1 + if uid == 0: + port = rpc.bindresvport(self.sock, '') + # 'port' is not used + else: + self.sock.bind(('', 0)) + + # This function is called to cough up a suitable + # authentication object for a call to procedure 'proc'. + def mkcred(self): + if self.cred == None: + self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default() + return self.cred + + # The methods Mnt, Dump etc. each implement one Remote + # Procedure Call. This is done by calling self.make_call() + # with as arguments: + # + # - the procedure number + # - the arguments (or None) + # - the "packer" function for the arguments (or None) + # - the "unpacker" function for the return value (or None) + # + # The packer and unpacker function, if not None, *must* be + # methods of self.packer and self.unpacker, respectively. + # A value of None means that there are no arguments or is no + # return value, respectively. + # + # The return value from make_call() is the return value from + # the remote procedure call, as unpacked by the "unpacker" + # function, or None if the unpacker function is None. + # + # (Even if you expect a result of None, you should still + # return the return value from make_call(), since this may be + # needed by a broadcasting version of the class.) + # + # If the call fails, make_call() raises an exception + # (this includes time-outs and invalid results). + # + # Note that (at least with the UDP protocol) there is no + # guarantee that a call is executed at most once. When you do + # get a reply, you know it has been executed at least once; + # when you don't get a reply, you know nothing. + + def Mnt(self, directory): + return self.make_call(1, directory, \ + self.packer.pack_string, \ + self.unpacker.unpack_fhstatus) + + def Dump(self): + return self.make_call(2, None, \ + None, self.unpacker.unpack_mountlist) + + def Umnt(self, directory): + return self.make_call(3, directory, \ + self.packer.pack_string, None) + + def Umntall(self): + return self.make_call(4, None, None, None) + + def Export(self): + return self.make_call(5, None, \ + None, self.unpacker.unpack_exportlist) # We turn the partial Mount client into a full one for either protocol @@ -162,14 +162,14 @@ class PartialMountClient: class TCPMountClient(PartialMountClient, TCPClient): - def __init__(self, host): - TCPClient.__init__(self, host, MOUNTPROG, MOUNTVERS) + def __init__(self, host): + TCPClient.__init__(self, host, MOUNTPROG, MOUNTVERS) class UDPMountClient(PartialMountClient, UDPClient): - def __init__(self, host): - UDPClient.__init__(self, host, MOUNTPROG, MOUNTVERS) + def __init__(self, host): + UDPClient.__init__(self, host, MOUNTPROG, MOUNTVERS) # A little test program for the Mount client. This takes a host as @@ -179,24 +179,24 @@ class UDPMountClient(PartialMountClient, UDPClient): # (TCP or UDP), default is UDP. def test(): - import sys - if sys.argv[1:] and sys.argv[1] == '-t': - C = TCPMountClient - del sys.argv[1] - elif sys.argv[1:] and sys.argv[1] == '-u': - C = UDPMountClient - del sys.argv[1] - else: - C = UDPMountClient - if sys.argv[1:]: host = sys.argv[1] - else: host = '' - mcl = C(host) - list = mcl.Export() - for item in list: - print item - try: - mcl.Mnt(item[0]) - except: - print 'Sorry' - continue - mcl.Umnt(item[0]) + import sys + if sys.argv[1:] and sys.argv[1] == '-t': + C = TCPMountClient + del sys.argv[1] + elif sys.argv[1:] and sys.argv[1] == '-u': + C = UDPMountClient + del sys.argv[1] + else: + C = UDPMountClient + if sys.argv[1:]: host = sys.argv[1] + else: host = '' + mcl = C(host) + list = mcl.Export() + for item in list: + print item + try: + mcl.Mnt(item[0]) + except: + print 'Sorry' + continue + mcl.Umnt(item[0]) diff --git a/Demo/rpc/nfsclient.py b/Demo/rpc/nfsclient.py index 37ec46c..c4387b4 100644 --- a/Demo/rpc/nfsclient.py +++ b/Demo/rpc/nfsclient.py @@ -28,174 +28,174 @@ NFLNK = 5 class NFSPacker(MountPacker): - def pack_sattrargs(self, sa): - file, attributes = sa - self.pack_fhandle(file) - self.pack_sattr(attributes) - - def pack_sattr(self, sa): - mode, uid, gid, size, atime, mtime = sa - self.pack_uint(mode) - self.pack_uint(uid) - self.pack_uint(gid) - self.pack_uint(size) - self.pack_timeval(atime) - self.pack_timeval(mtime) - - def pack_diropargs(self, da): - dir, name = da - self.pack_fhandle(dir) - self.pack_string(name) - - def pack_readdirargs(self, ra): - dir, cookie, count = ra - self.pack_fhandle(dir) - self.pack_uint(cookie) - self.pack_uint(count) - - def pack_timeval(self, tv): - secs, usecs = tv - self.pack_uint(secs) - self.pack_uint(usecs) + def pack_sattrargs(self, sa): + file, attributes = sa + self.pack_fhandle(file) + self.pack_sattr(attributes) + + def pack_sattr(self, sa): + mode, uid, gid, size, atime, mtime = sa + self.pack_uint(mode) + self.pack_uint(uid) + self.pack_uint(gid) + self.pack_uint(size) + self.pack_timeval(atime) + self.pack_timeval(mtime) + + def pack_diropargs(self, da): + dir, name = da + self.pack_fhandle(dir) + self.pack_string(name) + + def pack_readdirargs(self, ra): + dir, cookie, count = ra + self.pack_fhandle(dir) + self.pack_uint(cookie) + self.pack_uint(count) + + def pack_timeval(self, tv): + secs, usecs = tv + self.pack_uint(secs) + self.pack_uint(usecs) class NFSUnpacker(MountUnpacker): - def unpack_readdirres(self): - status = self.unpack_enum() - if status == NFS_OK: - entries = self.unpack_list(self.unpack_entry) - eof = self.unpack_bool() - rest = (entries, eof) - else: - rest = None - return (status, rest) - - def unpack_entry(self): - fileid = self.unpack_uint() - name = self.unpack_string() - cookie = self.unpack_uint() - return (fileid, name, cookie) - - def unpack_diropres(self): - status = self.unpack_enum() - if status == NFS_OK: - fh = self.unpack_fhandle() - fa = self.unpack_fattr() - rest = (fh, fa) - else: - rest = None - return (status, rest) - - def unpack_attrstat(self): - status = self.unpack_enum() - if status == NFS_OK: - attributes = self.unpack_fattr() - else: - attributes = None - return status, attributes - - def unpack_fattr(self): - type = self.unpack_enum() - mode = self.unpack_uint() - nlink = self.unpack_uint() - uid = self.unpack_uint() - gid = self.unpack_uint() - size = self.unpack_uint() - blocksize = self.unpack_uint() - rdev = self.unpack_uint() - blocks = self.unpack_uint() - fsid = self.unpack_uint() - fileid = self.unpack_uint() - atime = self.unpack_timeval() - mtime = self.unpack_timeval() - ctime = self.unpack_timeval() - return (type, mode, nlink, uid, gid, size, blocksize, \ - rdev, blocks, fsid, fileid, atime, mtime, ctime) - - def unpack_timeval(self): - secs = self.unpack_uint() - usecs = self.unpack_uint() - return (secs, usecs) + def unpack_readdirres(self): + status = self.unpack_enum() + if status == NFS_OK: + entries = self.unpack_list(self.unpack_entry) + eof = self.unpack_bool() + rest = (entries, eof) + else: + rest = None + return (status, rest) + + def unpack_entry(self): + fileid = self.unpack_uint() + name = self.unpack_string() + cookie = self.unpack_uint() + return (fileid, name, cookie) + + def unpack_diropres(self): + status = self.unpack_enum() + if status == NFS_OK: + fh = self.unpack_fhandle() + fa = self.unpack_fattr() + rest = (fh, fa) + else: + rest = None + return (status, rest) + + def unpack_attrstat(self): + status = self.unpack_enum() + if status == NFS_OK: + attributes = self.unpack_fattr() + else: + attributes = None + return status, attributes + + def unpack_fattr(self): + type = self.unpack_enum() + mode = self.unpack_uint() + nlink = self.unpack_uint() + uid = self.unpack_uint() + gid = self.unpack_uint() + size = self.unpack_uint() + blocksize = self.unpack_uint() + rdev = self.unpack_uint() + blocks = self.unpack_uint() + fsid = self.unpack_uint() + fileid = self.unpack_uint() + atime = self.unpack_timeval() + mtime = self.unpack_timeval() + ctime = self.unpack_timeval() + return (type, mode, nlink, uid, gid, size, blocksize, \ + rdev, blocks, fsid, fileid, atime, mtime, ctime) + + def unpack_timeval(self): + secs = self.unpack_uint() + usecs = self.unpack_uint() + return (secs, usecs) class NFSClient(UDPClient): - def __init__(self, host): - UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION) - - def addpackers(self): - self.packer = NFSPacker() - self.unpacker = NFSUnpacker('') - - def mkcred(self): - if self.cred == None: - self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default() - return self.cred - - def Getattr(self, fh): - return self.make_call(1, fh, \ - self.packer.pack_fhandle, \ - self.unpacker.unpack_attrstat) - - def Setattr(self, sa): - return self.make_call(2, sa, \ - self.packer.pack_sattrargs, \ - self.unpacker.unpack_attrstat) - - # Root() is obsolete - - def Lookup(self, da): - return self.make_call(4, da, \ - self.packer.pack_diropargs, \ - self.unpacker.unpack_diropres) - - # ... - - def Readdir(self, ra): - return self.make_call(16, ra, \ - self.packer.pack_readdirargs, \ - self.unpacker.unpack_readdirres) - - # Shorthand to get the entire contents of a directory - def Listdir(self, dir): - list = [] - ra = (dir, 0, 2000) - while 1: - (status, rest) = self.Readdir(ra) - if status <> NFS_OK: - break - entries, eof = rest - last_cookie = None - for fileid, name, cookie in entries: - list.append((fileid, name)) - last_cookie = cookie - if eof or last_cookie == None: - break - ra = (ra[0], last_cookie, ra[2]) - return list - - + def __init__(self, host): + UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION) + + def addpackers(self): + self.packer = NFSPacker() + self.unpacker = NFSUnpacker('') + + def mkcred(self): + if self.cred == None: + self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default() + return self.cred + + def Getattr(self, fh): + return self.make_call(1, fh, \ + self.packer.pack_fhandle, \ + self.unpacker.unpack_attrstat) + + def Setattr(self, sa): + return self.make_call(2, sa, \ + self.packer.pack_sattrargs, \ + self.unpacker.unpack_attrstat) + + # Root() is obsolete + + def Lookup(self, da): + return self.make_call(4, da, \ + self.packer.pack_diropargs, \ + self.unpacker.unpack_diropres) + + # ... + + def Readdir(self, ra): + return self.make_call(16, ra, \ + self.packer.pack_readdirargs, \ + self.unpacker.unpack_readdirres) + + # Shorthand to get the entire contents of a directory + def Listdir(self, dir): + list = [] + ra = (dir, 0, 2000) + while 1: + (status, rest) = self.Readdir(ra) + if status <> NFS_OK: + break + entries, eof = rest + last_cookie = None + for fileid, name, cookie in entries: + list.append((fileid, name)) + last_cookie = cookie + if eof or last_cookie == None: + break + ra = (ra[0], last_cookie, ra[2]) + return list + + def test(): - import sys - if sys.argv[1:]: host = sys.argv[1] - else: host = '' - if sys.argv[2:]: filesys = sys.argv[2] - else: filesys = None - from mountclient import UDPMountClient, TCPMountClient - mcl = TCPMountClient(host) - if filesys == None: - list = mcl.Export() - for item in list: - print item - return - sf = mcl.Mnt(filesys) - print sf - fh = sf[1] - if fh: - ncl = NFSClient(host) - as = ncl.Getattr(fh) - print as - list = ncl.Listdir(fh) - for item in list: print item - mcl.Umnt(filesys) + import sys + if sys.argv[1:]: host = sys.argv[1] + else: host = '' + if sys.argv[2:]: filesys = sys.argv[2] + else: filesys = None + from mountclient import UDPMountClient, TCPMountClient + mcl = TCPMountClient(host) + if filesys == None: + list = mcl.Export() + for item in list: + print item + return + sf = mcl.Mnt(filesys) + print sf + fh = sf[1] + if fh: + ncl = NFSClient(host) + as = ncl.Getattr(fh) + print as + list = ncl.Listdir(fh) + for item in list: print item + mcl.Umnt(filesys) diff --git a/Demo/rpc/rnusersclient.py b/Demo/rpc/rnusersclient.py index 90cbd6d..1f3a882 100644 --- a/Demo/rpc/rnusersclient.py +++ b/Demo/rpc/rnusersclient.py @@ -5,94 +5,94 @@ from rpc import Packer, Unpacker, UDPClient, BroadcastUDPClient class RnusersPacker(Packer): - def pack_utmp(self, ui): - ut_line, ut_name, ut_host, ut_time = utmp - self.pack_string(ut_line) - self.pack_string(ut_name) - self.pack_string(ut_host) - self.pack_int(ut_time) - def pack_utmpidle(self, ui): - ui_itmp, ui_idle = ui - self.pack_utmp(ui_utmp) - self.pack_uint(ui_idle) - def pack_utmpidlearr(self, list): - self.pack_array(list, self.pack_itmpidle) + def pack_utmp(self, ui): + ut_line, ut_name, ut_host, ut_time = utmp + self.pack_string(ut_line) + self.pack_string(ut_name) + self.pack_string(ut_host) + self.pack_int(ut_time) + def pack_utmpidle(self, ui): + ui_itmp, ui_idle = ui + self.pack_utmp(ui_utmp) + self.pack_uint(ui_idle) + def pack_utmpidlearr(self, list): + self.pack_array(list, self.pack_itmpidle) class RnusersUnpacker(Unpacker): - def unpack_utmp(self): - ut_line = self.unpack_string() - ut_name = self.unpack_string() - ut_host = self.unpack_string() - ut_time = self.unpack_int() - return ut_line, ut_name, ut_host, ut_time - def unpack_utmpidle(self): - ui_utmp = self.unpack_utmp() - ui_idle = self.unpack_uint() - return ui_utmp, ui_idle - def unpack_utmpidlearr(self): - return self.unpack_array(self.unpack_utmpidle) + def unpack_utmp(self): + ut_line = self.unpack_string() + ut_name = self.unpack_string() + ut_host = self.unpack_string() + ut_time = self.unpack_int() + return ut_line, ut_name, ut_host, ut_time + def unpack_utmpidle(self): + ui_utmp = self.unpack_utmp() + ui_idle = self.unpack_uint() + return ui_utmp, ui_idle + def unpack_utmpidlearr(self): + return self.unpack_array(self.unpack_utmpidle) class PartialRnusersClient: - def addpackers(self): - self.packer = RnusersPacker() - self.unpacker = RnusersUnpacker('') + def addpackers(self): + self.packer = RnusersPacker() + self.unpacker = RnusersUnpacker('') - def Num(self): - return self.make_call(1, None, None, self.unpacker.unpack_int) + def Num(self): + return self.make_call(1, None, None, self.unpacker.unpack_int) - def Names(self): - return self.make_call(2, None, \ - None, self.unpacker.unpack_utmpidlearr) + def Names(self): + return self.make_call(2, None, \ + None, self.unpacker.unpack_utmpidlearr) - def Allnames(self): - return self.make_call(3, None, \ - None, self.unpacker.unpack_utmpidlearr) + def Allnames(self): + return self.make_call(3, None, \ + None, self.unpacker.unpack_utmpidlearr) class RnusersClient(PartialRnusersClient, UDPClient): - def __init__(self, host): - UDPClient.__init__(self, host, 100002, 2) + def __init__(self, host): + UDPClient.__init__(self, host, 100002, 2) class BroadcastRnusersClient(PartialRnusersClient, BroadcastUDPClient): - def __init__(self, bcastaddr): - BroadcastUDPClient.__init__(self, bcastaddr, 100002, 2) + def __init__(self, bcastaddr): + BroadcastUDPClient.__init__(self, bcastaddr, 100002, 2) def test(): - import sys - if not sys.argv[1:]: - testbcast() - return - else: - host = sys.argv[1] - c = RnusersClient(host) - list = c.Names() - for (line, name, host, time), idle in list: - line = strip0(line) - name = strip0(name) - host = strip0(host) - print "%r %r %r %s %s" % (name, host, line, time, idle) + import sys + if not sys.argv[1:]: + testbcast() + return + else: + host = sys.argv[1] + c = RnusersClient(host) + list = c.Names() + for (line, name, host, time), idle in list: + line = strip0(line) + name = strip0(name) + host = strip0(host) + print "%r %r %r %s %s" % (name, host, line, time, idle) def testbcast(): - c = BroadcastRnusersClient('<broadcast>') - def listit(list, fromaddr): - host, port = fromaddr - print host + '\t:', - for (line, name, host, time), idle in list: - print strip0(name), - print - c.set_reply_handler(listit) - all = c.Names() - print 'Total Count:', len(all) + c = BroadcastRnusersClient('<broadcast>') + def listit(list, fromaddr): + host, port = fromaddr + print host + '\t:', + for (line, name, host, time), idle in list: + print strip0(name), + print + c.set_reply_handler(listit) + all = c.Names() + print 'Total Count:', len(all) def strip0(s): - while s and s[-1] == '\0': s = s[:-1] - return s + while s and s[-1] == '\0': s = s[:-1] + return s test() diff --git a/Demo/rpc/rpc.py b/Demo/rpc/rpc.py index 6b15db4..452b47b 100644 --- a/Demo/rpc/rpc.py +++ b/Demo/rpc/rpc.py @@ -25,56 +25,56 @@ AUTH_DES = 3 MSG_ACCEPTED = 0 MSG_DENIED = 1 -SUCCESS = 0 # RPC executed successfully -PROG_UNAVAIL = 1 # remote hasn't exported program -PROG_MISMATCH = 2 # remote can't support version # -PROC_UNAVAIL = 3 # program can't support procedure -GARBAGE_ARGS = 4 # procedure can't decode params +SUCCESS = 0 # RPC executed successfully +PROG_UNAVAIL = 1 # remote hasn't exported program +PROG_MISMATCH = 2 # remote can't support version # +PROC_UNAVAIL = 3 # program can't support procedure +GARBAGE_ARGS = 4 # procedure can't decode params -RPC_MISMATCH = 0 # RPC version number != 2 -AUTH_ERROR = 1 # remote can't authenticate caller +RPC_MISMATCH = 0 # RPC version number != 2 +AUTH_ERROR = 1 # remote can't authenticate caller -AUTH_BADCRED = 1 # bad credentials (seal broken) -AUTH_REJECTEDCRED = 2 # client must begin new session -AUTH_BADVERF = 3 # bad verifier (seal broken) -AUTH_REJECTEDVERF = 4 # verifier expired or replayed -AUTH_TOOWEAK = 5 # rejected for security reasons +AUTH_BADCRED = 1 # bad credentials (seal broken) +AUTH_REJECTEDCRED = 2 # client must begin new session +AUTH_BADVERF = 3 # bad verifier (seal broken) +AUTH_REJECTEDVERF = 4 # verifier expired or replayed +AUTH_TOOWEAK = 5 # rejected for security reasons class Packer(xdr.Packer): - def pack_auth(self, auth): - flavor, stuff = auth - self.pack_enum(flavor) - self.pack_opaque(stuff) - - def pack_auth_unix(self, stamp, machinename, uid, gid, gids): - self.pack_uint(stamp) - self.pack_string(machinename) - self.pack_uint(uid) - self.pack_uint(gid) - self.pack_uint(len(gids)) - for i in gids: - self.pack_uint(i) - - def pack_callheader(self, xid, prog, vers, proc, cred, verf): - self.pack_uint(xid) - self.pack_enum(CALL) - self.pack_uint(RPCVERSION) - self.pack_uint(prog) - self.pack_uint(vers) - self.pack_uint(proc) - self.pack_auth(cred) - self.pack_auth(verf) - # Caller must add procedure-specific part of call - - def pack_replyheader(self, xid, verf): - self.pack_uint(xid) - self.pack_enum(REPLY) - self.pack_uint(MSG_ACCEPTED) - self.pack_auth(verf) - self.pack_enum(SUCCESS) - # Caller must add procedure-specific part of reply + def pack_auth(self, auth): + flavor, stuff = auth + self.pack_enum(flavor) + self.pack_opaque(stuff) + + def pack_auth_unix(self, stamp, machinename, uid, gid, gids): + self.pack_uint(stamp) + self.pack_string(machinename) + self.pack_uint(uid) + self.pack_uint(gid) + self.pack_uint(len(gids)) + for i in gids: + self.pack_uint(i) + + def pack_callheader(self, xid, prog, vers, proc, cred, verf): + self.pack_uint(xid) + self.pack_enum(CALL) + self.pack_uint(RPCVERSION) + self.pack_uint(prog) + self.pack_uint(vers) + self.pack_uint(proc) + self.pack_auth(cred) + self.pack_auth(verf) + # Caller must add procedure-specific part of call + + def pack_replyheader(self, xid, verf): + self.pack_uint(xid) + self.pack_enum(REPLY) + self.pack_uint(MSG_ACCEPTED) + self.pack_auth(verf) + self.pack_enum(SUCCESS) + # Caller must add procedure-specific part of reply # Exceptions @@ -84,87 +84,87 @@ GarbageArgs = 'rpc.GarbageArgs' class Unpacker(xdr.Unpacker): - def unpack_auth(self): - flavor = self.unpack_enum() - stuff = self.unpack_opaque() - return (flavor, stuff) - - def unpack_callheader(self): - xid = self.unpack_uint(xid) - temp = self.unpack_enum() - if temp <> CALL: - raise BadRPCFormat, 'no CALL but %r' % (temp,) - temp = self.unpack_uint() - if temp <> RPCVERSION: - raise BadRPCVerspion, 'bad RPC version %r' % (temp,) - prog = self.unpack_uint() - vers = self.unpack_uint() - proc = self.unpack_uint() - cred = self.unpack_auth() - verf = self.unpack_auth() - return xid, prog, vers, proc, cred, verf - # Caller must add procedure-specific part of call - - def unpack_replyheader(self): - xid = self.unpack_uint() - mtype = self.unpack_enum() - if mtype <> REPLY: - raise RuntimeError, 'no REPLY but %r' % (mtype,) - stat = self.unpack_enum() - if stat == MSG_DENIED: - stat = self.unpack_enum() - if stat == RPC_MISMATCH: - low = self.unpack_uint() - high = self.unpack_uint() - raise RuntimeError, \ - 'MSG_DENIED: RPC_MISMATCH: %r' % ((low, high),) - if stat == AUTH_ERROR: - stat = self.unpack_uint() - raise RuntimeError, \ - 'MSG_DENIED: AUTH_ERROR: %r' % (stat,) - raise RuntimeError, 'MSG_DENIED: %r' % (stat,) - if stat <> MSG_ACCEPTED: - raise RuntimeError, \ - 'Neither MSG_DENIED nor MSG_ACCEPTED: %r' % (stat,) - verf = self.unpack_auth() - stat = self.unpack_enum() - if stat == PROG_UNAVAIL: - raise RuntimeError, 'call failed: PROG_UNAVAIL' - if stat == PROG_MISMATCH: - low = self.unpack_uint() - high = self.unpack_uint() - raise RuntimeError, \ - 'call failed: PROG_MISMATCH: %r' % ((low, high),) - if stat == PROC_UNAVAIL: - raise RuntimeError, 'call failed: PROC_UNAVAIL' - if stat == GARBAGE_ARGS: - raise RuntimeError, 'call failed: GARBAGE_ARGS' - if stat <> SUCCESS: - raise RuntimeError, 'call failed: %r' % (stat,) - return xid, verf - # Caller must get procedure-specific part of reply + def unpack_auth(self): + flavor = self.unpack_enum() + stuff = self.unpack_opaque() + return (flavor, stuff) + + def unpack_callheader(self): + xid = self.unpack_uint(xid) + temp = self.unpack_enum() + if temp <> CALL: + raise BadRPCFormat, 'no CALL but %r' % (temp,) + temp = self.unpack_uint() + if temp <> RPCVERSION: + raise BadRPCVerspion, 'bad RPC version %r' % (temp,) + prog = self.unpack_uint() + vers = self.unpack_uint() + proc = self.unpack_uint() + cred = self.unpack_auth() + verf = self.unpack_auth() + return xid, prog, vers, proc, cred, verf + # Caller must add procedure-specific part of call + + def unpack_replyheader(self): + xid = self.unpack_uint() + mtype = self.unpack_enum() + if mtype <> REPLY: + raise RuntimeError, 'no REPLY but %r' % (mtype,) + stat = self.unpack_enum() + if stat == MSG_DENIED: + stat = self.unpack_enum() + if stat == RPC_MISMATCH: + low = self.unpack_uint() + high = self.unpack_uint() + raise RuntimeError, \ + 'MSG_DENIED: RPC_MISMATCH: %r' % ((low, high),) + if stat == AUTH_ERROR: + stat = self.unpack_uint() + raise RuntimeError, \ + 'MSG_DENIED: AUTH_ERROR: %r' % (stat,) + raise RuntimeError, 'MSG_DENIED: %r' % (stat,) + if stat <> MSG_ACCEPTED: + raise RuntimeError, \ + 'Neither MSG_DENIED nor MSG_ACCEPTED: %r' % (stat,) + verf = self.unpack_auth() + stat = self.unpack_enum() + if stat == PROG_UNAVAIL: + raise RuntimeError, 'call failed: PROG_UNAVAIL' + if stat == PROG_MISMATCH: + low = self.unpack_uint() + high = self.unpack_uint() + raise RuntimeError, \ + 'call failed: PROG_MISMATCH: %r' % ((low, high),) + if stat == PROC_UNAVAIL: + raise RuntimeError, 'call failed: PROC_UNAVAIL' + if stat == GARBAGE_ARGS: + raise RuntimeError, 'call failed: GARBAGE_ARGS' + if stat <> SUCCESS: + raise RuntimeError, 'call failed: %r' % (stat,) + return xid, verf + # Caller must get procedure-specific part of reply # Subroutines to create opaque authentication objects def make_auth_null(): - return '' + return '' def make_auth_unix(seed, host, uid, gid, groups): - p = Packer() - p.pack_auth_unix(seed, host, uid, gid, groups) - return p.get_buf() + p = Packer() + p.pack_auth_unix(seed, host, uid, gid, groups) + return p.get_buf() def make_auth_unix_default(): - try: - from os import getuid, getgid - uid = getuid() - gid = getgid() - except ImportError: - uid = gid = 0 - import time - return make_auth_unix(int(time.time()-unix_epoch()), \ - socket.gethostname(), uid, gid, []) + try: + from os import getuid, getgid + uid = getuid() + gid = getgid() + except ImportError: + uid = gid = 0 + import time + return make_auth_unix(int(time.time()-unix_epoch()), \ + socket.gethostname(), uid, gid, []) _unix_epoch = -1 def unix_epoch(): @@ -182,7 +182,7 @@ def unix_epoch(): if _unix_epoch >= 0: return _unix_epoch import time now = time.time() - localt = time.localtime(now) # (y, m, d, hh, mm, ss, ..., ..., ...) + localt = time.localtime(now) # (y, m, d, hh, mm, ss, ..., ..., ...) gmt = time.gmtime(now) offset = time.mktime(localt) - time.mktime(gmt) y, m, d, hh, mm, ss = 1970, 1, 1, 0, 0, 0 @@ -199,259 +199,259 @@ def unix_epoch(): class Client: - def __init__(self, host, prog, vers, port): - self.host = host - self.prog = prog - self.vers = vers - self.port = port - self.makesocket() # Assigns to self.sock - self.bindsocket() - self.connsocket() - self.lastxid = 0 # XXX should be more random? - self.addpackers() - self.cred = None - self.verf = None - - def close(self): - self.sock.close() - - def makesocket(self): - # This MUST be overridden - raise RuntimeError, 'makesocket not defined' - - def connsocket(self): - # Override this if you don't want/need a connection - self.sock.connect((self.host, self.port)) - - def bindsocket(self): - # Override this to bind to a different port (e.g. reserved) - self.sock.bind(('', 0)) - - def addpackers(self): - # Override this to use derived classes from Packer/Unpacker - self.packer = Packer() - self.unpacker = Unpacker('') - - def make_call(self, proc, args, pack_func, unpack_func): - # Don't normally override this (but see Broadcast) - if pack_func is None and args is not None: - raise TypeError, 'non-null args with null pack_func' - self.start_call(proc) - if pack_func: - pack_func(args) - self.do_call() - if unpack_func: - result = unpack_func() - else: - result = None - self.unpacker.done() - return result - - def start_call(self, proc): - # Don't override this - self.lastxid = xid = self.lastxid + 1 - cred = self.mkcred() - verf = self.mkverf() - p = self.packer - p.reset() - p.pack_callheader(xid, self.prog, self.vers, proc, cred, verf) - - def do_call(self): - # This MUST be overridden - raise RuntimeError, 'do_call not defined' - - def mkcred(self): - # Override this to use more powerful credentials - if self.cred == None: - self.cred = (AUTH_NULL, make_auth_null()) - return self.cred - - def mkverf(self): - # Override this to use a more powerful verifier - if self.verf == None: - self.verf = (AUTH_NULL, make_auth_null()) - return self.verf - - def call_0(self): # Procedure 0 is always like this - return self.make_call(0, None, None, None) + def __init__(self, host, prog, vers, port): + self.host = host + self.prog = prog + self.vers = vers + self.port = port + self.makesocket() # Assigns to self.sock + self.bindsocket() + self.connsocket() + self.lastxid = 0 # XXX should be more random? + self.addpackers() + self.cred = None + self.verf = None + + def close(self): + self.sock.close() + + def makesocket(self): + # This MUST be overridden + raise RuntimeError, 'makesocket not defined' + + def connsocket(self): + # Override this if you don't want/need a connection + self.sock.connect((self.host, self.port)) + + def bindsocket(self): + # Override this to bind to a different port (e.g. reserved) + self.sock.bind(('', 0)) + + def addpackers(self): + # Override this to use derived classes from Packer/Unpacker + self.packer = Packer() + self.unpacker = Unpacker('') + + def make_call(self, proc, args, pack_func, unpack_func): + # Don't normally override this (but see Broadcast) + if pack_func is None and args is not None: + raise TypeError, 'non-null args with null pack_func' + self.start_call(proc) + if pack_func: + pack_func(args) + self.do_call() + if unpack_func: + result = unpack_func() + else: + result = None + self.unpacker.done() + return result + + def start_call(self, proc): + # Don't override this + self.lastxid = xid = self.lastxid + 1 + cred = self.mkcred() + verf = self.mkverf() + p = self.packer + p.reset() + p.pack_callheader(xid, self.prog, self.vers, proc, cred, verf) + + def do_call(self): + # This MUST be overridden + raise RuntimeError, 'do_call not defined' + + def mkcred(self): + # Override this to use more powerful credentials + if self.cred == None: + self.cred = (AUTH_NULL, make_auth_null()) + return self.cred + + def mkverf(self): + # Override this to use a more powerful verifier + if self.verf == None: + self.verf = (AUTH_NULL, make_auth_null()) + return self.verf + + def call_0(self): # Procedure 0 is always like this + return self.make_call(0, None, None, None) # Record-Marking standard support def sendfrag(sock, last, frag): - x = len(frag) - if last: x = x | 0x80000000L - header = (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \ - chr(int(x>>8 & 0xff)) + chr(int(x & 0xff))) - sock.send(header + frag) + x = len(frag) + if last: x = x | 0x80000000L + header = (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \ + chr(int(x>>8 & 0xff)) + chr(int(x & 0xff))) + sock.send(header + frag) def sendrecord(sock, record): - sendfrag(sock, 1, record) + sendfrag(sock, 1, record) def recvfrag(sock): - header = sock.recv(4) - if len(header) < 4: - raise EOFError - x = long(ord(header[0]))<<24 | ord(header[1])<<16 | \ - ord(header[2])<<8 | ord(header[3]) - last = ((x & 0x80000000) != 0) - n = int(x & 0x7fffffff) - frag = '' - while n > 0: - buf = sock.recv(n) - if not buf: raise EOFError - n = n - len(buf) - frag = frag + buf - return last, frag + header = sock.recv(4) + if len(header) < 4: + raise EOFError + x = long(ord(header[0]))<<24 | ord(header[1])<<16 | \ + ord(header[2])<<8 | ord(header[3]) + last = ((x & 0x80000000) != 0) + n = int(x & 0x7fffffff) + frag = '' + while n > 0: + buf = sock.recv(n) + if not buf: raise EOFError + n = n - len(buf) + frag = frag + buf + return last, frag def recvrecord(sock): - record = '' - last = 0 - while not last: - last, frag = recvfrag(sock) - record = record + frag - return record + record = '' + last = 0 + while not last: + last, frag = recvfrag(sock) + record = record + frag + return record # Try to bind to a reserved port (must be root) last_resv_port_tried = None def bindresvport(sock, host): - global last_resv_port_tried - FIRST, LAST = 600, 1024 # Range of ports to try - if last_resv_port_tried == None: - import os - last_resv_port_tried = FIRST + os.getpid() % (LAST-FIRST) - for i in range(last_resv_port_tried, LAST) + \ - range(FIRST, last_resv_port_tried): - last_resv_port_tried = i - try: - sock.bind((host, i)) - return last_resv_port_tried - except socket.error, (errno, msg): - if errno <> 114: - raise socket.error, (errno, msg) - raise RuntimeError, 'can\'t assign reserved port' + global last_resv_port_tried + FIRST, LAST = 600, 1024 # Range of ports to try + if last_resv_port_tried == None: + import os + last_resv_port_tried = FIRST + os.getpid() % (LAST-FIRST) + for i in range(last_resv_port_tried, LAST) + \ + range(FIRST, last_resv_port_tried): + last_resv_port_tried = i + try: + sock.bind((host, i)) + return last_resv_port_tried + except socket.error, (errno, msg): + if errno <> 114: + raise socket.error, (errno, msg) + raise RuntimeError, 'can\'t assign reserved port' # Client using TCP to a specific port class RawTCPClient(Client): - def makesocket(self): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + def makesocket(self): + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - def do_call(self): - call = self.packer.get_buf() - sendrecord(self.sock, call) - reply = recvrecord(self.sock) - u = self.unpacker - u.reset(reply) - xid, verf = u.unpack_replyheader() - if xid <> self.lastxid: - # Can't really happen since this is TCP... - raise RuntimeError, 'wrong xid in reply %r instead of %r' % ( - xid, self.lastxid) + def do_call(self): + call = self.packer.get_buf() + sendrecord(self.sock, call) + reply = recvrecord(self.sock) + u = self.unpacker + u.reset(reply) + xid, verf = u.unpack_replyheader() + if xid <> self.lastxid: + # Can't really happen since this is TCP... + raise RuntimeError, 'wrong xid in reply %r instead of %r' % ( + xid, self.lastxid) # Client using UDP to a specific port class RawUDPClient(Client): - def makesocket(self): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - - def do_call(self): - call = self.packer.get_buf() - self.sock.send(call) - try: - from select import select - except ImportError: - print 'WARNING: select not found, RPC may hang' - select = None - BUFSIZE = 8192 # Max UDP buffer size - timeout = 1 - count = 5 - while 1: - r, w, x = [self.sock], [], [] - if select: - r, w, x = select(r, w, x, timeout) - if self.sock not in r: - count = count - 1 - if count < 0: raise RuntimeError, 'timeout' - if timeout < 25: timeout = timeout *2 -## print 'RESEND', timeout, count - self.sock.send(call) - continue - reply = self.sock.recv(BUFSIZE) - u = self.unpacker - u.reset(reply) - xid, verf = u.unpack_replyheader() - if xid <> self.lastxid: -## print 'BAD xid' - continue - break + def makesocket(self): + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + def do_call(self): + call = self.packer.get_buf() + self.sock.send(call) + try: + from select import select + except ImportError: + print 'WARNING: select not found, RPC may hang' + select = None + BUFSIZE = 8192 # Max UDP buffer size + timeout = 1 + count = 5 + while 1: + r, w, x = [self.sock], [], [] + if select: + r, w, x = select(r, w, x, timeout) + if self.sock not in r: + count = count - 1 + if count < 0: raise RuntimeError, 'timeout' + if timeout < 25: timeout = timeout *2 +## print 'RESEND', timeout, count + self.sock.send(call) + continue + reply = self.sock.recv(BUFSIZE) + u = self.unpacker + u.reset(reply) + xid, verf = u.unpack_replyheader() + if xid <> self.lastxid: +## print 'BAD xid' + continue + break # Client using UDP broadcast to a specific port class RawBroadcastUDPClient(RawUDPClient): - def __init__(self, bcastaddr, prog, vers, port): - RawUDPClient.__init__(self, bcastaddr, prog, vers, port) - self.reply_handler = None - self.timeout = 30 - - def connsocket(self): - # Don't connect -- use sendto - self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - - def set_reply_handler(self, reply_handler): - self.reply_handler = reply_handler - - def set_timeout(self, timeout): - self.timeout = timeout # Use None for infinite timeout - - def make_call(self, proc, args, pack_func, unpack_func): - if pack_func is None and args is not None: - raise TypeError, 'non-null args with null pack_func' - self.start_call(proc) - if pack_func: - pack_func(args) - call = self.packer.get_buf() - self.sock.sendto(call, (self.host, self.port)) - try: - from select import select - except ImportError: - print 'WARNING: select not found, broadcast will hang' - select = None - BUFSIZE = 8192 # Max UDP buffer size (for reply) - replies = [] - if unpack_func is None: - def dummy(): pass - unpack_func = dummy - while 1: - r, w, x = [self.sock], [], [] - if select: - if self.timeout is None: - r, w, x = select(r, w, x) - else: - r, w, x = select(r, w, x, self.timeout) - if self.sock not in r: - break - reply, fromaddr = self.sock.recvfrom(BUFSIZE) - u = self.unpacker - u.reset(reply) - xid, verf = u.unpack_replyheader() - if xid <> self.lastxid: -## print 'BAD xid' - continue - reply = unpack_func() - self.unpacker.done() - replies.append((reply, fromaddr)) - if self.reply_handler: - self.reply_handler(reply, fromaddr) - return replies + def __init__(self, bcastaddr, prog, vers, port): + RawUDPClient.__init__(self, bcastaddr, prog, vers, port) + self.reply_handler = None + self.timeout = 30 + + def connsocket(self): + # Don't connect -- use sendto + self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + + def set_reply_handler(self, reply_handler): + self.reply_handler = reply_handler + + def set_timeout(self, timeout): + self.timeout = timeout # Use None for infinite timeout + + def make_call(self, proc, args, pack_func, unpack_func): + if pack_func is None and args is not None: + raise TypeError, 'non-null args with null pack_func' + self.start_call(proc) + if pack_func: + pack_func(args) + call = self.packer.get_buf() + self.sock.sendto(call, (self.host, self.port)) + try: + from select import select + except ImportError: + print 'WARNING: select not found, broadcast will hang' + select = None + BUFSIZE = 8192 # Max UDP buffer size (for reply) + replies = [] + if unpack_func is None: + def dummy(): pass + unpack_func = dummy + while 1: + r, w, x = [self.sock], [], [] + if select: + if self.timeout is None: + r, w, x = select(r, w, x) + else: + r, w, x = select(r, w, x, self.timeout) + if self.sock not in r: + break + reply, fromaddr = self.sock.recvfrom(BUFSIZE) + u = self.unpacker + u.reset(reply) + xid, verf = u.unpack_replyheader() + if xid <> self.lastxid: +## print 'BAD xid' + continue + reply = unpack_func() + self.unpacker.done() + replies.append((reply, fromaddr)) + if self.reply_handler: + self.reply_handler(reply, fromaddr) + return replies # Port mapper interface @@ -462,12 +462,12 @@ PMAP_VERS = 2 PMAP_PORT = 111 # Procedure numbers -PMAPPROC_NULL = 0 # (void) -> void -PMAPPROC_SET = 1 # (mapping) -> bool -PMAPPROC_UNSET = 2 # (mapping) -> bool -PMAPPROC_GETPORT = 3 # (mapping) -> unsigned int -PMAPPROC_DUMP = 4 # (void) -> pmaplist -PMAPPROC_CALLIT = 5 # (call_args) -> call_result +PMAPPROC_NULL = 0 # (void) -> void +PMAPPROC_SET = 1 # (mapping) -> bool +PMAPPROC_UNSET = 2 # (mapping) -> bool +PMAPPROC_GETPORT = 3 # (mapping) -> unsigned int +PMAPPROC_DUMP = 4 # (void) -> pmaplist +PMAPPROC_CALLIT = 5 # (call_args) -> call_result # A mapping is (prog, vers, prot, port) and prot is one of: @@ -483,162 +483,162 @@ IPPROTO_UDP = 17 class PortMapperPacker(Packer): - def pack_mapping(self, mapping): - prog, vers, prot, port = mapping - self.pack_uint(prog) - self.pack_uint(vers) - self.pack_uint(prot) - self.pack_uint(port) + def pack_mapping(self, mapping): + prog, vers, prot, port = mapping + self.pack_uint(prog) + self.pack_uint(vers) + self.pack_uint(prot) + self.pack_uint(port) - def pack_pmaplist(self, list): - self.pack_list(list, self.pack_mapping) + def pack_pmaplist(self, list): + self.pack_list(list, self.pack_mapping) - def pack_call_args(self, ca): - prog, vers, proc, args = ca - self.pack_uint(prog) - self.pack_uint(vers) - self.pack_uint(proc) - self.pack_opaque(args) + def pack_call_args(self, ca): + prog, vers, proc, args = ca + self.pack_uint(prog) + self.pack_uint(vers) + self.pack_uint(proc) + self.pack_opaque(args) class PortMapperUnpacker(Unpacker): - def unpack_mapping(self): - prog = self.unpack_uint() - vers = self.unpack_uint() - prot = self.unpack_uint() - port = self.unpack_uint() - return prog, vers, prot, port + def unpack_mapping(self): + prog = self.unpack_uint() + vers = self.unpack_uint() + prot = self.unpack_uint() + port = self.unpack_uint() + return prog, vers, prot, port - def unpack_pmaplist(self): - return self.unpack_list(self.unpack_mapping) + def unpack_pmaplist(self): + return self.unpack_list(self.unpack_mapping) - def unpack_call_result(self): - port = self.unpack_uint() - res = self.unpack_opaque() - return port, res + def unpack_call_result(self): + port = self.unpack_uint() + res = self.unpack_opaque() + return port, res class PartialPortMapperClient: - def addpackers(self): - self.packer = PortMapperPacker() - self.unpacker = PortMapperUnpacker('') + def addpackers(self): + self.packer = PortMapperPacker() + self.unpacker = PortMapperUnpacker('') - def Set(self, mapping): - return self.make_call(PMAPPROC_SET, mapping, \ - self.packer.pack_mapping, \ - self.unpacker.unpack_uint) + def Set(self, mapping): + return self.make_call(PMAPPROC_SET, mapping, \ + self.packer.pack_mapping, \ + self.unpacker.unpack_uint) - def Unset(self, mapping): - return self.make_call(PMAPPROC_UNSET, mapping, \ - self.packer.pack_mapping, \ - self.unpacker.unpack_uint) + def Unset(self, mapping): + return self.make_call(PMAPPROC_UNSET, mapping, \ + self.packer.pack_mapping, \ + self.unpacker.unpack_uint) - def Getport(self, mapping): - return self.make_call(PMAPPROC_GETPORT, mapping, \ - self.packer.pack_mapping, \ - self.unpacker.unpack_uint) + def Getport(self, mapping): + return self.make_call(PMAPPROC_GETPORT, mapping, \ + self.packer.pack_mapping, \ + self.unpacker.unpack_uint) - def Dump(self): - return self.make_call(PMAPPROC_DUMP, None, \ - None, \ - self.unpacker.unpack_pmaplist) + def Dump(self): + return self.make_call(PMAPPROC_DUMP, None, \ + None, \ + self.unpacker.unpack_pmaplist) - def Callit(self, ca): - return self.make_call(PMAPPROC_CALLIT, ca, \ - self.packer.pack_call_args, \ - self.unpacker.unpack_call_result) + def Callit(self, ca): + return self.make_call(PMAPPROC_CALLIT, ca, \ + self.packer.pack_call_args, \ + self.unpacker.unpack_call_result) class TCPPortMapperClient(PartialPortMapperClient, RawTCPClient): - def __init__(self, host): - RawTCPClient.__init__(self, \ - host, PMAP_PROG, PMAP_VERS, PMAP_PORT) + def __init__(self, host): + RawTCPClient.__init__(self, \ + host, PMAP_PROG, PMAP_VERS, PMAP_PORT) class UDPPortMapperClient(PartialPortMapperClient, RawUDPClient): - def __init__(self, host): - RawUDPClient.__init__(self, \ - host, PMAP_PROG, PMAP_VERS, PMAP_PORT) + def __init__(self, host): + RawUDPClient.__init__(self, \ + host, PMAP_PROG, PMAP_VERS, PMAP_PORT) class BroadcastUDPPortMapperClient(PartialPortMapperClient, \ - RawBroadcastUDPClient): + RawBroadcastUDPClient): - def __init__(self, bcastaddr): - RawBroadcastUDPClient.__init__(self, \ - bcastaddr, PMAP_PROG, PMAP_VERS, PMAP_PORT) + def __init__(self, bcastaddr): + RawBroadcastUDPClient.__init__(self, \ + bcastaddr, PMAP_PROG, PMAP_VERS, PMAP_PORT) # Generic clients that find their server through the Port mapper class TCPClient(RawTCPClient): - def __init__(self, host, prog, vers): - pmap = TCPPortMapperClient(host) - port = pmap.Getport((prog, vers, IPPROTO_TCP, 0)) - pmap.close() - if port == 0: - raise RuntimeError, 'program not registered' - RawTCPClient.__init__(self, host, prog, vers, port) + def __init__(self, host, prog, vers): + pmap = TCPPortMapperClient(host) + port = pmap.Getport((prog, vers, IPPROTO_TCP, 0)) + pmap.close() + if port == 0: + raise RuntimeError, 'program not registered' + RawTCPClient.__init__(self, host, prog, vers, port) class UDPClient(RawUDPClient): - def __init__(self, host, prog, vers): - pmap = UDPPortMapperClient(host) - port = pmap.Getport((prog, vers, IPPROTO_UDP, 0)) - pmap.close() - if port == 0: - raise RuntimeError, 'program not registered' - RawUDPClient.__init__(self, host, prog, vers, port) + def __init__(self, host, prog, vers): + pmap = UDPPortMapperClient(host) + port = pmap.Getport((prog, vers, IPPROTO_UDP, 0)) + pmap.close() + if port == 0: + raise RuntimeError, 'program not registered' + RawUDPClient.__init__(self, host, prog, vers, port) class BroadcastUDPClient(Client): - def __init__(self, bcastaddr, prog, vers): - self.pmap = BroadcastUDPPortMapperClient(bcastaddr) - self.pmap.set_reply_handler(self.my_reply_handler) - self.prog = prog - self.vers = vers - self.user_reply_handler = None - self.addpackers() - - def close(self): - self.pmap.close() - - def set_reply_handler(self, reply_handler): - self.user_reply_handler = reply_handler - - def set_timeout(self, timeout): - self.pmap.set_timeout(timeout) - - def my_reply_handler(self, reply, fromaddr): - port, res = reply - self.unpacker.reset(res) - result = self.unpack_func() - self.unpacker.done() - self.replies.append((result, fromaddr)) - if self.user_reply_handler is not None: - self.user_reply_handler(result, fromaddr) - - def make_call(self, proc, args, pack_func, unpack_func): - self.packer.reset() - if pack_func: - pack_func(args) - if unpack_func is None: - def dummy(): pass - self.unpack_func = dummy - else: - self.unpack_func = unpack_func - self.replies = [] - packed_args = self.packer.get_buf() - dummy_replies = self.pmap.Callit( \ - (self.prog, self.vers, proc, packed_args)) - return self.replies + def __init__(self, bcastaddr, prog, vers): + self.pmap = BroadcastUDPPortMapperClient(bcastaddr) + self.pmap.set_reply_handler(self.my_reply_handler) + self.prog = prog + self.vers = vers + self.user_reply_handler = None + self.addpackers() + + def close(self): + self.pmap.close() + + def set_reply_handler(self, reply_handler): + self.user_reply_handler = reply_handler + + def set_timeout(self, timeout): + self.pmap.set_timeout(timeout) + + def my_reply_handler(self, reply, fromaddr): + port, res = reply + self.unpacker.reset(res) + result = self.unpack_func() + self.unpacker.done() + self.replies.append((result, fromaddr)) + if self.user_reply_handler is not None: + self.user_reply_handler(result, fromaddr) + + def make_call(self, proc, args, pack_func, unpack_func): + self.packer.reset() + if pack_func: + pack_func(args) + if unpack_func is None: + def dummy(): pass + self.unpack_func = dummy + else: + self.unpack_func = unpack_func + self.replies = [] + packed_args = self.packer.get_buf() + dummy_replies = self.pmap.Callit( \ + (self.prog, self.vers, proc, packed_args)) + return self.replies # Server classes @@ -648,203 +648,203 @@ class BroadcastUDPClient(Client): class Server: - def __init__(self, host, prog, vers, port): - self.host = host # Should normally be '' for default interface - self.prog = prog - self.vers = vers - self.port = port # Should normally be 0 for random port - self.makesocket() # Assigns to self.sock and self.prot - self.bindsocket() - self.host, self.port = self.sock.getsockname() - self.addpackers() - - def register(self): - mapping = self.prog, self.vers, self.prot, self.port - p = TCPPortMapperClient(self.host) - if not p.Set(mapping): - raise RuntimeError, 'register failed' - - def unregister(self): - mapping = self.prog, self.vers, self.prot, self.port - p = TCPPortMapperClient(self.host) - if not p.Unset(mapping): - raise RuntimeError, 'unregister failed' - - def handle(self, call): - # Don't use unpack_header but parse the header piecewise - # XXX I have no idea if I am using the right error responses! - self.unpacker.reset(call) - self.packer.reset() - xid = self.unpacker.unpack_uint() - self.packer.pack_uint(xid) - temp = self.unpacker.unpack_enum() - if temp <> CALL: - return None # Not worthy of a reply - self.packer.pack_uint(REPLY) - temp = self.unpacker.unpack_uint() - if temp <> RPCVERSION: - self.packer.pack_uint(MSG_DENIED) - self.packer.pack_uint(RPC_MISMATCH) - self.packer.pack_uint(RPCVERSION) - self.packer.pack_uint(RPCVERSION) - return self.packer.get_buf() - self.packer.pack_uint(MSG_ACCEPTED) - self.packer.pack_auth((AUTH_NULL, make_auth_null())) - prog = self.unpacker.unpack_uint() - if prog <> self.prog: - self.packer.pack_uint(PROG_UNAVAIL) - return self.packer.get_buf() - vers = self.unpacker.unpack_uint() - if vers <> self.vers: - self.packer.pack_uint(PROG_MISMATCH) - self.packer.pack_uint(self.vers) - self.packer.pack_uint(self.vers) - return self.packer.get_buf() - proc = self.unpacker.unpack_uint() - methname = 'handle_' + repr(proc) - try: - meth = getattr(self, methname) - except AttributeError: - self.packer.pack_uint(PROC_UNAVAIL) - return self.packer.get_buf() - cred = self.unpacker.unpack_auth() - verf = self.unpacker.unpack_auth() - try: - meth() # Unpack args, call turn_around(), pack reply - except (EOFError, GarbageArgs): - # Too few or too many arguments - self.packer.reset() - self.packer.pack_uint(xid) - self.packer.pack_uint(REPLY) - self.packer.pack_uint(MSG_ACCEPTED) - self.packer.pack_auth((AUTH_NULL, make_auth_null())) - self.packer.pack_uint(GARBAGE_ARGS) - return self.packer.get_buf() - - def turn_around(self): - try: - self.unpacker.done() - except RuntimeError: - raise GarbageArgs - self.packer.pack_uint(SUCCESS) - - def handle_0(self): # Handle NULL message - self.turn_around() - - def makesocket(self): - # This MUST be overridden - raise RuntimeError, 'makesocket not defined' - - def bindsocket(self): - # Override this to bind to a different port (e.g. reserved) - self.sock.bind((self.host, self.port)) - - def addpackers(self): - # Override this to use derived classes from Packer/Unpacker - self.packer = Packer() - self.unpacker = Unpacker('') + def __init__(self, host, prog, vers, port): + self.host = host # Should normally be '' for default interface + self.prog = prog + self.vers = vers + self.port = port # Should normally be 0 for random port + self.makesocket() # Assigns to self.sock and self.prot + self.bindsocket() + self.host, self.port = self.sock.getsockname() + self.addpackers() + + def register(self): + mapping = self.prog, self.vers, self.prot, self.port + p = TCPPortMapperClient(self.host) + if not p.Set(mapping): + raise RuntimeError, 'register failed' + + def unregister(self): + mapping = self.prog, self.vers, self.prot, self.port + p = TCPPortMapperClient(self.host) + if not p.Unset(mapping): + raise RuntimeError, 'unregister failed' + + def handle(self, call): + # Don't use unpack_header but parse the header piecewise + # XXX I have no idea if I am using the right error responses! + self.unpacker.reset(call) + self.packer.reset() + xid = self.unpacker.unpack_uint() + self.packer.pack_uint(xid) + temp = self.unpacker.unpack_enum() + if temp <> CALL: + return None # Not worthy of a reply + self.packer.pack_uint(REPLY) + temp = self.unpacker.unpack_uint() + if temp <> RPCVERSION: + self.packer.pack_uint(MSG_DENIED) + self.packer.pack_uint(RPC_MISMATCH) + self.packer.pack_uint(RPCVERSION) + self.packer.pack_uint(RPCVERSION) + return self.packer.get_buf() + self.packer.pack_uint(MSG_ACCEPTED) + self.packer.pack_auth((AUTH_NULL, make_auth_null())) + prog = self.unpacker.unpack_uint() + if prog <> self.prog: + self.packer.pack_uint(PROG_UNAVAIL) + return self.packer.get_buf() + vers = self.unpacker.unpack_uint() + if vers <> self.vers: + self.packer.pack_uint(PROG_MISMATCH) + self.packer.pack_uint(self.vers) + self.packer.pack_uint(self.vers) + return self.packer.get_buf() + proc = self.unpacker.unpack_uint() + methname = 'handle_' + repr(proc) + try: + meth = getattr(self, methname) + except AttributeError: + self.packer.pack_uint(PROC_UNAVAIL) + return self.packer.get_buf() + cred = self.unpacker.unpack_auth() + verf = self.unpacker.unpack_auth() + try: + meth() # Unpack args, call turn_around(), pack reply + except (EOFError, GarbageArgs): + # Too few or too many arguments + self.packer.reset() + self.packer.pack_uint(xid) + self.packer.pack_uint(REPLY) + self.packer.pack_uint(MSG_ACCEPTED) + self.packer.pack_auth((AUTH_NULL, make_auth_null())) + self.packer.pack_uint(GARBAGE_ARGS) + return self.packer.get_buf() + + def turn_around(self): + try: + self.unpacker.done() + except RuntimeError: + raise GarbageArgs + self.packer.pack_uint(SUCCESS) + + def handle_0(self): # Handle NULL message + self.turn_around() + + def makesocket(self): + # This MUST be overridden + raise RuntimeError, 'makesocket not defined' + + def bindsocket(self): + # Override this to bind to a different port (e.g. reserved) + self.sock.bind((self.host, self.port)) + + def addpackers(self): + # Override this to use derived classes from Packer/Unpacker + self.packer = Packer() + self.unpacker = Unpacker('') class TCPServer(Server): - def makesocket(self): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.prot = IPPROTO_TCP - - def loop(self): - self.sock.listen(0) - while 1: - self.session(self.sock.accept()) - - def session(self, connection): - sock, (host, port) = connection - while 1: - try: - call = recvrecord(sock) - except EOFError: - break - except socket.error, msg: - print 'socket error:', msg - break - reply = self.handle(call) - if reply is not None: - sendrecord(sock, reply) - - def forkingloop(self): - # Like loop but uses forksession() - self.sock.listen(0) - while 1: - self.forksession(self.sock.accept()) - - def forksession(self, connection): - # Like session but forks off a subprocess - import os - # Wait for deceased children - try: - while 1: - pid, sts = os.waitpid(0, 1) - except os.error: - pass - pid = None - try: - pid = os.fork() - if pid: # Parent - connection[0].close() - return - # Child - self.session(connection) - finally: - # Make sure we don't fall through in the parent - if pid == 0: - os._exit(0) + def makesocket(self): + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.prot = IPPROTO_TCP + + def loop(self): + self.sock.listen(0) + while 1: + self.session(self.sock.accept()) + + def session(self, connection): + sock, (host, port) = connection + while 1: + try: + call = recvrecord(sock) + except EOFError: + break + except socket.error, msg: + print 'socket error:', msg + break + reply = self.handle(call) + if reply is not None: + sendrecord(sock, reply) + + def forkingloop(self): + # Like loop but uses forksession() + self.sock.listen(0) + while 1: + self.forksession(self.sock.accept()) + + def forksession(self, connection): + # Like session but forks off a subprocess + import os + # Wait for deceased children + try: + while 1: + pid, sts = os.waitpid(0, 1) + except os.error: + pass + pid = None + try: + pid = os.fork() + if pid: # Parent + connection[0].close() + return + # Child + self.session(connection) + finally: + # Make sure we don't fall through in the parent + if pid == 0: + os._exit(0) class UDPServer(Server): - def makesocket(self): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.prot = IPPROTO_UDP + def makesocket(self): + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.prot = IPPROTO_UDP - def loop(self): - while 1: - self.session() + def loop(self): + while 1: + self.session() - def session(self): - call, host_port = self.sock.recvfrom(8192) - reply = self.handle(call) - if reply <> None: - self.sock.sendto(reply, host_port) + def session(self): + call, host_port = self.sock.recvfrom(8192) + reply = self.handle(call) + if reply <> None: + self.sock.sendto(reply, host_port) # Simple test program -- dump local portmapper status def test(): - pmap = UDPPortMapperClient('') - list = pmap.Dump() - list.sort() - for prog, vers, prot, port in list: - print prog, vers, - if prot == IPPROTO_TCP: print 'tcp', - elif prot == IPPROTO_UDP: print 'udp', - else: print prot, - print port + pmap = UDPPortMapperClient('') + list = pmap.Dump() + list.sort() + for prog, vers, prot, port in list: + print prog, vers, + if prot == IPPROTO_TCP: print 'tcp', + elif prot == IPPROTO_UDP: print 'udp', + else: print prot, + print port # Test program for broadcast operation -- dump everybody's portmapper status def testbcast(): - import sys - if sys.argv[1:]: - bcastaddr = sys.argv[1] - else: - bcastaddr = '<broadcast>' - def rh(reply, fromaddr): - host, port = fromaddr - print host + '\t' + repr(reply) - pmap = BroadcastUDPPortMapperClient(bcastaddr) - pmap.set_reply_handler(rh) - pmap.set_timeout(5) - replies = pmap.Getport((100002, 1, IPPROTO_UDP, 0)) + import sys + if sys.argv[1:]: + bcastaddr = sys.argv[1] + else: + bcastaddr = '<broadcast>' + def rh(reply, fromaddr): + host, port = fromaddr + print host + '\t' + repr(reply) + pmap = BroadcastUDPPortMapperClient(bcastaddr) + pmap.set_reply_handler(rh) + pmap.set_timeout(5) + replies = pmap.Getport((100002, 1, IPPROTO_UDP, 0)) # Test program for server, with corresponding client @@ -853,39 +853,39 @@ def testbcast(): # (A may be == B) def testsvr(): - # Simple test class -- proc 1 doubles its string argument as reply - class S(UDPServer): - def handle_1(self): - arg = self.unpacker.unpack_string() - self.turn_around() - print 'RPC function 1 called, arg', repr(arg) - self.packer.pack_string(arg + arg) - # - s = S('', 0x20000000, 1, 0) - try: - s.unregister() - except RuntimeError, msg: - print 'RuntimeError:', msg, '(ignored)' - s.register() - print 'Service started...' - try: - s.loop() - finally: - s.unregister() - print 'Service interrupted.' + # Simple test class -- proc 1 doubles its string argument as reply + class S(UDPServer): + def handle_1(self): + arg = self.unpacker.unpack_string() + self.turn_around() + print 'RPC function 1 called, arg', repr(arg) + self.packer.pack_string(arg + arg) + # + s = S('', 0x20000000, 1, 0) + try: + s.unregister() + except RuntimeError, msg: + print 'RuntimeError:', msg, '(ignored)' + s.register() + print 'Service started...' + try: + s.loop() + finally: + s.unregister() + print 'Service interrupted.' def testclt(): - import sys - if sys.argv[1:]: host = sys.argv[1] - else: host = '' - # Client for above server - class C(UDPClient): - def call_1(self, arg): - return self.make_call(1, arg, \ - self.packer.pack_string, \ - self.unpacker.unpack_string) - c = C(host, 0x20000000, 1) - print 'making call...' - reply = c.call_1('hello, world, ') - print 'call returned', repr(reply) + import sys + if sys.argv[1:]: host = sys.argv[1] + else: host = '' + # Client for above server + class C(UDPClient): + def call_1(self, arg): + return self.make_call(1, arg, \ + self.packer.pack_string, \ + self.unpacker.unpack_string) + c = C(host, 0x20000000, 1) + print 'making call...' + reply = c.call_1('hello, world, ') + print 'call returned', repr(reply) diff --git a/Demo/rpc/xdr.py b/Demo/rpc/xdr.py index 5338aef..df5cbaf 100644 --- a/Demo/rpc/xdr.py +++ b/Demo/rpc/xdr.py @@ -2,9 +2,9 @@ try: - import struct + import struct except ImportError: - struct = None + struct = None Long = type(0L) @@ -12,189 +12,189 @@ Long = type(0L) class Packer: - def __init__(self): - self.reset() + def __init__(self): + self.reset() - def reset(self): - self.buf = '' + def reset(self): + self.buf = '' - def get_buf(self): - return self.buf + def get_buf(self): + return self.buf - def pack_uint(self, x): - self.buf = self.buf + \ - (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \ - chr(int(x>>8 & 0xff)) + chr(int(x & 0xff))) - if struct and struct.pack('l', 1) == '\0\0\0\1': - def pack_uint(self, x): - if type(x) == Long: - x = int((x + 0x80000000L) % 0x100000000L \ - - 0x80000000L) - self.buf = self.buf + struct.pack('l', x) + def pack_uint(self, x): + self.buf = self.buf + \ + (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \ + chr(int(x>>8 & 0xff)) + chr(int(x & 0xff))) + if struct and struct.pack('l', 1) == '\0\0\0\1': + def pack_uint(self, x): + if type(x) == Long: + x = int((x + 0x80000000L) % 0x100000000L \ + - 0x80000000L) + self.buf = self.buf + struct.pack('l', x) - pack_int = pack_uint + pack_int = pack_uint - pack_enum = pack_int + pack_enum = pack_int - def pack_bool(self, x): - if x: self.buf = self.buf + '\0\0\0\1' - else: self.buf = self.buf + '\0\0\0\0' + def pack_bool(self, x): + if x: self.buf = self.buf + '\0\0\0\1' + else: self.buf = self.buf + '\0\0\0\0' - def pack_uhyper(self, x): - self.pack_uint(int(x>>32 & 0xffffffff)) - self.pack_uint(int(x & 0xffffffff)) + def pack_uhyper(self, x): + self.pack_uint(int(x>>32 & 0xffffffff)) + self.pack_uint(int(x & 0xffffffff)) - pack_hyper = pack_uhyper + pack_hyper = pack_uhyper - def pack_float(self, x): - # XXX - self.buf = self.buf + struct.pack('f', x) + def pack_float(self, x): + # XXX + self.buf = self.buf + struct.pack('f', x) - def pack_double(self, x): - # XXX - self.buf = self.buf + struct.pack('d', x) + def pack_double(self, x): + # XXX + self.buf = self.buf + struct.pack('d', x) - def pack_fstring(self, n, s): - if n < 0: - raise ValueError, 'fstring size must be nonnegative' - n = ((n+3)/4)*4 - data = s[:n] - data = data + (n - len(data)) * '\0' - self.buf = self.buf + data + def pack_fstring(self, n, s): + if n < 0: + raise ValueError, 'fstring size must be nonnegative' + n = ((n+3)/4)*4 + data = s[:n] + data = data + (n - len(data)) * '\0' + self.buf = self.buf + data - pack_fopaque = pack_fstring + pack_fopaque = pack_fstring - def pack_string(self, s): - n = len(s) - self.pack_uint(n) - self.pack_fstring(n, s) + def pack_string(self, s): + n = len(s) + self.pack_uint(n) + self.pack_fstring(n, s) - pack_opaque = pack_string + pack_opaque = pack_string - def pack_list(self, list, pack_item): - for item in list: - self.pack_uint(1) - pack_item(item) - self.pack_uint(0) + def pack_list(self, list, pack_item): + for item in list: + self.pack_uint(1) + pack_item(item) + self.pack_uint(0) - def pack_farray(self, n, list, pack_item): - if len(list) <> n: - raise ValueError, 'wrong array size' - for item in list: - pack_item(item) + def pack_farray(self, n, list, pack_item): + if len(list) <> n: + raise ValueError, 'wrong array size' + for item in list: + pack_item(item) - def pack_array(self, list, pack_item): - n = len(list) - self.pack_uint(n) - self.pack_farray(n, list, pack_item) + def pack_array(self, list, pack_item): + n = len(list) + self.pack_uint(n) + self.pack_farray(n, list, pack_item) class Unpacker: - def __init__(self, data): - self.reset(data) - - def reset(self, data): - self.buf = data - self.pos = 0 - - def done(self): - if self.pos < len(self.buf): - raise RuntimeError, 'unextracted data remains' - - def unpack_uint(self): - i = self.pos - self.pos = j = i+4 - data = self.buf[i:j] - if len(data) < 4: - raise EOFError - x = long(ord(data[0]))<<24 | ord(data[1])<<16 | \ - ord(data[2])<<8 | ord(data[3]) - # Return a Python long only if the value is not representable - # as a nonnegative Python int - if x < 0x80000000L: x = int(x) - return x - if struct and struct.unpack('l', '\0\0\0\1') == 1: - def unpack_uint(self): - i = self.pos - self.pos = j = i+4 - data = self.buf[i:j] - if len(data) < 4: - raise EOFError - return struct.unpack('l', data) - - def unpack_int(self): - x = self.unpack_uint() - if x >= 0x80000000L: x = x - 0x100000000L - return int(x) - - unpack_enum = unpack_int - - unpack_bool = unpack_int - - def unpack_uhyper(self): - hi = self.unpack_uint() - lo = self.unpack_uint() - return long(hi)<<32 | lo - - def unpack_hyper(self): - x = self.unpack_uhyper() - if x >= 0x8000000000000000L: x = x - 0x10000000000000000L - return x - - def unpack_float(self): - # XXX - i = self.pos - self.pos = j = i+4 - data = self.buf[i:j] - if len(data) < 4: - raise EOFError - return struct.unpack('f', data)[0] - - def unpack_double(self): - # XXX - i = self.pos - self.pos = j = i+8 - data = self.buf[i:j] - if len(data) < 8: - raise EOFError - return struct.unpack('d', data)[0] - - def unpack_fstring(self, n): - if n < 0: - raise ValueError, 'fstring size must be nonnegative' - i = self.pos - j = i + (n+3)/4*4 - if j > len(self.buf): - raise EOFError - self.pos = j - return self.buf[i:i+n] - - unpack_fopaque = unpack_fstring - - def unpack_string(self): - n = self.unpack_uint() - return self.unpack_fstring(n) - - unpack_opaque = unpack_string - - def unpack_list(self, unpack_item): - list = [] - while 1: - x = self.unpack_uint() - if x == 0: break - if x <> 1: - raise RuntimeError, '0 or 1 expected, got %r' % (x, ) - item = unpack_item() - list.append(item) - return list - - def unpack_farray(self, n, unpack_item): - list = [] - for i in range(n): - list.append(unpack_item()) - return list - - def unpack_array(self, unpack_item): - n = self.unpack_uint() - return self.unpack_farray(n, unpack_item) + def __init__(self, data): + self.reset(data) + + def reset(self, data): + self.buf = data + self.pos = 0 + + def done(self): + if self.pos < len(self.buf): + raise RuntimeError, 'unextracted data remains' + + def unpack_uint(self): + i = self.pos + self.pos = j = i+4 + data = self.buf[i:j] + if len(data) < 4: + raise EOFError + x = long(ord(data[0]))<<24 | ord(data[1])<<16 | \ + ord(data[2])<<8 | ord(data[3]) + # Return a Python long only if the value is not representable + # as a nonnegative Python int + if x < 0x80000000L: x = int(x) + return x + if struct and struct.unpack('l', '\0\0\0\1') == 1: + def unpack_uint(self): + i = self.pos + self.pos = j = i+4 + data = self.buf[i:j] + if len(data) < 4: + raise EOFError + return struct.unpack('l', data) + + def unpack_int(self): + x = self.unpack_uint() + if x >= 0x80000000L: x = x - 0x100000000L + return int(x) + + unpack_enum = unpack_int + + unpack_bool = unpack_int + + def unpack_uhyper(self): + hi = self.unpack_uint() + lo = self.unpack_uint() + return long(hi)<<32 | lo + + def unpack_hyper(self): + x = self.unpack_uhyper() + if x >= 0x8000000000000000L: x = x - 0x10000000000000000L + return x + + def unpack_float(self): + # XXX + i = self.pos + self.pos = j = i+4 + data = self.buf[i:j] + if len(data) < 4: + raise EOFError + return struct.unpack('f', data)[0] + + def unpack_double(self): + # XXX + i = self.pos + self.pos = j = i+8 + data = self.buf[i:j] + if len(data) < 8: + raise EOFError + return struct.unpack('d', data)[0] + + def unpack_fstring(self, n): + if n < 0: + raise ValueError, 'fstring size must be nonnegative' + i = self.pos + j = i + (n+3)/4*4 + if j > len(self.buf): + raise EOFError + self.pos = j + return self.buf[i:i+n] + + unpack_fopaque = unpack_fstring + + def unpack_string(self): + n = self.unpack_uint() + return self.unpack_fstring(n) + + unpack_opaque = unpack_string + + def unpack_list(self, unpack_item): + list = [] + while 1: + x = self.unpack_uint() + if x == 0: break + if x <> 1: + raise RuntimeError, '0 or 1 expected, got %r' % (x, ) + item = unpack_item() + list.append(item) + return list + + def unpack_farray(self, n, unpack_item): + list = [] + for i in range(n): + list.append(unpack_item()) + return list + + def unpack_array(self, unpack_item): + n = self.unpack_uint() + return self.unpack_farray(n, unpack_item) diff --git a/Demo/scripts/eqfix.py b/Demo/scripts/eqfix.py index 2139d2b..deac4f8 100755 --- a/Demo/scripts/eqfix.py +++ b/Demo/scripts/eqfix.py @@ -1,9 +1,9 @@ #! /usr/bin/env python # Fix Python source files to use the new equality test operator, i.e., -# if x = y: ... +# if x = y: ... # is changed to -# if x == y: ... +# if x == y: ... # The script correctly tokenizes the Python program to reliably # distinguish between assignments and equality tests. # @@ -39,160 +39,160 @@ dbg = err rep = sys.stdout.write def main(): - bad = 0 - if not sys.argv[1:]: # No arguments - err('usage: ' + sys.argv[0] + ' file-or-directory ...\n') - sys.exit(2) - for arg in sys.argv[1:]: - if os.path.isdir(arg): - if recursedown(arg): bad = 1 - elif os.path.islink(arg): - err(arg + ': will not process symbolic links\n') - bad = 1 - else: - if fix(arg): bad = 1 - sys.exit(bad) + bad = 0 + if not sys.argv[1:]: # No arguments + err('usage: ' + sys.argv[0] + ' file-or-directory ...\n') + sys.exit(2) + for arg in sys.argv[1:]: + if os.path.isdir(arg): + if recursedown(arg): bad = 1 + elif os.path.islink(arg): + err(arg + ': will not process symbolic links\n') + bad = 1 + else: + if fix(arg): bad = 1 + sys.exit(bad) ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$') def ispython(name): - return ispythonprog.match(name) >= 0 + return ispythonprog.match(name) >= 0 def recursedown(dirname): - dbg('recursedown(%r)\n' % (dirname,)) - bad = 0 - try: - names = os.listdir(dirname) - except os.error, msg: - err('%s: cannot list directory: %r\n' % (dirname, msg)) - return 1 - names.sort() - subdirs = [] - for name in names: - if name in (os.curdir, os.pardir): continue - fullname = os.path.join(dirname, name) - if os.path.islink(fullname): pass - elif os.path.isdir(fullname): - subdirs.append(fullname) - elif ispython(name): - if fix(fullname): bad = 1 - for fullname in subdirs: - if recursedown(fullname): bad = 1 - return bad + dbg('recursedown(%r)\n' % (dirname,)) + bad = 0 + try: + names = os.listdir(dirname) + except os.error, msg: + err('%s: cannot list directory: %r\n' % (dirname, msg)) + return 1 + names.sort() + subdirs = [] + for name in names: + if name in (os.curdir, os.pardir): continue + fullname = os.path.join(dirname, name) + if os.path.islink(fullname): pass + elif os.path.isdir(fullname): + subdirs.append(fullname) + elif ispython(name): + if fix(fullname): bad = 1 + for fullname in subdirs: + if recursedown(fullname): bad = 1 + return bad def fix(filename): -## dbg('fix(%r)\n' % (dirname,)) - try: - f = open(filename, 'r') - except IOError, msg: - err('%s: cannot open: %r\n' % (filename, msg)) - return 1 - head, tail = os.path.split(filename) - tempname = os.path.join(head, '@' + tail) - g = None - # If we find a match, we rewind the file and start over but - # now copy everything to a temp file. - lineno = 0 - while 1: - line = f.readline() - if not line: break - lineno = lineno + 1 - if g is None and '\0' in line: - # Check for binary files - err(filename + ': contains null bytes; not fixed\n') - f.close() - return 1 - if lineno == 1 and g is None and line[:2] == '#!': - # Check for non-Python scripts - words = string.split(line[2:]) - if words and regex.search('[pP]ython', words[0]) < 0: - msg = filename + ': ' + words[0] - msg = msg + ' script; not fixed\n' - err(msg) - f.close() - return 1 - while line[-2:] == '\\\n': - nextline = f.readline() - if not nextline: break - line = line + nextline - lineno = lineno + 1 - newline = fixline(line) - if newline != line: - if g is None: - try: - g = open(tempname, 'w') - except IOError, msg: - f.close() - err('%s: cannot create: %r\n' % (tempname, msg)) - return 1 - f.seek(0) - lineno = 0 - rep(filename + ':\n') - continue # restart from the beginning - rep(repr(lineno) + '\n') - rep('< ' + line) - rep('> ' + newline) - if g is not None: - g.write(newline) - - # End of file - f.close() - if not g: return 0 # No changes - - # Finishing touch -- move files - - # First copy the file's mode to the temp file - try: - statbuf = os.stat(filename) - os.chmod(tempname, statbuf[ST_MODE] & 07777) - except os.error, msg: - err('%s: warning: chmod failed (%r)\n' % (tempname, msg)) - # Then make a backup of the original file as filename~ - try: - os.rename(filename, filename + '~') - except os.error, msg: - err('%s: warning: backup failed (%r)\n' % (filename, msg)) - # Now move the temp file to the original file - try: - os.rename(tempname, filename) - except os.error, msg: - err('%s: rename failed (%r)\n' % (filename, msg)) - return 1 - # Return succes - return 0 +## dbg('fix(%r)\n' % (dirname,)) + try: + f = open(filename, 'r') + except IOError, msg: + err('%s: cannot open: %r\n' % (filename, msg)) + return 1 + head, tail = os.path.split(filename) + tempname = os.path.join(head, '@' + tail) + g = None + # If we find a match, we rewind the file and start over but + # now copy everything to a temp file. + lineno = 0 + while 1: + line = f.readline() + if not line: break + lineno = lineno + 1 + if g is None and '\0' in line: + # Check for binary files + err(filename + ': contains null bytes; not fixed\n') + f.close() + return 1 + if lineno == 1 and g is None and line[:2] == '#!': + # Check for non-Python scripts + words = string.split(line[2:]) + if words and regex.search('[pP]ython', words[0]) < 0: + msg = filename + ': ' + words[0] + msg = msg + ' script; not fixed\n' + err(msg) + f.close() + return 1 + while line[-2:] == '\\\n': + nextline = f.readline() + if not nextline: break + line = line + nextline + lineno = lineno + 1 + newline = fixline(line) + if newline != line: + if g is None: + try: + g = open(tempname, 'w') + except IOError, msg: + f.close() + err('%s: cannot create: %r\n' % (tempname, msg)) + return 1 + f.seek(0) + lineno = 0 + rep(filename + ':\n') + continue # restart from the beginning + rep(repr(lineno) + '\n') + rep('< ' + line) + rep('> ' + newline) + if g is not None: + g.write(newline) + + # End of file + f.close() + if not g: return 0 # No changes + + # Finishing touch -- move files + + # First copy the file's mode to the temp file + try: + statbuf = os.stat(filename) + os.chmod(tempname, statbuf[ST_MODE] & 07777) + except os.error, msg: + err('%s: warning: chmod failed (%r)\n' % (tempname, msg)) + # Then make a backup of the original file as filename~ + try: + os.rename(filename, filename + '~') + except os.error, msg: + err('%s: warning: backup failed (%r)\n' % (filename, msg)) + # Now move the temp file to the original file + try: + os.rename(tempname, filename) + except os.error, msg: + err('%s: rename failed (%r)\n' % (filename, msg)) + return 1 + # Return succes + return 0 from tokenize import tokenprog match = {'if':':', 'elif':':', 'while':':', 'return':'\n', \ - '(':')', '[':']', '{':'}', '`':'`'} + '(':')', '[':']', '{':'}', '`':'`'} def fixline(line): - # Quick check for easy case - if '=' not in line: return line - - i, n = 0, len(line) - stack = [] - while i < n: - j = tokenprog.match(line, i) - if j < 0: - # A bad token; forget about the rest of this line - print '(Syntax error:)' - print line, - return line - a, b = tokenprog.regs[3] # Location of the token proper - token = line[a:b] - i = i+j - if stack and token == stack[-1]: - del stack[-1] - elif match.has_key(token): - stack.append(match[token]) - elif token == '=' and stack: - line = line[:a] + '==' + line[b:] - i, n = a + len('=='), len(line) - elif token == '==' and not stack: - print '(Warning: \'==\' at top level:)' - print line, - return line + # Quick check for easy case + if '=' not in line: return line + + i, n = 0, len(line) + stack = [] + while i < n: + j = tokenprog.match(line, i) + if j < 0: + # A bad token; forget about the rest of this line + print '(Syntax error:)' + print line, + return line + a, b = tokenprog.regs[3] # Location of the token proper + token = line[a:b] + i = i+j + if stack and token == stack[-1]: + del stack[-1] + elif match.has_key(token): + stack.append(match[token]) + elif token == '=' and stack: + line = line[:a] + '==' + line[b:] + i, n = a + len('=='), len(line) + elif token == '==' and not stack: + print '(Warning: \'==\' at top level:)' + print line, + return line main() diff --git a/Demo/scripts/fact.py b/Demo/scripts/fact.py index 6cc389e..5497f66 100755 --- a/Demo/scripts/fact.py +++ b/Demo/scripts/fact.py @@ -8,41 +8,41 @@ import sys from math import sqrt -error = 'fact.error' # exception +error = 'fact.error' # exception def fact(n): - if n < 1: raise error # fact() argument should be >= 1 - if n == 1: return [] # special case - res = [] - # Treat even factors special, so we can use i = i+2 later - while n%2 == 0: - res.append(2) - n = n/2 - # Try odd numbers up to sqrt(n) - limit = sqrt(float(n+1)) - i = 3 - while i <= limit: - if n%i == 0: - res.append(i) - n = n/i - limit = sqrt(n+1) - else: - i = i+2 - if n != 1: - res.append(n) - return res + if n < 1: raise error # fact() argument should be >= 1 + if n == 1: return [] # special case + res = [] + # Treat even factors special, so we can use i = i+2 later + while n%2 == 0: + res.append(2) + n = n/2 + # Try odd numbers up to sqrt(n) + limit = sqrt(float(n+1)) + i = 3 + while i <= limit: + if n%i == 0: + res.append(i) + n = n/i + limit = sqrt(n+1) + else: + i = i+2 + if n != 1: + res.append(n) + return res def main(): - if len(sys.argv) > 1: - for arg in sys.argv[1:]: - n = eval(arg) - print n, fact(n) - else: - try: - while 1: - n = input() - print n, fact(n) - except EOFError: - pass + if len(sys.argv) > 1: + for arg in sys.argv[1:]: + n = eval(arg) + print n, fact(n) + else: + try: + while 1: + n = input() + print n, fact(n) + except EOFError: + pass main() diff --git a/Demo/scripts/ftpstats.py b/Demo/scripts/ftpstats.py index 8af72b5..13d0553 100755 --- a/Demo/scripts/ftpstats.py +++ b/Demo/scripts/ftpstats.py @@ -21,124 +21,124 @@ pat = '^\([a-zA-Z0-9 :]*\)!\(.*\)!\(.*\)!\([<>].*\)!\([0-9]+\)!\([0-9]+\)$' prog = regex.compile(pat) def main(): - maxitems = 25 - search = None - try: - opts, args = getopt.getopt(sys.argv[1:], 'm:s:') - except getopt.error, msg: - print msg - print 'usage: ftpstats [-m maxitems] [file]' - sys.exit(2) - for o, a in opts: - if o == '-m': - maxitems = string.atoi(a) - if o == '-s': - search = a - file = '/usr/adm/ftpd' - if args: file = args[0] - if file == '-': - f = sys.stdin - else: - try: - f = open(file, 'r') - except IOError, msg: - print file, ':', msg - sys.exit(1) - bydate = {} - bytime = {} - byfile = {} - bydir = {} - byhost = {} - byuser = {} - bytype = {} - lineno = 0 - try: - while 1: - line = f.readline() - if not line: break - lineno = lineno + 1 - if search and string.find(line, search) < 0: - continue - if prog.match(line) < 0: - print 'Bad line', lineno, ':', repr(line) - continue - items = prog.group(1, 2, 3, 4, 5, 6) - (logtime, loguser, loghost, logfile, logbytes, - logxxx2) = items -## print logtime -## print '-->', loguser -## print '--> -->', loghost -## print '--> --> -->', logfile -## print '--> --> --> -->', logbytes -## print '--> --> --> --> -->', logxxx2 -## for i in logtime, loghost, logbytes, logxxx2: -## if '!' in i: print '???', i - add(bydate, logtime[-4:] + ' ' + logtime[:6], items) - add(bytime, logtime[7:9] + ':00-59', items) - direction, logfile = logfile[0], logfile[1:] - # The real path probably starts at the last //... - while 1: - i = string.find(logfile, '//') - if i < 0: break - logfile = logfile[i+1:] - add(byfile, logfile + ' ' + direction, items) - logdir = os.path.dirname(logfile) -## logdir = os.path.normpath(logdir) + '/.' - while 1: - add(bydir, logdir + ' ' + direction, items) - dirhead = os.path.dirname(logdir) - if dirhead == logdir: break - logdir = dirhead - add(byhost, loghost, items) - add(byuser, loguser, items) - add(bytype, direction, items) - except KeyboardInterrupt: - print 'Interrupted at line', lineno - show(bytype, 'by transfer direction', maxitems) - show(bydir, 'by directory', maxitems) - show(byfile, 'by file', maxitems) - show(byhost, 'by host', maxitems) - show(byuser, 'by user', maxitems) - showbar(bydate, 'by date') - showbar(bytime, 'by time of day') + maxitems = 25 + search = None + try: + opts, args = getopt.getopt(sys.argv[1:], 'm:s:') + except getopt.error, msg: + print msg + print 'usage: ftpstats [-m maxitems] [file]' + sys.exit(2) + for o, a in opts: + if o == '-m': + maxitems = string.atoi(a) + if o == '-s': + search = a + file = '/usr/adm/ftpd' + if args: file = args[0] + if file == '-': + f = sys.stdin + else: + try: + f = open(file, 'r') + except IOError, msg: + print file, ':', msg + sys.exit(1) + bydate = {} + bytime = {} + byfile = {} + bydir = {} + byhost = {} + byuser = {} + bytype = {} + lineno = 0 + try: + while 1: + line = f.readline() + if not line: break + lineno = lineno + 1 + if search and string.find(line, search) < 0: + continue + if prog.match(line) < 0: + print 'Bad line', lineno, ':', repr(line) + continue + items = prog.group(1, 2, 3, 4, 5, 6) + (logtime, loguser, loghost, logfile, logbytes, + logxxx2) = items +## print logtime +## print '-->', loguser +## print '--> -->', loghost +## print '--> --> -->', logfile +## print '--> --> --> -->', logbytes +## print '--> --> --> --> -->', logxxx2 +## for i in logtime, loghost, logbytes, logxxx2: +## if '!' in i: print '???', i + add(bydate, logtime[-4:] + ' ' + logtime[:6], items) + add(bytime, logtime[7:9] + ':00-59', items) + direction, logfile = logfile[0], logfile[1:] + # The real path probably starts at the last //... + while 1: + i = string.find(logfile, '//') + if i < 0: break + logfile = logfile[i+1:] + add(byfile, logfile + ' ' + direction, items) + logdir = os.path.dirname(logfile) +## logdir = os.path.normpath(logdir) + '/.' + while 1: + add(bydir, logdir + ' ' + direction, items) + dirhead = os.path.dirname(logdir) + if dirhead == logdir: break + logdir = dirhead + add(byhost, loghost, items) + add(byuser, loguser, items) + add(bytype, direction, items) + except KeyboardInterrupt: + print 'Interrupted at line', lineno + show(bytype, 'by transfer direction', maxitems) + show(bydir, 'by directory', maxitems) + show(byfile, 'by file', maxitems) + show(byhost, 'by host', maxitems) + show(byuser, 'by user', maxitems) + showbar(bydate, 'by date') + showbar(bytime, 'by time of day') def showbar(dict, title): - n = len(title) - print '='*((70-n)/2), title, '='*((71-n)/2) - list = [] - keys = dict.keys() - keys.sort() - for key in keys: - n = len(str(key)) - list.append((len(dict[key]), key)) - maxkeylength = 0 - maxcount = 0 - for count, key in list: - maxkeylength = max(maxkeylength, len(key)) - maxcount = max(maxcount, count) - maxbarlength = 72 - maxkeylength - 7 - for count, key in list: - barlength = int(round(maxbarlength*float(count)/maxcount)) - bar = '*'*barlength - print '%5d %-*s %s' % (count, maxkeylength, key, bar) + n = len(title) + print '='*((70-n)/2), title, '='*((71-n)/2) + list = [] + keys = dict.keys() + keys.sort() + for key in keys: + n = len(str(key)) + list.append((len(dict[key]), key)) + maxkeylength = 0 + maxcount = 0 + for count, key in list: + maxkeylength = max(maxkeylength, len(key)) + maxcount = max(maxcount, count) + maxbarlength = 72 - maxkeylength - 7 + for count, key in list: + barlength = int(round(maxbarlength*float(count)/maxcount)) + bar = '*'*barlength + print '%5d %-*s %s' % (count, maxkeylength, key, bar) def show(dict, title, maxitems): - if len(dict) > maxitems: - title = title + ' (first %d)'%maxitems - n = len(title) - print '='*((70-n)/2), title, '='*((71-n)/2) - list = [] - keys = dict.keys() - for key in keys: - list.append((-len(dict[key]), key)) - list.sort() - for count, key in list[:maxitems]: - print '%5d %s' % (-count, key) + if len(dict) > maxitems: + title = title + ' (first %d)'%maxitems + n = len(title) + print '='*((70-n)/2), title, '='*((71-n)/2) + list = [] + keys = dict.keys() + for key in keys: + list.append((-len(dict[key]), key)) + list.sort() + for count, key in list[:maxitems]: + print '%5d %s' % (-count, key) def add(dict, key, item): - if dict.has_key(key): - dict[key].append(item) - else: - dict[key] = [item] + if dict.has_key(key): + dict[key].append(item) + else: + dict[key] = [item] main() diff --git a/Demo/scripts/lpwatch.py b/Demo/scripts/lpwatch.py index 00afba9..0af3cbd 100755 --- a/Demo/scripts/lpwatch.py +++ b/Demo/scripts/lpwatch.py @@ -12,98 +12,98 @@ DEF_PRINTER = 'psc' DEF_DELAY = 10 def main(): - delay = DEF_DELAY # XXX Use getopt() later - try: - thisuser = posix.environ['LOGNAME'] - except: - thisuser = posix.environ['USER'] - printers = sys.argv[1:] - if printers: - # Strip '-P' from printer names just in case - # the user specified it... - for i in range(len(printers)): - if printers[i][:2] == '-P': - printers[i] = printers[i][2:] - else: - if posix.environ.has_key('PRINTER'): - printers = [posix.environ['PRINTER']] - else: - printers = [DEF_PRINTER] - # - clearhome = posix.popen('clear', 'r').read() - # - while 1: - text = clearhome - for name in printers: - text = text + makestatus(name, thisuser) + '\n' - print text - time.sleep(delay) + delay = DEF_DELAY # XXX Use getopt() later + try: + thisuser = posix.environ['LOGNAME'] + except: + thisuser = posix.environ['USER'] + printers = sys.argv[1:] + if printers: + # Strip '-P' from printer names just in case + # the user specified it... + for i in range(len(printers)): + if printers[i][:2] == '-P': + printers[i] = printers[i][2:] + else: + if posix.environ.has_key('PRINTER'): + printers = [posix.environ['PRINTER']] + else: + printers = [DEF_PRINTER] + # + clearhome = posix.popen('clear', 'r').read() + # + while 1: + text = clearhome + for name in printers: + text = text + makestatus(name, thisuser) + '\n' + print text + time.sleep(delay) def makestatus(name, thisuser): - pipe = posix.popen('lpq -P' + name + ' 2>&1', 'r') - lines = [] - users = {} - aheadbytes = 0 - aheadjobs = 0 - userseen = 0 - totalbytes = 0 - totaljobs = 0 - while 1: - line = pipe.readline() - if not line: break - fields = string.split(line) - n = len(fields) - if len(fields) >= 6 and fields[n-1] == 'bytes': - rank = fields[0] - user = fields[1] - job = fields[2] - files = fields[3:-2] - bytes = eval(fields[n-2]) - if user == thisuser: - userseen = 1 - elif not userseen: - aheadbytes = aheadbytes + bytes - aheadjobs = aheadjobs + 1 - totalbytes = totalbytes + bytes - totaljobs = totaljobs + 1 - if users.has_key(user): - ujobs, ubytes = users[user] - else: - ujobs, ubytes = 0, 0 - ujobs = ujobs + 1 - ubytes = ubytes + bytes - users[user] = ujobs, ubytes - else: - if fields and fields[0] <> 'Rank': - line = string.strip(line) - if line == 'no entries': - line = name + ': idle' - elif line[-22:] == ' is ready and printing': - line = name - lines.append(line) - # - if totaljobs: - line = '%d K' % ((totalbytes+1023)/1024) - if totaljobs <> len(users): - line = line + ' (%d jobs)' % totaljobs - if len(users) == 1: - line = line + ' for %s' % (users.keys()[0],) - else: - line = line + ' for %d users' % len(users) - if userseen: - if aheadjobs == 0: - line = line + ' (%s first)' % thisuser - else: - line = line + ' (%d K before %s)' % ( - (aheadbytes+1023)/1024, thisuser) - lines.append(line) - # - sts = pipe.close() - if sts: - lines.append('lpq exit status %r' % (sts,)) - return string.joinfields(lines, ': ') + pipe = posix.popen('lpq -P' + name + ' 2>&1', 'r') + lines = [] + users = {} + aheadbytes = 0 + aheadjobs = 0 + userseen = 0 + totalbytes = 0 + totaljobs = 0 + while 1: + line = pipe.readline() + if not line: break + fields = string.split(line) + n = len(fields) + if len(fields) >= 6 and fields[n-1] == 'bytes': + rank = fields[0] + user = fields[1] + job = fields[2] + files = fields[3:-2] + bytes = eval(fields[n-2]) + if user == thisuser: + userseen = 1 + elif not userseen: + aheadbytes = aheadbytes + bytes + aheadjobs = aheadjobs + 1 + totalbytes = totalbytes + bytes + totaljobs = totaljobs + 1 + if users.has_key(user): + ujobs, ubytes = users[user] + else: + ujobs, ubytes = 0, 0 + ujobs = ujobs + 1 + ubytes = ubytes + bytes + users[user] = ujobs, ubytes + else: + if fields and fields[0] <> 'Rank': + line = string.strip(line) + if line == 'no entries': + line = name + ': idle' + elif line[-22:] == ' is ready and printing': + line = name + lines.append(line) + # + if totaljobs: + line = '%d K' % ((totalbytes+1023)/1024) + if totaljobs <> len(users): + line = line + ' (%d jobs)' % totaljobs + if len(users) == 1: + line = line + ' for %s' % (users.keys()[0],) + else: + line = line + ' for %d users' % len(users) + if userseen: + if aheadjobs == 0: + line = line + ' (%s first)' % thisuser + else: + line = line + ' (%d K before %s)' % ( + (aheadbytes+1023)/1024, thisuser) + lines.append(line) + # + sts = pipe.close() + if sts: + lines.append('lpq exit status %r' % (sts,)) + return string.joinfields(lines, ': ') try: - main() + main() except KeyboardInterrupt: - pass + pass diff --git a/Demo/scripts/makedir.py b/Demo/scripts/makedir.py index 4c00d88..209f6c4 100755 --- a/Demo/scripts/makedir.py +++ b/Demo/scripts/makedir.py @@ -8,13 +8,13 @@ import sys, os def main(): - for p in sys.argv[1:]: - makedirs(p) + for p in sys.argv[1:]: + makedirs(p) def makedirs(p): - if p and not os.path.isdir(p): - head, tail = os.path.split(p) - makedirs(head) - os.mkdir(p, 0777) + if p and not os.path.isdir(p): + head, tail = os.path.split(p) + makedirs(head) + os.mkdir(p, 0777) main() diff --git a/Demo/scripts/markov.py b/Demo/scripts/markov.py index b0583d1..3329351 100755 --- a/Demo/scripts/markov.py +++ b/Demo/scripts/markov.py @@ -1,116 +1,116 @@ #! /usr/bin/env python class Markov: - def __init__(self, histsize, choice): - self.histsize = histsize - self.choice = choice - self.trans = {} - def add(self, state, next): - if not self.trans.has_key(state): - self.trans[state] = [next] - else: - self.trans[state].append(next) - def put(self, seq): - n = self.histsize - add = self.add - add(None, seq[:0]) - for i in range(len(seq)): - add(seq[max(0, i-n):i], seq[i:i+1]) - add(seq[len(seq)-n:], None) - def get(self): - choice = self.choice - trans = self.trans - n = self.histsize - seq = choice(trans[None]) - while 1: - subseq = seq[max(0, len(seq)-n):] - options = trans[subseq] - next = choice(options) - if not next: break - seq = seq + next - return seq + def __init__(self, histsize, choice): + self.histsize = histsize + self.choice = choice + self.trans = {} + def add(self, state, next): + if not self.trans.has_key(state): + self.trans[state] = [next] + else: + self.trans[state].append(next) + def put(self, seq): + n = self.histsize + add = self.add + add(None, seq[:0]) + for i in range(len(seq)): + add(seq[max(0, i-n):i], seq[i:i+1]) + add(seq[len(seq)-n:], None) + def get(self): + choice = self.choice + trans = self.trans + n = self.histsize + seq = choice(trans[None]) + while 1: + subseq = seq[max(0, len(seq)-n):] + options = trans[subseq] + next = choice(options) + if not next: break + seq = seq + next + return seq def test(): - import sys, string, random, getopt - args = sys.argv[1:] - try: - opts, args = getopt.getopt(args, '0123456789cdw') - except getopt.error: - print 'Usage: markov [-#] [-cddqw] [file] ...' - print 'Options:' - print '-#: 1-digit history size (default 2)' - print '-c: characters (default)' - print '-w: words' - print '-d: more debugging output' - print '-q: no debugging output' - print 'Input files (default stdin) are split in paragraphs' - print 'separated blank lines and each paragraph is split' - print 'in words by whitespace, then reconcatenated with' - print 'exactly one space separating words.' - print 'Output consists of paragraphs separated by blank' - print 'lines, where lines are no longer than 72 characters.' - histsize = 2 - do_words = 0 - debug = 1 - for o, a in opts: - if '-0' <= o <= '-9': histsize = eval(o[1:]) - if o == '-c': do_words = 0 - if o == '-d': debug = debug + 1 - if o == '-q': debug = 0 - if o == '-w': do_words = 1 - if not args: args = ['-'] - m = Markov(histsize, random.choice) - try: - for filename in args: - if filename == '-': - f = sys.stdin - if f.isatty(): - print 'Sorry, need stdin from file' - continue - else: - f = open(filename, 'r') - if debug: print 'processing', filename, '...' - text = f.read() - f.close() - paralist = string.splitfields(text, '\n\n') - for para in paralist: - if debug > 1: print 'feeding ...' - words = string.split(para) - if words: - if do_words: data = tuple(words) - else: data = string.joinfields(words, ' ') - m.put(data) - except KeyboardInterrupt: - print 'Interrupted -- continue with data read so far' - if not m.trans: - print 'No valid input files' - return - if debug: print 'done.' - if debug > 1: - for key in m.trans.keys(): - if key is None or len(key) < histsize: - print repr(key), m.trans[key] - if histsize == 0: print repr(''), m.trans[''] - print - while 1: - data = m.get() - if do_words: words = data - else: words = string.split(data) - n = 0 - limit = 72 - for w in words: - if n + len(w) > limit: - print - n = 0 - print w, - n = n + len(w) + 1 - print - print + import sys, string, random, getopt + args = sys.argv[1:] + try: + opts, args = getopt.getopt(args, '0123456789cdw') + except getopt.error: + print 'Usage: markov [-#] [-cddqw] [file] ...' + print 'Options:' + print '-#: 1-digit history size (default 2)' + print '-c: characters (default)' + print '-w: words' + print '-d: more debugging output' + print '-q: no debugging output' + print 'Input files (default stdin) are split in paragraphs' + print 'separated blank lines and each paragraph is split' + print 'in words by whitespace, then reconcatenated with' + print 'exactly one space separating words.' + print 'Output consists of paragraphs separated by blank' + print 'lines, where lines are no longer than 72 characters.' + histsize = 2 + do_words = 0 + debug = 1 + for o, a in opts: + if '-0' <= o <= '-9': histsize = eval(o[1:]) + if o == '-c': do_words = 0 + if o == '-d': debug = debug + 1 + if o == '-q': debug = 0 + if o == '-w': do_words = 1 + if not args: args = ['-'] + m = Markov(histsize, random.choice) + try: + for filename in args: + if filename == '-': + f = sys.stdin + if f.isatty(): + print 'Sorry, need stdin from file' + continue + else: + f = open(filename, 'r') + if debug: print 'processing', filename, '...' + text = f.read() + f.close() + paralist = string.splitfields(text, '\n\n') + for para in paralist: + if debug > 1: print 'feeding ...' + words = string.split(para) + if words: + if do_words: data = tuple(words) + else: data = string.joinfields(words, ' ') + m.put(data) + except KeyboardInterrupt: + print 'Interrupted -- continue with data read so far' + if not m.trans: + print 'No valid input files' + return + if debug: print 'done.' + if debug > 1: + for key in m.trans.keys(): + if key is None or len(key) < histsize: + print repr(key), m.trans[key] + if histsize == 0: print repr(''), m.trans[''] + print + while 1: + data = m.get() + if do_words: words = data + else: words = string.split(data) + n = 0 + limit = 72 + for w in words: + if n + len(w) > limit: + print + n = 0 + print w, + n = n + len(w) + 1 + print + print def tuple(list): - if len(list) == 0: return () - if len(list) == 1: return (list[0],) - i = len(list)/2 - return tuple(list[:i]) + tuple(list[i:]) + if len(list) == 0: return () + if len(list) == 1: return (list[0],) + i = len(list)/2 + return tuple(list[:i]) + tuple(list[i:]) test() diff --git a/Demo/scripts/mboxconvert.py b/Demo/scripts/mboxconvert.py index 996537d..ba1f734 100755 --- a/Demo/scripts/mboxconvert.py +++ b/Demo/scripts/mboxconvert.py @@ -13,111 +13,111 @@ import getopt import regex def main(): - dofile = mmdf - try: - opts, args = getopt.getopt(sys.argv[1:], 'f') - except getopt.error, msg: - sys.stderr.write('%s\n' % msg) - sys.exit(2) - for o, a in opts: - if o == '-f': - dofile = message - if not args: - args = ['-'] - sts = 0 - for arg in args: - if arg == '-' or arg == '': - sts = dofile(sys.stdin) or sts - elif os.path.isdir(arg): - sts = mh(arg) or sts - elif os.path.isfile(arg): - try: - f = open(arg) - except IOError, msg: - sys.stderr.write('%s: %s\n' % (arg, msg)) - sts = 1 - continue - sts = dofile(f) or sts - f.close() - else: - sys.stderr.write('%s: not found\n' % arg) - sts = 1 - if sts: - sys.exit(sts) + dofile = mmdf + try: + opts, args = getopt.getopt(sys.argv[1:], 'f') + except getopt.error, msg: + sys.stderr.write('%s\n' % msg) + sys.exit(2) + for o, a in opts: + if o == '-f': + dofile = message + if not args: + args = ['-'] + sts = 0 + for arg in args: + if arg == '-' or arg == '': + sts = dofile(sys.stdin) or sts + elif os.path.isdir(arg): + sts = mh(arg) or sts + elif os.path.isfile(arg): + try: + f = open(arg) + except IOError, msg: + sys.stderr.write('%s: %s\n' % (arg, msg)) + sts = 1 + continue + sts = dofile(f) or sts + f.close() + else: + sys.stderr.write('%s: not found\n' % arg) + sts = 1 + if sts: + sys.exit(sts) numeric = regex.compile('[1-9][0-9]*') def mh(dir): - sts = 0 - msgs = os.listdir(dir) - for msg in msgs: - if numeric.match(msg) != len(msg): - continue - fn = os.path.join(dir, msg) - try: - f = open(fn) - except IOError, msg: - sys.stderr.write('%s: %s\n' % (fn, msg)) - sts = 1 - continue - sts = message(f) or sts - return sts + sts = 0 + msgs = os.listdir(dir) + for msg in msgs: + if numeric.match(msg) != len(msg): + continue + fn = os.path.join(dir, msg) + try: + f = open(fn) + except IOError, msg: + sys.stderr.write('%s: %s\n' % (fn, msg)) + sts = 1 + continue + sts = message(f) or sts + return sts def mmdf(f): - sts = 0 - while 1: - line = f.readline() - if not line: - break - if line == '\1\1\1\1\n': - sts = message(f, line) or sts - else: - sys.stderr.write( - 'Bad line in MMFD mailbox: %r\n' % (line,)) - return sts + sts = 0 + while 1: + line = f.readline() + if not line: + break + if line == '\1\1\1\1\n': + sts = message(f, line) or sts + else: + sys.stderr.write( + 'Bad line in MMFD mailbox: %r\n' % (line,)) + return sts counter = 0 # for generating unique Message-ID headers def message(f, delimiter = ''): - sts = 0 - # Parse RFC822 header - m = rfc822.Message(f) - # Write unix header line - fullname, email = m.getaddr('From') - tt = m.getdate('Date') - if tt: - t = time.mktime(tt) - else: - sys.stderr.write( - 'Unparseable date: %r\n' % (m.getheader('Date'),)) - t = os.fstat(f.fileno())[stat.ST_MTIME] - print 'From', email, time.ctime(t) - # Copy RFC822 header - for line in m.headers: - print line, - # Invent Message-ID header if none is present - if not m.has_key('message-id'): - global counter - counter = counter + 1 - msgid = "<%s.%d>" % (hex(t), counter) - sys.stderr.write("Adding Message-ID %s (From %s)\n" % - (msgid, email)) - print "Message-ID:", msgid - print - # Copy body - while 1: - line = f.readline() - if line == delimiter: - break - if not line: - sys.stderr.write('Unexpected EOF in message\n') - sts = 1 - break - if line[:5] == 'From ': - line = '>' + line - print line, - # Print trailing newline - print - return sts + sts = 0 + # Parse RFC822 header + m = rfc822.Message(f) + # Write unix header line + fullname, email = m.getaddr('From') + tt = m.getdate('Date') + if tt: + t = time.mktime(tt) + else: + sys.stderr.write( + 'Unparseable date: %r\n' % (m.getheader('Date'),)) + t = os.fstat(f.fileno())[stat.ST_MTIME] + print 'From', email, time.ctime(t) + # Copy RFC822 header + for line in m.headers: + print line, + # Invent Message-ID header if none is present + if not m.has_key('message-id'): + global counter + counter = counter + 1 + msgid = "<%s.%d>" % (hex(t), counter) + sys.stderr.write("Adding Message-ID %s (From %s)\n" % + (msgid, email)) + print "Message-ID:", msgid + print + # Copy body + while 1: + line = f.readline() + if line == delimiter: + break + if not line: + sys.stderr.write('Unexpected EOF in message\n') + sts = 1 + break + if line[:5] == 'From ': + line = '>' + line + print line, + # Print trailing newline + print + return sts main() diff --git a/Demo/scripts/mkrcs.py b/Demo/scripts/mkrcs.py index 917b4fe..45a68b9 100755 --- a/Demo/scripts/mkrcs.py +++ b/Demo/scripts/mkrcs.py @@ -9,52 +9,52 @@ import os def main(): - rcstree = 'RCStree' - rcs = 'RCS' - if os.path.islink(rcs): - print '%r is a symlink to %r' % (rcs, os.readlink(rcs)) - return - if os.path.isdir(rcs): - print '%r is an ordinary directory' % (rcs,) - return - if os.path.exists(rcs): - print '%r is a file?!?!' % (rcs,) - return - # - p = os.getcwd() - up = '' - down = '' - # Invariants: - # (1) join(p, down) is the current directory - # (2) up is the same directory as p - # Ergo: - # (3) join(up, down) is the current directory - #print 'p =', repr(p) - while not os.path.isdir(os.path.join(p, rcstree)): - head, tail = os.path.split(p) - #print 'head = %r; tail = %r' % (head, tail) - if not tail: - print 'Sorry, no ancestor dir contains %r' % (rcstree,) - return - p = head - up = os.path.join(os.pardir, up) - down = os.path.join(tail, down) - #print 'p = %r; up = %r; down = %r' % (p, up, down) - there = os.path.join(up, rcstree) - there = os.path.join(there, down) - there = os.path.join(there, rcs) - if os.path.isdir(there): - print '%r already exists' % (there, ) - else: - print 'making %r' % (there,) - makedirs(there) - print 'making symlink %r -> %r' % (rcs, there) - os.symlink(there, rcs) + rcstree = 'RCStree' + rcs = 'RCS' + if os.path.islink(rcs): + print '%r is a symlink to %r' % (rcs, os.readlink(rcs)) + return + if os.path.isdir(rcs): + print '%r is an ordinary directory' % (rcs,) + return + if os.path.exists(rcs): + print '%r is a file?!?!' % (rcs,) + return + # + p = os.getcwd() + up = '' + down = '' + # Invariants: + # (1) join(p, down) is the current directory + # (2) up is the same directory as p + # Ergo: + # (3) join(up, down) is the current directory + #print 'p =', repr(p) + while not os.path.isdir(os.path.join(p, rcstree)): + head, tail = os.path.split(p) + #print 'head = %r; tail = %r' % (head, tail) + if not tail: + print 'Sorry, no ancestor dir contains %r' % (rcstree,) + return + p = head + up = os.path.join(os.pardir, up) + down = os.path.join(tail, down) + #print 'p = %r; up = %r; down = %r' % (p, up, down) + there = os.path.join(up, rcstree) + there = os.path.join(there, down) + there = os.path.join(there, rcs) + if os.path.isdir(there): + print '%r already exists' % (there, ) + else: + print 'making %r' % (there,) + makedirs(there) + print 'making symlink %r -> %r' % (rcs, there) + os.symlink(there, rcs) def makedirs(p): - if not os.path.isdir(p): - head, tail = os.path.split(p) - makedirs(head) - os.mkdir(p, 0777) + if not os.path.isdir(p): + head, tail = os.path.split(p) + makedirs(head) + os.mkdir(p, 0777) main() diff --git a/Demo/scripts/morse.py b/Demo/scripts/morse.py index 2cea83e..3da49da 100755 --- a/Demo/scripts/morse.py +++ b/Demo/scripts/morse.py @@ -7,57 +7,57 @@ import sys, math, audiodev DOT = 30 DAH = 3 * DOT -OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ... +OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ... morsetab = { - 'A': '.-', 'a': '.-', - 'B': '-...', 'b': '-...', - 'C': '-.-.', 'c': '-.-.', - 'D': '-..', 'd': '-..', - 'E': '.', 'e': '.', - 'F': '..-.', 'f': '..-.', - 'G': '--.', 'g': '--.', - 'H': '....', 'h': '....', - 'I': '..', 'i': '..', - 'J': '.---', 'j': '.---', - 'K': '-.-', 'k': '-.-', - 'L': '.-..', 'l': '.-..', - 'M': '--', 'm': '--', - 'N': '-.', 'n': '-.', - 'O': '---', 'o': '---', - 'P': '.--.', 'p': '.--.', - 'Q': '--.-', 'q': '--.-', - 'R': '.-.', 'r': '.-.', - 'S': '...', 's': '...', - 'T': '-', 't': '-', - 'U': '..-', 'u': '..-', - 'V': '...-', 'v': '...-', - 'W': '.--', 'w': '.--', - 'X': '-..-', 'x': '-..-', - 'Y': '-.--', 'y': '-.--', - 'Z': '--..', 'z': '--..', - '0': '-----', - '1': '.----', - '2': '..---', - '3': '...--', - '4': '....-', - '5': '.....', - '6': '-....', - '7': '--...', - '8': '---..', - '9': '----.', - ',': '--..--', - '.': '.-.-.-', - '?': '..--..', - ';': '-.-.-.', - ':': '---...', - "'": '.----.', - '-': '-....-', - '/': '-..-.', - '(': '-.--.-', - ')': '-.--.-', - '_': '..--.-', - ' ': ' ' + 'A': '.-', 'a': '.-', + 'B': '-...', 'b': '-...', + 'C': '-.-.', 'c': '-.-.', + 'D': '-..', 'd': '-..', + 'E': '.', 'e': '.', + 'F': '..-.', 'f': '..-.', + 'G': '--.', 'g': '--.', + 'H': '....', 'h': '....', + 'I': '..', 'i': '..', + 'J': '.---', 'j': '.---', + 'K': '-.-', 'k': '-.-', + 'L': '.-..', 'l': '.-..', + 'M': '--', 'm': '--', + 'N': '-.', 'n': '-.', + 'O': '---', 'o': '---', + 'P': '.--.', 'p': '.--.', + 'Q': '--.-', 'q': '--.-', + 'R': '.-.', 'r': '.-.', + 'S': '...', 's': '...', + 'T': '-', 't': '-', + 'U': '..-', 'u': '..-', + 'V': '...-', 'v': '...-', + 'W': '.--', 'w': '.--', + 'X': '-..-', 'x': '-..-', + 'Y': '-.--', 'y': '-.--', + 'Z': '--..', 'z': '--..', + '0': '-----', + '1': '.----', + '2': '..---', + '3': '...--', + '4': '....-', + '5': '.....', + '6': '-....', + '7': '--...', + '8': '---..', + '9': '----.', + ',': '--..--', + '.': '.-.-.-', + '?': '..--..', + ';': '-.-.-.', + ':': '---...', + "'": '.----.', + '-': '-....-', + '/': '-..-.', + '(': '-.--.-', + ')': '-.--.-', + '_': '..--.-', + ' ': ' ' } # If we play at 44.1 kHz (which we do), then if we produce one sine @@ -65,85 +65,85 @@ morsetab = { # sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz # appears to be a nice one for playing morse code. def mkwave(octave): - global sinewave, nowave - sinewave = '' - for i in range(100): - val = int(math.sin(math.pi * float(i) * octave / 50.0) * 30000) - sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255) - nowave = '\0' * 200 + global sinewave, nowave + sinewave = '' + for i in range(100): + val = int(math.sin(math.pi * float(i) * octave / 50.0) * 30000) + sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255) + nowave = '\0' * 200 mkwave(OCTAVE) def main(): - import getopt, string - try: - opts, args = getopt.getopt(sys.argv[1:], 'o:p:') - except getopt.error: - sys.stderr.write('Usage ' + sys.argv[0] + - ' [ -o outfile ] [ args ] ...\n') - sys.exit(1) - dev = None - for o, a in opts: - if o == '-o': - import aifc - dev = aifc.open(a, 'w') - dev.setframerate(44100) - dev.setsampwidth(2) - dev.setnchannels(1) - if o == '-p': - mkwave(string.atoi(a)) - if not dev: - import audiodev - dev = audiodev.AudioDev() - dev.setoutrate(44100) - dev.setsampwidth(2) - dev.setnchannels(1) - dev.close = dev.stop - dev.writeframesraw = dev.writeframes - if args: - line = string.join(args) - else: - line = sys.stdin.readline() - while line: - mline = morse(line) - play(mline, dev) - if hasattr(dev, 'wait'): - dev.wait() - if not args: - line = sys.stdin.readline() - else: - line = '' - dev.close() + import getopt, string + try: + opts, args = getopt.getopt(sys.argv[1:], 'o:p:') + except getopt.error: + sys.stderr.write('Usage ' + sys.argv[0] + + ' [ -o outfile ] [ args ] ...\n') + sys.exit(1) + dev = None + for o, a in opts: + if o == '-o': + import aifc + dev = aifc.open(a, 'w') + dev.setframerate(44100) + dev.setsampwidth(2) + dev.setnchannels(1) + if o == '-p': + mkwave(string.atoi(a)) + if not dev: + import audiodev + dev = audiodev.AudioDev() + dev.setoutrate(44100) + dev.setsampwidth(2) + dev.setnchannels(1) + dev.close = dev.stop + dev.writeframesraw = dev.writeframes + if args: + line = string.join(args) + else: + line = sys.stdin.readline() + while line: + mline = morse(line) + play(mline, dev) + if hasattr(dev, 'wait'): + dev.wait() + if not args: + line = sys.stdin.readline() + else: + line = '' + dev.close() # Convert a string to morse code with \001 between the characters in # the string. def morse(line): - res = '' - for c in line: - try: - res = res + morsetab[c] + '\001' - except KeyError: - pass - return res + res = '' + for c in line: + try: + res = res + morsetab[c] + '\001' + except KeyError: + pass + return res # Play a line of morse code. def play(line, dev): - for c in line: - if c == '.': - sine(dev, DOT) - elif c == '-': - sine(dev, DAH) - else: # space - pause(dev, DAH + DOT) - pause(dev, DOT) + for c in line: + if c == '.': + sine(dev, DOT) + elif c == '-': + sine(dev, DAH) + else: # space + pause(dev, DAH + DOT) + pause(dev, DOT) def sine(dev, length): - for i in range(length): - dev.writeframesraw(sinewave) + for i in range(length): + dev.writeframesraw(sinewave) def pause(dev, length): - for i in range(length): - dev.writeframesraw(nowave) + for i in range(length): + dev.writeframesraw(nowave) if __name__ == '__main__' or sys.argv[0] == __name__: - main() + main() diff --git a/Demo/scripts/mpzpi.py b/Demo/scripts/mpzpi.py index ccf591d..70b1a51 100755 --- a/Demo/scripts/mpzpi.py +++ b/Demo/scripts/mpzpi.py @@ -11,24 +11,24 @@ import sys from mpz import mpz def main(): - mpzone, mpztwo, mpzten = mpz(1), mpz(2), mpz(10) - k, a, b, a1, b1 = mpz(2), mpz(4), mpz(1), mpz(12), mpz(4) - while 1: - # Next approximation - p, q, k = k*k, mpztwo*k+mpzone, k+mpzone - a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1 - # Print common digits - d, d1 = a/b, a1/b1 - while d == d1: - output(d) - a, a1 = mpzten*(a%b), mpzten*(a1%b1) - d, d1 = a/b, a1/b1 + mpzone, mpztwo, mpzten = mpz(1), mpz(2), mpz(10) + k, a, b, a1, b1 = mpz(2), mpz(4), mpz(1), mpz(12), mpz(4) + while 1: + # Next approximation + p, q, k = k*k, mpztwo*k+mpzone, k+mpzone + a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1 + # Print common digits + d, d1 = a/b, a1/b1 + while d == d1: + output(d) + a, a1 = mpzten*(a%b), mpzten*(a1%b1) + d, d1 = a/b, a1/b1 def output(d): - # Use write() to avoid spaces between the digits - # Use int(d) to avoid a trailing L after each digit - sys.stdout.write(repr(int(d))) - # Flush so the output is seen immediately - sys.stdout.flush() + # Use write() to avoid spaces between the digits + # Use int(d) to avoid a trailing L after each digit + sys.stdout.write(repr(int(d))) + # Flush so the output is seen immediately + sys.stdout.flush() main() diff --git a/Demo/scripts/newslist.py b/Demo/scripts/newslist.py index b06b452..b9f9c0e 100755 --- a/Demo/scripts/newslist.py +++ b/Demo/scripts/newslist.py @@ -5,27 +5,27 @@ # Syntax: # newslist [ -a ] # -# This is a program to create a directory full of HTML pages +# This is a program to create a directory full of HTML pages # which between them contain links to all the newsgroups available # on your server. # -# The -a option causes a complete list of all groups to be read from +# The -a option causes a complete list of all groups to be read from # the server rather than just the ones which have appeared since last # execution. This recreates the local list from scratch. Use this on # the first invocation of the program, and from time to time thereafter. -# When new groups are first created they may appear on your server as +# When new groups are first created they may appear on your server as # empty groups. By default, empty groups are ignored by the -a option. # However, these new groups will not be created again, and so will not # appear in the server's list of 'new groups' at a later date. Hence it # won't appear until you do a '-a' after some articles have appeared. -# +# # I should really keep a list of ignored empty groups and re-check them # for articles on every run, but I haven't got around to it yet. # # This assumes an NNTP news feed. # -# Feel free to copy, distribute and modify this code for -# non-commercial use. If you make any useful modifications, let me +# Feel free to copy, distribute and modify this code for +# non-commercial use. If you make any useful modifications, let me # know! # # (c) Quentin Stafford-Fraser 1994 @@ -42,9 +42,9 @@ import sys,nntplib, string, marshal, time, os, posix, string topdir='/anfs/qsbigdisc/web/html/newspage' # The name of your NNTP host -# eg. +# eg. # newshost = 'nntp-serv.cl.cam.ac.uk' -# or use following to get the name from the NNTPSERVER environment +# or use following to get the name from the NNTPSERVER environment # variable: # newshost = posix.environ['NNTPSERVER'] newshost = 'nntp-serv.cl.cam.ac.uk' @@ -60,17 +60,17 @@ descfile = 'newsgroups' # The directory in which HTML pages should be created # eg. # pagedir = '/usr/local/lib/html/newspage' -# pagedir = 'pages' +# pagedir = 'pages' pagedir = topdir # The html prefix which will refer to this directory -# eg. -# httppref = '/newspage/', +# eg. +# httppref = '/newspage/', # or leave blank for relative links between pages: (Recommended) # httppref = '' httppref = '' -# The name of the 'root' news page in this directory. +# The name of the 'root' news page in this directory. # A .html suffix will be added. rootpage = 'root' @@ -88,7 +88,7 @@ pagelinkicon='... <img src="http://pelican.cl.cam.ac.uk/icons/page.xbm"> ' # Sublistsize controls the maximum number of items the will appear as # an indented sub-list before the whole thing is moved onto a different -# page. The smaller this is, the more pages you will have, but the +# page. The smaller this is, the more pages you will have, but the # shorter each will be. sublistsize = 4 @@ -118,246 +118,246 @@ page = os.path.join(topdir,pagedir) # Addtotree creates/augments a tree from a list of group names def addtotree(tree, groups): - print 'Updating tree...' - for i in groups: + print 'Updating tree...' + for i in groups: parts = string.splitfields(i,'.') makeleaf(tree, parts) # Makeleaf makes a leaf and the branch leading to it if necessary def makeleaf(tree,path): - j = path[0] - l = len(path) + j = path[0] + l = len(path) - if not tree.has_key(j): - tree[j] = {} - if l == 1: - tree[j]['.'] = '.' - if l > 1: - makeleaf(tree[j],path[1:]) + if not tree.has_key(j): + tree[j] = {} + if l == 1: + tree[j]['.'] = '.' + if l > 1: + makeleaf(tree[j],path[1:]) -# Then the bits for outputting trees as pages ---------------- +# Then the bits for outputting trees as pages ---------------- # Createpage creates an HTML file named <root>.html containing links # to those groups beginning with <root>. def createpage(root, tree, p): - filename = os.path.join(pagedir,root+'.html') - if root == rootpage: - detail = '' - else: - detail = ' under ' + root - f = open(filename,'w') - # f.write('Content-Type: text/html\n') - f.write('<TITLE>Newsgroups available' + detail + '</TITLE>\n') - f.write('<H1>Newsgroups available' + detail +'</H1>\n') - f.write('<A HREF="'+httppref+rootpage+'.html">Back to top level</A><P>\n') - printtree(f,tree,0,p) - f.write('<I>This page automatically created by \'newslist\' v. '+rcsrev+'.') - f.write(time.ctime(time.time()) + '</I><P>') - f.close() + filename = os.path.join(pagedir,root+'.html') + if root == rootpage: + detail = '' + else: + detail = ' under ' + root + f = open(filename,'w') + # f.write('Content-Type: text/html\n') + f.write('<TITLE>Newsgroups available' + detail + '</TITLE>\n') + f.write('<H1>Newsgroups available' + detail +'</H1>\n') + f.write('<A HREF="'+httppref+rootpage+'.html">Back to top level</A><P>\n') + printtree(f,tree,0,p) + f.write('<I>This page automatically created by \'newslist\' v. '+rcsrev+'.') + f.write(time.ctime(time.time()) + '</I><P>') + f.close() # Printtree prints the groups as a bulleted list. Groups with # more than <sublistsize> subgroups will be put on a separate page. # Other sets of subgroups are just indented. def printtree(f, tree, indent, p): - global desc - l = len(tree) - - if l > sublistsize and indent>0: - # Create a new page and a link to it - f.write('<LI><B><A HREF="'+httppref+p[1:]+'.html">') - f.write(p[1:]+'.*') - f.write('</A></B>'+pagelinkicon+'\n') - createpage(p[1:], tree, p) - return - - kl = tree.keys() - - if l > 1: - kl.sort() - if indent > 0: - # Create a sub-list - f.write('<LI>'+p[1:]+'\n<UL>') - else: - # Create a main list - f.write('<UL>') - indent = indent + 1 - - for i in kl: - if i == '.': - # Output a newsgroup - f.write('<LI><A HREF="news:' + p[1:] + '">'+ p[1:] + '</A> ') - if desc.has_key(p[1:]): - f.write(' <I>'+desc[p[1:]]+'</I>\n') - else: - f.write('\n') - else: - # Output a hierarchy - printtree(f,tree[i], indent, p+'.'+i) - - if l > 1: - f.write('\n</UL>') + global desc + l = len(tree) + + if l > sublistsize and indent>0: + # Create a new page and a link to it + f.write('<LI><B><A HREF="'+httppref+p[1:]+'.html">') + f.write(p[1:]+'.*') + f.write('</A></B>'+pagelinkicon+'\n') + createpage(p[1:], tree, p) + return + + kl = tree.keys() + + if l > 1: + kl.sort() + if indent > 0: + # Create a sub-list + f.write('<LI>'+p[1:]+'\n<UL>') + else: + # Create a main list + f.write('<UL>') + indent = indent + 1 + + for i in kl: + if i == '.': + # Output a newsgroup + f.write('<LI><A HREF="news:' + p[1:] + '">'+ p[1:] + '</A> ') + if desc.has_key(p[1:]): + f.write(' <I>'+desc[p[1:]]+'</I>\n') + else: + f.write('\n') + else: + # Output a hierarchy + printtree(f,tree[i], indent, p+'.'+i) + + if l > 1: + f.write('\n</UL>') # Reading descriptions file --------------------------------------- # This returns an array mapping group name to its description def readdesc(descfile): - global desc + global desc - desc = {} + desc = {} - if descfile == '': + if descfile == '': return - try: - d = open(descfile, 'r') - print 'Reading descriptions...' - except (IOError): - print 'Failed to open description file ' + descfile - return - l = d.readline() - while l != '': - bits = string.split(l) - try: - grp = bits[0] - dsc = string.join(bits[1:]) - if len(dsc)>1: - desc[grp] = dsc - except (IndexError): - pass - l = d.readline() + try: + d = open(descfile, 'r') + print 'Reading descriptions...' + except (IOError): + print 'Failed to open description file ' + descfile + return + l = d.readline() + while l != '': + bits = string.split(l) + try: + grp = bits[0] + dsc = string.join(bits[1:]) + if len(dsc)>1: + desc[grp] = dsc + except (IndexError): + pass + l = d.readline() # Check that ouput directory exists, ------------------------------ # and offer to create it if not def checkopdir(pagedir): - if not os.path.isdir(pagedir): - print 'Directory '+pagedir+' does not exist.' - print 'Shall I create it for you? (y/n)' - if sys.stdin.readline()[0] == 'y': - try: - os.mkdir(pagedir,0777) - except: - print 'Sorry - failed!' + if not os.path.isdir(pagedir): + print 'Directory '+pagedir+' does not exist.' + print 'Shall I create it for you? (y/n)' + if sys.stdin.readline()[0] == 'y': + try: + os.mkdir(pagedir,0777) + except: + print 'Sorry - failed!' + sys.exit(1) + else: + print 'OK. Exiting.' sys.exit(1) - else: - print 'OK. Exiting.' - sys.exit(1) # Read and write current local tree ---------------------------------- def readlocallist(treefile): - print 'Reading current local group list...' - tree = {} - try: - treetime = time.localtime(os.stat(treefile)[ST_MTIME]) - except: - print '\n*** Failed to open local group cache '+treefile - print 'If this is the first time you have run newslist, then' - print 'use the -a option to create it.' - sys.exit(1) - treedate = '%02d%02d%02d' % (treetime[0] % 100 ,treetime[1], treetime[2]) - try: - dump = open(treefile,'r') - tree = marshal.load(dump) - dump.close() - except (IOError): - print 'Cannot open local group list ' + treefile - return (tree, treedate) + print 'Reading current local group list...' + tree = {} + try: + treetime = time.localtime(os.stat(treefile)[ST_MTIME]) + except: + print '\n*** Failed to open local group cache '+treefile + print 'If this is the first time you have run newslist, then' + print 'use the -a option to create it.' + sys.exit(1) + treedate = '%02d%02d%02d' % (treetime[0] % 100 ,treetime[1], treetime[2]) + try: + dump = open(treefile,'r') + tree = marshal.load(dump) + dump.close() + except (IOError): + print 'Cannot open local group list ' + treefile + return (tree, treedate) def writelocallist(treefile, tree): - try: - dump = open(treefile,'w') - groups = marshal.dump(tree,dump) - dump.close() - print 'Saved list to '+treefile+'\n' - except: - print 'Sorry - failed to write to local group cache '+treefile - print 'Does it (or its directory) have the correct permissions?' - sys.exit(1) + try: + dump = open(treefile,'w') + groups = marshal.dump(tree,dump) + dump.close() + print 'Saved list to '+treefile+'\n' + except: + print 'Sorry - failed to write to local group cache '+treefile + print 'Does it (or its directory) have the correct permissions?' + sys.exit(1) # Return list of all groups on server ----------------------------- def getallgroups(server): - print 'Getting list of all groups...' - treedate='010101' - info = server.list()[1] - groups = [] - print 'Processing...' - if skipempty: - print '\nIgnoring following empty groups:' - for i in info: - grpname = string.split(i[0])[0] - if skipempty and string.atoi(i[1]) < string.atoi(i[2]): - print grpname+' ', - else: - groups.append(grpname) - print '\n' - if skipempty: - print '(End of empty groups)' - return groups + print 'Getting list of all groups...' + treedate='010101' + info = server.list()[1] + groups = [] + print 'Processing...' + if skipempty: + print '\nIgnoring following empty groups:' + for i in info: + grpname = string.split(i[0])[0] + if skipempty and string.atoi(i[1]) < string.atoi(i[2]): + print grpname+' ', + else: + groups.append(grpname) + print '\n' + if skipempty: + print '(End of empty groups)' + return groups # Return list of new groups on server ----------------------------- def getnewgroups(server, treedate): - print 'Getting list of new groups since start of '+treedate+'...', - info = server.newgroups(treedate,'000001')[1] - print 'got %d.' % len(info) - print 'Processing...', - groups = [] - for i in info: - grpname = string.split(i)[0] - groups.append(grpname) - print 'Done' - return groups + print 'Getting list of new groups since start of '+treedate+'...', + info = server.newgroups(treedate,'000001')[1] + print 'got %d.' % len(info) + print 'Processing...', + groups = [] + for i in info: + grpname = string.split(i)[0] + groups.append(grpname) + print 'Done' + return groups # Now the main program -------------------------------------------- def main(): - global desc - - tree={} - - # Check that the output directory exists - checkopdir(pagedir); - - try: - print 'Connecting to '+newshost+'...' - if sys.version[0] == '0': - s = NNTP.init(newshost) - else: - s = NNTP(newshost) - connected = 1 - except (nntplib.error_temp, nntplib.error_perm), x: - print 'Error connecting to host:', x - print 'I\'ll try to use just the local list.' - connected = 0 - - # If -a is specified, read the full list of groups from server - if connected and len(sys.argv) > 1 and sys.argv[1] == '-a': - - groups = getallgroups(s) - - # Otherwise just read the local file and then add - # groups created since local file last modified. - else: - - (tree, treedate) = readlocallist(treefile) - if connected: - groups = getnewgroups(s, treedate) - - if connected: - addtotree(tree, groups) - writelocallist(treefile,tree) - - # Read group descriptions - readdesc(descfile) - - print 'Creating pages...' - createpage(rootpage, tree, '') - print 'Done' + global desc + + tree={} + + # Check that the output directory exists + checkopdir(pagedir); + + try: + print 'Connecting to '+newshost+'...' + if sys.version[0] == '0': + s = NNTP.init(newshost) + else: + s = NNTP(newshost) + connected = 1 + except (nntplib.error_temp, nntplib.error_perm), x: + print 'Error connecting to host:', x + print 'I\'ll try to use just the local list.' + connected = 0 + + # If -a is specified, read the full list of groups from server + if connected and len(sys.argv) > 1 and sys.argv[1] == '-a': + + groups = getallgroups(s) + + # Otherwise just read the local file and then add + # groups created since local file last modified. + else: + + (tree, treedate) = readlocallist(treefile) + if connected: + groups = getnewgroups(s, treedate) + + if connected: + addtotree(tree, groups) + writelocallist(treefile,tree) + + # Read group descriptions + readdesc(descfile) + + print 'Creating pages...' + createpage(rootpage, tree, '') + print 'Done' main() diff --git a/Demo/scripts/pp.py b/Demo/scripts/pp.py index 92a1104..0491fa9 100755 --- a/Demo/scripts/pp.py +++ b/Demo/scripts/pp.py @@ -34,89 +34,89 @@ NFLAG = 0 PFLAG = 0 try: - optlist, ARGS = getopt.getopt(sys.argv[1:], 'acde:F:np') + optlist, ARGS = getopt.getopt(sys.argv[1:], 'acde:F:np') except getopt.error, msg: - sys.stderr.write(sys.argv[0] + ': ' + msg + '\n') - sys.exit(2) + sys.stderr.write(sys.argv[0] + ': ' + msg + '\n') + sys.exit(2) for option, optarg in optlist: - if option == '-a': - AFLAG = 1 - elif option == '-c': - CFLAG = 1 - elif option == '-d': - DFLAG = 1 - elif option == '-e': - for line in string.splitfields(optarg, '\n'): - SCRIPT.append(line) - elif option == '-F': - FS = optarg - elif option == '-n': - NFLAG = 1 - PFLAG = 0 - elif option == '-p': - NFLAG = 1 - PFLAG = 1 - else: - print option, 'not recognized???' + if option == '-a': + AFLAG = 1 + elif option == '-c': + CFLAG = 1 + elif option == '-d': + DFLAG = 1 + elif option == '-e': + for line in string.splitfields(optarg, '\n'): + SCRIPT.append(line) + elif option == '-F': + FS = optarg + elif option == '-n': + NFLAG = 1 + PFLAG = 0 + elif option == '-p': + NFLAG = 1 + PFLAG = 1 + else: + print option, 'not recognized???' if not ARGS: ARGS.append('-') if not SCRIPT: - if ARGS[0] == '-': - fp = sys.stdin - else: - fp = open(ARGS[0], 'r') - while 1: - line = fp.readline() - if not line: break - SCRIPT.append(line[:-1]) - del fp - del ARGS[0] - if not ARGS: ARGS.append('-') + if ARGS[0] == '-': + fp = sys.stdin + else: + fp = open(ARGS[0], 'r') + while 1: + line = fp.readline() + if not line: break + SCRIPT.append(line[:-1]) + del fp + del ARGS[0] + if not ARGS: ARGS.append('-') if CFLAG: - prologue = ['if 0:'] - epilogue = [] + prologue = ['if 0:'] + epilogue = [] elif NFLAG: - # Note that it is on purpose that AFLAG and PFLAG are - # tested dynamically each time through the loop - prologue = [ \ - 'LINECOUNT = 0', \ - 'for FILE in ARGS:', \ - ' \tif FILE == \'-\':', \ - ' \t \tFP = sys.stdin', \ - ' \telse:', \ - ' \t \tFP = open(FILE, \'r\')', \ - ' \tLINENO = 0', \ - ' \twhile 1:', \ - ' \t \tLINE = FP.readline()', \ - ' \t \tif not LINE: break', \ - ' \t \tLINENO = LINENO + 1', \ - ' \t \tLINECOUNT = LINECOUNT + 1', \ - ' \t \tL = LINE[:-1]', \ - ' \t \taflag = AFLAG', \ - ' \t \tif aflag:', \ - ' \t \t \tif FS: F = string.splitfields(L, FS)', \ - ' \t \t \telse: F = string.split(L)' \ - ] - epilogue = [ \ - ' \t \tif not PFLAG: continue', \ - ' \t \tif aflag:', \ - ' \t \t \tif FS: print string.joinfields(F, FS)', \ - ' \t \t \telse: print string.join(F)', \ - ' \t \telse: print L', \ - ] + # Note that it is on purpose that AFLAG and PFLAG are + # tested dynamically each time through the loop + prologue = [ \ + 'LINECOUNT = 0', \ + 'for FILE in ARGS:', \ + ' \tif FILE == \'-\':', \ + ' \t \tFP = sys.stdin', \ + ' \telse:', \ + ' \t \tFP = open(FILE, \'r\')', \ + ' \tLINENO = 0', \ + ' \twhile 1:', \ + ' \t \tLINE = FP.readline()', \ + ' \t \tif not LINE: break', \ + ' \t \tLINENO = LINENO + 1', \ + ' \t \tLINECOUNT = LINECOUNT + 1', \ + ' \t \tL = LINE[:-1]', \ + ' \t \taflag = AFLAG', \ + ' \t \tif aflag:', \ + ' \t \t \tif FS: F = string.splitfields(L, FS)', \ + ' \t \t \telse: F = string.split(L)' \ + ] + epilogue = [ \ + ' \t \tif not PFLAG: continue', \ + ' \t \tif aflag:', \ + ' \t \t \tif FS: print string.joinfields(F, FS)', \ + ' \t \t \telse: print string.join(F)', \ + ' \t \telse: print L', \ + ] else: - prologue = ['if 1:'] - epilogue = [] + prologue = ['if 1:'] + epilogue = [] # Note that we indent using tabs only, so that any indentation style # used in 'command' will come out right after re-indentation. program = string.joinfields(prologue, '\n') + '\n' for line in SCRIPT: - program = program + (' \t \t' + line + '\n') + program = program + (' \t \t' + line + '\n') program = program + (string.joinfields(epilogue, '\n') + '\n') import tempfile @@ -124,7 +124,7 @@ fp = tempfile.NamedTemporaryFile() fp.write(program) fp.flush() if DFLAG: - import pdb - pdb.run('execfile(%r)' % (tfn,)) + import pdb + pdb.run('execfile(%r)' % (tfn,)) else: - execfile(tfn) + execfile(tfn) diff --git a/Demo/scripts/primes.py b/Demo/scripts/primes.py index 477c57b..00eb05f 100755 --- a/Demo/scripts/primes.py +++ b/Demo/scripts/primes.py @@ -3,24 +3,24 @@ # Print prime numbers in a given range def main(): - import sys - min, max = 2, 0x7fffffff - if sys.argv[1:]: - min = int(eval(sys.argv[1])) - if sys.argv[2:]: - max = int(eval(sys.argv[2])) - primes(min, max) + import sys + min, max = 2, 0x7fffffff + if sys.argv[1:]: + min = int(eval(sys.argv[1])) + if sys.argv[2:]: + max = int(eval(sys.argv[2])) + primes(min, max) def primes(min, max): - if 2 >= min: print 2 - primes = [2] - i = 3 - while i <= max: - for p in primes: - if i%p == 0 or p*p > i: break - if i%p <> 0: - primes.append(i) - if i >= min: print i - i = i+2 + if 2 >= min: print 2 + primes = [2] + i = 3 + while i <= max: + for p in primes: + if i%p == 0 or p*p > i: break + if i%p <> 0: + primes.append(i) + if i >= min: print i + i = i+2 main() diff --git a/Demo/scripts/script.py b/Demo/scripts/script.py index cbad367..6eaa7ae 100755 --- a/Demo/scripts/script.py +++ b/Demo/scripts/script.py @@ -1,8 +1,8 @@ #! /usr/bin/env python # script.py -- Make typescript of terminal session. # Usage: -# -a Append to typescript. -# -p Use Python as shell. +# -a Append to typescript. +# -p Use Python as shell. # Author: Steen Lumholt. @@ -10,19 +10,19 @@ import os, time, sys import pty def read(fd): - data = os.read(fd, 1024) - file.write(data) - return data + data = os.read(fd, 1024) + file.write(data) + return data shell = 'sh' filename = 'typescript' mode = 'w' if os.environ.has_key('SHELL'): - shell = os.environ['SHELL'] + shell = os.environ['SHELL'] if '-a' in sys.argv: - mode = 'a' + mode = 'a' if '-p' in sys.argv: - shell = 'python' + shell = 'python' file = open(filename, mode) diff --git a/Demo/scripts/update.py b/Demo/scripts/update.py index 2db65dc..67a0783 100755 --- a/Demo/scripts/update.py +++ b/Demo/scripts/update.py @@ -4,7 +4,7 @@ # The input file contains lines of the form <filename>:<lineno>:<text>, # meaning that the given line of the given file is to be replaced # by the given text. This is useful for performing global substitutions -# on grep output: +# on grep output: import os import sys @@ -14,78 +14,78 @@ pat = '^\([^: \t\n]+\):\([1-9][0-9]*\):' prog = regex.compile(pat) class FileObj: - def __init__(self, filename): - self.filename = filename - self.changed = 0 - try: - self.lines = open(filename, 'r').readlines() - except IOError, msg: - print '*** Can\'t open "%s":' % filename, msg - self.lines = None - return - print 'diffing', self.filename + def __init__(self, filename): + self.filename = filename + self.changed = 0 + try: + self.lines = open(filename, 'r').readlines() + except IOError, msg: + print '*** Can\'t open "%s":' % filename, msg + self.lines = None + return + print 'diffing', self.filename - def finish(self): - if not self.changed: - print 'no changes to', self.filename - return - try: - os.rename(self.filename, self.filename + '~') - fp = open(self.filename, 'w') - except (os.error, IOError), msg: - print '*** Can\'t rewrite "%s":' % self.filename, msg - return - print 'writing', self.filename - for line in self.lines: - fp.write(line) - fp.close() - self.changed = 0 + def finish(self): + if not self.changed: + print 'no changes to', self.filename + return + try: + os.rename(self.filename, self.filename + '~') + fp = open(self.filename, 'w') + except (os.error, IOError), msg: + print '*** Can\'t rewrite "%s":' % self.filename, msg + return + print 'writing', self.filename + for line in self.lines: + fp.write(line) + fp.close() + self.changed = 0 - def process(self, lineno, rest): - if self.lines is None: - print '(not processed): %s:%s:%s' % ( - self.filename, lineno, rest), - return - i = eval(lineno) - 1 - if not 0 <= i < len(self.lines): - print '*** Line number out of range: %s:%s:%s' % ( - self.filename, lineno, rest), - return - if self.lines[i] == rest: - print '(no change): %s:%s:%s' % ( - self.filename, lineno, rest), - return - if not self.changed: - self.changed = 1 - print '%sc%s' % (lineno, lineno) - print '<', self.lines[i], - print '---' - self.lines[i] = rest - print '>', self.lines[i], + def process(self, lineno, rest): + if self.lines is None: + print '(not processed): %s:%s:%s' % ( + self.filename, lineno, rest), + return + i = eval(lineno) - 1 + if not 0 <= i < len(self.lines): + print '*** Line number out of range: %s:%s:%s' % ( + self.filename, lineno, rest), + return + if self.lines[i] == rest: + print '(no change): %s:%s:%s' % ( + self.filename, lineno, rest), + return + if not self.changed: + self.changed = 1 + print '%sc%s' % (lineno, lineno) + print '<', self.lines[i], + print '---' + self.lines[i] = rest + print '>', self.lines[i], def main(): - if sys.argv[1:]: - try: - fp = open(sys.argv[1], 'r') - except IOError, msg: - print 'Can\'t open "%s":' % sys.argv[1], msg - sys.exit(1) - else: - fp = sys.stdin - curfile = None - while 1: - line = fp.readline() - if not line: - if curfile: curfile.finish() - break - n = prog.match(line) - if n < 0: - print 'Funny line:', line, - continue - filename, lineno = prog.group(1, 2) - if not curfile or filename <> curfile.filename: - if curfile: curfile.finish() - curfile = FileObj(filename) - curfile.process(lineno, line[n:]) + if sys.argv[1:]: + try: + fp = open(sys.argv[1], 'r') + except IOError, msg: + print 'Can\'t open "%s":' % sys.argv[1], msg + sys.exit(1) + else: + fp = sys.stdin + curfile = None + while 1: + line = fp.readline() + if not line: + if curfile: curfile.finish() + break + n = prog.match(line) + if n < 0: + print 'Funny line:', line, + continue + filename, lineno = prog.group(1, 2) + if not curfile or filename <> curfile.filename: + if curfile: curfile.finish() + curfile = FileObj(filename) + curfile.process(lineno, line[n:]) main() diff --git a/Demo/sockets/broadcast.py b/Demo/sockets/broadcast.py index 010162c..6d2b1e8 100755 --- a/Demo/sockets/broadcast.py +++ b/Demo/sockets/broadcast.py @@ -10,8 +10,6 @@ s.bind(('', 0)) s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) while 1: - data = repr(time.time()) + '\n' - s.sendto(data, ('<broadcast>', MYPORT)) - time.sleep(2) - - + data = repr(time.time()) + '\n' + s.sendto(data, ('<broadcast>', MYPORT)) + time.sleep(2) diff --git a/Demo/sockets/echosvr.py b/Demo/sockets/echosvr.py index a37f9c2..f8a9623 100755 --- a/Demo/sockets/echosvr.py +++ b/Demo/sockets/echosvr.py @@ -13,19 +13,19 @@ ECHO_PORT = 50000 + 7 BUFSIZE = 1024 def main(): - if len(sys.argv) > 1: - port = int(eval(sys.argv[1])) - else: - port = ECHO_PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - conn, (remotehost, remoteport) = s.accept() - print 'connected by', remotehost, remoteport - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - conn.send(data) + if len(sys.argv) > 1: + port = int(eval(sys.argv[1])) + else: + port = ECHO_PORT + s = socket(AF_INET, SOCK_STREAM) + s.bind(('', port)) + s.listen(1) + conn, (remotehost, remoteport) = s.accept() + print 'connected by', remotehost, remoteport + while 1: + data = conn.recv(BUFSIZE) + if not data: + break + conn.send(data) main() diff --git a/Demo/sockets/finger.py b/Demo/sockets/finger.py index 0c2baed..e8b9ed2 100755 --- a/Demo/sockets/finger.py +++ b/Demo/sockets/finger.py @@ -22,35 +22,35 @@ FINGER_PORT = 79 # Output goes directly to stdout (although this can be changed). # def finger(host, args): - s = socket(AF_INET, SOCK_STREAM) - s.connect((host, FINGER_PORT)) - s.send(args + '\n') - while 1: - buf = s.recv(1024) - if not buf: break - sys.stdout.write(buf) - sys.stdout.flush() + s = socket(AF_INET, SOCK_STREAM) + s.connect((host, FINGER_PORT)) + s.send(args + '\n') + while 1: + buf = s.recv(1024) + if not buf: break + sys.stdout.write(buf) + sys.stdout.flush() # Main function: argument parsing. # def main(): - options = '' - i = 1 - while i < len(sys.argv) and sys.argv[i][:1] == '-': - options = options + sys.argv[i] + ' ' - i = i+1 - args = sys.argv[i:] - if not args: - args = [''] - for arg in args: - if '@' in arg: - at = string.index(arg, '@') - host = arg[at+1:] - arg = arg[:at] - else: - host = '' - finger(host, options + arg) + options = '' + i = 1 + while i < len(sys.argv) and sys.argv[i][:1] == '-': + options = options + sys.argv[i] + ' ' + i = i+1 + args = sys.argv[i:] + if not args: + args = [''] + for arg in args: + if '@' in arg: + at = string.index(arg, '@') + host = arg[at+1:] + arg = arg[:at] + else: + host = '' + finger(host, options + arg) # Call the main function. diff --git a/Demo/sockets/ftp.py b/Demo/sockets/ftp.py index 9e1d5a1..6e9282a 100755 --- a/Demo/sockets/ftp.py +++ b/Demo/sockets/ftp.py @@ -37,35 +37,35 @@ FTP_DATA_PORT = FTP_DATA_PORT + 50000 # Main program (called at the end of this file). # def main(): - hostname = sys.argv[1] - control(hostname) + hostname = sys.argv[1] + control(hostname) # Control process (user interface and user protocol interpreter). # def control(hostname): - # - # Create control connection - # - s = socket(AF_INET, SOCK_STREAM) - s.connect((hostname, FTP_PORT)) - f = s.makefile('r') # Reading the replies is easier from a file... - # - # Control loop - # - r = None - while 1: - code = getreply(f) - if code in ('221', 'EOF'): break - if code == '150': - getdata(r) - code = getreply(f) - r = None - if not r: - r = newdataport(s, f) - cmd = getcommand() - if not cmd: break - s.send(cmd + '\r\n') + # + # Create control connection + # + s = socket(AF_INET, SOCK_STREAM) + s.connect((hostname, FTP_PORT)) + f = s.makefile('r') # Reading the replies is easier from a file... + # + # Control loop + # + r = None + while 1: + code = getreply(f) + if code in ('221', 'EOF'): break + if code == '150': + getdata(r) + code = getreply(f) + r = None + if not r: + r = newdataport(s, f) + cmd = getcommand() + if not cmd: break + s.send(cmd + '\r\n') # Create a new data port and send a PORT command to the server for it. @@ -75,27 +75,27 @@ def control(hostname): nextport = 0 # def newdataport(s, f): - global nextport - port = nextport + FTP_DATA_PORT - nextport = (nextport+1) % 16 - r = socket(AF_INET, SOCK_STREAM) - r.bind((gethostbyname(gethostname()), port)) - r.listen(1) - sendportcmd(s, f, port) - return r + global nextport + port = nextport + FTP_DATA_PORT + nextport = (nextport+1) % 16 + r = socket(AF_INET, SOCK_STREAM) + r.bind((gethostbyname(gethostname()), port)) + r.listen(1) + sendportcmd(s, f, port) + return r # Send an appropriate port command. # def sendportcmd(s, f, port): - hostname = gethostname() - hostaddr = gethostbyname(hostname) - hbytes = string.splitfields(hostaddr, '.') - pbytes = [repr(port/256), repr(port%256)] - bytes = hbytes + pbytes - cmd = 'PORT ' + string.joinfields(bytes, ',') - s.send(cmd + '\r\n') - code = getreply(f) + hostname = gethostname() + hostaddr = gethostbyname(hostname) + hbytes = string.splitfields(hostaddr, '.') + pbytes = [repr(port/256), repr(port%256)] + bytes = hbytes + pbytes + cmd = 'PORT ' + string.joinfields(bytes, ',') + s.send(cmd + '\r\n') + code = getreply(f) # Process an ftp reply and return the 3-digit reply code (as a string). @@ -105,40 +105,40 @@ def sendportcmd(s, f, port): # Any text while receiving the reply is echoed to the file. # def getreply(f): - line = f.readline() - if not line: return 'EOF' - print line, - code = line[:3] - if line[3:4] == '-': - while 1: - line = f.readline() - if not line: break # Really an error - print line, - if line[:3] == code and line[3:4] != '-': break - return code + line = f.readline() + if not line: return 'EOF' + print line, + code = line[:3] + if line[3:4] == '-': + while 1: + line = f.readline() + if not line: break # Really an error + print line, + if line[:3] == code and line[3:4] != '-': break + return code # Get the data from the data connection. # def getdata(r): - print '(accepting data connection)' - conn, host = r.accept() - print '(data connection accepted)' - while 1: - data = conn.recv(BUFSIZE) - if not data: break - sys.stdout.write(data) - print '(end of data connection)' + print '(accepting data connection)' + conn, host = r.accept() + print '(data connection accepted)' + while 1: + data = conn.recv(BUFSIZE) + if not data: break + sys.stdout.write(data) + print '(end of data connection)' # Get a command from the user. # def getcommand(): - try: - while 1: - line = raw_input('ftp.py> ') - if line: return line - except EOFError: - return '' + try: + while 1: + line = raw_input('ftp.py> ') + if line: return line + except EOFError: + return '' # Call the main program. diff --git a/Demo/sockets/gopher.py b/Demo/sockets/gopher.py index 4e1cb30..cd76659 100755 --- a/Demo/sockets/gopher.py +++ b/Demo/sockets/gopher.py @@ -30,8 +30,8 @@ T_SOUND = 's' # Dictionary mapping types to strings typename = {'0': '<TEXT>', '1': '<DIR>', '2': '<CSO>', '3': '<ERROR>', \ - '4': '<BINHEX>', '5': '<DOS>', '6': '<UUENCODE>', '7': '<SEARCH>', \ - '8': '<TELNET>', '9': '<BINARY>', '+': '<REDUNDANT>', 's': '<SOUND>'} + '4': '<BINHEX>', '5': '<DOS>', '6': '<UUENCODE>', '7': '<SEARCH>', \ + '8': '<TELNET>', '9': '<BINARY>', '+': '<REDUNDANT>', 's': '<SOUND>'} # Oft-used characters and strings CRLF = '\r\n' @@ -39,309 +39,309 @@ TAB = '\t' # Open a TCP connection to a given host and port def open_socket(host, port): - if not port: - port = DEF_PORT - elif type(port) == type(''): - port = string.atoi(port) - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((host, port)) - return s + if not port: + port = DEF_PORT + elif type(port) == type(''): + port = string.atoi(port) + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect((host, port)) + return s # Send a selector to a given host and port, return a file with the reply def send_request(selector, host, port): - s = open_socket(host, port) - s.send(selector + CRLF) - s.shutdown(1) - return s.makefile('r') + s = open_socket(host, port) + s.send(selector + CRLF) + s.shutdown(1) + return s.makefile('r') # Get a menu in the form of a list of entries def get_menu(selector, host, port): - f = send_request(selector, host, port) - list = [] - while 1: - line = f.readline() - if not line: - print '(Unexpected EOF from server)' - break - if line[-2:] == CRLF: - line = line[:-2] - elif line[-1:] in CRLF: - line = line[:-1] - if line == '.': - break - if not line: - print '(Empty line from server)' - continue - typechar = line[0] - parts = string.splitfields(line[1:], TAB) - if len(parts) < 4: - print '(Bad line from server: %r)' % (line,) - continue - if len(parts) > 4: - print '(Extra info from server: %r)' % (parts[4:],) - parts.insert(0, typechar) - list.append(parts) - f.close() - return list + f = send_request(selector, host, port) + list = [] + while 1: + line = f.readline() + if not line: + print '(Unexpected EOF from server)' + break + if line[-2:] == CRLF: + line = line[:-2] + elif line[-1:] in CRLF: + line = line[:-1] + if line == '.': + break + if not line: + print '(Empty line from server)' + continue + typechar = line[0] + parts = string.splitfields(line[1:], TAB) + if len(parts) < 4: + print '(Bad line from server: %r)' % (line,) + continue + if len(parts) > 4: + print '(Extra info from server: %r)' % (parts[4:],) + parts.insert(0, typechar) + list.append(parts) + f.close() + return list # Get a text file as a list of lines, with trailing CRLF stripped def get_textfile(selector, host, port): - list = [] - get_alt_textfile(selector, host, port, list.append) - return list + list = [] + get_alt_textfile(selector, host, port, list.append) + return list # Get a text file and pass each line to a function, with trailing CRLF stripped def get_alt_textfile(selector, host, port, func): - f = send_request(selector, host, port) - while 1: - line = f.readline() - if not line: - print '(Unexpected EOF from server)' - break - if line[-2:] == CRLF: - line = line[:-2] - elif line[-1:] in CRLF: - line = line[:-1] - if line == '.': - break - if line[:2] == '..': - line = line[1:] - func(line) - f.close() + f = send_request(selector, host, port) + while 1: + line = f.readline() + if not line: + print '(Unexpected EOF from server)' + break + if line[-2:] == CRLF: + line = line[:-2] + elif line[-1:] in CRLF: + line = line[:-1] + if line == '.': + break + if line[:2] == '..': + line = line[1:] + func(line) + f.close() # Get a binary file as one solid data block def get_binary(selector, host, port): - f = send_request(selector, host, port) - data = f.read() - f.close() - return data + f = send_request(selector, host, port) + data = f.read() + f.close() + return data # Get a binary file and pass each block to a function def get_alt_binary(selector, host, port, func, blocksize): - f = send_request(selector, host, port) - while 1: - data = f.read(blocksize) - if not data: - break - func(data) + f = send_request(selector, host, port) + while 1: + data = f.read(blocksize) + if not data: + break + func(data) # A *very* simple interactive browser # Browser main command, has default arguments def browser(*args): - selector = DEF_SELECTOR - host = DEF_HOST - port = DEF_PORT - n = len(args) - if n > 0 and args[0]: - selector = args[0] - if n > 1 and args[1]: - host = args[1] - if n > 2 and args[2]: - port = args[2] - if n > 3: - raise RuntimeError, 'too many args' - try: - browse_menu(selector, host, port) - except socket.error, msg: - print 'Socket error:', msg - sys.exit(1) - except KeyboardInterrupt: - print '\n[Goodbye]' + selector = DEF_SELECTOR + host = DEF_HOST + port = DEF_PORT + n = len(args) + if n > 0 and args[0]: + selector = args[0] + if n > 1 and args[1]: + host = args[1] + if n > 2 and args[2]: + port = args[2] + if n > 3: + raise RuntimeError, 'too many args' + try: + browse_menu(selector, host, port) + except socket.error, msg: + print 'Socket error:', msg + sys.exit(1) + except KeyboardInterrupt: + print '\n[Goodbye]' # Browse a menu def browse_menu(selector, host, port): - list = get_menu(selector, host, port) - while 1: - print '----- MENU -----' - print 'Selector:', repr(selector) - print 'Host:', host, ' Port:', port - print - for i in range(len(list)): - item = list[i] - typechar, description = item[0], item[1] - print string.rjust(repr(i+1), 3) + ':', description, - if typename.has_key(typechar): - print typename[typechar] - else: - print '<TYPE=' + repr(typechar) + '>' - print - while 1: - try: - str = raw_input('Choice [CR == up a level]: ') - except EOFError: - print - return - if not str: - return - try: - choice = string.atoi(str) - except string.atoi_error: - print 'Choice must be a number; try again:' - continue - if not 0 < choice <= len(list): - print 'Choice out of range; try again:' - continue - break - item = list[choice-1] - typechar = item[0] - [i_selector, i_host, i_port] = item[2:5] - if typebrowser.has_key(typechar): - browserfunc = typebrowser[typechar] - try: - browserfunc(i_selector, i_host, i_port) - except (IOError, socket.error): - print '***', sys.exc_type, ':', sys.exc_value - else: - print 'Unsupported object type' + list = get_menu(selector, host, port) + while 1: + print '----- MENU -----' + print 'Selector:', repr(selector) + print 'Host:', host, ' Port:', port + print + for i in range(len(list)): + item = list[i] + typechar, description = item[0], item[1] + print string.rjust(repr(i+1), 3) + ':', description, + if typename.has_key(typechar): + print typename[typechar] + else: + print '<TYPE=' + repr(typechar) + '>' + print + while 1: + try: + str = raw_input('Choice [CR == up a level]: ') + except EOFError: + print + return + if not str: + return + try: + choice = string.atoi(str) + except string.atoi_error: + print 'Choice must be a number; try again:' + continue + if not 0 < choice <= len(list): + print 'Choice out of range; try again:' + continue + break + item = list[choice-1] + typechar = item[0] + [i_selector, i_host, i_port] = item[2:5] + if typebrowser.has_key(typechar): + browserfunc = typebrowser[typechar] + try: + browserfunc(i_selector, i_host, i_port) + except (IOError, socket.error): + print '***', sys.exc_type, ':', sys.exc_value + else: + print 'Unsupported object type' # Browse a text file def browse_textfile(selector, host, port): - x = None - try: - p = os.popen('${PAGER-more}', 'w') - x = SaveLines(p) - get_alt_textfile(selector, host, port, x.writeln) - except IOError, msg: - print 'IOError:', msg - if x: - x.close() - f = open_savefile() - if not f: - return - x = SaveLines(f) - try: - get_alt_textfile(selector, host, port, x.writeln) - print 'Done.' - except IOError, msg: - print 'IOError:', msg - x.close() + x = None + try: + p = os.popen('${PAGER-more}', 'w') + x = SaveLines(p) + get_alt_textfile(selector, host, port, x.writeln) + except IOError, msg: + print 'IOError:', msg + if x: + x.close() + f = open_savefile() + if not f: + return + x = SaveLines(f) + try: + get_alt_textfile(selector, host, port, x.writeln) + print 'Done.' + except IOError, msg: + print 'IOError:', msg + x.close() # Browse a search index def browse_search(selector, host, port): - while 1: - print '----- SEARCH -----' - print 'Selector:', repr(selector) - print 'Host:', host, ' Port:', port - print - try: - query = raw_input('Query [CR == up a level]: ') - except EOFError: - print - break - query = string.strip(query) - if not query: - break - if '\t' in query: - print 'Sorry, queries cannot contain tabs' - continue - browse_menu(selector + TAB + query, host, port) + while 1: + print '----- SEARCH -----' + print 'Selector:', repr(selector) + print 'Host:', host, ' Port:', port + print + try: + query = raw_input('Query [CR == up a level]: ') + except EOFError: + print + break + query = string.strip(query) + if not query: + break + if '\t' in query: + print 'Sorry, queries cannot contain tabs' + continue + browse_menu(selector + TAB + query, host, port) # "Browse" telnet-based information, i.e. open a telnet session def browse_telnet(selector, host, port): - if selector: - print 'Log in as', repr(selector) - if type(port) <> type(''): - port = repr(port) - sts = os.system('set -x; exec telnet ' + host + ' ' + port) - if sts: - print 'Exit status:', sts + if selector: + print 'Log in as', repr(selector) + if type(port) <> type(''): + port = repr(port) + sts = os.system('set -x; exec telnet ' + host + ' ' + port) + if sts: + print 'Exit status:', sts # "Browse" a binary file, i.e. save it to a file def browse_binary(selector, host, port): - f = open_savefile() - if not f: - return - x = SaveWithProgress(f) - get_alt_binary(selector, host, port, x.write, 8*1024) - x.close() + f = open_savefile() + if not f: + return + x = SaveWithProgress(f) + get_alt_binary(selector, host, port, x.write, 8*1024) + x.close() # "Browse" a sound file, i.e. play it or save it def browse_sound(selector, host, port): - browse_binary(selector, host, port) + browse_binary(selector, host, port) # Dictionary mapping types to browser functions typebrowser = {'0': browse_textfile, '1': browse_menu, \ - '4': browse_binary, '5': browse_binary, '6': browse_textfile, \ - '7': browse_search, \ - '8': browse_telnet, '9': browse_binary, 's': browse_sound} + '4': browse_binary, '5': browse_binary, '6': browse_textfile, \ + '7': browse_search, \ + '8': browse_telnet, '9': browse_binary, 's': browse_sound} # Class used to save lines, appending a newline to each line class SaveLines: - def __init__(self, f): - self.f = f - def writeln(self, line): - self.f.write(line + '\n') - def close(self): - sts = self.f.close() - if sts: - print 'Exit status:', sts + def __init__(self, f): + self.f = f + def writeln(self, line): + self.f.write(line + '\n') + def close(self): + sts = self.f.close() + if sts: + print 'Exit status:', sts # Class used to save data while showing progress class SaveWithProgress: - def __init__(self, f): - self.f = f - def write(self, data): - sys.stdout.write('#') - sys.stdout.flush() - self.f.write(data) - def close(self): - print - sts = self.f.close() - if sts: - print 'Exit status:', sts + def __init__(self, f): + self.f = f + def write(self, data): + sys.stdout.write('#') + sys.stdout.flush() + self.f.write(data) + def close(self): + print + sts = self.f.close() + if sts: + print 'Exit status:', sts # Ask for and open a save file, or return None if not to save def open_savefile(): - try: - savefile = raw_input( \ - 'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ') - except EOFError: - print - return None - savefile = string.strip(savefile) - if not savefile: - return None - if savefile[0] == '|': - cmd = string.strip(savefile[1:]) - try: - p = os.popen(cmd, 'w') - except IOError, msg: - print repr(cmd), ':', msg - return None - print 'Piping through', repr(cmd), '...' - return p - if savefile[0] == '~': - savefile = os.path.expanduser(savefile) - try: - f = open(savefile, 'w') - except IOError, msg: - print repr(savefile), ':', msg - return None - print 'Saving to', repr(savefile), '...' - return f + try: + savefile = raw_input( \ + 'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ') + except EOFError: + print + return None + savefile = string.strip(savefile) + if not savefile: + return None + if savefile[0] == '|': + cmd = string.strip(savefile[1:]) + try: + p = os.popen(cmd, 'w') + except IOError, msg: + print repr(cmd), ':', msg + return None + print 'Piping through', repr(cmd), '...' + return p + if savefile[0] == '~': + savefile = os.path.expanduser(savefile) + try: + f = open(savefile, 'w') + except IOError, msg: + print repr(savefile), ':', msg + return None + print 'Saving to', repr(savefile), '...' + return f # Test program def test(): - if sys.argv[4:]: - print 'usage: gopher [ [selector] host [port] ]' - sys.exit(2) - elif sys.argv[3:]: - browser(sys.argv[1], sys.argv[2], sys.argv[3]) - elif sys.argv[2:]: - try: - port = string.atoi(sys.argv[2]) - selector = '' - host = sys.argv[1] - except string.atoi_error: - selector = sys.argv[1] - host = sys.argv[2] - port = '' - browser(selector, host, port) - elif sys.argv[1:]: - browser('', sys.argv[1]) - else: - browser() + if sys.argv[4:]: + print 'usage: gopher [ [selector] host [port] ]' + sys.exit(2) + elif sys.argv[3:]: + browser(sys.argv[1], sys.argv[2], sys.argv[3]) + elif sys.argv[2:]: + try: + port = string.atoi(sys.argv[2]) + selector = '' + host = sys.argv[1] + except string.atoi_error: + selector = sys.argv[1] + host = sys.argv[2] + port = '' + browser(selector, host, port) + elif sys.argv[1:]: + browser('', sys.argv[1]) + else: + browser() # Call the test program as a main program test() diff --git a/Demo/sockets/mcast.py b/Demo/sockets/mcast.py index 71bcc75..122dad7 100755 --- a/Demo/sockets/mcast.py +++ b/Demo/sockets/mcast.py @@ -19,76 +19,76 @@ from socket import * # Main program def main(): - flags = sys.argv[1:] - # - if flags: - sender(flags[0]) - else: - receiver() + flags = sys.argv[1:] + # + if flags: + sender(flags[0]) + else: + receiver() # Sender subroutine (only one per local area network) def sender(flag): - s = socket(AF_INET, SOCK_DGRAM) - if flag == '-b': - s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) - mygroup = '<broadcast>' - else: - mygroup = MYGROUP - ttl = struct.pack('b', 1) # Time-to-live - s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, ttl) - while 1: - data = repr(time.time()) -## data = data + (1400 - len(data)) * '\0' - s.sendto(data, (mygroup, MYPORT)) - time.sleep(1) + s = socket(AF_INET, SOCK_DGRAM) + if flag == '-b': + s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) + mygroup = '<broadcast>' + else: + mygroup = MYGROUP + ttl = struct.pack('b', 1) # Time-to-live + s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, ttl) + while 1: + data = repr(time.time()) +## data = data + (1400 - len(data)) * '\0' + s.sendto(data, (mygroup, MYPORT)) + time.sleep(1) # Receiver subroutine (as many as you like) def receiver(): - # Open and initialize the socket - s = openmcastsock(MYGROUP, MYPORT) - # - # Loop, printing any data we receive - while 1: - data, sender = s.recvfrom(1500) - while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's - print sender, ':', repr(data) + # Open and initialize the socket + s = openmcastsock(MYGROUP, MYPORT) + # + # Loop, printing any data we receive + while 1: + data, sender = s.recvfrom(1500) + while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's + print sender, ':', repr(data) # Open a UDP socket, bind it to a port and select a multicast group def openmcastsock(group, port): - # Import modules used only here - import string - import struct - # - # Create a socket - s = socket(AF_INET, SOCK_DGRAM) - # - # Allow multiple copies of this program on one machine - # (not strictly needed) - s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) - # - # Bind it to the port - s.bind(('', port)) - # - # Look up multicast group address in name server - # (doesn't hurt if it is already in ddd.ddd.ddd.ddd format) - group = gethostbyname(group) - # - # Construct binary group address - bytes = map(int, string.split(group, ".")) - grpaddr = 0 - for byte in bytes: grpaddr = (grpaddr << 8) | byte - # - # Construct struct mreq from grpaddr and ifaddr - ifaddr = INADDR_ANY - mreq = struct.pack('ll', htonl(grpaddr), htonl(ifaddr)) - # - # Add group membership - s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq) - # - return s + # Import modules used only here + import string + import struct + # + # Create a socket + s = socket(AF_INET, SOCK_DGRAM) + # + # Allow multiple copies of this program on one machine + # (not strictly needed) + s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) + # + # Bind it to the port + s.bind(('', port)) + # + # Look up multicast group address in name server + # (doesn't hurt if it is already in ddd.ddd.ddd.ddd format) + group = gethostbyname(group) + # + # Construct binary group address + bytes = map(int, string.split(group, ".")) + grpaddr = 0 + for byte in bytes: grpaddr = (grpaddr << 8) | byte + # + # Construct struct mreq from grpaddr and ifaddr + ifaddr = INADDR_ANY + mreq = struct.pack('ll', htonl(grpaddr), htonl(ifaddr)) + # + # Add group membership + s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq) + # + return s main() diff --git a/Demo/sockets/radio.py b/Demo/sockets/radio.py index b68a4ec..fa4ce75 100755 --- a/Demo/sockets/radio.py +++ b/Demo/sockets/radio.py @@ -9,6 +9,6 @@ s = socket(AF_INET, SOCK_DGRAM) s.bind(('', MYPORT)) while 1: - data, wherefrom = s.recvfrom(1500, 0) - sys.stderr.write(repr(wherefrom) + '\n') - sys.stdout.write(data) + data, wherefrom = s.recvfrom(1500, 0) + sys.stderr.write(repr(wherefrom) + '\n') + sys.stdout.write(data) diff --git a/Demo/sockets/rpython.py b/Demo/sockets/rpython.py index 77b2a7a..8333d39 100755 --- a/Demo/sockets/rpython.py +++ b/Demo/sockets/rpython.py @@ -11,25 +11,25 @@ PORT = 4127 BUFSIZE = 1024 def main(): - if len(sys.argv) < 3: - print "usage: rpython host command" - sys.exit(2) - host = sys.argv[1] - port = PORT - i = string.find(host, ':') - if i >= 0: - port = string.atoi(port[i+1:]) - host = host[:i] - command = string.join(sys.argv[2:]) - s = socket(AF_INET, SOCK_STREAM) - s.connect((host, port)) - s.send(command) - s.shutdown(1) - reply = '' - while 1: - data = s.recv(BUFSIZE) - if not data: break - reply = reply + data - print reply, + if len(sys.argv) < 3: + print "usage: rpython host command" + sys.exit(2) + host = sys.argv[1] + port = PORT + i = string.find(host, ':') + if i >= 0: + port = string.atoi(port[i+1:]) + host = host[:i] + command = string.join(sys.argv[2:]) + s = socket(AF_INET, SOCK_STREAM) + s.connect((host, port)) + s.send(command) + s.shutdown(1) + reply = '' + while 1: + data = s.recv(BUFSIZE) + if not data: break + reply = reply + data + print reply, main() diff --git a/Demo/sockets/rpythond.py b/Demo/sockets/rpythond.py index 1109a99..81397d6 100755 --- a/Demo/sockets/rpythond.py +++ b/Demo/sockets/rpythond.py @@ -14,39 +14,39 @@ PORT = 4127 BUFSIZE = 1024 def main(): - if len(sys.argv) > 1: - port = int(eval(sys.argv[1])) - else: - port = PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - while 1: - conn, (remotehost, remoteport) = s.accept() - print 'connected by', remotehost, remoteport - request = '' - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - request = request + data - reply = execute(request) - conn.send(reply) - conn.close() + if len(sys.argv) > 1: + port = int(eval(sys.argv[1])) + else: + port = PORT + s = socket(AF_INET, SOCK_STREAM) + s.bind(('', port)) + s.listen(1) + while 1: + conn, (remotehost, remoteport) = s.accept() + print 'connected by', remotehost, remoteport + request = '' + while 1: + data = conn.recv(BUFSIZE) + if not data: + break + request = request + data + reply = execute(request) + conn.send(reply) + conn.close() def execute(request): - stdout = sys.stdout - stderr = sys.stderr - sys.stdout = sys.stderr = fakefile = StringIO.StringIO() - try: - try: - exec request in {}, {} - except: - print - traceback.print_exc(100) - finally: - sys.stderr = stderr - sys.stdout = stdout - return fakefile.getvalue() + stdout = sys.stdout + stderr = sys.stderr + sys.stdout = sys.stderr = fakefile = StringIO.StringIO() + try: + try: + exec request in {}, {} + except: + print + traceback.print_exc(100) + finally: + sys.stderr = stderr + sys.stdout = stdout + return fakefile.getvalue() main() diff --git a/Demo/sockets/telnet.py b/Demo/sockets/telnet.py index d86cbeb..d50c37f 100755 --- a/Demo/sockets/telnet.py +++ b/Demo/sockets/telnet.py @@ -20,90 +20,90 @@ BUFSIZE = 1024 # Telnet protocol characters -IAC = chr(255) # Interpret as command +IAC = chr(255) # Interpret as command DONT = chr(254) DO = chr(253) WONT = chr(252) WILL = chr(251) def main(): - host = sys.argv[1] - try: - hostaddr = gethostbyname(host) - except error: - sys.stderr.write(sys.argv[1] + ': bad host name\n') - sys.exit(2) - # - if len(sys.argv) > 2: - servname = sys.argv[2] - else: - servname = 'telnet' - # - if '0' <= servname[:1] <= '9': - port = eval(servname) - else: - try: - port = getservbyname(servname, 'tcp') - except error: - sys.stderr.write(servname + ': bad tcp service name\n') - sys.exit(2) - # - s = socket(AF_INET, SOCK_STREAM) - # - try: - s.connect((host, port)) - except error, msg: - sys.stderr.write('connect failed: ' + repr(msg) + '\n') - sys.exit(1) - # - pid = posix.fork() - # - if pid == 0: - # child -- read stdin, write socket - while 1: - line = sys.stdin.readline() - s.send(line) - else: - # parent -- read socket, write stdout - iac = 0 # Interpret next char as command - opt = '' # Interpret next char as option - while 1: - data = s.recv(BUFSIZE) - if not data: - # EOF; kill child and exit - sys.stderr.write( '(Closed by remote host)\n') - posix.kill(pid, 9) - sys.exit(1) - cleandata = '' - for c in data: - if opt: - print ord(c) - s.send(opt + c) - opt = '' - elif iac: - iac = 0 - if c == IAC: - cleandata = cleandata + c - elif c in (DO, DONT): - if c == DO: print '(DO)', - else: print '(DONT)', - opt = IAC + WONT - elif c in (WILL, WONT): - if c == WILL: print '(WILL)', - else: print '(WONT)', - opt = IAC + DONT - else: - print '(command)', ord(c) - elif c == IAC: - iac = 1 - print '(IAC)', - else: - cleandata = cleandata + c - sys.stdout.write(cleandata) - sys.stdout.flush() + host = sys.argv[1] + try: + hostaddr = gethostbyname(host) + except error: + sys.stderr.write(sys.argv[1] + ': bad host name\n') + sys.exit(2) + # + if len(sys.argv) > 2: + servname = sys.argv[2] + else: + servname = 'telnet' + # + if '0' <= servname[:1] <= '9': + port = eval(servname) + else: + try: + port = getservbyname(servname, 'tcp') + except error: + sys.stderr.write(servname + ': bad tcp service name\n') + sys.exit(2) + # + s = socket(AF_INET, SOCK_STREAM) + # + try: + s.connect((host, port)) + except error, msg: + sys.stderr.write('connect failed: ' + repr(msg) + '\n') + sys.exit(1) + # + pid = posix.fork() + # + if pid == 0: + # child -- read stdin, write socket + while 1: + line = sys.stdin.readline() + s.send(line) + else: + # parent -- read socket, write stdout + iac = 0 # Interpret next char as command + opt = '' # Interpret next char as option + while 1: + data = s.recv(BUFSIZE) + if not data: + # EOF; kill child and exit + sys.stderr.write( '(Closed by remote host)\n') + posix.kill(pid, 9) + sys.exit(1) + cleandata = '' + for c in data: + if opt: + print ord(c) + s.send(opt + c) + opt = '' + elif iac: + iac = 0 + if c == IAC: + cleandata = cleandata + c + elif c in (DO, DONT): + if c == DO: print '(DO)', + else: print '(DONT)', + opt = IAC + WONT + elif c in (WILL, WONT): + if c == WILL: print '(WILL)', + else: print '(WONT)', + opt = IAC + DONT + else: + print '(command)', ord(c) + elif c == IAC: + iac = 1 + print '(IAC)', + else: + cleandata = cleandata + c + sys.stdout.write(cleandata) + sys.stdout.flush() try: - main() + main() except KeyboardInterrupt: - pass + pass diff --git a/Demo/sockets/throughput.py b/Demo/sockets/throughput.py index fa250e7..b8df1f3 100755 --- a/Demo/sockets/throughput.py +++ b/Demo/sockets/throughput.py @@ -3,8 +3,8 @@ # Test network throughput. # # Usage: -# 1) on host_A: throughput -s [port] # start a server -# 2) on host_B: throughput -c count host_A [port] # start a client +# 1) on host_A: throughput -s [port] # start a server +# 2) on host_B: throughput -c count host_A [port] # start a client # # The server will service multiple clients until it is killed. # @@ -21,73 +21,73 @@ BUFSIZE = 1024 def main(): - if len(sys.argv) < 2: - usage() - if sys.argv[1] == '-s': - server() - elif sys.argv[1] == '-c': - client() - else: - usage() + if len(sys.argv) < 2: + usage() + if sys.argv[1] == '-s': + server() + elif sys.argv[1] == '-c': + client() + else: + usage() def usage(): - sys.stdout = sys.stderr - print 'Usage: (on host_A) throughput -s [port]' - print 'and then: (on host_B) throughput -c count host_A [port]' - sys.exit(2) + sys.stdout = sys.stderr + print 'Usage: (on host_A) throughput -s [port]' + print 'and then: (on host_B) throughput -c count host_A [port]' + sys.exit(2) def server(): - if len(sys.argv) > 2: - port = eval(sys.argv[2]) - else: - port = MY_PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - print 'Server ready...' - while 1: - conn, (host, remoteport) = s.accept() - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - del data - conn.send('OK\n') - conn.close() - print 'Done with', host, 'port', remoteport + if len(sys.argv) > 2: + port = eval(sys.argv[2]) + else: + port = MY_PORT + s = socket(AF_INET, SOCK_STREAM) + s.bind(('', port)) + s.listen(1) + print 'Server ready...' + while 1: + conn, (host, remoteport) = s.accept() + while 1: + data = conn.recv(BUFSIZE) + if not data: + break + del data + conn.send('OK\n') + conn.close() + print 'Done with', host, 'port', remoteport def client(): - if len(sys.argv) < 4: - usage() - count = int(eval(sys.argv[2])) - host = sys.argv[3] - if len(sys.argv) > 4: - port = eval(sys.argv[4]) - else: - port = MY_PORT - testdata = 'x' * (BUFSIZE-1) + '\n' - t1 = time.time() - s = socket(AF_INET, SOCK_STREAM) - t2 = time.time() - s.connect((host, port)) - t3 = time.time() - i = 0 - while i < count: - i = i+1 - s.send(testdata) - s.shutdown(1) # Send EOF - t4 = time.time() - data = s.recv(BUFSIZE) - t5 = time.time() - print data - print 'Raw timers:', t1, t2, t3, t4, t5 - print 'Intervals:', t2-t1, t3-t2, t4-t3, t5-t4 - print 'Total:', t5-t1 - print 'Throughput:', round((BUFSIZE*count*0.001) / (t5-t1), 3), - print 'K/sec.' + if len(sys.argv) < 4: + usage() + count = int(eval(sys.argv[2])) + host = sys.argv[3] + if len(sys.argv) > 4: + port = eval(sys.argv[4]) + else: + port = MY_PORT + testdata = 'x' * (BUFSIZE-1) + '\n' + t1 = time.time() + s = socket(AF_INET, SOCK_STREAM) + t2 = time.time() + s.connect((host, port)) + t3 = time.time() + i = 0 + while i < count: + i = i+1 + s.send(testdata) + s.shutdown(1) # Send EOF + t4 = time.time() + data = s.recv(BUFSIZE) + t5 = time.time() + print data + print 'Raw timers:', t1, t2, t3, t4, t5 + print 'Intervals:', t2-t1, t3-t2, t4-t3, t5-t4 + print 'Total:', t5-t1 + print 'Throughput:', round((BUFSIZE*count*0.001) / (t5-t1), 3), + print 'K/sec.' main() diff --git a/Demo/sockets/udpecho.py b/Demo/sockets/udpecho.py index 720cfe1..5181c82 100755 --- a/Demo/sockets/udpecho.py +++ b/Demo/sockets/udpecho.py @@ -12,52 +12,52 @@ ECHO_PORT = 50000 + 7 BUFSIZE = 1024 def main(): - if len(sys.argv) < 2: - usage() - if sys.argv[1] == '-s': - server() - elif sys.argv[1] == '-c': - client() - else: - usage() + if len(sys.argv) < 2: + usage() + if sys.argv[1] == '-s': + server() + elif sys.argv[1] == '-c': + client() + else: + usage() def usage(): - sys.stdout = sys.stderr - print 'Usage: udpecho -s [port] (server)' - print 'or: udpecho -c host [port] <file (client)' - sys.exit(2) + sys.stdout = sys.stderr + print 'Usage: udpecho -s [port] (server)' + print 'or: udpecho -c host [port] <file (client)' + sys.exit(2) def server(): - if len(sys.argv) > 2: - port = eval(sys.argv[2]) - else: - port = ECHO_PORT - s = socket(AF_INET, SOCK_DGRAM) - s.bind(('', port)) - print 'udp echo server ready' - while 1: - data, addr = s.recvfrom(BUFSIZE) - print 'server received %r from %r' % (data, addr) - s.sendto(data, addr) + if len(sys.argv) > 2: + port = eval(sys.argv[2]) + else: + port = ECHO_PORT + s = socket(AF_INET, SOCK_DGRAM) + s.bind(('', port)) + print 'udp echo server ready' + while 1: + data, addr = s.recvfrom(BUFSIZE) + print 'server received %r from %r' % (data, addr) + s.sendto(data, addr) def client(): - if len(sys.argv) < 3: - usage() - host = sys.argv[2] - if len(sys.argv) > 3: - port = eval(sys.argv[3]) - else: - port = ECHO_PORT - addr = host, port - s = socket(AF_INET, SOCK_DGRAM) - s.bind(('', 0)) - print 'udp echo client ready, reading stdin' - while 1: - line = sys.stdin.readline() - if not line: - break - s.sendto(line, addr) - data, fromaddr = s.recvfrom(BUFSIZE) - print 'client received %r from %r' % (data, fromaddr) + if len(sys.argv) < 3: + usage() + host = sys.argv[2] + if len(sys.argv) > 3: + port = eval(sys.argv[3]) + else: + port = ECHO_PORT + addr = host, port + s = socket(AF_INET, SOCK_DGRAM) + s.bind(('', 0)) + print 'udp echo client ready, reading stdin' + while 1: + line = sys.stdin.readline() + if not line: + break + s.sendto(line, addr) + data, fromaddr = s.recvfrom(BUFSIZE) + print 'client received %r from %r' % (data, fromaddr) main() diff --git a/Demo/sockets/unicast.py b/Demo/sockets/unicast.py index 0a30f35..dd15e3c 100644 --- a/Demo/sockets/unicast.py +++ b/Demo/sockets/unicast.py @@ -9,8 +9,6 @@ s = socket(AF_INET, SOCK_DGRAM) s.bind(('', 0)) while 1: - data = repr(time.time()) + '\n' - s.sendto(data, ('', MYPORT)) - time.sleep(2) - - + data = repr(time.time()) + '\n' + s.sendto(data, ('', MYPORT)) + time.sleep(2) diff --git a/Demo/sockets/unixserver.py b/Demo/sockets/unixserver.py index d4425f0..5eccabb 100644 --- a/Demo/sockets/unixserver.py +++ b/Demo/sockets/unixserver.py @@ -2,7 +2,7 @@ # Piet van Oostrum import os from socket import * -FILE = 'blabla' +FILE = 'blabla' s = socket(AF_UNIX, SOCK_STREAM) s.bind(FILE) print 'Sock name is: ['+s.getsockname()+']' |