[#41581] Ruby 1.6.7 dieing of segfault — Dossy <dossy@...>

I've got something that's fairly reproducible in 1.6.7. Is

11 messages 2002/06/02
[#41582] Re: Ruby 1.6.7 dieing of segfault — Nobuyoshi Nakada <nobu.nokada@...> 2002/06/02

Hi,

[#41660] dynamic attr_accessor?? — Markus Jais <mjais@...>

hello

16 messages 2002/06/03

[#41755] HTML Parser suggestions wanted — Ned Konz <ned@...>

I've written an HTML parser that builds trees from HTML source. After

13 messages 2002/06/04

[#41809] eval and local variable — "Park Heesob" <phasis@...>

15 messages 2002/06/05

[#41819] mod_ruby and module space — "Sean O'Dell" <sean@...>

It seems that if I execute a script using mod_ruby, I cannot call

18 messages 2002/06/05

[#41867] Pascal-like 'with' statement? — Philip Mak <pmak@...>

Is there something like Pascal's with statement? I'd like to turn this

18 messages 2002/06/06

[#41919] 1-second events — Paul Brannan <pbrannan@...>

I need to create an event that occurs exactly once per second.

15 messages 2002/06/06

[#42086] ANN: REXML 2.3.5 && 2.2.3 — Sean Russell <ser@...>

<posted & mailed>

31 messages 2002/06/09
[#42091] Re: ANN: REXML 2.3.5 && 2.2.3 — Sean Russell <ser@...> 2002/06/09

<posted & mailed>

[#42092] RE: ANN: REXML 2.3.5 && 2.2.3 — <james@...> 2002/06/09

> Well, XMLSchema may be troublesome to interpret, but it isn't

[#42192] ruby-dev summary 17252-17356 — Minero Aoki <aamine@...>

Hi all,

81 messages 2002/06/11
[#42290] Re: a new block parameter/variable notation (Re: ruby-dev summary 17252-17356) — Kent Dahl <kentda@...> 2002/06/12

Not wanting to flog a dead horse, but I just wonder what the final word

[#42295] Re: a new block parameter/variable notation (Re: ruby-dev summary 17252-17356) — matz@... (Yukihiro Matsumoto) 2002/06/12

Hi,

[#42455] Application server & web developement enviroment — "Radu M. Obad磚 <whizkid@...>

Howdy,

14 messages 2002/06/14
[#42459] Re: Application server & web developement enviroment — Austin Ziegler <austin@...> 2002/06/14

On Fri, 14 Jun 2002 15:55:31 +0900, Radu M. Obadwrote:

[#42472] ANN: Programmierung in Ruby — "Juergen Katins" <katins.juergen@...>

Programmierung in Ruby Online gibt es jetzt mit ausfrlichem

14 messages 2002/06/14

[#42504] Are Unix tools just slow? — Chris Gehlker <gehlker@...>

Awhile back I was asking for help with a unixy way to search the mounted

48 messages 2002/06/14
[#42506] Re: Are Unix tools just slow? — Rick Bradley <rick@...> 2002/06/14

* Chris Gehlker (gehlker@fastq.com) [020614 17:18]:

[#42512] Re: Are Unix tools just slow? — Chris Gehlker <gehlker@...> 2002/06/15

On 6/14/02 3:34 PM, "Rick Bradley" <rick@rickbradley.com> wrote:

[#42513] opengl for ruby, please help — ccos <ccos@...> 2002/06/15

unix newby failing miserably here:

[#42516] Re: Are Unix tools just slow? — "Daniel P. Zepeda" <daniel@...> 2002/06/15

On Sat, 15 Jun 2002 07:14:38 +0900

[#42507] mpg123 — Tobias Reif <tobiasreif@...>

Hi,

15 messages 2002/06/14

[#42546] File.new('foo', 0600 , 'wb') — Tobias Reif <tobiasreif@...>

Hi,

21 messages 2002/06/15
[#42552] Re: File.new('foo', 0600 , 'wb') — Tobias Reif <tobiasreif@...> 2002/06/15

Dossy wrote:

[#42591] Kernel#select questions — Wilkes Joiner <boognish23@...>

I'm trying to track down a bug where Kernel#select is returning [[],[],[]] as

12 messages 2002/06/17

[#42617] eRuby on Mac OS X — Jim Menard <jimm@...>

I've searched ruby-talk for this topic, and the only messages I found show

13 messages 2002/06/17

[#42674] REXML in C — "Radu M. Obad磚 <whizkid@...>

Hi,

20 messages 2002/06/18

[#42771] Why is I/O slow? — Clifford Heath <cjh_nospam@...>

Ok, folk, time to try again. It's nothing to do with SHA-1.

61 messages 2002/06/20
[#42831] Re: Why is I/O slow? — Clifford Heath <cjh_nospam@...> 2002/06/21

Yukihiro Matsumoto wrote:

[#42836] RE: Why is I/O slow? — "Mike Campbell" <michael_s_campbell@...> 2002/06/21

> With respect, this doesn't sound like a smart idea. The glibc folk have

[#42838] Re: Why is I/O slow? — Albert Wagner <alwagner@...> 2002/06/21

On Thursday 20 June 2002 10:10 pm, Mike Campbell wrote:

[#42839] Re: Why is I/O slow? — Austin Ziegler <austin@...> 2002/06/21

On Fri, 21 Jun 2002 12:16:24 +0900, Albert Wagner wrote:

[#42928] GOOD DEAL — "DR. ISA BELLO" <dr_isa@...>

FROM:DR ISA BELLO

11 messages 2002/06/22

[#42982] No exceptions from String#to_i — "Hal E. Fulton" <hal9000@...>

I've been bitten by this before... maybe

19 messages 2002/06/24
[#42983] Re: No exceptions from String#to_i — ts <decoux@...> 2002/06/24

>>>>> "H" == Hal E Fulton <hal9000@hypermetrics.com> writes:

[#42986] Re: No exceptions from String#to_i — Nikodemus Siivola <tsiivola@...> 2002/06/24

[#43122] Re: help (ruby-talk ML) — Benjamin Peterson <bjsp123@...>

20 messages 2002/06/27
[#43123] Re: help (ruby-talk ML) — Dave Thomas <Dave@...> 2002/06/27

Benjamin Peterson <bjsp123@yahoo.com> writes:

[#43124] RE: help (ruby-talk ML) — Bob Calco <robert.calco@...> 2002/06/27

Yes, I would gladly volunteer considerable effort to this end. I have

[#43147] Ruby on Mac OS X — Tobias Reif <tobiasreif@...>

Hi,

24 messages 2002/06/28

[#43174] eruby SAFE question — Dylan Northrup <docx@...>

I'm trying to implement a replacement for the standard apache file listings

39 messages 2002/06/28
[#43249] documentation licenses (was: eruby SAFE question) — Tobias Reif <tobiasreif@...> 2002/06/30

Dave Thomas wrote:

[#43250] Re: documentation licenses (was: eruby SAFE question) — Dave Thomas <Dave@...> 2002/06/30

Tobias Reif <tobiasreif@pinkjuice.com> writes:

[#43255] RE: documentation licenses (was: eruby SAFE question) — <james@...> 2002/06/30

>

[#43280] Re: documentation licenses (was: eruby SAFE question) — "Juergen Katins" <juergen.katins@...> 2002/07/01

Tobias Reif wrote

[#43282] Re: documentation licenses (was: eruby SAFE question) — David Alan Black <dblack@...> 2002/07/01

On Mon, 1 Jul 2002, Juergen Katins wrote:

[#43381] RE: documentation licenses (was: eruby SAFE question) — <james@...> 2002/07/02

> From: David Alan Black [mailto:dblack@candle.superlink.net]

rubycam.rb v 1.7 CGI webcam script for use with cqcam, etc...

From: Phil <JUNK_pvnews1@..._nekophile.JUNK_com>
Date: 2002-06-20 00:07:22 UTC
List: ruby-talk #42765
I don't want to mess with Sourceforge, so consider this my form of 
dissemination in case the server disappears some time.  Please forward 
mods to the email address listed under AUTHOR below.  PS: New to ruby 
when I wrote it - now have RSI - probably not going to make it very 
slick.  ;-)

-------------

#!/usr/bin/env ruby

########################################################################
## VERSION: $Id: rubycam.rb,v 1.7 2002/03/22 20:08:52 rubycam Exp $
##
## AUTHOR: Phil Voris <rubycam at nekophile.com>
##
## LICENSE: Ruby License - must include this header comment block
##          http://www.ruby-lang.org/en/LICENSE.txt
##
## DESCRIPTION:
## This CGI webcam script attempts to conserve resources by not
## creating images more often than the number of seconds indicated by
## the refresh setting.  Maximum flexibility is given by allowing the
## administrator to set the image-producing command line.  The
## defaults are arranged to use cqcam
## (http://www.cs.duke.edu/~reynolds/cqcam/).
##
## REQUIRES: ruby
##           ruby modules: net/smtp (for error reporting), ftools
##           rb2html.rb (for viewing source)
##           some image-grabber, such as cqcam
##           optionally, some image manipulation software
##
## USAGE:
## * Install under cgi-bin or wherever cgi executables are allowed.
## * Configure the global config section below.
## * Configure the default config section below.
## * Optionally create one or more config files to call in the PATH_INFO.
## * Ensure that img_file_web_directory exists and is writable by the
##   web server
## * [See end of script for recommendations for config and calling from
##   html.]
##
## TO DO:
## It would be nice to add caching.  That is, deliver a header
## indicating that the page (the image) hasn't changed until it
## actually does.  I attempted this, but found that
## HTTP_IF_MODIFIED_SINCE didn't appear in the environment.  I then
## attempted to use a session to track if the use had seen the page
## with the current image - however sessions weren't quite working for
## me - perhaps someone else can resolve this issue.
########################################################################


#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# GLOBAL CONFIGURATION - EDIT HERE
#
# These options must be set
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

## allow options from URL (true / false)
use_config_files = true

## img file directory [relative to DOC_ROOT]
img_file_web_directory = '/img/cam'

## configuration files directory
config_dir = './config'

## directory where rb2html and associated files may be found
## (used for /view)
rb2html_directory = './rb2html-1.0'

## file base-name
lock_filename = 'rubycam.lock'

## maximum age to keep a lock file (seconds, must exceed refresh time)
max_lockfile_age = 500

## shows a little (R) which links to the source.  Specify the target
## frame ('_new', '_self', etc) or nil to not display it.
source_link_target = '_new'

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# END GLOBAL CONFIGURATION
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# PER-CAM CONFIGURATION - SET DEFAULTS HERE
#                       - MAY MODIFY IN CONFIG FILES
#
# Anything listed in this section may be set - as below - in a
# separate file.
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

## default_cqcam_opts
cmd_line = 'cqcam -r -q 25 -s 1 -j'

## filename for the images
img_filename = 'plain.jpg'

## admin email address
admin_email_address = 'webmaster@localhost'

## page title
title = 'Rubycam'

## background (color)
bgcolor = 'black'

## text (color)
text_color = 'yellow'

## browser refresh length (in seconds)
refresh = 60

## img_background_color (color | nil to disable globally)
img_background_color = nil

## randomize transparency_background_color (true / false)
use_randomize_img_background_color = false

## randomize transparency_background_color (true / false)
use_randomize_text_color = false

## match text and img backgrounds - useful for randomization
## (true / false)
text_color_matches_img_background_color = false

## color for the source link, if it appears (color)
source_link_color = 'darkred'

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# END PER-CAM CONFIGURATION
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>






##########################################
### PROCESS URL OPTIONS FROM PATH_INFO ###
##########################################
## If the script is called from a URL with path info equal to 'view' or
## 'get' the contents of the script will be displayed.  'get' results
## in text/plain output while view - relying on rb2html - output color-
## coded html output with line numbers.
path_info = ENV['PATH_INFO'].untaint

if path_info == '/get'
   ## Print source
   puts( "Content-type: text/plain\n\n" )
   IO::foreach( ENV['SCRIPT_FILENAME'].untaint ) { |l|
     puts l
   }
   exit
elsif path_info == '/view'
   ## Print formatted source
   puts( "Content-type: text/html\n\n" )
   rb2html_executable = rb2html_directory + '/rb2html.rb'
   if File::file?( rb2html_executable )
     begin
       htmlpipe = IO::popen( 'ruby ' + rb2html_executable + ' ' +
			   ENV['SCRIPT_FILENAME'].untaint )
       puts( htmlpipe.readlines() )
     rescue SystemCallError
       ## Mail admin if any errors - if you don't want mail, change
       ## the admin address.
       require 'net/smtp'
       smtp = Net::SMTP::new( "localhost" )
       smtp.start
       body = "Error:\nruby " + rb2html_executable + ' ' +
	ENV['SCRIPT_FILENAME'].untaint
       smtp.sendmail( body, 'rubycam_user@localhost', admin_email_address )
       smtp.finish
     end
     exit
   else
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: cannot execute " + rb2html_executable )
     exit
   end
elsif path_info != nil
   if not File::file?( config_dir + path_info )
     ## Print error
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: invalid config file: '" + config_dir + path_info + 
"'\n" +
	 "Set the PATH_INFO (in the url) to a valid config file name." )
     exit
   elsif path_info.index( '../' ) != nil
     ## Print error
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: invalid config file: '" + config_dir + path_info + 
"'\n" +
	 "'../' not permitted in config file pathname." )
     exit
   elsif not File::readable?( config_dir + path_info )
     ## Print error
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: unreadable config file: '" + config_dir + path_info + 
"'" )
     exit
   else
     ## Process config file
     config_file_string = ''
     File::open( config_dir + path_info ).readlines.each do |line|
       config_file_string.concat( line )
     end
     eval config_file_string
   end
end


###########################
### DETERMINE FILE INFO ###
###########################

## First, we determine the colors to be used for text (the image time)
## and for the background of the image (not the page bgcolor).
color_hash = {
   0 => 'white',
   1 => 'red',
   2 => 'orange',
   3 => 'yellow',
   4 => 'green',
   5 => 'blue',
   6 => 'purple',
   7 => 'lightgreen',
   8 => 'pink',
   9 => 'lightyellow',
   10 => 'lightblue',
   11 => 'lightgray',
   12 => 'gray'
}

## If img_background_color is set to nil, then no image background
## color options will apply.
if img_background_color != nil and
     use_randomize_img_background_color
   img_background_color = color_hash[rand(13)]
end

## If randomization is used for text and image, then the image
## background color is used for both.
if  use_randomize_text_color and
     not text_color_matches_img_background_color
   text_color = color_hash[rand(13)]
elsif ( img_background_color != nil ) and
       text_color_matches_img_background_color
   text_color = img_background_color
end

img_file_webpath = img_file_web_directory + '/' + img_filename
img_file_pathname = ENV['DOCUMENT_ROOT'] + img_file_webpath
img_file_pathname.untaint
img_file_tmp_pathname = img_file_pathname + '.tmp'

## Time
time_now = Time::now

## Mtime
if File::exist?( img_file_pathname )
   img_file_mtime = File::mtime( img_file_pathname )
   img_file_mtime_int = img_file_mtime.to_i
   img_file_mtime_string = img_file_mtime.to_s
   img_file_age = time_now.to_i - img_file_mtime_int
end

###########################
###    LOCKFILE CODE    ###
###########################

## Lock file name is global - there is only one camera and it can take
## only one picture at a time.  The lockfile is set during this process.
lock_file_pathname = ENV['DOCUMENT_ROOT'] + img_file_web_directory + '/' +
   lock_filename
lock_file_pathname.untaint

## If the lockfile somehow gets stale, it will be removed.
locked = false
if File::exist?( lock_file_pathname )
   if ( File::mtime( lock_file_pathname ) < ( time_now - ( 
max_lockfile_age ) ) )
     File::unlink( lock_file_pathname )
   else
     locked = true
   end
end

###########################
###       EXECUTE       ###
###########################

## If there's no image, or it's an old one, and the camera is free,
## then we take a new picture.
if  ( ( not File::exist?( img_file_pathname ) ) or
       ( img_file_age >= refresh ) ) and
     ( not locked )

   lockfile = File::new( lock_file_pathname, mode='w' )

   begin
     ## Execute
     img_file = File::open( img_file_tmp_pathname, mode='w').write( 
IO::popen( cmd_line ).read() )
     require 'ftools'
     File::mv( img_file_tmp_pathname, img_file_pathname )
     File::unlink( lock_file_pathname )
     img_file_mtime = Time::now
     img_file_mtime_string = img_file_mtime.to_s
   rescue SystemCallError
     ## Mail admin if any errors - if you don't want mail, change
     ## the admin address.
     require 'net/smtp'
     smtp = Net::SMTP::new( "localhost" )
     smtp.start
     body = "Subject: Error with rubycam\n" +
       "Failed to execute:\n" + cmd_line + "\n\nSee logs for details."
     smtp.sendmail( body, 'rubycam_user@localhost', admin_email_address )
     smtp.finish
     File::unlink( lock_file_pathname )
   end

end

###########################
###        HTML         ###
###########################

puts( "Content-type: text/html\n" +
      'Last-Modified: ' + img_file_mtime_string + "\n" +
      'Expires: ' + ( img_file_mtime + refresh ).to_s +
      "\n\n" )

puts( '<head><title>' + title + '</title>' +
      '<META HTTP-EQUIV="Refresh" CONTENT="' + refresh.to_s + '"></head>' )

puts( '<body bgcolor="' + bgcolor + '" text="' + text_color + '">' )

puts( '<center><table><tr><td' )

if img_background_color != nil
   puts( ' bgcolor="' + img_background_color + '"' )
end

puts( '><img src="' + img_file_webpath + '"></td></tr></table><p>' )

puts( '<p><b>' + img_file_mtime_string + '</b>' )

if source_link_target != nil
   puts( ' <small><a href="' + ENV['SCRIPT_NAME'].untaint + '/get" 
target="' + source_link_target + '"><font color="' + source_link_color + 
'">&reg;</font></a></small>' )
end

puts( '</center></body></html>' )



###########################
###  CALLING FROM HTML  ###
###########################
##
## Include the following in your page head:
##
##     <script language=javascript>
##     function openwin(url){
##         var hWnd =
## 
window.open(url,"","width=350,height=300,resizable=yes,scrollbars=yes"); 

##         if (!hWnd.opener) hWnd.opener = self;
##     }
##     function openminiwin(url){
##         var hWnd =
## 
window.open(url,"","width=180,height=140,resizable=yes,scrollbars=yes"); 

##         if (!hWnd.opener) hWnd.opener = self;
##     }
##     </script>
##
## Call within body of page as:
##
## <ul>
##         <li><a 
href="Javascript:openwin('/cgi-bin/webcam/rubycam.rb');">Webcam</a>
##         <li><a 
href="Javascript:openwin('/cgi-bin/webcam/rubycam.rb/transgif.conf');">Psychedelicam</a>
##         <li><a 
href="Javascript:openwin('/cgi-bin/webcam/rubycam.rb/greyjpeg.conf');">Greycam</a>
##
##
##         <li><a href="/cgi-bin/webcam/rubycam.rb/view">Formatted 
Source</a>
##         <li><a href="/cgi-bin/webcam/rubycam.rb/get">Source</a>
## </ul>
##

###########################
###   CONFIG FILE # 1   ###
###########################
## greyjpeg.conf - produces a grey jpeg
#  cmd_line = 'cqcam -s 1 | ppmtojpeg --progressive --greyscale 
--optimize --quality=33 --comment="Made with Rubycam"'
#  img_filename = 'grey.jpg'
#  title = 'Greycam'
#  refresh = 60

###########################
###   CONFIG FILE # 2   ###
###########################
## transgif.conf - produces a transparent gif with weird effects
#  cmd_line = 'cqcam -s 1 | ppmquant 2 | ppmtogif -transparent grey 
-interlace -sort -comment="Made with Rubycam"'
#  img_filename = 'transparent.gif'
#  title = 'Psychedelicam'
#  refresh = 60
#  img_background_color = 'red'
#  use_randomize_img_background_color = true
#  use_randomize_text_color = true
#  text_color_matches_img_background_color = true


## EOF
#!/usr/bin/env ruby

########################################################################
## VERSION: $Id: rubycam.rb,v 1.7 2002/03/22 20:08:52 pvoris Exp $
##
## AUTHOR: Phil Voris <rubycam@nekophile.com>
##
## LICENSE: Ruby License - must include this header comment block
##          http://www.ruby-lang.org/en/LICENSE.txt
##
## DESCRIPTION:
## This CGI webcam script attempts to conserve resources by not
## creating images more often than the number of seconds indicated by
## the refresh setting.  Maximum flexibility is given by allowing the
## administrator to set the image-producing command line.  The
## defaults are arranged to use cqcam
## (http://www.cs.duke.edu/~reynolds/cqcam/).
##
## REQUIRES: ruby
##           ruby modules: net/smtp (for error reporting), ftools
##           rb2html.rb (for viewing source)
##           some image-grabber, such as cqcam
##           optionally, some image manipulation software
##
## USAGE:
## * Install under cgi-bin or wherever cgi executables are allowed.
## * Configure the global config section below.
## * Configure the default config section below.
## * Optionally create one or more config files to call in the PATH_INFO.
## * Ensure that img_file_web_directory exists and is writable by the
##   web server
## * [See end of script for recommendations for config and calling from
##   html.]
##
## TO DO:
## It would be nice to add caching.  That is, deliver a header
## indicating that the page (the image) hasn't changed until it
## actually does.  I attempted this, but found that
## HTTP_IF_MODIFIED_SINCE didn't appear in the environment.  I then
## attempted to use a session to track if the use had seen the page
## with the current image - however sessions weren't quite working for
## me - perhaps someone else can resolve this issue.
########################################################################


#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# GLOBAL CONFIGURATION - EDIT HERE
#
# These options must be set
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

## allow options from URL (true / false)
use_config_files = true

## img file directory [relative to DOC_ROOT]
img_file_web_directory = '/img/cam'

## configuration files directory
config_dir = './config'

## directory where rb2html and associated files may be found
## (used for /view)
rb2html_directory = './rb2html-1.0'

## file base-name
lock_filename = 'rubycam.lock'

## maximum age to keep a lock file (seconds, must exceed refresh time)
max_lockfile_age = 500

## shows a little (R) which links to the source.  Specify the target
## frame ('_new', '_self', etc) or nil to not display it.
source_link_target = '_new'

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# END GLOBAL CONFIGURATION
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# PER-CAM CONFIGURATION - SET DEFAULTS HERE
#                       - MAY MODIFY IN CONFIG FILES
#
# Anything listed in this section may be set - as below - in a
# separate file.
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

## default_cqcam_opts
cmd_line = 'cqcam -r -q 25 -s 1 -j'

## filename for the images
img_filename = 'plain.jpg'

## admin email address
admin_email_address = 'webmaster@localhost'

## page title
title = 'Rubycam'

## background (color)
bgcolor = 'black'

## text (color)
text_color = 'yellow'

## browser refresh length (in seconds)
refresh = 60

## img_background_color (color | nil to disable globally)
img_background_color = nil

## randomize transparency_background_color (true / false)
use_randomize_img_background_color = false

## randomize transparency_background_color (true / false)
use_randomize_text_color = false

## match text and img backgrounds - useful for randomization
## (true / false)
text_color_matches_img_background_color = false

## color for the source link, if it appears (color)
source_link_color = 'darkred'

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# END PER-CAM CONFIGURATION
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>






##########################################
### PROCESS URL OPTIONS FROM PATH_INFO ###
##########################################
## If the script is called from a URL with path info equal to 'view' or
## 'get' the contents of the script will be displayed.  'get' results
## in text/plain output while view - relying on rb2html - output color-
## coded html output with line numbers.
path_info = ENV['PATH_INFO'].untaint

if path_info == '/get'
   ## Print source
   puts( "Content-type: text/plain\n\n" )
   IO::foreach( ENV['SCRIPT_FILENAME'].untaint ) { |l|
     puts l
   }
   exit
elsif path_info == '/view'
   ## Print formatted source
   puts( "Content-type: text/html\n\n" )
   rb2html_executable = rb2html_directory + '/rb2html.rb'
   if File::file?( rb2html_executable )
     begin
       htmlpipe = IO::popen( 'ruby ' + rb2html_executable + ' ' +
			   ENV['SCRIPT_FILENAME'].untaint )
       puts( htmlpipe.readlines() )
     rescue SystemCallError
       ## Mail admin if any errors - if you don't want mail, change
       ## the admin address.
       require 'net/smtp'
       smtp = Net::SMTP::new( "localhost" )
       smtp.start
       body = "Error:\nruby " + rb2html_executable + ' ' +
	ENV['SCRIPT_FILENAME'].untaint
       smtp.sendmail( body, 'rubycam_user@localhost', admin_email_address )
       smtp.finish
     end
     exit
   else
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: cannot execute " + rb2html_executable )
     exit
   end
elsif path_info != nil
   if not File::file?( config_dir + path_info )
     ## Print error
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: invalid config file: '" + config_dir + path_info + 
"'\n" +
	 "Set the PATH_INFO (in the url) to a valid config file name." )
     exit
   elsif path_info.index( '../' ) != nil
     ## Print error
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: invalid config file: '" + config_dir + path_info + 
"'\n" +
	 "'../' not permitted in config file pathname." )
     exit
   elsif not File::readable?( config_dir + path_info )
     ## Print error
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: unreadable config file: '" + config_dir + path_info + 
"'" )
     exit
   else
     ## Process config file
     config_file_string = ''
     File::open( config_dir + path_info ).readlines.each do |line|
       config_file_string.concat( line )
     end
     eval config_file_string
   end
end


###########################
### DETERMINE FILE INFO ###
###########################

## First, we determine the colors to be used for text (the image time)
## and for the background of the image (not the page bgcolor).
color_hash = {
   0 => 'white',
   1 => 'red',
   2 => 'orange',
   3 => 'yellow',
   4 => 'green',
   5 => 'blue',
   6 => 'purple',
   7 => 'lightgreen',
   8 => 'pink',
   9 => 'lightyellow',
   10 => 'lightblue',
   11 => 'lightgray',
   12 => 'gray'
}

## If img_background_color is set to nil, then no image background
## color options will apply.
if img_background_color != nil and
     use_randomize_img_background_color
   img_background_color = color_hash[rand(13)]
end

## If randomization is used for text and image, then the image
## background color is used for both.
if  use_randomize_text_color and
     not text_color_matches_img_background_color
   text_color = color_hash[rand(13)]
elsif ( img_background_color != nil ) and
       text_color_matches_img_background_color
   text_color = img_background_color
end

img_file_webpath = img_file_web_directory + '/' + img_filename
img_file_pathname = ENV['DOCUMENT_ROOT'] + img_file_webpath
img_file_pathname.untaint
img_file_tmp_pathname = img_file_pathname + '.tmp'

## Time
time_now = Time::now

## Mtime
if File::exist?( img_file_pathname )
   img_file_mtime = File::mtime( img_file_pathname )
   img_file_mtime_int = img_file_mtime.to_i
   img_file_mtime_string = img_file_mtime.to_s
   img_file_age = time_now.to_i - img_file_mtime_int
end

###########################
###    LOCKFILE CODE    ###
###########################

## Lock file name is global - there is only one camera and it can take
## only one picture at a time.  The lockfile is set during this process.
lock_file_pathname = ENV['DOCUMENT_ROOT'] + img_file_web_directory + '/' +
   lock_filename
lock_file_pathname.untaint

## If the lockfile somehow gets stale, it will be removed.
locked = false
if File::exist?( lock_file_pathname )
   if ( File::mtime( lock_file_pathname ) < ( time_now - ( 
max_lockfile_age ) ) )
     File::unlink( lock_file_pathname )
   else
     locked = true
   end
end

###########################
###       EXECUTE       ###
###########################

## If there's no image, or it's an old one, and the camera is free,
## then we take a new picture.
if  ( ( not File::exist?( img_file_pathname ) ) or
       ( img_file_age >= refresh ) ) and
     ( not locked )

   lockfile = File::new( lock_file_pathname, mode='w' )

   begin
     ## Execute
     img_file = File::open( img_file_tmp_pathname, mode='w').write( 
IO::popen( cmd_line ).read() )
     require 'ftools'
     File::mv( img_file_tmp_pathname, img_file_pathname )
     File::unlink( lock_file_pathname )
     img_file_mtime = Time::now
     img_file_mtime_string = img_file_mtime.to_s
   rescue SystemCallError
     ## Mail admin if any errors - if you don't want mail, change
     ## the admin address.
     require 'net/smtp'
     smtp = Net::SMTP::new( "localhost" )
     smtp.start
     body = "Subject: Error with rubycam\n" +
       "Failed to execute:\n" + cmd_line + "\n\nSee logs for details."
     smtp.sendmail( body, 'rubycam_user@localhost', admin_email_address )
     smtp.finish
     File::unlink( lock_file_pathname )
   end

end

###########################
###        HTML         ###
###########################

puts( "Content-type: text/html\n" +
      'Last-Modified: ' + img_file_mtime_string + "\n" +
      'Expires: ' + ( img_file_mtime + refresh ).to_s +
      "\n\n" )

puts( '<head><title>' + title + '</title>' +
      '<META HTTP-EQUIV="Refresh" CONTENT="' + refresh.to_s + '"></head>' )

puts( '<body bgcolor="' + bgcolor + '" text="' + text_color + '">' )

puts( '<center><table><tr><td' )

if img_background_color != nil
   puts( ' bgcolor="' + img_background_color + '"' )
end

puts( '><img src="' + img_file_webpath + '"></td></tr></table><p>' )

puts( '<p><b>' + img_file_mtime_string + '</b>' )

if source_link_target != nil
   puts( ' <small><a href="' + ENV['SCRIPT_NAME'].untaint + '/get" 
target="' + source_link_target + '"><font color="' + source_link_color + 
'">&reg;</font></a></small>' )
end

puts( '</center></body></html>' )



###########################
###  CALLING FROM HTML  ###
###########################
##
## Include the following in your page head:
##
##     <script language=javascript>
##     function openwin(url){
##         var hWnd =
## 
window.open(url,"","width=350,height=300,resizable=yes,scrollbars=yes"); 

##         if (!hWnd.opener) hWnd.opener = self;
##     }
##     function openminiwin(url){
##         var hWnd =
## 
window.open(url,"","width=180,height=140,resizable=yes,scrollbars=yes"); 

##         if (!hWnd.opener) hWnd.opener = self;
##     }
##     </script>
##
## Call within body of page as:
##
## <ul>
##         <li><a 
href="Javascript:openwin('/cgi-bin/webcam/rubycam.rb');">Webcam</a>
##         <li><a 
href="Javascript:openwin('/cgi-bin/webcam/rubycam.rb/transgif.conf');">Psychedelicam</a>
##         <li><a 
href="Javascript:openwin('/cgi-bin/webcam/rubycam.rb/greyjpeg.conf');">Greycam</a>
##
##
##         <li><a href="/cgi-bin/webcam/rubycam.rb/view">Formatted 
Source</a>
##         <li><a href="/cgi-bin/webcam/rubycam.rb/get">Source</a>
## </ul>
##

###########################
###   CONFIG FILE # 1   ###
###########################
## greyjpeg.conf - produces a grey jpeg
#  cmd_line = 'cqcam -s 1 | ppmtojpeg --progressive --greyscale 
--optimize --quality=33 --comment="Made with Rubycam"'
#  img_filename = 'grey.jpg'
#  title = 'Greycam'
#  refresh = 60

###########################
###   CONFIG FILE # 2   ###
###########################
## transgif.conf - produces a transparent gif with weird effects
#  cmd_line = 'cqcam -s 1 | ppmquant 2 | ppmtogif -transparent grey 
-interlace -sort -comment="Made with Rubycam"'
#  img_filename = 'transparent.gif'
#  title = 'Psychedelicam'
#  refresh = 60
#  img_background_color = 'red'
#  use_randomize_img_background_color = true
#  use_randomize_text_color = true
#  text_color_matches_img_background_color = true


## EOF
#!/usr/bin/env ruby

########################################################################
## VERSION: $Id: rubycam.rb,v 1.7 2002/03/22 20:08:52 pvoris Exp $
##
## AUTHOR: Phil Voris <rubycam@nekophile.com>
##
## LICENSE: Ruby License - must include this header comment block
##          http://www.ruby-lang.org/en/LICENSE.txt
##
## DESCRIPTION:
## This CGI webcam script attempts to conserve resources by not
## creating images more often than the number of seconds indicated by
## the refresh setting.  Maximum flexibility is given by allowing the
## administrator to set the image-producing command line.  The
## defaults are arranged to use cqcam
## (http://www.cs.duke.edu/~reynolds/cqcam/).
##
## REQUIRES: ruby
##           ruby modules: net/smtp (for error reporting), ftools
##           rb2html.rb (for viewing source)
##           some image-grabber, such as cqcam
##           optionally, some image manipulation software
##
## USAGE:
## * Install under cgi-bin or wherever cgi executables are allowed.
## * Configure the global config section below.
## * Configure the default config section below.
## * Optionally create one or more config files to call in the PATH_INFO.
## * Ensure that img_file_web_directory exists and is writable by the
##   web server
## * [See end of script for recommendations for config and calling from
##   html.]
##
## TO DO:
## It would be nice to add caching.  That is, deliver a header
## indicating that the page (the image) hasn't changed until it
## actually does.  I attempted this, but found that
## HTTP_IF_MODIFIED_SINCE didn't appear in the environment.  I then
## attempted to use a session to track if the use had seen the page
## with the current image - however sessions weren't quite working for
## me - perhaps someone else can resolve this issue.
########################################################################


#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# GLOBAL CONFIGURATION - EDIT HERE
#
# These options must be set
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

## allow options from URL (true / false)
use_config_files = true

## img file directory [relative to DOC_ROOT]
img_file_web_directory = '/img/cam'

## configuration files directory
config_dir = './config'

## directory where rb2html and associated files may be found
## (used for /view)
rb2html_directory = './rb2html-1.0'

## file base-name
lock_filename = 'rubycam.lock'

## maximum age to keep a lock file (seconds, must exceed refresh time)
max_lockfile_age = 500

## shows a little (R) which links to the source.  Specify the target
## frame ('_new', '_self', etc) or nil to not display it.
source_link_target = '_new'

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# END GLOBAL CONFIGURATION
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# PER-CAM CONFIGURATION - SET DEFAULTS HERE
#                       - MAY MODIFY IN CONFIG FILES
#
# Anything listed in this section may be set - as below - in a
# separate file.
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

## default_cqcam_opts
cmd_line = 'cqcam -r -q 25 -s 1 -j'

## filename for the images
img_filename = 'plain.jpg'

## admin email address
admin_email_address = 'webmaster@localhost'

## page title
title = 'Rubycam'

## background (color)
bgcolor = 'black'

## text (color)
text_color = 'yellow'

## browser refresh length (in seconds)
refresh = 60

## img_background_color (color | nil to disable globally)
img_background_color = nil

## randomize transparency_background_color (true / false)
use_randomize_img_background_color = false

## randomize transparency_background_color (true / false)
use_randomize_text_color = false

## match text and img backgrounds - useful for randomization
## (true / false)
text_color_matches_img_background_color = false

## color for the source link, if it appears (color)
source_link_color = 'darkred'

#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# END PER-CAM CONFIGURATION
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>






##########################################
### PROCESS URL OPTIONS FROM PATH_INFO ###
##########################################
## If the script is called from a URL with path info equal to 'view' or
## 'get' the contents of the script will be displayed.  'get' results
## in text/plain output while view - relying on rb2html - output color-
## coded html output with line numbers.
path_info = ENV['PATH_INFO'].untaint

if path_info == '/get'
   ## Print source
   puts( "Content-type: text/plain\n\n" )
   IO::foreach( ENV['SCRIPT_FILENAME'].untaint ) { |l|
     puts l
   }
   exit
elsif path_info == '/view'
   ## Print formatted source
   puts( "Content-type: text/html\n\n" )
   rb2html_executable = rb2html_directory + '/rb2html.rb'
   if File::file?( rb2html_executable )
     begin
       htmlpipe = IO::popen( 'ruby ' + rb2html_executable + ' ' +
			   ENV['SCRIPT_FILENAME'].untaint )
       puts( htmlpipe.readlines() )
     rescue SystemCallError
       ## Mail admin if any errors - if you don't want mail, change
       ## the admin address.
       require 'net/smtp'
       smtp = Net::SMTP::new( "localhost" )
       smtp.start
       body = "Error:\nruby " + rb2html_executable + ' ' +
	ENV['SCRIPT_FILENAME'].untaint
       smtp.sendmail( body, 'rubycam_user@localhost', admin_email_address )
       smtp.finish
     end
     exit
   else
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: cannot execute " + rb2html_executable )
     exit
   end
elsif path_info != nil
   if not File::file?( config_dir + path_info )
     ## Print error
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: invalid config file: '" + config_dir + path_info + 
"'\n" +
	 "Set the PATH_INFO (in the url) to a valid config file name." )
     exit
   elsif path_info.index( '../' ) != nil
     ## Print error
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: invalid config file: '" + config_dir + path_info + 
"'\n" +
	 "'../' not permitted in config file pathname." )
     exit
   elsif not File::readable?( config_dir + path_info )
     ## Print error
     puts( "Content-type: text/plain\n\n" )
     puts( "Error: unreadable config file: '" + config_dir + path_info + 
"'" )
     exit
   else
     ## Process config file
     config_file_string = ''
     File::open( config_dir + path_info ).readlines.each do |line|
       config_file_string.concat( line )
     end
     eval config_file_string
   end
end


###########################
### DETERMINE FILE INFO ###
###########################

## First, we determine the colors to be used for text (the image time)
## and for the background of the image (not the page bgcolor).
color_hash = {
   0 => 'white',
   1 => 'red',
   2 => 'orange',
   3 => 'yellow',
   4 => 'green',
   5 => 'blue',
   6 => 'purple',
   7 => 'lightgreen',
   8 => 'pink',
   9 => 'lightyellow',
   10 => 'lightblue',
   11 => 'lightgray',
   12 => 'gray'
}

## If img_background_color is set to nil, then no image background
## color options will apply.
if img_background_color != nil and
     use_randomize_img_background_color
   img_background_color = color_hash[rand(13)]
end

## If randomization is used for text and image, then the image
## background color is used for both.
if  use_randomize_text_color and
     not text_color_matches_img_background_color
   text_color = color_hash[rand(13)]
elsif ( img_background_color != nil ) and
       text_color_matches_img_background_color
   text_color = img_background_color
end

img_file_webpath = img_file_web_directory + '/' + img_filename
img_file_pathname = ENV['DOCUMENT_ROOT'] + img_file_webpath
img_file_pathname.untaint
img_file_tmp_pathname = img_file_pathname + '.tmp'

## Time
time_now = Time::now

## Mtime
if File::exist?( img_file_pathname )
   img_file_mtime = File::mtime( img_file_pathname )
   img_file_mtime_int = img_file_mtime.to_i
   img_file_mtime_string = img_file_mtime.to_s
   img_file_age = time_now.to_i - img_file_mtime_int
end

###########################
###    LOCKFILE CODE    ###
###########################

## Lock file name is global - there is only one camera and it can take
## only one picture at a time.  The lockfile is set during this process.
lock_file_pathname = ENV['DOCUMENT_ROOT'] + img_file_web_directory + '/' +
   lock_filename
lock_file_pathname.untaint

## If the lockfile somehow gets stale, it will be removed.
locked = false
if File::exist?( lock_file_pathname )
   if ( File::mtime( lock_file_pathname ) < ( time_now - ( 
max_lockfile_age ) ) )
     File::unlink( lock_file_pathname )
   else
     locked = true
   end
end

###########################
###       EXECUTE       ###
###########################

## If there's no image, or it's an old one, and the camera is free,
## then we take a new picture.
if  ( ( not File::exist?( img_file_pathname ) ) or
       ( img_file_age >= refresh ) ) and
     ( not locked )

   lockfile = File::new( lock_file_pathname, mode='w' )

   begin
     ## Execute
     img_file = File::open( img_file_tmp_pathname, mode='w').write( 
IO::popen( cmd_line ).read() )
     require 'ftools'
     File::mv( img_file_tmp_pathname, img_file_pathname )
     File::unlink( lock_file_pathname )
     img_file_mtime = Time::now
     img_file_mtime_string = img_file_mtime.to_s
   rescue SystemCallError
     ## Mail admin if any errors - if you don't want mail, change
     ## the admin address.
     require 'net/smtp'
     smtp = Net::SMTP::new( "localhost" )
     smtp.start
     body = "Subject: Error with rubycam\n" +
       "Failed to execute:\n" + cmd_line + "\n\nSee logs for details."
     smtp.sendmail( body, 'rubycam_user@localhost', admin_email_address )
     smtp.finish
     File::unlink( lock_file_pathname )
   end

end

###########################
###        HTML         ###
###########################

puts( "Content-type: text/html\n" +
      'Last-Modified: ' + img_file_mtime_string + "\n" +
      'Expires: ' + ( img_file_mtime + refresh ).to_s +
      "\n\n" )

puts( '<head><title>' + title + '</title>' +
      '<META HTTP-EQUIV="Refresh" CONTENT="' + refresh.to_s + '"></head>' )

puts( '<body bgcolor="' + bgcolor + '" text="' + text_color + '">' )

puts( '<center><table><tr><td' )

if img_background_color != nil
   puts( ' bgcolor="' + img_background_color + '"' )
end

puts( '><img src="' + img_file_webpath + '"></td></tr></table><p>' )

puts( '<p><b>' + img_file_mtime_string + '</b>' )

if source_link_target != nil
   puts( ' <small><a href="' + ENV['SCRIPT_NAME'].untaint + '/get" 
target="' + source_link_target + '"><font color="' + source_link_color + 
'">&reg;</font></a></small>' )
end

puts( '</center></body></html>' )














###########################
###  CALLING FROM HTML  ###
###########################
##
## Include the following in your page head:
##
##     <script language=javascript>
##     function openwin(url){
##         var hWnd =
## 
window.open(url,"","width=350,height=300,resizable=yes,scrollbars=yes"); 

##         if (!hWnd.opener) hWnd.opener = self;
##     }
##     function openminiwin(url){
##         var hWnd =
## 
window.open(url,"","width=180,height=140,resizable=yes,scrollbars=yes"); 

##         if (!hWnd.opener) hWnd.opener = self;
##     }
##     </script>
##
## Call within body of page as:
##
## <ul>
##         <li><a 
href="Javascript:openwin('/cgi-bin/webcam/rubycam.rb');">Webcam</a>
##         <li><a 
href="Javascript:openwin('/cgi-bin/webcam/rubycam.rb/transgif.conf');">Psychedelicam</a>
##         <li><a 
href="Javascript:openwin('/cgi-bin/webcam/rubycam.rb/greyjpeg.conf');">Greycam</a>
##
##
##         <li><a href="/cgi-bin/webcam/rubycam.rb/view">Formatted 
Source</a>
##         <li><a href="/cgi-bin/webcam/rubycam.rb/get">Source</a>
## </ul>
##













###########################
###   CONFIG FILE # 1   ###
###########################
## greyjpeg.conf - produces a grey jpeg
#  cmd_line = 'cqcam -s 1 | ppmtojpeg --progressive --greyscale 
--optimize --quality=33 --comment="Made with Rubycam"'
#  img_filename = 'grey.jpg'
#  title = 'Greycam'
#  refresh = 60














###########################
###   CONFIG FILE # 2   ###
###########################
## transgif.conf - produces a transparent gif with weird effects
#  cmd_line = 'cqcam -s 1 | ppmquant 2 | ppmtogif -transparent grey 
-interlace -sort -comment="Made with Rubycam"'
#  img_filename = 'transparent.gif'
#  title = 'Psychedelicam'
#  refresh = 60
#  img_background_color = 'red'
#  use_randomize_img_background_color = true
#  use_randomize_text_color = true
#  text_color_matches_img_background_color = true


## EOF

In This Thread

Prev Next