flow-tools 0.66用パッチ
Linux (Debian SargeとかCentOS)にてflow-tools 0.66(NetFlowコレクタ)のコンパイルが通らなかったので,いくつか修正してパッチファイル作った.
直したのは,ANSI C非互換のキャストの使い方をしていた部分と,ブロックの最後にラベルがあるとエラーになる問題.
前者は例えば以下のようなもの.
/* だめな例 */ void *foo = bar; (char *)foo += 2; /* 左辺値はキャストしたらだめー */ /* 修正後 */ void *foo = bar; foo = (char *)foo + 2;
後者は例えば以下のようなもの.
/* だめな例 */ for (;;) { do_something1(); if (cond) goto skip; do_something2(); skip: /* これだめ */ } /* 修正後 */ for (;;) { do_something1(); if (cond) goto skip; do_something2(); skip: ; /* とにかく何か文があればいいらしい */ }
パッチ (flow-tools-0.66-patch)
flow-tools-0.66ディレクトリ以下で patch -p0 < flow-tools-0.66-patch てな具合にするとよし.
diff -ru -x '*.Po' flow-tools-0.66.orig/lib/ftchash.c flow-tools-0.66/lib/ftchash.c --- flow-tools-0.66.orig/lib/ftchash.c 2003-02-13 11:38:41.000000000 +0900 +++ flow-tools-0.66/lib/ftchash.c 2008-05-12 16:32:07.000000000 +0900 @@ -326,7 +326,7 @@ (char*)ftch->traverse_chunk->base+ftch->traverse_chunk->next) { ret = ftch->traverse_rec; - (char*)ftch->traverse_rec += ftch->d_size; + ftch->traverse_rec = (char*)ftch->traverse_rec + ftch->d_size; return ret; } else { diff -ru -x '*.Po' flow-tools-0.66.orig/lib/ftio.c flow-tools-0.66/lib/ftio.c --- flow-tools-0.66.orig/lib/ftio.c 2003-02-24 09:51:47.000000000 +0900 +++ flow-tools-0.66/lib/ftio.c 2008-05-12 16:29:11.000000000 +0900 @@ -2267,7 +2267,7 @@ break; nleft -= nread; - (char*)ptr += nread; + ptr = (char*)ptr + nread; } return (nbytes - nleft); } /* readn */ @@ -2292,7 +2292,7 @@ return(nwritten); /* error */ nleft -= nwritten; - (char*)ptr += nwritten; + ptr = (char*)ptr + nwritten; } return(nbytes - nleft); } /* writen */ diff -ru -x '*.Po' flow-tools-0.66.orig/lib/fttlv.c flow-tools-0.66/lib/fttlv.c --- flow-tools-0.66.orig/lib/fttlv.c 2003-02-13 11:38:43.000000000 +0900 +++ flow-tools-0.66/lib/fttlv.c 2008-05-12 16:31:31.000000000 +0900 @@ -68,10 +68,10 @@ } bcopy(&t, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&len, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&v, buf, 4); @@ -107,10 +107,10 @@ } bcopy(&t, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&len, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&v, buf, 2); @@ -145,10 +145,10 @@ } bcopy(&t, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&len, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&v, buf, 1); @@ -183,10 +183,10 @@ } bcopy(&t, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&len, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(v, buf, len); @@ -230,16 +230,16 @@ return -1; bcopy(&t, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&len, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&ip, buf, 4); - (char*)buf += 4; + buf = (char*)buf + 4; bcopy(&ifIndex, buf, 2); - (char*)buf += 2; + buf = (char*)buf + 2; bcopy(name, buf, n); @@ -287,19 +287,19 @@ } bcopy(&t, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&len, buf, 2); - (char*)buf+= 2; + buf = (char*)buf + 2; bcopy(&ip, buf, 4); - (char*)buf += 4; + buf = (char*)buf + 4; bcopy(&entries, buf, 2); - (char*)buf += 2; + buf = (char*)buf + 2; bcopy(ifIndex_list, buf, esize); - (char*)buf += esize; + buf = (char*)buf + esize; bcopy(name, buf, n); diff -ru -x '*.Po' flow-tools-0.66.orig/src/flow-cat.c flow-tools-0.66/src/flow-cat.c --- flow-tools-0.66.orig/src/flow-cat.c 2003-04-03 03:03:01.000000000 +0900 +++ flow-tools-0.66/src/flow-cat.c 2008-05-12 16:33:59.000000000 +0900 @@ -551,7 +551,7 @@ break; next_file: - + ; } /* FOREACH filename in dir */ } /* foreach dir bundle */ diff -ru -x '*.Po' flow-tools-0.66.orig/src/flow-dscan.c flow-tools-0.66/src/flow-dscan.c --- flow-tools-0.66.orig/src/flow-dscan.c 2003-04-03 03:03:01.000000000 +0900 +++ flow-tools-0.66/src/flow-dscan.c 2008-05-12 16:34:28.000000000 +0900 @@ -560,7 +560,7 @@ ager(&ds, total_flows32); skip2: - + ; } /* while rec */ @@ -805,6 +805,7 @@ fterr_info("ager: reset hash run"); skip3: + ; } /* ager */ diff -ru -x '*.Po' flow-tools-0.66.orig/src/flow-fanout.c flow-tools-0.66/src/flow-fanout.c --- flow-tools-0.66.orig/src/flow-fanout.c 2003-04-04 11:24:40.000000000 +0900 +++ flow-tools-0.66/src/flow-fanout.c 2008-05-12 16:35:39.000000000 +0900 @@ -809,7 +809,7 @@ } /* fte.buf_size */ skip1: - + ; } /* if FD_ISSET */ if (sig_quit_flag) { diff -ru -x '*.Po' flow-tools-0.66.orig/src/flow-receive.c flow-tools-0.66/src/flow-receive.c --- flow-tools-0.66.orig/src/flow-receive.c 2003-04-03 03:03:02.000000000 +0900 +++ flow-tools-0.66/src/flow-receive.c 2008-05-12 16:34:46.000000000 +0900 @@ -753,7 +753,7 @@ } /* for */ skip1: - + ; } /* if FD_ISSET */ } /* while 1 */
こういうのCodeReposに上げてもいいのかなあ…….
リストのリストから,ハッシュのリストを作る
「怠慢はプログラマの美徳」というけれど - kなんとかの日記 を見て,
例えば、スクリプト言語で次のような Hash や Dict を書いたとする。
data = [ {'name'=>'Foo', 'age'=>20, 'email'=>'foo@mail.com'}, {'name'=>'Bar', 'age'=>21, 'email'=>'bar@mail.net'}, {'name'=>'Baz', 'age'=>22, 'email'=>'baz@mail.org'}, ]もしこれをみて何も感じないのであれば、スクリプト言語屋といえど Java 屋を笑うことはできない。本質的でない記述に嫌悪感を感じるセンスがあれば、同じキーが何度も現れていることを「めんどくさい」と感じるはずだ。そして、こんなふうに書けないだろうかと一度は思うはずだ。
data = %h{ ['name', 'age', 'email'], ['Foo', 20, 'foo@mail.com'], ['Bar', 21, 'bar@mail.net'], ['Baz', 22, 'baz@mail.org'], }「怠慢はプログラマの美徳」というけれど - kなんとかの日記
何だかむずむずしてきたので,リストのリストからハッシュのリストを生成するコード片を書いてみた.
#!/usr/local/bin/ruby require 'pp' class Array def to_AoH lambda {|keys, columns| columns.map! {|column| Hash[*keys.zip(column).flatten] } }.call(self.shift, self) end end table = [ [:name, :age, :email], ['Foo', 20, 'foo@mail.com'], ['Bar', 21, 'bar@mail.net'], ['Baz', 22, 'baz@mail.org'], ] pp table.to_AoH
実行結果はこんな感じ.
% ./table2arrayOfHash.rb [{:email=>"foo@mail.com", :name=>"Foo", :age=>20}, {:email=>"bar@mail.net", :name=>"Bar", :age=>21}, {:email=>"baz@mail.org", :name=>"Baz", :age=>22}]
でも,こっちの方が好みかなぁ.
#!/usr/local/bin/ruby require 'pp' class Array def to_AoH(*keys) map {|column| Hash[*keys.zip(column).flatten] } end end aoh = [ ['Foo', 20, 'foo@mail.com'], ['Bar', 21, 'bar@mail.net'], ['Baz', 22, 'baz@mail.org'], ].to_AoH(:name, :age, :email) pp aoh
いや,やはりキーはまず値より先に現れるべきか,と思い直してさらに修正.
#!/usr/local/bin/ruby require 'pp' class Array def to_AoH(*lists) lists.map {|values| Hash[*self.zip(values).flatten]} end end aoh = [:name, :age, :email].to_AoH( ['Foo', 20, 'foo@mail.com'], ['Bar', 21, 'bar@mail.net'], ['Baz', 22, 'baz@mail.org'] ) pp aoh
各リストをそれぞれメソッドの引数に積んでいるので,最後の要素の後ろにカンマ(',')を書けないところが若干気持ち悪いけど,こんなところかなぁ.
テイルズ・エール・ハウス
ピンクの象さんの看板でお馴染みの,テイルズ・エール・ハウスに行ってきました.
このお店は,やたらとクオリティの高いベルギービールが飲める,とても危険なお店です.
店内の様子はこんな感じ
お店に着くや否や,最初からロシュフォール10をオーダするだめ人間なわたし
こちらはマスターに教えていただいた「セント・ベルナンデュス ベリオール」というベルギービール.通称「赤ボウズ」と言うらしい.これがまたアホみたいに美味く,当方のメートルも上がる一方.
マルール12.濃厚な味わいと香り.ロシュフォールよりこちらの方が好きかも.
こちらは「青ボウズ」.腰が抜けるほどうまい.
ごちそうさま!
SMTP-AUTH用の証明書を作る
酔っぱらった日は証明書のメンテナンスに限る.
ということで,デフォルトで入ってたSnakeOil証明書に甘んじていた我が家のPostfixを,もう少しましな感じにしようかなと決意する.結局,第四種オレオレ証明書だけどね.
作業手順
/etc/ssl/demoCAができてる事が前提.無い人は/usr/lib/ssl/misc/CA.pl -newcaで.
秘密鍵作る
# cd /etc/ssl # openssl genrsa -out demoCA/private/`hostname`.key 2048 Generating RSA private key, 2048 bit long modulus ............................................+++ ...............................................+++ e is 65537 (0x10001)
作った秘密鍵の中身を確認したければ以下のような感じで.
# openssl rsa -in demoCA/private/`hostname`.key -text
CSRつくる
# openssl req -new -key demoCA/private/`hostname`.key -out csr.pem
OUとかコモンネーム(CN)などを聞かれるので適切に答えていくと,CSRファイルができる.
作ったCSRの中身を確認するには,以下のような感じで.
# openssl req -in csr.pem -text
署名するぜ(by CA)
ここでCAの立場になる.
先ほど作ったCSRをもとに,証明書を発行する.
# openssl ca -in csr.pem -out demoCA/certs/`hostname`.pem -days 3650 Using configuration from /usr/lib/ssl/openssl.cnf Check that the request matches the signature Signature ok Certificate Details: Serial Number: de:ad:be:ef:ab:ad:ca:fe Validity Not Before: Apr 25 00:00:00 2008 GMT Not After : Apr 25 00:00:00 2018 GMT Subject: countryName = JP stateOrProvinceName = Foreign organizationName = My company organizationalUnitName = My Unit commonName = mail.example.com emailAddress = webmaster@example.com X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: DE:AD:BE:EF:AB:AD:CA:FE:DE:AD:BE:EF:AB:AD:CA:FE:DE:AD:BE:EF X509v3 Authority Key Identifier: keyid:DE:AD:BE:EF:AB:AD:CA:FE:DE:AD:BE:EF:AB:AD:CA:FE:DE:AD:BE:EF Certificate is to be certified until Apr 25 00:00:00 2018 GMT (3650 days) Sign the certificate? [y/n]:
証明書の中身を確認し,問題がなければ y と入力.
Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
これで完了
Postix SMTP-AUTH用設定
main.cfで
smtpd_tls_cert_file=/etc/ssl/demoCA/certs/EXAMPLE.pem smtpd_tls_key_file=/etc/ssl/demoCA/private/EXAMPLE.key
再読み込み
# /etc/init.d/postfix reload Reloading Postfix configuration...done.
これでSnakeOilから脱却.やったね.
VMware上のUbuntuでMozilla Trunkビルド環境を作る
VMware上にUbuntu 7.10環境を構築し,Mozilla Trunk(Minefield)のビルド環境を構築するためのメモ.
作業手順 (Ubuntuセットアップ)
VMware上にUbuntu用ゲストOSを作成
ゲストOS作成後,vmxファイルをテキストエディタで開き,以下を追加する.これは,VMware上でUbuntuのインストーラを起動させた際,解像度がやたら高くなってしまう問題を回避するため.
svga.maxWidth = "1024" svga.maxHeight = "768"
D: にUbuntu 7.10のisoイメージをマウントし,普通にインストール.再起動する.
まずはアップデート
GUIが好きな人は,タスクトレイ(?)の所にあるアレをクリックしてアップデートしてもよいと思う.
% sudo apt-get update % sudo apt-get upgrade
一度再起動が必要かも.
Mozillaのビルドに必要なパッケージをapt-get install
がんがんapt-get installする.
% sudo apt-get -y install build-essential % sudo apt-get -y build-dep firefox-3.0 % sudo apt-get -y install cvs % sudo apt-get -y install libdbus-glib-1-dev % sudo apt-get -y install libcurl3 % sudo apt-get -y install libcurl4-openssl-dev
生活環境も整える.
% sudo apt-get -y install vim lv % sudo apt-get -y install subversion zsh openssh-server % sudo apt-get -y install ddd global
zshが無いと死ぬ人はchshしておく.
VMware toolsをビルドするのに必要なパッケージもインストール.
% sudo apt-get install libqt3-headers libqt3-mt-dev % sudo apt-get install bin86 kernel-package
VMware toolsをここでインストールしてもよいし,しなくてもよい.
私は上記を毎回手で打つのも面倒なので,.sshや.zshenv, .zshrc, .screenrc, ... etc ... を展開する作業とあわせてシェルスクリプトにした.このあたりは各自お好みで.
Mozilla Firefox(Minefield)ビルド手順
ビルド環境を整える
${HOME}/.mozconfigを作る
. $topsrcdir/browser/config/mozconfig export CC=/usr/bin/gcc export CXX=/usr/bin/g++ mk_add_options MOZ_CO_PROJECT=browser mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/firefox-build ac_add_options --enable-application=browser ac_add_options --enable-default-toolkit=cairo-gtk2 # below are not necessary. do as you like: ac_add_options --disable-ldap ac_add_options --disable-postscript ac_add_options --disable-accessibility ac_add_options --disable-printing ac_add_options --disable-composer ac_add_options --disable-mathml ac_add_options --disable-svg ac_add_options --disable-svg-foreignobject ac_add_options --enable-debug ac_add_options --enable-optimize=-O
ビルドの度に手でコマンドを打つのも面倒なので,シェルスクリプト書く.
- build-trunk.sh
#!/bin/sh # build-trunk.sh # $Id: build-trunk.sh 87 2008-04-07 08:57:04Z genta $ # BRANCH="-r MOZILLA_1_8_BRANCH" BRANCH="" DIRNAME="mozilla_trunk" LOG=${HOME}/log/build.${DIRNAME}.log export CVSROOT=':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot' # Output to STDOUT and STDERR gose to file ${LOG} exec 4>&1 5>&2 exec 3>${LOG} 1>&3 2>&3 echo 'Begin building' LANG=C date # rotate dir and mkdir if [ -d ${DIRNAME} ]; then if [ -d ${DIRNAME}.old ]; then mv ${DIRNAME}.old ${DIRNAME}.trash rm -rf ${DIRNAME}.trash fi mv ${DIRNAME} ${DIRNAME}.old fi mkdir ${DIRNAME}; cd ${DIRNAME} cvs co ${BRANCH} mozilla/client.mk cvs co ${BRANCH} mozilla/browser/config/mozconfig mkdir mozilla/firefox-build cd mozilla cp ${HOME}/.mozconfig . make -f client.mk checkout make -f client.mk build 2>&1 echo 'Build done' LANG=C date echo 'Creating gtags' LANG=C date gtags -v htags -saF echo 'Done'
gtagsとかしている部分はお好みで.
ビルド中のログを出力するためのディレクトリを掘る.
% mkdir ~/log
ビルド
% ./build-trunk.sh
ビルド中のログは~/log/build.mozilla_trunk.logに落ちているので,気になる人は他の端末エミュレータを開いてtail -fしておくとよいと思う.
起動
無事ビルドが終わったら,起動してみる.
% cd mozilla_trunk/mozilla/firefox-build/dist/bin % ./run-mozilla.sh ./firefox
run-mozilla.shの引数には "./firefox" と,"./" を忘れないように注意.忘れると/usr/bin/firefoxの方が起動したりしてわりと混乱することになる.
デバッガ(ddd)の上でfirefoxを起動するときは以下のようにする.
% ./run-mozilla.sh -g ./firefox-bin
runさせて適当なタイミングでinfo threadsとかして途方に暮れるのもよし.
ssh経由で起動するときは,DISPLAY環境変数を適当に設定しておくとよし.手元にX11が起動していればそれを使ってもいいと思う.
% env DISPLAY=:0.0 ./run-mozilla.sh ./firefox-bin
GNU Globalで作ったHTMLを閲覧
htagsが~/mozilla_trunk/mozilla/HTML以下にHTMLファイルを作ってくれているので,これをソースコード解析の基点にすることができる.普通にUbuntuの上でWebブラウザを用いて閲覧するか,またはlighttpdとか適当なHTTPdをインストールして他のマシンから閲覧してもよい.
lighttpdのセットアップ (おまけ)
public_htmlを用意
% mkdir ~/public_html % cd ~/public_html % ln -s ../mozilla_trunk/mozilla/HTML
- build-lighttpd.sh
#!/bin/sh # build-lighttpd.sh -- Build lighttpd environment for reading source code apt-get install lighttpd cp lighttpd.user /etc/lighttpd (cd /etc/lighttpd; patch ) < patch.lighttpd.conf (cd /etc/lighttpd/conf-available; patch -p1 ) < patch.auth.conf /usr/sbin/lighty-enable-mod auth /usr/sbin/lighty-enable-mod userdir /etc/init.d/lighttpd force-reload
- lighttpd.user
yourname:yourBasicAuthPassword
お好みで.
- patch.lighttpd.conf
*** lighttpd.conf.orig 2008-03-12 04:23:02.000000000 +0900 --- lighttpd.conf 2008-04-07 12:03:07.000000000 +0900 *************** *** 63,68 **** --- 63,69 ---- ## bind to port (default: 80) # server.port = 81 + server.port = 10080 ## bind to localhost only (default: all interfaces) ## server.bind = "localhost"
server.portはお好みで.
- patch.auth.conf
*** conf-available/10-auth.conf.orig 2008-03-12 04:23:02.000000000 +0900 --- conf-available/10-auth.conf 2008-04-07 12:17:00.000000000 +0900 *************** *** 5,13 **** server.modules += ( "mod_auth" ) ! # auth.backend = "plain" ! # auth.backend.plain.userfile = "lighttpd.user" ! # auth.backend.plain.groupfile = "lighttpd.group" # auth.backend.ldap.hostname = "localhost" # auth.backend.ldap.base-dn = "dc=my-domain,dc=com" --- 5,20 ---- server.modules += ( "mod_auth" ) ! auth.backend = "plain" ! auth.backend.plain.userfile = "/etc/lighttpd/lighttpd.user" ! auth.backend.plain.groupfile = "lighttpd.group" ! ! auth.require = ( "/" => ! ( "method" => "digest", ! "realm" => "Permitted user", ! "require" => "valid-user" ! ) ! ) # auth.backend.ldap.hostname = "localhost" # auth.backend.ldap.base-dn = "dc=my-domain,dc=com"
BASIC認証の設定ファイル.これまたお好みで.
インストール用スクリプトを実行.
% sudo ./build-lighttpd.sh
他のマシンから http://
または,mozilla.orgが提供しているLXRも便利かも.
WEBrickをちょこっとだけ触ってみる
デバッグ用にちょっとしたWebサーバを作ってみたくなったので,WEBrickを触ってみた.
#!/usr/local/bin/ruby require 'webrick' require 'pp' class MyServlet < WEBrick::HTTPServlet::AbstractServlet # Process GET Request # # _req_:: WEBrick::HTTPRequest # _res_:: WEBrick::HTTPResponse # returns:: WEBrick::HTTPResponse def do_GET(req, res) res['Content-Type'] = 'text/html; charset=utf-8' you = req.query['name'] || 'you' greeting = {'morning' => 'Good morning', 'evening' => 'Good evening' }[req.query['time']] || 'Hello' res.body = "<html><body><p>#{greeting}, #{you}!</p></body></html>\n" return res end end srv = WEBrick::HTTPServer.new(:BindAddress => '127.0.0.1', :Port => 10080 ) ['INT', 'TERM'].each do |signal| trap(signal) { srv.shutdown } end srv.mount('/app', MyServlet) srv.start
たったこれだけのコードで,localhost:10080上でWebサーバが起動した.こりゃおもしろい.何より,わかりやすい所がいい.AbstractServletを継承したクラスを作って,扱いたいHTTPリクエストのメソッドを処理する関数(do_GETとかdo_HEADとか)を定義して,WEBrick::HTTPServer#mountするだけ.シンプルで良い.
難点は,セッション管理とか細かい所の面倒を見てくれない所かな.探せばライブラリあるんだろうか.
Smartyをちょこっとだけ触ってみる
ほとんど忘れていたPHP5の復習がてら,Smarty触ってみた.
とりあえずサンプルコードから適当にコピペしてでっちあげる.動く.全く簡単だ(動かす分には).
メモ
- {$var|escape:"htmlall":char_set}はhtmlentities($string, ENT_QUOTES, $char_set)相当
- default_modifiersに書くと全項目で適用されるescapeを書けるけど,charsetを忘れずに指定しておく
- テンプレート中で,meta〜charsetを何よりも先に書く.またはApacheの方でAddDefaultCharset: UTF-8とかしてHTTPレスポンスヘッダでcharset吐く(UTF-7 XSS対策)
- PHPに限らないけど
- 属性値をクォートしない奴はクビ
- PHPに限らないけど
- テンプレート例)
- フォーム入力例)
- `` style=`background-image: url(javascript:alert(document.URL))`
- HTML出力例)
- <input value=`` style=`background-image: url(javascript:alert(document.URL))`>
- IE6は,バッククォートで属性値をクォートできるという素敵仕様のため,こんな感じでhtmlentitiesに引っかからない文字列だけでXSSできる(クォート忘れてると)
- その他XSSの例: http://ha.ckers.org/xss
ToDo
ソース
index.php
<?php require_once('smarty/Smarty.class.php'); $smarty = new Smarty; $smarty->default_modifiers = array('escape:"htmlall":"UTF-8"'); $name = isset($_POST['name']) ? $_POST['name'] : 'id:ihag'; $url = isset($_POST['url']) ? $_POST['url'] : 'http://d.hatena.ne.jp/ihag/'; $smarty->assign('name', $name); $smarty->assign('url', $url); $smarty->display('index.tpl'); ?>
template/index.tpl
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Index page</title> </head> <body> <p>ユーザ情報表示:</p> <form method="POST" action="/index.php"> 名前: <input type="text" size="60" name="name" value="{$name}"><br> URL: <input type="text" size="80" name="url" value="{$url}"><br> <input type="submit" value="Submit"> </form> </body> </html>