├── .gitattributes ├── .gitignore ├── .htaccess ├── README ├── cgiirc.config ├── cgiirc.config.full ├── client-perl.cgi ├── client.c ├── docs ├── CHANGES ├── COPYING ├── TODO ├── decode.pl ├── help.html ├── help.ru.html ├── identd.pl ├── identd.xinetd ├── smilies.conf.example └── viewconnects.pl ├── formats ├── dark ├── default ├── dutch ├── german ├── gothic ├── mirc ├── norwegian ├── romanian └── russian ├── images ├── actmsg.wav ├── actsound.gif ├── angry.gif ├── cgiirc.gif ├── cheesy.gif ├── closedn.gif ├── closeup.gif ├── confused.gif ├── cool.gif ├── cry.gif ├── embarassed.gif ├── entry.gif ├── favicon.ico ├── flat.gif ├── font.gif ├── grin.gif ├── happy.gif ├── happycry.gif ├── helpdn.gif ├── helpup.gif ├── hmmm.gif ├── join.wav ├── joinsound.gif ├── kiss.gif ├── love.gif ├── notsure.gif ├── optionsdn.gif ├── optionsup.gif ├── scrollback.gif ├── sleep.gif ├── smile.gif ├── sorry.gif ├── surprised.gif ├── taras │ ├── angry.gif │ ├── cheesy.gif │ ├── closedn.gif │ ├── closeup.gif │ ├── confused.gif │ ├── cool.gif │ ├── cry.gif │ ├── embarassed.gif │ ├── entry.gif │ ├── flat.gif │ ├── font.gif │ ├── grin.gif │ ├── happy.gif │ ├── helpdn.gif │ ├── helpup.gif │ ├── love.gif │ ├── notsure.gif │ ├── optionsdn.gif │ ├── optionsup.gif │ ├── smile.gif │ ├── surprised.gif │ ├── time.gif │ ├── tongue.gif │ ├── unhappy.gif │ └── wink.gif ├── time.gif ├── tongue.gif ├── unhappy.gif ├── what.gif └── wink.gif ├── interfaces ├── .gitignore ├── default.pm ├── interface-make │ ├── fform.pm │ ├── fmain.pm │ ├── fuserlist.pm │ ├── fwindowlist.pm │ ├── main.pm │ └── make-js-interfaces.pl ├── nonjs.pm ├── opera.pm ├── style-dark.css ├── style-default.css ├── style-gothic.css └── style-mirc.css ├── ipaccess.example ├── irc.cgi ├── modules ├── .htaccess ├── Command.pm ├── Event.pm ├── IRC.pm ├── IRC │ ├── Channel.pm │ ├── Channel │ │ └── Nick.pm │ ├── Event.pm │ ├── RawCommands.pm │ ├── UniqueHash.pm │ └── Util.pm ├── Timer.pm └── parse.pl └── nph-irc.cgi /.gitattributes: -------------------------------------------------------------------------------- 1 | *.cgi ident 2 | *.c ident 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | client.cgi 2 | .*.swp 3 | *.gz 4 | *.tgz 5 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | deny from all 4 | 5 | 6 | 7 | #DirectoryIndex irc.cgi 8 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | CGI:IRC - http://cgiirc.org/ 2 | ---------------------------- 3 | 4 | CGI:IRC is a Perl/CGI program that lets you access IRC from a web browser, it 5 | is designed to be flexible and has many uses such as an IRC gateway for an IRC 6 | network, a chat-room for a website or to access IRC when stuck behind a 7 | restrictive firewall. 8 | 9 | This is a very quick guide to CGI:IRC, you will find more documentation in the 10 | docs directory and on the website. 11 | 12 | Requirements 13 | ------------ 14 | 15 | 1. Ability to run CGI scripts using Perl 5.004 or greater 16 | 2. UNIX based system 17 | 3. Acceptable use policy allows access to IRC 18 | 19 | Generally if you pay your host enough they will let you run CGI:IRC, but beware 20 | it does use a lot of memory because each user uses a web server process and a 21 | perl process. This is due to the stream based nature and the fact most 22 | webservers are designed to serve static content. 23 | 24 | Installing 25 | ---------- 26 | These are very simple instructions, see the website for more in depth 27 | instructions. 28 | 29 | 1. Edit the cgiirc.config or cgiirc.config.full (if you use cgiirc.config.full 30 | make sure to rename it to cgiirc.config). 31 | 2. Copy or upload all the files to your cgi-bin directory, and put the images 32 | directory in the correct location (may or may not be inside the cgi-bin 33 | directory). 34 | If you don't want to the docs directory does not need to be uploaded to the 35 | server. 36 | 3. Check that all the files have the correct permissions and so on 37 | 4. Visit the location you installed irc.cgi to. 38 | 39 | If it doesn't work see the website as it has answers to common problems. 40 | 41 | Support 42 | ------- 43 | 44 | CGI:IRC has a mailing list for support questions and anything else: 45 | http://lists.sourceforge.net/lists/listinfo/cgiirc-general 46 | 47 | Make sure you read the FAQ on the website before posting though ;-) 48 | 49 | -- 50 | David Leadbeater 51 | -------------------------------------------------------------------------------- /cgiirc.config: -------------------------------------------------------------------------------- 1 | # This is the default configuration file for CGI:IRC 0.5 2 | # See http://cgiirc.org/docs/config.php for help editing it. 3 | 4 | # If you want to allow the use of multiple servers or enable more 5 | # advanced options please copy cgiirc.config.full over this file, 6 | # then edit that. 7 | 8 | # Set the server(s) that access is allowed to, to allow more than one entry 9 | # seperate the servers with commas. 10 | default_server = irc.blitzed.org 11 | default_port = 6667 12 | # Channel(s) to allow access to, a comma seperated list 13 | default_channel = #cgiirc 14 | # The default name (shown in /whois) of a user 15 | default_name = CGI:IRC User 16 | # The default nickname, any ? is replaced with a random number 17 | default_nick=CGI??? 18 | 19 | # The path to images for the browser (a URL!) 20 | # In script aliased directories (cgi-bin) the default will *not* work, 21 | # you need to move the directory elsewhere and change this to something 22 | # like /images. 23 | image_path = images 24 | 25 | # You can change the location of the scripts if needed. 26 | # This doesn't usually need to be changed but they *must* be set. 27 | script_nph = nph-irc.cgi 28 | script_form = client-perl.cgi 29 | script_login = irc.cgi 30 | 31 | -------------------------------------------------------------------------------- /cgiirc.config.full: -------------------------------------------------------------------------------- 1 | # This is the full access CGI:IRC 0.5 config file 2 | # It will allow access to *all* servers and channels 3 | # See http://cgiirc.org/docs/config.php for help editing it. 4 | 5 | # ----- 6 | # These are the default settings to show on the login form 7 | 8 | # default server(s) to connect to, more than one server can 9 | # be entered as a comma seperated list 10 | default_server = irc.blitzed.org 11 | default_port = 6667 12 | 13 | # default channel(s), again this can be a comma seperated list 14 | default_channel = #cgiirc 15 | 16 | # Realname to use (in /whois) 17 | default_name = CGI:IRC User 18 | 19 | # default nickname, a ? is replaced with a random number 20 | default_nick = CGI??? 21 | 22 | # The default username to send, this will only be sent if 23 | # encoded_ip (below) is set to 1 or less and will have no affect 24 | # if the system is running identd. 25 | default_user = cgiirc 26 | 27 | # Default quit message 28 | #quit_message = CGI:IRC 29 | # Quit prefix added to EOF messages and other quits not from /quit 30 | #quit_prefix = CGI:IRC 31 | 32 | # ----- 33 | # System setup options 34 | 35 | # You can change the default locations of the scripts with these 36 | # settings, generally they don't need to be changed 37 | script_nph = nph-irc.cgi 38 | script_form = client-perl.cgi 39 | script_login = irc.cgi 40 | 41 | # The path to images for the browser (a URL!) 42 | # In script aliased directories (cgi-bin) the default will *not* work, 43 | # you need to move the directory elsewhere and change this to something 44 | # like /images. 45 | image_path = images 46 | 47 | # The charset to send to IRC, to send anything other than UTF-8 you will 48 | # need the Encode perl module installed. 49 | # See perldoc Encode::Supported for a list of supported encodings. 50 | # If you see the wrong characters in CGI:IRC or with a normal IRC client 51 | # you probably need to change this or set it on the login form. 52 | # Note that this config file should be encoded in UTF8, regardless of this 53 | # setting. 54 | # Extended ASCII: 55 | #irc charset = iso-8859-1 56 | 57 | # Additionally a fallback character set can be specified so if multiple 58 | # character sets are in use an attempt can be made to decode using the fallback 59 | # if decoding using the main character set fails. Default is iso-8859-1. 60 | # Set to the same character set as above to avoid falling back to this 61 | # character set and use substitution characters for unknown characters. 62 | #irc charset fallback = 63 | 64 | # The location to *append* before the location of the socket directory 65 | # (don't change this unless you understand it - and then think about it again). 66 | # Remember you will need to either edit client-perl.cgi or 67 | # client.c and recompile client.cgi if you change this 68 | 69 | # IF YOU CHANGE THIS AND HAVE ANY PROBLEMS TRY THE DEFAULT BEFORE ASKING FOR 70 | # HELP 71 | socket_prefix = /tmp/cgiirc- 72 | 73 | # Virtual Host - Bind to a specific IP address 74 | # (this must be a valid interface or IP alias on your system). 75 | #vhost = 0.0.0.0 76 | # For IPv6 77 | #vhost6 = 78 | 79 | # Prefer IPv6 addresses if both addresses resolve (default is IPv4). 80 | #prefer_v6 = 0 (XXX: This option does not currently work) 81 | 82 | # ----- 83 | # Access related settings 84 | 85 | # encoded_ip, set to 3 to send real IP in realname and encoded in username 86 | # set to 2 to send hex encoded IP address in username 87 | # and in realname, set to 1 to send only in realname and 0 to 88 | # disable. 89 | encoded_ip = 2 90 | 91 | # If the ip_access_file option is set to the filename that 92 | # contains ipaccess information then CGI:IRC will check this file. 93 | # See ipaccess.example for more information, rename it to ipaccess 94 | # and uncomment the line below to enable. 95 | # NOTE: If the file does not exist, all clients are denied! 96 | #ip_access_file = ipaccess 97 | # If the ip_access_file option is set to a comma-separated list 98 | # of filenames, they are checked sequentially, as if they were 99 | # concatenated. 100 | #ip_access_file = ipaccess.deny,ipaccess.allow 101 | 102 | # The maximum number of users that can connect to this CGI:IRC script at once 103 | # Please note, sometimes CGI:IRC leaves files in the socket_prefix location, if 104 | # it is killed (kill -9) or maybe a bug - this option still counts those as users. 105 | #max_users = 20 106 | 107 | # Allow access to servers, ports and channels not set in the default 108 | # settings above and use access_channel, access_port and access_server below. 109 | allow_non_default = 1 110 | 111 | # This is regular expression that sets what channels access should 112 | # be allowed to. 113 | access_channel = .* 114 | 115 | # This is regular expression that sets what servers access should 116 | # be allowed to. 117 | access_server = .* 118 | 119 | # This is regular expression that sets what ports access should 120 | # be allowed to. 121 | access_port = .* 122 | 123 | # A list of commands to allow and deny access to, this is a space 124 | # seperated list of commands to allow access to or if prefixed 125 | # with an ! commands to disallow access to. 126 | # Eg to only allow access to, msg, me, whois, join, nick 127 | # = msg me whois join nick ! 128 | # Note the ! on the end, it disallows all other commands 129 | 130 | # It is recommened that you disable quote if you are limiting 131 | # access to channels. 132 | #access_command = !quote 133 | access_command = 134 | 135 | # Session timeout (timeout after this many seconds of inactivity). 136 | # 18000 is 5 hours 137 | session_timeout = 18000 138 | 139 | # Admin password (used for /ctcp kill) 140 | # Remember this is a crypt of the password - not the actual password. 141 | # You can generate this by running (at a Unix shell prompt): 142 | # perl -le'print crypt(shift,$$)' password 143 | # where password is the password to generate a crypt for. 144 | #admin password = 145 | 146 | # If your server is password protected and you wish to provide the password in 147 | # the script rather than get the user to enter the password then set this 148 | # option to the password (The user can still override this with a password on 149 | # the login form). 150 | #server_password = 151 | 152 | # Send extra information (e.g. proxy headers) on ctcp USERINFO. 153 | #extra_userinfo = 1 154 | 155 | # If the IRC server has been configured to allow CGI:IRC host spoofing (web irc 156 | # spoofing), then set this to the password to use. 157 | #webirc_password = 158 | 159 | # If the irc server you are connecting to accepts hostnames encoded into 160 | # passwords (old style CGI:IRC host spoofing) and it has been setup for your 161 | # host uncomment the following line. 162 | #realhost_as_password = 1 163 | 164 | # Check clients connecting against a DNSBL (deny access if their IP address is in 165 | # it), seperate with spaces to check more than one. 166 | #dnsbl = dnsbl.dronebl.org 167 | 168 | # Redirect to a different URL (eg. custom login form) instead of the default. 169 | #form_redirect = http://cgiirc.org/docs/custom.php 170 | 171 | # List of URLs (seperated with ,) which this copy of CGI:IRC should 172 | # balance requests over. All the URLs should be within the domain set for 173 | # javascript_domain below and should point to the directory which the 174 | # CGI:IRC install is in without a trailing /. 175 | #balance_servers = http://a.cgiirc.org, http://foo.cgiirc.org/cgi-bin/cgiirc 176 | 177 | # Set JavaScript document.domain. 178 | #javascript_domain = cgiirc.org 179 | 180 | # Set the login secret (used to make it slightly harder to abuse CGI:IRC by 181 | # opening lots of connections to it). This should be a hard to guess sequence 182 | # of characters (you never need to type it in). If balance_servers is used this 183 | # should be set to the same value on all servers. This requires the Digest::MD5 184 | # module. 185 | #login secret = 186 | 187 | # ----- 188 | # Appearence settings 189 | 190 | # The options to show on the basic and advanced login forms. 191 | # Simply a space seperated list of the fields to display. 192 | #login basic = Nickname, Channel 193 | #login advanced = Nickname, Realname, Channel, Server, Password, Format, Character set 194 | 195 | # The default format to use 196 | format = default 197 | 198 | # These options control where output goes. Parameters are comma seperated 199 | # and are the types (e.g. the names used in the format files), only the 200 | # first two words are matched. 201 | 202 | # Do not output joins, parts or quits. 203 | #output none = join, part, quit 204 | # Hide a lot of information that is shown at connect time 205 | #output none = raw 439, reply welcome, reply yourhost, reply created, reply myinfo, reply protoctl, raw 251, raw 252, raw 254, raw 255, raw 265, raw 266, looking up, connecting, reply motd start, reply motd end, reply names 206 | 207 | # Show whois in the active window 208 | #output active = reply whois 209 | 210 | # Show the names output in the Status window 211 | #output status = reply names 212 | 213 | # Perform these commands (seperated with) ; on connect. 214 | #perform = 215 | 216 | # Remove almost all colour from the output 217 | #removecolour = 0 218 | 219 | # By default CGI:IRC shorterns the text inside links to 120 characters to work 220 | # around browser bugs. This changes the length text is shortened to 221 | #linkshorten = 120 222 | 223 | # If set this disables the input of %C, %B, etc so that the user 224 | # cannot enter colours, etc 225 | #disable_format_input = 1 226 | 227 | # Location of smilies configuration file 228 | #smilies = smilies.conf 229 | 230 | # Show a popup for users to select smilies from? 231 | # The smilies option above must also be set to a valid file. 232 | #smilies_popup = 1 233 | 234 | # Number of smilies per row in popup. 235 | #smilies_perrow = 5 236 | 237 | # ---- 238 | # Interface settings 239 | # These control the options for the user - the user can change these via the 240 | # options dialog. 241 | # Uncommenting the options below will change from the default value. 242 | 243 | # Enable Timestamps for all text 244 | #interface timestamp = 1 245 | # Convert :-) and so on into smilie images 246 | #interface smilies = 1 247 | # Default font to use 248 | #interface font = monospace 249 | # Show users nickname next to text entry area 250 | #interface shownick = 1 251 | # Show long scrollback (uses more memory) 252 | #interface scrollback = 1 253 | # Enable activity sounds by default 254 | #interface actsound = 1 255 | # Enable join sounds by default 256 | #interface joinsound = 1 257 | 258 | -------------------------------------------------------------------------------- /client-perl.cgi: -------------------------------------------------------------------------------- 1 | #! /usr/bin/perl -w 2 | # CGI:IRC - http://cgiirc.org/ 3 | # Copyright (C) 2000-2007 David Leadbeater 4 | # vim:set ts=3 expandtab shiftwidth=3 cindent: 5 | 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | 20 | use strict; 21 | use lib qw/modules/; 22 | use vars qw($VERSION $PREFIX); 23 | 24 | # change this if needed 25 | $PREFIX = "/tmp/cgiirc-"; 26 | 27 | use Socket; 28 | use Symbol; 29 | $|++; 30 | require 'parse.pl'; 31 | 32 | sub net_unixconnect { 33 | my($local) = @_; 34 | my $fh = Symbol::gensym; 35 | 36 | socket($fh, PF_UNIX, SOCK_STREAM, 0) or return (0, $!); 37 | connect($fh, sockaddr_un($local)) or return (0, $!); 38 | 39 | return $fh; 40 | } 41 | 42 | sub net_send { 43 | my($fh,$data) = @_; 44 | syswrite($fh, $data, length $data); 45 | } 46 | 47 | sub error { 48 | my($message) = @_; 49 | print "Content-type: text/html\r\n\r\n"; 50 | print "An error occurred: $message\n"; 51 | exit; 52 | } 53 | 54 | my $cookie = parse_cookie(); 55 | my($input,$rand) = cgi_read(); 56 | error("Invalid random value") if !defined $rand || $rand =~ /[^a-z0-9]/i; 57 | 58 | my($fh,$error) = net_unixconnect($PREFIX . ($rand =~ /([a-z0-9]+)/)[0] . '/sock'); 59 | error("Connection to unix-domain socket($PREFIX$rand/sock): $error") if $fh == 0; 60 | 61 | net_send($fh, "COOKIE=$cookie&$input\n"); 62 | print while(<$fh>); 63 | exit; 64 | 65 | sub cgi_read { 66 | return (undef,undef) unless defined $ENV{REQUEST_METHOD}; 67 | if($ENV{REQUEST_METHOD} eq 'GET' && $ENV{QUERY_STRING}) { 68 | my $cgi = parse_query($ENV{QUERY_STRING}); 69 | return($ENV{QUERY_STRING},$cgi->{R}); 70 | }elsif($ENV{REQUEST_METHOD} eq 'POST' && $ENV{CONTENT_LENGTH}) { 71 | my $tmp; 72 | read(STDIN, $tmp, $ENV{CONTENT_LENGTH}); 73 | my $cgi = parse_query($tmp); 74 | return($tmp,$cgi->{R}); 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /client.c: -------------------------------------------------------------------------------- 1 | /* CGI:IRC C Helper CGI 2 | * Copyright (c) David Leadbeater 2002-2007 3 | * Released Under the GNU GPLv2 or Later 4 | * NO WARRANTY - See GNU GPL for more 5 | * $Id: 3cc9101e199095f574c9bd8b2c53f0f9042eeae9 $ 6 | */ 7 | /* To compile: cc -O2 -o client.cgi client.c */ 8 | /* Add -lsocket on Solaris */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | /* Change this to the tmpfile path set in the CGI:IRC Config */ 21 | #define TMPLOCATION "/tmp/cgiirc-" 22 | 23 | /****************************************************************************** 24 | * Stralloc (from libowfat(-ish)) 25 | * If you'd rather use dietlibc/libowfat: 26 | * diet -Os gcc -include stralloc.h -o client.cgi client.c -lowfat */ 27 | 28 | #ifndef STRALLOC_H 29 | typedef struct stralloc { 30 | char* s; 31 | unsigned long int len; 32 | unsigned long int a; 33 | } stralloc; 34 | 35 | int stralloc_ready(stralloc *sa,unsigned long int len) { 36 | register int wanted=len+(len>>3)+30; /* heuristic from djb */ 37 | if(!sa->s || sa->as,wanted))) 40 | return 0; 41 | sa->a=wanted; 42 | sa->s=tmp; 43 | } 44 | return 1; 45 | } 46 | 47 | int stralloc_readyplus(stralloc *sa,unsigned long len) { 48 | if (sa->s) { 49 | if (sa->len + len < len) return 0; /* catch integer overflow */ 50 | return stralloc_ready(sa,sa->len+len); 51 | } else 52 | return stralloc_ready(sa,len); 53 | } 54 | 55 | int stralloc_catb(stralloc *sa,const char *buf,unsigned long int len) { 56 | if (stralloc_readyplus(sa,len)) { 57 | memcpy(sa->s+sa->len,buf,len); 58 | sa->len+=len; 59 | return 1; 60 | } 61 | return 0; 62 | } 63 | 64 | int stralloc_cats(stralloc *sa,const char *buf) { 65 | return stralloc_catb(sa,buf,strlen(buf)); 66 | } 67 | 68 | int stralloc_cat(stralloc *sa,stralloc *sa2) { 69 | return stralloc_catb(sa,sa2->s,sa2->len); 70 | } 71 | 72 | int stralloc_append(stralloc *sa,const char *in) { 73 | if (stralloc_readyplus(sa,1)) { 74 | sa->s[sa->len]=*in; 75 | ++sa->len; 76 | return 1; 77 | } 78 | return 0; 79 | } 80 | 81 | #define stralloc_0(sa) stralloc_append(sa,"") 82 | 83 | #endif 84 | /******************************************************************************/ 85 | 86 | int unix_connect(stralloc *where); 87 | int error(char *error); 88 | void readinput(stralloc *); 89 | void get_rand(stralloc *, stralloc *); 90 | void get_cookie(stralloc *); 91 | 92 | int main(void) { 93 | int fd, sz; 94 | char tmp[2048]; 95 | stralloc params = {0}, random = {0}, cookie = {0}; 96 | 97 | readinput(¶ms); 98 | 99 | if(!params.len) 100 | error("No input found"); 101 | 102 | stralloc_0(¶ms); 103 | 104 | get_rand(¶ms, &random); 105 | 106 | if(!random.len) 107 | error("Random value not found"); 108 | 109 | params.len--; 110 | 111 | get_cookie(&cookie); 112 | 113 | if(cookie.len) { 114 | stralloc_cats(¶ms, "&COOKIE="); 115 | stralloc_cat(¶ms, &cookie); 116 | } 117 | 118 | fd = unix_connect(&random); 119 | send(fd, params.s, params.len, 0); 120 | send(fd, "\n", 1, 0); 121 | 122 | while((sz = read(fd, tmp, sizeof tmp)) > 0) { 123 | write(STDOUT_FILENO, tmp, sz); 124 | } 125 | 126 | return 0; 127 | } 128 | 129 | int error(char *error) { 130 | puts("Content-type: text/html\nStatus: 500\n"); 131 | puts("An error occurred:"); 132 | puts(error); 133 | exit(1); 134 | } 135 | 136 | void readinput(stralloc *input) { 137 | char *method = getenv("REQUEST_METHOD"); 138 | if(!method) return; 139 | 140 | if(strcmp(method, "GET") == 0) { 141 | char *query = getenv("QUERY_STRING"); 142 | if(query) 143 | stralloc_cats(input, query); 144 | }else if(strcmp(method, "POST") == 0) { 145 | int length; 146 | char *ctlength = getenv("CONTENT_LENGTH"); 147 | size_t sz; 148 | if(!ctlength) return; 149 | length = atoi(ctlength); 150 | 151 | /* Hopefully noone will need to send more than 5KB */ 152 | if(length <= 0 || length > (1024*5)) return; 153 | stralloc_ready(input, length); 154 | sz = read(STDIN_FILENO, input->s, length); 155 | if(sz <= 0) return; 156 | input->len = sz; 157 | } 158 | } 159 | 160 | void get_rand(stralloc *params, stralloc *random) { 161 | char *ptr = strstr(params->s, "R="); 162 | 163 | if(!ptr) 164 | return; 165 | 166 | ptr += 2; 167 | 168 | while(ptr < params->s + params->len) { 169 | if(!isalpha((unsigned char)*ptr) && !isdigit((unsigned char)*ptr)) 170 | break; 171 | stralloc_append(random, ptr++); 172 | } 173 | } 174 | 175 | void get_cookie(stralloc *cookie) { 176 | char *httpcookie; 177 | char *sptr, *end_ptr; 178 | 179 | httpcookie = getenv("HTTP_COOKIE"); 180 | if(!httpcookie) return; 181 | 182 | #define COOKIE_NAME "cgiircauth=" 183 | sptr = strstr(httpcookie, COOKIE_NAME); 184 | if(sptr == NULL) return; 185 | sptr += strlen(COOKIE_NAME); 186 | if(!*sptr) return; 187 | 188 | end_ptr = strchr(sptr, ';'); 189 | if(end_ptr == NULL) 190 | end_ptr = sptr + strlen(sptr) - 1; 191 | 192 | stralloc_catb(cookie, sptr, 1 + end_ptr - sptr); 193 | } 194 | 195 | #ifndef SUN_LEN 196 | #define SUN_LEN(x) (sizeof(*(x)) - sizeof((x)->sun_path) + strlen((x)->sun_path)) 197 | #endif 198 | 199 | int unix_connect(stralloc *where) { 200 | stralloc filename = {0}, errmsg = {0}; 201 | struct sockaddr_un saddr; 202 | int sock; 203 | 204 | stralloc_cats(&filename, TMPLOCATION); 205 | stralloc_cat(&filename, where); 206 | stralloc_cats(&filename, "/sock"); 207 | stralloc_0(&filename); 208 | 209 | sock = socket(AF_UNIX, SOCK_STREAM, 0); 210 | if(sock == -1) error("socket() error"); 211 | 212 | saddr.sun_family = AF_UNIX; 213 | strncpy(saddr.sun_path, filename.s, sizeof(saddr.sun_path)); 214 | saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; 215 | 216 | if(connect(sock, (struct sockaddr *)&saddr, SUN_LEN(&saddr)) == -1) { 217 | stralloc_cats(&errmsg, "connect(): "); 218 | stralloc_cats(&errmsg, strerror(errno)); 219 | stralloc_0(&errmsg); 220 | error(errmsg.s); 221 | } 222 | 223 | return sock; 224 | } 225 | 226 | -------------------------------------------------------------------------------- /docs/CHANGES: -------------------------------------------------------------------------------- 1 | Summary of changes 2 | 3 | 0.5.8 4 | - Translations into German, Dutch, Romanian and Norwegian (thanks 5 | OUTsider/scarynet) 6 | - Russian translation of help 7 | - Some more UTF-8 fixes (including joining channels with non-ASCII chars, 8 | thanks to Jonas Liljegren) 9 | - Server balancing support 10 | - Identd supports multiple installs 11 | - Fix buffer overflow in client.cgi 12 | - Other misc fixes (see http://cvs.cgiirc.org/timeline?d=300&e=2006-Apr-30&c=2) 13 | 14 | 0.5.7 15 | - Fixed to work on Perl <5.8 16 | - Perform config option 17 | 18 | 0.5.6 19 | - UTF-8 fixes and /charset command 20 | 21 | 0.5.5 22 | - Various bugfixes including: Firefox CSS, paste 23 | - Proper UTF-8 support (uses Encode) 24 | - Now looks for configuration files in /etc as well 25 | - Multiple ipaccess files 26 | 27 | 0.5.4 28 | - New options images 29 | - XMLHTTP support 30 | 31 | 0.5.3 32 | - Lots of bug fixes (+/!channels, ( key in mozilla and some smaller things) 33 | - Use of iframes removed (IE sometimes does not load the JS needed properly) 34 | - ipaccess can now use hostnames (see ipaccess.example) 35 | - config file updates (documented new options in cgiirc.config.full) 36 | - sound support (IE only) 37 | - Opera 7 support 38 | - Output options (display items in active window, status or not at all) 39 | (eg: whois in active window, hide joins, etc), see cgiirc.config.full 40 | for details. 41 | - Better support for prefixes sent in 005 42 | - disable_format_input option to disable the "<<" and %B, %C, etc. 43 | 44 | 0.5.2 45 | - New Icons (thanks to Johnny). 46 | - Handle pastes in a much better way (IE only). 47 | - Bug fixes for encoded IP, disconnection problems, URL hilighting, nicknames 48 | with a | in them, sending @#channel notices and Internet Explorer on Mac. 49 | 50 | 0.5.1 51 | - Style selection 52 | - KDE Konqueror 3+ support 53 | - Trusted web proxies 54 | - ipaccess can now match based on netmask (patch from Piotr KUCHARSKI). 55 | - Lots of bug fixes 56 | 57 | -------------------------------------------------------------------------------- /docs/TODO: -------------------------------------------------------------------------------- 1 | TODO 2 | ---- 3 | 4 | bugs: 5 | - horzontal scrolling with really long lines 6 | 7 | features: 8 | - adding code to check for op to add op/voice/deop/devoice/ban/kick to userlist 9 | - scrolling locks if the window is scrolled upwards 10 | - topic bar 11 | this is going to be difficult as it comes along with wanting to reposition 12 | the tab bar as well, i'm not sure of the best way of doing this (and 13 | interfaces are already too messy). 14 | - 0.4 had a status bar in text-* themes, make shownick into something better? 15 | - who list format 16 | - right click context menus 17 | - admin interface? 18 | - nonjs interface needs a few more features... 19 | - fix nonjs - setbackground colour 20 | - @ prefix (in lines like <@user>) 21 | - css for login? 22 | - /quit window.close 23 | - title 24 | - maxlength in input field 25 | 26 | docs: 27 | - admin password 28 | - remember to update cgiirc-form.txt 29 | 30 | Sucky bits of code need rewriting: 31 | - Use more events (slight redesign on Event.pm with global handlers) 32 | - The whole interface thing 33 | - Options 34 | - Formats could be in their own module 35 | - IPv6 handling, most stuff should work with IPv6, but some is messy :( 36 | 37 | -------------------------------------------------------------------------------- /docs/decode.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # (C) 2000 David Leadbeater (http://contact.dgl.cx/) 3 | # cgi-irc comes with ABSOLUTELY NO WARRANTY 4 | # This is free software, and you are welcome to redistribute it 5 | # under certain conditions; read the file COPYING for details 6 | 7 | # Decode hex ip addresses as found in CGI:IRC whois (realname) output with the 8 | # encode ip addresses option turned on 9 | 10 | # Now i understand wtf pack and unpack do: 11 | # perl -le'print join ".", unpack "C*",pack "H*", $ARGV[0]' 12 | 13 | use strict; 14 | use Socket; 15 | my($input,$output); 16 | 17 | if($#ARGV >= $[) { 18 | $input = shift; 19 | } else { 20 | print "Type the Hex IP to decode into a normal IP address\n"; 21 | $input=<>; 22 | } 23 | 24 | $input =~ s/[^a-z0-9]//gi; 25 | 26 | $output = pack "H*", $input; 27 | 28 | print "IP: " . join(".", unpack "C*", $output) . "\n"; 29 | print "Host: " . scalar gethostbyaddr($output, AF_INET) . "\n"; 30 | 31 | -------------------------------------------------------------------------------- /docs/help.html: -------------------------------------------------------------------------------- 1 |

CGI:IRC Help

2 | 3 |

Interface

4 | 5 | The interface of CGI:IRC is very similar to a standard graphical IRC client, it 6 | should be easy to use if you are familiar with IRC clients. Along the top is a 7 | list of tabs, there will be a tab here for each channel you are in and each 8 | query (private message) you have open. To close a window click the X button on 9 | the far right of the tab list.
10 | The userlist is on the right, when in a channel tab it will show a list of all 11 | the people in that channel. Double clicking a nickname will open a query with 12 | that user or perform whichever other action you select in the select box at the 13 | bottom.
14 | The text entry box should be simple, the little arrow to the right of the text 15 | entry area shows a toolbar that allows easy typing of colour, bold and underline. It is also where you enter all the commands. 16 | 17 |

Commands

18 | Commands begin with / and should be familiar to anyone who has used IRC before 19 | - here is a quick summary of the most useful commands. 20 | 21 | 23 | 24 | 26 | 28 | 29 | 30 | 31 |
/meThis turns the text after /me into an action, eg: /me looks 22 | around.
/joinJoins the specified channel. eg: /join #cgiirc
/listLists all the channels on the network (this outputs a lot 25 | of information).
/partLeaves the current channel (same as clicking the X while 27 | in the channel).
/quitQuits IRC totally (same as clicking X in Status window).
/msgSends a private message to a user. eg: /msg someone Hi
/whoisGives some information about a user.
32 | 33 |

Options

34 | The options window lets you change some settings in CGI:IRC. Hopefully it 35 | should be fairly self explanatory, change a setting and it should take effect 36 | immediately. 37 | 38 |

Keyboard shortcuts

39 | There are several shortcuts to help make using CGI:IRC nicer. 40 | 41 | 42 | 44 | 45 | 46 | 47 |
TabWill autocomplete a nickname or channel.
Ctrl+number / Alt+numberWill go to that number window if you number 43 | the windows from the left (Status = 1 and so on).
Ctrl+BWrite "%B" for bold text.
Ctrl+CWrite "%C" for colored text.
Cursor Up/DownMove in the command history.
48 | 49 |

About CGI:IRC

50 | CGI:IRC is written in Perl by David Leadbeater with help from lots of people. See the website for more information. 52 | -------------------------------------------------------------------------------- /docs/help.ru.html: -------------------------------------------------------------------------------- 1 | 

Помощь CGI:IRC

2 | 3 |

Интерфейс

4 | 5 | Интерфейс CGI:IRC очень схож со стандартным интерфейсом IRC клиентов, и у 6 | вас не возникнет трудностей, если вы уже были знакомы с ними. На верхней 7 | панели находится список вкладок в виде кнопок, по одной кнопке на каждый из каналов, 8 | на котором вы находитесь, и на каждый приват, открытый вами. Чтобы закрыть окно, 9 | нажмите на кнопку со значком X справа от кнопок списка вкладок.
10 | Список пользователей находится справа. Когда вы находитесь на вкладке с каналом, 11 | он будет показывать список всех пользователей находящихся на этом канале. Двойной 12 | щелчок мышкой по нику откроет приват с этим пользователем или выполнит действие, 13 | выбранное вами в выпадающем списке снизу.
14 | Поле ввода текста не представляет собой ничего сложного. Маленькая стрелка справа 15 | от него показывает строку панели инструментов, позволяющую леко 16 | вставлять коды цвета, выделять текст жирным шрифтом или подчеркиванием. 17 | 18 |

Команды

19 | Команды, начинающиеся на / должны быть знакомы каждому, кто пользовался IRC раньше 20 | - вот короткий список наиболее часто используемых комманд. 21 | 22 | 24 | 25 | 27 | 29 | 31 | 32 | 33 |
/meЭта команда преобразовывает текст, введенный после /me в действие, 23 | например: /me осматривается вокруг.
/joinПозволяет войти на указанный канал. Например: /join #cgiirc
/listПокажет все каналы в этой сети (выводит достаточно много 26 | информации).
/partПокинуть текущий канал (тоже, что и нажатие на X, находясь 28 | на канале).
/quitПолностью выйти из IRC (тоже, что и нажатие на X, находясь 30 | в окне Статуса).
/msgОтправка сообщения в приват пользователю. Например: /msg someone Привет
/whoisВыводит некоторую информацию о пользователе.
34 | 35 |

Опции

36 | Окно опций позволяет вам изменять некоторые настройки CGI:IRC. Будем надеяться, 37 | что они вполне объясняют свое назначение. Измените настройку, и они немедленно 38 | дадут эффект. 39 | 40 |

Комбинации клавиш

41 | Комбинации клавиш помогут вам более удобно использовать CGI:IRC. 42 | 43 | 44 | 46 | 47 | 48 | 49 |
TabАвтоматически дополнит ввод ника или названия канала.
Ctrl+число / Alt+числоПереход на вкладку по ее номеру, 45 | если считать их начиная слева (Статус = 1 и так далее).
Ctrl+BПишет "%B" для ввода жирного текста.
Ctrl+CПишет "%C" для ввода цветного текста.
Клавиши стрелок Вверх/ВнизПеремещение по истории команд.
50 | 51 |

О программе CGI:IRC

52 | CGI:IRC написан на Perl David'ом Leadbeater'ом в соавторстве с другими. Смотрите эту страничку для дополнительной 54 | информации. 55 | -------------------------------------------------------------------------------- /docs/identd.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -T 2 | use strict; 3 | use Socket; 4 | 5 | # Basically you need to add a line like this to /etc/inetd.conf and 6 | # run killall -HUP inetd. 7 | # ident stream tcp nowait nobody /usr/local/sbin/identd.pl /tmp/cgiirc-=nobody 8 | 9 | # The parameter on the end is the location of the socket files and 10 | # the user which CGI:IRC is running as, for example 11 | # /tmp/cgiirc-=www-data means that CGI:IRC has the socket_prefix 12 | # set to /tmp/cgiirc- and is running as user www-data. Multiple 13 | # directories can be specified. 14 | 15 | # How to deal with unknown requests: 16 | # nouser reply with NO-USER 17 | # reply:text reply with USERID 'text' 18 | # linuxproc use /proc/net/tcp on linux to do 'real' identd replies 19 | # forward:port forward to a real identd 20 | my $reply = "nouser"; 21 | 22 | # Use custom ident (currently HTTP USER set by CGI:IRC). 23 | my $customident = 0; 24 | 25 | # Default: 26 | my %cgiircprefixes = ( '/tmp/cgiirc-' => $<); 27 | 28 | %cgiircprefixes = () if @ARGV; 29 | for(@ARGV) { 30 | my($p, $u) = split /=/; 31 | $u = getpwnam($u) || $<; 32 | $cgiircprefixes{$p} = $u; 33 | } 34 | 35 | # Taken from midentd 36 | my $in = ''; 37 | ret(0, 0, "ERROR : NO-USER") unless sysread STDIN, $in, 128; 38 | my($local, $remote) = $in =~ /^\s*(\d+)\s*,\s*(\d+)/; 39 | 40 | ret(0, 0, "ERROR : INVALID-PORT") unless defined $local && defined $remote; 41 | 42 | $remote = 0 if $remote !~ /^([ \d])+$/; 43 | $local = 0 if $local !~ /^([ \d])+$/; 44 | 45 | if($remote<1 || $remote>65535 || $local<1 || $local>65535) { 46 | ret($local, $remote, "ERROR : INVALID-PORT") 47 | } 48 | 49 | my $socket = find_socket($local, $remote); 50 | 51 | if(defined $socket) { 52 | my $user = encode_ip($socket); 53 | if($customident && -f "$socket/ident") { 54 | open(TMP, "<$socket/ident") or 55 | ret($local, $remote, "USERID : UNIX : $user"); 56 | $user = ; 57 | chomp($user); 58 | $user ||= encode_ip($socket); 59 | } 60 | ret($local, $remote, "USERID : UNIX : $user"); 61 | } else { 62 | if($reply eq 'nouser') { 63 | ret($local, $remote, "ERROR : NO-USER"); 64 | } elsif($reply =~ /reply:\s*(.*)/) { 65 | ret($local, $remote, "USERID : UNIX : $1"); 66 | } elsif($reply eq 'linuxproc') { 67 | ret($local, $remote, linuxproc($local, $remote)); 68 | } elsif($reply =~ /forward:\s*(.*)/) { 69 | print forward($1, $local, $remote); 70 | exit; 71 | } 72 | 73 | ret($local, $remote, "ERROR : INVALID-PORT"); 74 | } 75 | 76 | sub ret{ 77 | my($l, $r, $t) = @_; 78 | print "$l , $r : $t\r\n"; 79 | exit; 80 | } 81 | 82 | sub find_socket { 83 | my($l, $r) = @_; 84 | foreach my $cgiircprefix (keys %cgiircprefixes) { 85 | (my $dir, my $prefix) = $cgiircprefix =~ /^(.*\/)([^\/]+)$/; 86 | opendir(TMPDIR, $dir) or return undef; 87 | for(readdir TMPDIR) { 88 | next unless /^\Q$prefix\E/; 89 | next unless -d $dir . $_ && -x $dir . $_; 90 | 91 | next unless $cgiircprefixes{$cgiircprefix} == (stat($dir . $_))[4]; 92 | 93 | local *TMP; 94 | open(TMP, "<$dir$_/server") or next; 95 | chomp(my $tmp = ); 96 | next unless $tmp =~ /:$r$/; 97 | 98 | chomp($tmp = ); 99 | next unless $tmp =~ /:$l$/; 100 | close TMP; 101 | 102 | closedir TMPDIR; 103 | return $dir . $_; 104 | } 105 | closedir TMPDIR; 106 | } 107 | return undef; 108 | } 109 | 110 | sub encode_ip { 111 | my($socket) = @_; 112 | open(TMP, "<$socket/ip") or return 0; 113 | chomp(my $ip = ); 114 | close TMP; 115 | return join('', map(sprintf("%0.2x", $_), split(/\./, $ip))); 116 | } 117 | 118 | sub linuxproc { 119 | my($l, $r) = @_; 120 | open(PNT, "; 122 | while() { 123 | s/^\s+//; 124 | s/\s+/ /g; 125 | my($sl,$local,$remote,$st,$queue,$tr,$retrnsmt,$uid,$timeout,$inode) = split(/\s/); 126 | next unless decode_port($local) == $l && decode_port($remote) == $r; 127 | return "USERID : UNIX : " . getusername($uid); 128 | } 129 | close(PNT); 130 | return "ERROR : NO-USER"; 131 | 132 | } 133 | 134 | sub decode_port{ 135 | return hex((split(/:/,shift,2))[1]); 136 | } 137 | 138 | sub getusername{ 139 | my $uid = shift; 140 | if(my $u=(getpwuid($uid))[0]) { 141 | return $u; 142 | } else { 143 | return $uid; 144 | } 145 | } 146 | 147 | sub forward { 148 | my($where, $l, $r) = @_; 149 | eval("use IO::Socket;"); 150 | my $forward = IO::Socket::INET->new($where =~ /:/ ? $where : '127.0.0.1:' . $where); 151 | return "$l , $r : ERROR : NO-USER\r\n" unless ref $forward; 152 | print $forward "$l , $r\r\n"; 153 | return scalar <$forward>; 154 | } 155 | -------------------------------------------------------------------------------- /docs/identd.xinetd: -------------------------------------------------------------------------------- 1 | # default: on 2 | # description: identd.pl for CGI:IRC 3 | service auth 4 | { 5 | disable = no 6 | socket_type = stream 7 | wait = no 8 | user = nobody 9 | server = /usr/local/sbin/identd.pl 10 | log_on_success = 11 | } 12 | 13 | -------------------------------------------------------------------------------- /docs/smilies.conf.example: -------------------------------------------------------------------------------- 1 | "\;-?\)" = wink 2 | "\;-?D" = grin 3 | ":\'\(?" = cry 4 | ":-?/(?!\S)" = notsure 5 | ":-?[xX]" = confused 6 | ":-?\]" = embarassed 7 | ":-?\*" = love 8 | ":-?[pP]" = tongue 9 | ":-?\)" = happy 10 | "\:-?D" = cheesy 11 | ":-?\(" = unhappy 12 | ":-[oO]" = surprised 13 | "8-?\)" = cool 14 | ":-?\|" = flat 15 | ":\'\)\)?" = happycry 16 | "\004\>\004:-?/" = hmmm 17 | "\004\>\004:-?\(" = angry 18 | ":-?\*\*" = kiss 19 | ":-z" = sleep 20 | ":-\." = sorry 21 | "8-@" = what 22 | -------------------------------------------------------------------------------- /docs/viewconnects.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # CGI:IRC - http://cgiirc.org/ 3 | # Copyright (C) 2000-2002 David Leadbeater 4 | # vim:set ts=3 expandtab shiftwidth=3 cindent: 5 | 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | 20 | use strict; 21 | use vars qw($VERSION); 22 | use Socket; 23 | 24 | ($VERSION = 25 | '$Name: $ 0_5_CVS $Id: viewconnects.pl,v 1.5 2007/05/06 01:05:35 dgl Exp $' 26 | ) =~ s/^.*?(\d\S+) .*$/$1/; 27 | $VERSION =~ s/_/./g; 28 | 29 | # Change these if needed. 30 | my $cgiircprefix="/tmp/cgiirc-"; 31 | my $resolve = 1; 32 | 33 | if($ENV{GATEWAY_INTERFACE} =~ /CGI/) { # We aren't really a CGI script.. 34 | print "Content-type: text/plain\n\n"; 35 | } 36 | 37 | my @connects = list_connects(); 38 | 39 | if(!@connects) { 40 | print "No connections found.\n"; 41 | exit; 42 | } 43 | 44 | my $format = "%-9.9s %-15.15s " . 45 | ($resolve ? "%-38.38s" : "%-15.15s") . 46 | " %-9.9s %-5.5s\n"; 47 | 48 | printf($format, "1st Nick", "Server", "Client", "Login", "Idle"); 49 | 50 | for my $u(@connects) { 51 | my %user; 52 | @user{qw/remoteip localip server nick clientip forwardedip ltime idle/} = @$u; 53 | if($resolve) { 54 | $user{clientip} = gethostbyaddr(inet_aton($user{clientip}), AF_INET) . " ($user{clientip})"; 55 | } 56 | printf($format, @user{qw/nick server clientip ltime idle/}); 57 | } 58 | 59 | sub list_connects { 60 | my @connects; 61 | (my $dir, my $prefix) = $cgiircprefix =~ /^(.*\/)([^\/]+)$/; 62 | opendir(TMPDIR, $dir) or return undef; 63 | for my $path(readdir TMPDIR) { 64 | my @u; 65 | next unless $path =~ /^\Q$prefix\E/; 66 | $path = $dir . $path; 67 | next unless -d $path; 68 | 69 | local *TMP; 70 | open(TMP, "<$path/server") or next; 71 | @u = ; 72 | chomp(@u); 73 | close(TMP); 74 | 75 | open(TMP, "<$path/ip") or next; 76 | for my $n(0..1) { 77 | chomp($_ = ); 78 | $u[$n + 4] = $_; 79 | } 80 | close(TMP); 81 | 82 | # login time 83 | # ctime of the directory has highest chance to be the right one here 84 | my @t = localtime((stat("$path"))[10]); 85 | my @today = localtime(); 86 | my @days = qw/Sun Mon Tue Wed Thu Fri Sat/; 87 | # anyone logged on for longer than a week/(since sun) will be wrong 88 | # too bad eh? 89 | if($t[6] == $today[6]) { 90 | $u[6] = sprintf '%02d:%02d', $t[2], $t[1]; 91 | }else{ 92 | $u[6] = "$days[$t[6]] " . ($t[2] > 11 ? $t[2] - 12 . 'pm' : "$t[2]am"); 93 | } 94 | 95 | # idle time 96 | # mtime of the socket is the right one here 97 | @t = gmtime(time - (stat("$path/sock"))[9]); 98 | $u[7] = sprintf '%02d:%02d', $t[2] + $t[7] * 24, $t[1]; 99 | 100 | push(@connects, \@u); 101 | } 102 | return @connects; 103 | } 104 | -------------------------------------------------------------------------------- /formats/dark: -------------------------------------------------------------------------------- 1 | looking up = {prefix-client} Looking up {server $0} 2 | connecting = {prefix-client} Connecting to {server $0} [$1] port {hilight $2} 3 | 4 | access denied = {prefix-client} Access Denied: $0 5 | access server denied = {prefix-client} Access to server $0 is blocked 6 | access port denied = {prefix-client} Access to port $0 is blocked 7 | access channel denied = {prefix-client} Access to channel $0 is blocked 8 | command denied = {prefix-client} Access to that command is blocked 9 | session timeout = {prefix-client} Timeout - Your session has been inactive too long 10 | 11 | kill ok = {prefix-error} You were killed by $1 ($2) 12 | kill wrong = {prefix-error} $1 tried to kill you but got the password wrong! ($2) 13 | 14 | command notparams = {prefix-client} Not enough parameters for command 15 | command error = {prefix-client} Error running command 16 | error = {prefix-error} An error occurred: $0 17 | not supported = {prefix-client} $0 attempted to $3 to you but CGI:IRC does not support it ($2) 18 | 19 | cgiirc welcome = {prefix-client} Welcome to CGI:IRC $VERSION 20 | 21 | join = {prefix-user} $0 {host $1} has joined {channel $T} 22 | nick = {prefix-user} $0 is now known as $2 23 | quit = {prefix-user} $0 {host $1} has quit {reason $2} 24 | part = {prefix-user} $0 left {channel $T} {reason $2} 25 | user mode = {prefix-user} usermode/$0 $2 26 | mode = {prefix-user} mode/$T [$2] by $0 27 | topic = {prefix-user} $0 changed the topic to: $2 28 | invite = {prefix-user} $0 invites you to join $2 29 | kick = {prefix-user} $2 was kicked from $T by $0 {reason $3} 30 | 31 | prefix-error = %04***%n 32 | prefix-info = %03***%n 33 | prefix-user = %03***%n 34 | prefix-client = %02***%n 35 | prefix-server = %05***%n 36 | 37 | notice public = {notice-target $0 $T} {text $2} 38 | notice special = {notice-target $0 $2} {text $3} 39 | notice private = %05-{notice-nick $0}%05-%n {text $2} 40 | notice server = %05-$0%05-%n {text $2} 41 | notice public own = {notice-target $0 $T} {text $2} 42 | notice private own = [notice:$T] {text $2} 43 | 44 | notice-target = %05-$0:$1%05-%n 45 | notice-nick = %03$0%n 46 | notice-host = [$0] 47 | 48 | message public = {message-nick $0} {text $2} 49 | message public hilight = {message-nick-hilight $0} {text $2} 50 | message private window = {message-nick $0} {text $2} 51 | message private = [$0($1)] {text $2} 52 | message special = <$0:$2> {text $3} 53 | 54 | message-nick = %02<%n$0%02>%n 55 | message-nick-own = %03<%n$0%03>%n 56 | message-nick-hilight = %02<%07$0%02>%n 57 | 58 | message public own = {message-nick-own $0} {text $2} 59 | message private window own = {message-nick-own $0} {text $2} 60 | message private own = [msg->$T] {text $2} 61 | 62 | action-nick = %_*%_ $0 63 | action public = {action-nick $0} {text $2} 64 | action private = {action-nick $0} {text $2} 65 | 66 | action public own = {action-nick $0} {text $2} 67 | action private own = {action-nick $0} {text $2} 68 | 69 | ctcp own msg = {prefix-user} CTCP to $T: $1 70 | ctcp msg = {prefix-user} $1 requested CTCP %_$3%_ from $0: $4 71 | ctcp reply = {prefix-user} CTCP %_$2%_ reply from $0: $3 72 | 73 | text = $0 74 | channel = %_$0%_ 75 | reason = [$0] 76 | 77 | server = %_$0%_ 78 | hilight = %_$0%_ 79 | host = [$0] 80 | 81 | default = {prefix-server} $0- 82 | 83 | ignore list = {prefix-client} Ignore: $0- 84 | ignored = {prefix-client} Ignored: $0- 85 | unignored = {prefix-client} Unignored: $0- 86 | 87 | reply away = {prefix-user} $T is away: $0 88 | reply nowaway = {prefix-server} You are now set as away 89 | reply unaway = {prefix-server} You are no longer set as away 90 | 91 | reply channel time = {prefix-server} Channel created on $0 92 | reply notopic = {prefix-server} No topic set 93 | reply topic = {prefix-server} Topic is: $0 94 | reply topicwhotime = {prefix-server} Topic set by $0 [$1] 95 | 96 | reply whois user = {prefix-user} $T [$0@$1]: $2 97 | reply whowas user = {prefix-user} $T [$0@$1]: $2 98 | reply whois channel = {prefix-user} channels: $0 99 | reply whois regnick = {prefix-user} registered: $0 100 | reply whois operator = {prefix-user} ircop: $0 101 | reply whois idle = {prefix-user} idle: $0 signon: $1 102 | time = $7 days $2 hours $1 min $0 sec 103 | reply whois server = {prefix-user} server: $0 [$1] 104 | reply whois end = {prefix-user} $0 105 | 106 | error nosuchnick = {prefix-server} %_$T%_ No such nick/channel 107 | error nickinuse = {prefix-server} Nickname $0 is already in use, type /nick newnick to use another. 108 | 109 | irc close = {prefix-error} Disconnected from IRC (click to reconnect) 110 | 111 | bg = 00 112 | fg = 01 113 | 00 = #303030 114 | 01 = #909090 115 | 02 = #000080 116 | 03 = #008000 117 | 04 = #ff0000 118 | 05 = #800000 119 | 06 = #800080 120 | 07 = #ff6600 121 | 08 = #ffff00 122 | 09 = #00ff00 123 | 10 = #008080 124 | 11 = #00ffff 125 | 12 = #0000ff 126 | 13 = #ff00ff 127 | 14 = #808080 128 | 15 = #c0c0c0 129 | 130 | style = dark 131 | -------------------------------------------------------------------------------- /formats/default: -------------------------------------------------------------------------------- 1 | looking up = {prefix-client} Looking up {server $0} 2 | connecting = {prefix-client} Connecting to {server $0} [$1] port {hilight $2} 3 | 4 | access denied = {prefix-client} Access Denied: $0 5 | access server denied = {prefix-client} Access to server $0 is blocked 6 | access port denied = {prefix-client} Access to port $0 is blocked 7 | access channel denied = {prefix-client} Access to channel $0 is blocked 8 | command denied = {prefix-client} Access to that command is blocked 9 | session timeout = {prefix-client} Timeout - Your session has been inactive too long 10 | 11 | kill ok = {prefix-error} You were killed by $0 ($1) 12 | kill wrong = {prefix-error} $0 tried to kill you but got the password wrong! ($1) 13 | 14 | command notparams = {prefix-client} Not enough parameters for command 15 | command error = {prefix-client} Error running command 16 | error = {prefix-error} An error occurred: $0 17 | not supported = {prefix-client} $0 attempted to $3 to you but CGI:IRC does not support it ($2) 18 | 19 | cgiirc welcome = {prefix-client} Welcome to CGI:IRC $VERSION 20 | 21 | join = {prefix-user} $0 {host $1} has joined {channel $T} 22 | nick = {prefix-user} $0 is now known as $2 23 | quit = {prefix-user} $0 {host $1} has quit {reason $2} 24 | part = {prefix-user} $0 left {channel $T} {reason $2} 25 | user mode = {prefix-user} usermode/$0 $2 26 | mode = {prefix-user} mode/$T [$2] by $0 27 | topic = {prefix-user} $0 changed the topic to: $2 28 | invite = {prefix-user} $0 invites you to join $2 29 | kick = {prefix-user} $2 was kicked from $T by $0 {reason $3} 30 | 31 | prefix-error = %04***%n 32 | prefix-info = %03***%n 33 | prefix-user = %03***%n 34 | prefix-client = %02***%n 35 | prefix-server = %05***%n 36 | 37 | notice public = {notice-target $0 $T} {text $2} 38 | notice special = {notice-target $0 $2} {text $3} 39 | notice private = -{notice-nick $0}- {text $2} 40 | notice server = %05-$0%05-%n {text $2} 41 | notice public own = {notice-target $0 $T} {text $2} 42 | notice private own = [notice:$T] {text $2} 43 | 44 | notice-target = %05-$0:$1%05-%n 45 | notice-nick = %03$0%n 46 | notice-host = [$0] 47 | 48 | message public = {message-nick $0} {text $2} 49 | message public hilight = {message-nick-hilight $0} {text $2} 50 | message private window = {message-nick $0} {text $2} 51 | message private = [$0($1)] {text $2} 52 | message special = <$0:$2> {text $3} 53 | 54 | message-nick = %02<%n$0%02>%n 55 | message-nick-own = %03<%n$0%03>%n 56 | message-nick-hilight = %02<%07$0%02>%n 57 | 58 | message public own = {message-nick-own $0} {text $2} 59 | message private window own = {message-nick-own $0} {text $2} 60 | message private own = [msg->$T] {text $2} 61 | 62 | action-nick = %_*%_ $0 63 | action public = {action-nick $0} {text $2} 64 | action private = {action-nick $0} {text $2} 65 | 66 | action public own = {action-nick $0} {text $2} 67 | action private own = {action-nick $0} {text $2} 68 | 69 | ctcp own msg = {prefix-user} CTCP to $T: $1 70 | ctcp msg = {prefix-user} $1 requested CTCP %_$3%_ from $0: $4 71 | ctcp reply = {prefix-user} CTCP %_$2%_ reply from $0: $3 72 | 73 | text = $0 74 | channel = %_$0%_ 75 | reason = [$0] 76 | 77 | server = %_$0%_ 78 | hilight = %_$0%_ 79 | host = [$0] 80 | 81 | default = {prefix-server} $0- 82 | raw = {prefix-server} $0- 83 | 84 | ignore list = {prefix-client} Ignore: $0- 85 | ignored = {prefix-client} Ignored: $0- 86 | unignored = {prefix-client} Unignored: $0- 87 | 88 | reply away = {prefix-user} $T is away: $0 89 | reply nowaway = {prefix-server} You are now set as away 90 | reply unaway = {prefix-server} You are no longer set as away 91 | 92 | reply channel time = {prefix-server} Channel created on $0 93 | reply notopic = {prefix-server} No topic set 94 | reply topic = {prefix-server} Topic is: $0 95 | reply topicwhotime = {prefix-server} Topic set by $0 [$1] 96 | 97 | reply whois user = {prefix-user} $T [$0@$1]: $2 98 | reply whowas user = {prefix-user} $T [$0@$1]: $2 99 | reply whois channel = {prefix-user} channels: $0 100 | reply whois regnick = {prefix-user} registered: $0 101 | reply whois operator = {prefix-user} ircop: $0 102 | reply whois idle = {prefix-user} idle: $0, signon: $1 103 | time = $7 days $2 hours $1 min $0 sec 104 | reply whois server = {prefix-user} server: $0 [$1] 105 | reply whois end = {prefix-user} $0 106 | 107 | error nosuchnick = {prefix-server} {hilight $T}: No such nick/channel 108 | error nickinuse = {prefix-server} Nickname $0 is already in use, type /nick newnick to use another. 109 | 110 | irc close = {prefix-error} Disconnected from IRC (click to reconnect) 111 | 112 | 113 | bg = 00 114 | fg = 01 115 | 00 = #ffffff 116 | 01 = #000000 117 | 02 = #000080 118 | 03 = #008000 119 | 04 = #ff0000 120 | 05 = #800000 121 | 06 = #800080 122 | 07 = #ff6600 123 | 08 = #ffff00 124 | 09 = #00ff00 125 | 10 = #008080 126 | 11 = #00ffff 127 | 12 = #0000ff 128 | 13 = #ff00ff 129 | 14 = #808080 130 | 15 = #c0c0c0 131 | 132 | style = default 133 | -------------------------------------------------------------------------------- /formats/dutch: -------------------------------------------------------------------------------- 1 | looking up = {prefix-client} Bezig met opzoeken... 2 | connecting = {prefix-client} Verbinding aan het maken met de chatserver, even geduld... 3 | 4 | access denied = {prefix-error} Toegang Geweigerd: $0 5 | access server denied = {prefix-error} Verbinding tot deze server werd geweigerd ! 6 | access channel denied = {prefix-error} Toegang tot dit kanaal werd geweigerd ! 7 | command denied = {prefix-error} Toegang voor deze functie werd geweigerd ! 8 | session timeout = {prefix-error} Timeout - U bent te lang afwezig ! 9 | 10 | kill ok = {prefix-error} Uw verbinding werd verbroken door $0 ($1) 11 | kill wrong = {prefix-error} $0 probeerde u te killen, maar had het paswoord verkeerd! ($1) 12 | 13 | command notparams = {prefix-client} Onvoldoende karakters voor deze functie 14 | command error = {prefix-client} Error tijdens funcite 15 | error = {prefix-error} Een fout deed zich voor: $0 16 | not supported = {prefix-client} $0 probeerde een $3 bij je, maar CGI:IRC ondersteund dit niet ($2) 17 | 18 | cgiirc welcome = {prefix-client} Welkom op de html webchat! 19 | 20 | join = {prefix-channel} $0 is kamer {channel $T} binnengekomen 21 | nick = {prefix-channel} $0 heeft zijn/haar naam veranderd naar $2 22 | quit = {prefix-user} $0 heeft de chat verlaten ($1) 23 | part = {prefix-channel} $0 heeft {channel $T} verlaten {reason $2} 24 | 25 | user mode = {prefix-user} usermode/$0 $2 26 | mode = {prefix-channel} $0 zet mode: $2 27 | topic = {prefix-channel} $0 past de topic aan naar '$2' 28 | invite = {prefix-channel} $0 {host $1} nodigt u uit naar {channel $2} 29 | kick = {prefix-channel} $2 werd gekicked door $0 {reason $3} 30 | 31 | prefix-error = %04*** 32 | prefix-info = %03*** 33 | prefix-channel = %03*** 34 | prefix-user = %02*** 35 | prefix-client = %12*** 36 | prefix-server = %05*** 37 | prefix-ctcp = %04 38 | prefix-normal = *** 39 | 40 | notice public = {notice-target $0 $T} {text $2} 41 | notice special = {notice-target $0 $2} {text $3} 42 | notice private = {prefix-user} -{notice-nick $0}- {text $2} 43 | notice server = 44 | notice public own = {prefix-user} {notice-target $0 $T} {text $2} 45 | notice private own = {prefix-user} [notice:$T] {text $2} 46 | 47 | notice-target = %05-$0:$1- 48 | notice-nick = %03$0%n 49 | notice-host = [$0] 50 | 51 | message public = {message-nick $0} {text $2} 52 | message public hilight = {message-nick-hilight $0} {text $2} 53 | message private window = {message-nick $0} {text $2} 54 | message private = [$0($1)] {text $2} 55 | message special = <$0:$2> {text $3} 56 | 57 | message-nick = %02<%n$0%02>%n 58 | message-nick-own = %03<%n$0%03>%n 59 | message-nick-hilight = %02<%07$0%02>%n 60 | 61 | message public own = {message-nick-own $0} {text $2} 62 | message private window own = {message-nick-own $0} {text $2} 63 | message private own = [msg->$T] {text $2} 64 | 65 | action-nick = %06%_*%_ $0 66 | action public = {action-nick $0} {text $2} 67 | action private = {action-nick $0} {text $2} 68 | 69 | action public own = {action-nick $0} {text $2} 70 | action private own = {action-nick $0} {text $2} 71 | 72 | ctcp own msg = {prefix-ctcp} CTCP naar $T: $1 73 | ctcp msg = {prefix-ctcp} $1 aangevraagde CTCP %_$3%_ van $0: $4 74 | ctcp reply = {prefix-ctcp} CTCP %_$2%_ antwoord van $0: $3 75 | 76 | text = $0 77 | channel = %_$0%_ 78 | reason = ($0) 79 | 80 | server = %_$0%_ 81 | hilight = %_$0%_ 82 | host = ($0) 83 | 84 | default = 85 | raw = 86 | 87 | ignore list = {prefix-client} Blokeer: $0- 88 | ignored = {prefix-client} Geblokeerd: $0- 89 | unignored = {prefix-client} Deblokeerd: $0- 90 | 91 | reply away = {prefix-user} $T is afwezig: $0 92 | reply nowaway = {prefix-user} U staat nu als afwezig gemeld 93 | reply unaway = {prefix-user} U staat niet langer meer als afwezig gemeld 94 | 95 | reply channel time = 96 | reply notopic = 97 | reply topic = {prefix-channel} Chat Onderwerp: $0 98 | reply topicwhotime = {prefix-channel} Chat Onderwerp geplaatst door $0 99 | 100 | reply whois user = {prefix-user} $T [$0@$1]: $2 101 | reply whowas user = {prefix-user} $T [$0@$1]: $2 102 | reply whois channel = {prefix-user} Kanalen: $0 103 | reply whois regnick = {prefix-user} Geregistreerd: $0 104 | reply whois operator = {prefix-user} IRCop: $0 105 | reply whois idle = {prefix-user} Afwezig: $0 - Online sinds: $1 106 | time = $7 d $2 h $1 m $0 seconde(s) 107 | reply whois server = {prefix-user} Server: $0 108 | 109 | error nosuchnick = {prefix-server} {hilight $T} Geen nick/kanaal gevonden 110 | error nickinuse = {prefix-server} Nickname $0 is al in gebruik, tik /nick nicknaam om een ander te gebruiken. 111 | 112 | irc close = {prefix-error} Verbinding met de chatserver werd verbroken ! (reconnect) 113 | 114 | 115 | bg = 00 116 | fg = 01 117 | 00 = #ffffff 118 | 01 = #000000 119 | 02 = #000080 120 | 03 = #008000 121 | 04 = #ff0000 122 | 05 = #800000 123 | 06 = #800080 124 | 07 = #ff6600 125 | 08 = #ffff00 126 | 09 = #00ff00 127 | 10 = #008080 128 | 11 = #00ffff 129 | 12 = #000099 130 | 13 = #ff00ff 131 | 14 = #808080 132 | 15 = #c0c0c0 133 | 134 | style = dutch 135 | -------------------------------------------------------------------------------- /formats/german: -------------------------------------------------------------------------------- 1 | looking up = {prefix-client} Suche Server {server $0} 2 | connecting = {prefix-client} Verbindung mit {server $0} [$1] Port {hilight $2} 3 | 4 | access denied = {prefix-client} Zugang nicht gestattet: $0 5 | access server denied = {prefix-client} Der Zugang zum Server $0 wurde verweigert 6 | access port denied = {prefix-client} Der Zugang zum Port $0 wurde verweigert 7 | access channel denied = {prefix-client} Der Zugang zum Channel $0 wurde verweigert 8 | command denied = {prefix-client} Dieser Befehl ist nicht zugelassen 9 | session timeout = {prefix-client} Timeout - Die Verbindung wurde wegen Inaktivität getrennt 10 | 11 | kill ok = {prefix-error} Ihre Verbindung wurde durch $0 beendet ($1) 12 | kill wrong = {prefix-error} $0 hat probiert Ihre Verbindung zu beenden, aber das Password war falsch! ($1) 13 | 14 | command notparams = {prefix-client} Nicht genügend Parameter für diesen Befehl 15 | command error = {prefix-client} Fehler bei Ausführung des Befehls 16 | error = {prefix-error} Ein Fehler ist aufgetreten: $0 17 | not supported = {prefix-client} $0 hat ein $3 probiert, aber CGI:IRC fehlt die Unterstüzung dafür ($2) 18 | 19 | cgiirc welcome = {prefix-client} Willkommen bei CGI:IRC $VERSION 20 | 21 | join = {prefix-user} $0 {host $1} hat den Channel {channel $T} betreten 22 | nick = {prefix-user} $0 heißt jetzt $2 23 | quit = {prefix-user} $0 {host $1} hat den Chat verlassen {reason $2} 24 | part = {prefix-user} $0 hat {channel $T} verlassen {reason $2} 25 | user mode = {prefix-user} usermode/$0 $2 26 | mode = {prefix-user} mode/$T [$2] by $0 27 | topic = {prefix-user} $0 ändert das Topic in: $2 28 | invite = {prefix-user} $0 {host $1} lädt dich nach $2 ein 29 | kick = {prefix-user} $2 wurde gekicked durch $0 {reason $3} 30 | 31 | prefix-error = %04***%n 32 | prefix-info = %03***%n 33 | prefix-user = %03***%n 34 | prefix-client = %02***%n 35 | prefix-server = %05***%n 36 | 37 | notice public = {notice-target $0 $T} {text $2} 38 | notice special = {notice-target $0 $2} {text $3} 39 | notice private = -{notice-nick $0}- {text $2} 40 | notice server = %05-$0%05-%n {text $2} 41 | notice public own = {notice-target $0 $T} {text $2} 42 | notice private own = [notice:$T] {text $2} 43 | 44 | notice-target = %05-$0:$1%05-%n 45 | notice-nick = %03$0%n 46 | notice-host = [$0] 47 | 48 | message public = {message-nick $0} {text $2} 49 | message public hilight = {message-nick-hilight $0} {text $2} 50 | message private window = {message-nick $0} {text $2} 51 | message private = [$0($1)] {text $2} 52 | message special = <$0:$2> {text $3} 53 | 54 | message-nick = %02<%n$0%02>%n 55 | message-nick-own = %03<%n$0%03>%n 56 | message-nick-hilight = %02<%07$0%02>%n 57 | 58 | message public own = {message-nick-own $0} {text $2} 59 | message private window own = {message-nick-own $0} {text $2} 60 | message private own = [msg->$T] {text $2} 61 | 62 | action-nick = %_*%_ $0 63 | action public = {action-nick $0} {text $2} 64 | action private = {action-nick $0} {text $2} 65 | 66 | action public own = {action-nick $0} {text $2} 67 | action private own = {action-nick $0} {text $2} 68 | 69 | ctcp own msg = {prefix-user} CTCP zu $T: $1 70 | ctcp msg = {prefix-user} $1 CTCP %_$3%_ Anfrage von $0: $4 71 | ctcp reply = {prefix-user} CTCP %_$2%_ Antwort von $0: $3 72 | 73 | text = $0 74 | channel = %_$0%_ 75 | reason = [$0] 76 | 77 | server = %_$0%_ 78 | hilight = %_$0%_ 79 | host = [$0] 80 | 81 | default = {prefix-server} $0- 82 | raw = {prefix-server} $0- 83 | 84 | ignore list = {prefix-client} Ignoriere: $0- 85 | ignored = {prefix-client} Ignoriert: $0- 86 | unignored = {prefix-client} Ignoriere nicht mehr: $0- 87 | 88 | reply away = {prefix-user} $T ist abwesend: $0 89 | reply nowaway = {prefix-server} Du bist jetzt als abwesend markiert 90 | reply unaway = {prefix-server} Du bist jetzt nicht mehr als abwesend markiert 91 | 92 | reply channel time = {prefix-server} Channel erstellt am $0 93 | reply notopic = {prefix-server} Kein Topic gesetzt 94 | reply topic = {prefix-server} Topic: $0 95 | reply topicwhotime = {prefix-server} Topic gesetzt durch $0 [$1] 96 | 97 | reply whois user = {prefix-user} $T [$0@$1]: $2 98 | reply whowas user = {prefix-user} $T [$0@$1]: $2 99 | reply whois channel = {prefix-user} Channels: $0 100 | reply whois regnick = {prefix-user} Registriert: $0 101 | reply whois operator = {prefix-user} IRC-Op: $0 102 | reply whois idle = {prefix-user} Untätig: $0 – Online seit: $1 103 | time = $7 d $2 h $1 min $0 s 104 | reply whois server = {prefix-user} Server: $0 [$1] 105 | reply whois end = {prefix-user} $0 106 | 107 | error nosuchnick = {prefix-server} {hilight $T} Der Nick/Channel existiert nicht 108 | error nickinuse = {prefix-server} Der Nickname $0 wird bereits verwendet, bitte mit "/nick neuernick" (ohne Anführungszeichen) einen neuen Nickname wählen. 109 | 110 | irc close = {prefix-error} Die Verbindung zum Server wurde unterbrochen (Klicken um erneut zu Verbinden) 111 | 112 | 113 | bg = 00 114 | fg = 01 115 | 00 = #ffffff 116 | 01 = #000000 117 | 02 = #000080 118 | 03 = #008000 119 | 04 = #ff0000 120 | 05 = #800000 121 | 06 = #800080 122 | 07 = #ff6600 123 | 08 = #ffff00 124 | 09 = #00ff00 125 | 10 = #008080 126 | 11 = #00ffff 127 | 12 = #0000ff 128 | 13 = #ff00ff 129 | 14 = #808080 130 | 15 = #c0c0c0 131 | 132 | style = default 133 | -------------------------------------------------------------------------------- /formats/gothic: -------------------------------------------------------------------------------- 1 | looking up = {prefix-client} Looking up {server $0} 2 | connecting = {prefix-client} Connecting to {server $0} [$1] port {hilight $2} 3 | 4 | access denied = {prefix-client} Access Denied: $0 5 | access server denied = {prefix-client} Access to server $0 is blocked 6 | access port denied = {prefix-client} Access to port $0 is blocked 7 | access channel denied = {prefix-client} Access to channel $0 is blocked 8 | command denied = {prefix-client} Access to that command is blocked 9 | session timeout = {prefix-client} Timeout - Your session has been inactive too long 10 | 11 | kill ok = {prefix-error} You were killed by $1 ($2) 12 | kill wrong = {prefix-error} $1 tried to kill you but got the password wrong! ($2) 13 | 14 | command notparams = {prefix-client} Not enough parameters for command 15 | command error = {prefix-client} Error running command 16 | error = {prefix-error} An error occurred: $0 17 | not supported = {prefix-client} $0 attempted to $3 to you but CGI:IRC does not support it ($2) 18 | 19 | cgiirc welcome = {prefix-client} %04Welcome to the geiol webchat 20 | 21 | join = {prefix-user} $0 {host $1} has joined {channel $T} 22 | nick = {prefix-user} $0 is now known as $2 23 | quit = {prefix-user} $0 {host $1} has quit {reason $2} 24 | part = {prefix-user} $0 left {channel $T} {reason $2} 25 | user mode = {prefix-user} usermode/$0 $2 26 | mode = {prefix-user} mode/$T [$2] by $0 27 | topic = {prefix-user} $0 changed the topic to: $2 28 | invite = {prefix-user} $0 invites you to join $2 29 | kick = {prefix-user} $2 was kicked from $T by $0 {reason $3} 30 | 31 | prefix-error = %13***%n 32 | prefix-info = %13***%n 33 | prefix-user = %15***%n%15 34 | prefix-client = %13***%n 35 | prefix-server = %13***%n 36 | 37 | notice public = {notice-target $0 $T} {text $2} 38 | notice special = {notice-target $0 $2} {text $3} 39 | notice private = {notice-nick $0}{notice-host $1} {text $2} 40 | notice server = %05-$0%05-%n {text $2} 41 | notice public own = {notice-target $0 $T} {text $2} 42 | notice private own = [notice:$T] {text $2} 43 | 44 | notice-target = %05-$0:$1%05-%n 45 | notice-nick = %03$0%n 46 | notice-host = [$0] 47 | 48 | message public = {message-nick $0} {text $2} 49 | message public hilight = {message-nick-hilight $0} {text $2} 50 | message private window = {message-nick $0} {text $2} 51 | message private = [$0($1)] {text $2} 52 | message special = <$0:$2> {text $3} 53 | 54 | message-nick = %15<%n%04$0%15>%n 55 | message-nick-own = %15<%n%04$0%15>%n 56 | message-nick-hilight = %02<%07$0%02>%n 57 | 58 | message public own = {message-nick-own $0} {text $2} 59 | message private window own = {message-nick-own $0} {text $2} 60 | message private own = [msg->$T] {text $2} 61 | 62 | action-nick = %14 %_*%_ $0 63 | action public = {action-nick $0} {text $2} 64 | action private = {action-nick $0} {text $2} 65 | 66 | action public own = {action-nick $0} {text $2} 67 | action private own = {action-nick $0} {text $2} 68 | 69 | ctcp own msg = {prefix-user} CTCP to $T: $1 70 | ctcp msg = {prefix-user} $1 requested CTCP %_$3%_ from $0: $4 71 | ctcp reply = {prefix-user} CTCP %_$2%_ reply from $0: $3 72 | 73 | text = $0 74 | channel = %_$0%_ 75 | reason = [$0] 76 | 77 | server = %_$0%_ 78 | hilight = %_$0%_ 79 | host = [$0] 80 | 81 | default = {prefix-server} $0- 82 | 83 | ignore list = {prefix-client} Ignore: $0- 84 | ignored = {prefix-client} Ignored: $0- 85 | unignored = {prefix-client} Unignored: $0- 86 | 87 | reply away = {prefix-user} $T is away: $0 88 | reply nowaway = {prefix-server} You are now set as away 89 | reply unaway = {prefix-server} You are no longer set as away 90 | 91 | reply channel time = {prefix-server} Channel created on $0 92 | reply notopic = {prefix-server} No topic set 93 | reply topic = {prefix-server} Topic is: $0 94 | reply topicwhotime = {prefix-server} Topic set by $0 [$1] 95 | 96 | reply whois user = {prefix-user} $T [$0@$1]: $2 97 | reply whowas user = {prefix-user} $T [$0@$1]: $2 98 | reply whois channel = {prefix-user} channels: $0 99 | reply whois regnick = {prefix-user} registered: $0 100 | reply whois operator = {prefix-user} ircop: $0 101 | reply whois idle = {prefix-user} idle: $0 signon: $1 102 | time = $7 days $2 hours $1 min $0 sec 103 | reply whois server = {prefix-user} server: $0 [$1] 104 | reply whois end = {prefix-user} $0 105 | 106 | error nosuchnick = {prefix-server} %_$0%_ No such nick/channel 107 | error nickinuse = {prefix-server} Nickname $0 is already in use, type /nick newnick to use another. 108 | 109 | irc close = {prefix-error} Disconnected from IRC (click to reconnect) 110 | 111 | bg = 01 112 | fg = 00 113 | 00 = #ffffff 114 | 01 = #000000 115 | 02 = #999999 116 | 03 = #008000 117 | 04 = #991111 118 | 05 = #800000 119 | 06 = #800080 120 | 07 = #bb1111 121 | 08 = #ffff00 122 | 09 = #00ff00 123 | 10 = #008080 124 | 11 = #00ffff 125 | 12 = #aaaaaa 126 | 13 = #880088 127 | 14 = #fff000 128 | 15 = #666666 129 | 130 | style = gothic 131 | -------------------------------------------------------------------------------- /formats/mirc: -------------------------------------------------------------------------------- 1 | looking up = {prefix-client} Looking up {server $0} 2 | connecting = {prefix-client} Connecting to {server $0} [$1] port {hilight $2} 3 | 4 | access denied = {prefix-error} Access Denied: $0 5 | access server denied = {prefix-error} Access to server $0 is blocked 6 | access port denied = {prefix-error} Access to port $0 is blocked 7 | access channel denied = {prefix-error} Access to channel $0 is blocked 8 | command denied = {prefix-error} Access to that command is blocked 9 | session timeout = {prefix-error} Timeout - Your session has been inactive too long 10 | 11 | kill ok = {prefix-error} You were killed by $0 ($1) 12 | kill wrong = {prefix-error} $0 tried to kill you but got the password wrong! ($1) 13 | 14 | command notparams = {prefix-client} Not enough parameters for command 15 | command error = {prefix-client} Error running command 16 | error = {prefix-error} An error occurred: $0 17 | not supported = {prefix-client} $0 attempted to $3 to you but CGI:IRC does not support it ($2) 18 | 19 | cgiirc welcome = {prefix-client} Welcome to CGI:IRC $VERSION 20 | 21 | join = {prefix-channel} $0 has joined {channel $T} 22 | nick = {prefix-channel} $0 is now known as $2 23 | quit = {prefix-user} $0 Quit {reason $2} 24 | part = {prefix-channel} $0 left {channel $T} {reason $2} 25 | user mode = {prefix-channel} $0 sets mode: $2 26 | mode = {prefix-channel} $0 sets mode: $2 27 | topic = {prefix-channel} $0 changes topic to '$2' 28 | invite = {prefix-channel} $0 {host $1} invites you to join {channel $2} 29 | kick = {prefix-channel} $2 was kicked by $0 {reason $3} 30 | 31 | prefix-error = %04*** 32 | prefix-info = %03*** 33 | prefix-channel = %03*** 34 | prefix-user = %02*** 35 | prefix-client = %12*** 36 | prefix-server = %05*** 37 | prefix-ctcp = %04 38 | prefix-normal = *** 39 | 40 | notice public = {notice-target $0 $T} {text $2} 41 | notice special = {notice-target $0 $2} {text $3} 42 | notice private = {prefix-server}-{notice-nick $0}- {text $2} 43 | notice server = %05-$0%05-%n {text $2} 44 | notice public own = {notice-target $0 $T} {text $2} 45 | notice private own = [notice:$T] {text $2} 46 | 47 | notice-target = %05-$0:$1- 48 | notice-nick = %03$0%n 49 | notice-host = [$0] 50 | 51 | message public = {message-nick $0} {text $2} 52 | message public hilight = {message-nick-hilight $0} {text $2} 53 | message private window = {message-nick $0} {text $2} 54 | message private = [$0($1)] {text $2} 55 | message special = <$0:$2> {text $3} 56 | 57 | message-nick = %02<%n$0%02>%n 58 | message-nick-own = %03<%n$0%03>%n 59 | message-nick-hilight = %02<%07$0%02>%n 60 | 61 | message public own = {message-nick-own $0} {text $2} 62 | message private window own = {message-nick-own $0} {text $2} 63 | message private own = [msg->$T] {text $2} 64 | 65 | action-nick = %06%_*%_ $0 66 | action public = {action-nick $0} {text $2} 67 | action private = {action-nick $0} {text $2} 68 | 69 | action public own = {action-nick $0} {text $2} 70 | action private own = {action-nick $0} {text $2} 71 | 72 | ctcp own msg = {prefix-ctcp} CTCP to $T: $1 73 | ctcp msg = {prefix-ctcp} $1 requested CTCP %_$3%_ from $0: $4 74 | ctcp reply = {prefix-ctcp} CTCP %_$2%_ reply from $0: $3 75 | 76 | text = $0 77 | channel = %_$0%_ 78 | reason = ($0) 79 | 80 | server = %_$0%_ 81 | hilight = %_$0%_ 82 | host = ($0) 83 | 84 | default = {prefix-normal} $0- 85 | 86 | ignore list = {prefix-client} Ignore: $0- 87 | ignored = {prefix-client} Ignored: $0- 88 | unignored = {prefix-client} Unignored: $0- 89 | 90 | reply away = {prefix-user} $T is away: $0 91 | reply nowaway = {prefix-user} You are now set as away 92 | reply unaway = {prefix-user} You are no longer set as away 93 | 94 | reply channel time = {prefix-channel} Channel created on $0 95 | reply notopic = {prefix-channel} No topic set 96 | reply topic = {prefix-channel} Topic is: $0 97 | reply topicwhotime = {prefix-channel} Topic set by $0 [$1] 98 | 99 | reply whois user = {prefix-user} $T [$0@$1]: $2 100 | reply whowas user = {prefix-user} $T [$0@$1]: $2 101 | reply whois channel = {prefix-user} channels: $0 102 | reply whois regnick = {prefix-user} registered: $0 103 | reply whois operator = {prefix-user} ircop: $0 104 | reply whois idle = {prefix-user} idle: $0 signon: $1 105 | time = $7 days $2 hours $1 min $0 sec 106 | reply whois server = {prefix-user} server: $0 [$1] 107 | reply whois end = {prefix-user} $0 108 | 109 | error nosuchnick = {prefix-server} {hilight $T} No such nick/channel 110 | error nickinuse = {prefix-server} Nickname $0 is already in use, type /nick newnick to use another. 111 | 112 | irc close = {prefix-error} Disconnected from IRC (click to reconnect) 113 | 114 | 115 | bg = 00 116 | fg = 01 117 | 00 = #ffffff 118 | 01 = #000000 119 | 02 = #000080 120 | 03 = #008000 121 | 04 = #ff0000 122 | 05 = #800000 123 | 06 = #800080 124 | 07 = #ff6600 125 | 08 = #ffff00 126 | 09 = #00ff00 127 | 10 = #008080 128 | 11 = #00ffff 129 | 12 = #000099 130 | 13 = #ff00ff 131 | 14 = #808080 132 | 15 = #c0c0c0 133 | 134 | style = mirc 135 | -------------------------------------------------------------------------------- /formats/norwegian: -------------------------------------------------------------------------------- 1 | looking up = {prefix-client} Leter etter {server $0} 2 | connecting = {prefix-client} Kobler til {server $0} [$1] port {hilight $2} 3 | 4 | access denied = {prefix-client} Tilgang nektet: $0 5 | access server denied = {prefix-client} Tilgang til server $0 er sperret 6 | access port denied = {prefix-client} Tilgang til port $0 er sperret 7 | access channel denied = {prefix-client} Tilgang til kanalen $0 er sperret 8 | command denied = {prefix-client} Tilgang til kommandoen er sperret 9 | session timeout = {prefix-client} Timeout - Din tilkobling har vært inaktiv for lenge 10 | 11 | kill ok = {prefix-error} Din tilkobling ble drept av $0 ($1) 12 | kill wrong = {prefix-error} $0 prøvde å drepe tilkoblingen din, men skrev feil passord! ($1) 13 | 14 | command notparams = {prefix-client} Ikke nok data for kommandoen 15 | command error = {prefix-client} Feil ved kjøring av kommando 16 | error = {prefix-error} En feil oppsto: $0 17 | not supported = {prefix-client} $0 prøvde å $3 deg, men CGI:IRC støtter ikke operasjonen ($2) 18 | 19 | cgiirc welcome = {prefix-client} Velkommen til CGI:IRC $VERSION 20 | 21 | join = {prefix-user} $0 {host $1} har kommet til {channel $T} 22 | nick = {prefix-user} $0 har byttet kallenavn til $2 23 | quit = {prefix-user} $0 {host $1} har avsluttet {reason $2} 24 | part = {prefix-user} $0 forlot {channel $T} {reason $2} 25 | user mode = {prefix-user} brukermodus/$0 $2 26 | mode = {prefix-user} modus/$T [$2] av $0 27 | topic = {prefix-user} $0 byttet topic til: $2 28 | invite = {prefix-user} $0 inviterer deg til å komme til $2 29 | kick = {prefix-user} $2 ble sparket fra $T av $0 {reason $3} 30 | 31 | prefix-error = %04***%n 32 | prefix-info = %03***%n 33 | prefix-user = %03***%n 34 | prefix-client = %02***%n 35 | prefix-server = %05***%n 36 | 37 | notice public = {notice-target $0 $T} {text $2} 38 | notice special = {notice-target $0 $2} {text $3} 39 | notice private = -{notice-nick $0}- {text $2} 40 | notice server = %05-$0%05-%n {text $2} 41 | notice public own = {notice-target $0 $T} {text $2} 42 | notice private own = [notice:$T] {text $2} 43 | 44 | notice-target = %05-$0:$1%05-%n 45 | notice-nick = %03$0%n 46 | notice-host = [$0] 47 | 48 | message public = {message-nick $0} {text $2} 49 | message public hilight = {message-nick-hilight $0} {text $2} 50 | message private window = {message-nick $0} {text $2} 51 | message private = [$0($1)] {text $2} 52 | message special = <$0:$2> {text $3} 53 | 54 | message-nick = %02<%n$0%02>%n 55 | message-nick-own = %03<%n$0%03>%n 56 | message-nick-hilight = %02<%07$0%02>%n 57 | 58 | message public own = {message-nick-own $0} {text $2} 59 | message private window own = {message-nick-own $0} {text $2} 60 | message private own = [msg->$T] {text $2} 61 | 62 | action-nick = %_*%_ $0 63 | action public = {action-nick $0} {text $2} 64 | action private = {action-nick $0} {text $2} 65 | 66 | action public own = {action-nick $0} {text $2} 67 | action private own = {action-nick $0} {text $2} 68 | 69 | ctcp own msg = {prefix-user} CTCP til $T: $1 70 | ctcp msg = {prefix-user} $1 spurte om CTCP %_$3%_ av $0: $4 71 | ctcp reply = {prefix-user} CTCP %_$2%_ tilbakemelding fra $0: $3 72 | 73 | text = $0 74 | channel = %_$0%_ 75 | reason = [$0] 76 | 77 | server = %_$0%_ 78 | hilight = %_$0%_ 79 | host = [$0] 80 | 81 | default = {prefix-server} $0- 82 | raw = {prefix-server} $0- 83 | 84 | ignore list = {prefix-client} Ignorer: $0- 85 | ignored = {prefix-client} Ignorert: $0- 86 | unignored = {prefix-client} Ikke lenger ignorert: $0- 87 | 88 | reply away = {prefix-user} $T er borte: $0 89 | reply nowaway = {prefix-server} Du er nå satt som borte 90 | reply unaway = {prefix-server} Du er ikke lenger satt som borte 91 | 92 | reply channel time = {prefix-server} Kanalen ble laget $0 93 | reply notopic = {prefix-server} Ingen topic skrevet 94 | reply topic = {prefix-server} Topic er: $0 95 | reply topicwhotime = {prefix-server} Topic ble skrevet av $0 [$1] 96 | 97 | reply whois user = {prefix-user} $T [$0@$1]: $2 98 | reply whowas user = {prefix-user} $T [$0@$1]: $2 99 | reply whois channel = {prefix-user} kanaler: $0 100 | reply whois regnick = {prefix-user} registrerte: $0 101 | reply whois operator = {prefix-user} irc-operatør: $0 102 | reply whois idle = {prefix-user} idle: $0 koblet på: $1 103 | time = $7 days $2 hours $1 min $0 sec 104 | reply whois server = {prefix-user} server: $0 [$1] 105 | reply whois end = {prefix-user} $0 106 | 107 | error nosuchnick = {prefix-server} {hilight $T}: Ingen slik kanal/kallenavn 108 | error nickinuse = {prefix-server} Kallenavnet $0 er allerede i bruk, skriv /nick nytt_nick for å velge et nytt kallenavn. 109 | 110 | irc close = {prefix-error} Frakoblet fra ScaryNet IRC Nettverket (skriv /reconnect for å koble på igjen) 111 | 112 | 113 | bg = 00 114 | fg = 01 115 | 00 = #ffffff 116 | 01 = #000000 117 | 02 = #000080 118 | 03 = #008000 119 | 04 = #ff0000 120 | 05 = #800000 121 | 06 = #800080 122 | 07 = #ff6600 123 | 08 = #ffff00 124 | 09 = #00ff00 125 | 10 = #008080 126 | 11 = #00ffff 127 | 12 = #0000ff 128 | 13 = #ff00ff 129 | 14 = #808080 130 | 15 = #c0c0c0 131 | 132 | style = default 133 | -------------------------------------------------------------------------------- /formats/romanian: -------------------------------------------------------------------------------- 1 | looking up = {prefix-client} Verificare {server $0} 2 | connecting = {prefix-client} Conectare catre {server $0} [$1] port {hilight $2} 3 | 4 | access denied = {prefix-client} Acces interzis: $0 5 | access server denied = {prefix-client} Acces-ul la acest server este interzis 6 | access channel denied = {prefix-client} Acces-ul la acest canal este interzis 7 | command denied = {prefix-client} Acces-ul la aceasta comanda este interzis 8 | session timeout = {prefix-client} Timeout - Conexiunea ta a fost inactiva prea mult 9 | 10 | kill ok = {prefix-error} Ai primit 'kill' de la $0 ($1) 11 | kill wrong = {prefix-error} $0 a incercat sa iti dea 'kill' dar parola a fost incorecta! ($1) 12 | 13 | command notparams = {prefix-client} Parametrii insuficienti pentru aceasta comanda 14 | command error = {prefix-client} Eroare in timpul acestei comenzi 15 | error = {prefix-error} A aparut o eroare: $0 16 | not supported = {prefix-client} $0 a incercat la $3 catre tine dar CGI:IRC nu e compatibil ($2) 17 | 18 | cgiirc welcome = {prefix-client} Bine ati venit la CGI:IRC $VERSION 19 | 20 | join = {prefix-user} $0 {host $1} a intrat {channel $T} 21 | nick = {prefix-user} $0 este acum $2 22 | quit = {prefix-user} $0 {host $1} a iesit {reason $2} 23 | part = {prefix-user} $0 a parasit {channel $T} {reason $2} 24 | user mode = {prefix-user} usermode/$0 $2 25 | mode = {prefix-user} mode/$T [$2] by $0 26 | topic = {prefix-user} $0 topicul schimbat: $2 27 | invite = {prefix-user} $0 te invita sa intri pe $2 28 | kick = {prefix-user} $2 a fost dat afara de pe $T de $0 {reason $3} 29 | 30 | prefix-error = %04***%n 31 | prefix-info = %03***%n 32 | prefix-user = %03***%n 33 | prefix-client = %02***%n 34 | prefix-server = %05***%n 35 | 36 | notice public = {notice-target $0 $T} {text $2} 37 | notice special = {notice-target $0 $2} {text $3} 38 | notice private = -{notice-nick $0}- {text $2} 39 | notice server = %05-$0%05-%n {text $2} 40 | notice public own = {notice-target $0 $T} {text $2} 41 | notice private own = [notice:$T] {text $2} 42 | 43 | notice-target = %05-$0:$1%05-%n 44 | notice-nick = %03$0%n 45 | notice-host = [$0] 46 | 47 | message public = {message-nick $0} {text $2} 48 | message public hilight = {message-nick-hilight $0} {text $2} 49 | message private window = {message-nick $0} {text $2} 50 | message private = [$0($1)] {text $2} 51 | message special = <$0:$2> {text $3} 52 | 53 | message-nick = %02<%n$0%02>%n 54 | message-nick-own = %03<%n$0%03>%n 55 | message-nick-hilight = %02<%07$0%02>%n 56 | 57 | message public own = {message-nick-own $0} {text $2} 58 | message private window own = {message-nick-own $0} {text $2} 59 | message private own = [msg->$T] {text $2} 60 | 61 | action-nick = %_*%_ $0 62 | action public = {action-nick $0} {text $2} 63 | action private = {action-nick $0} {text $2} 64 | 65 | action public own = {action-nick $0} {text $2} 66 | action private own = {action-nick $0} {text $2} 67 | 68 | ctcp own msg = {prefix-user} CTCP to $T: $1 69 | ctcp msg = {prefix-user} $1 requested CTCP %_$3%_ from $0: $4 70 | ctcp reply = {prefix-user} CTCP %_$2%_ reply from $0: $3 71 | 72 | text = $0 73 | channel = %_$0%_ 74 | reason = [$0] 75 | 76 | server = %_$0%_ 77 | hilight = %_$0%_ 78 | host = [$0] 79 | 80 | default = {prefix-server} $0- 81 | raw = {prefix-server} $0- 82 | 83 | ignore list = {prefix-client} Lista de ignor: $0- 84 | ignored = {prefix-client} Ignorat: $0- 85 | unignored = {prefix-client} Ignor scos: $0- 86 | 87 | reply away = {prefix-user} $T este plecat: $0 88 | reply nowaway = {prefix-server} Ai fost marcat ca plecat 89 | reply unaway = {prefix-server} Nu mai figurezi ca fiind plecat 90 | 91 | reply channel time = {prefix-server} Canal creat pe $0 92 | reply notopic = {prefix-server} Nici un topic setat 93 | reply topic = {prefix-server} Topic-ul este: $0 94 | reply topicwhotime = {prefix-server} Topic setat de $0 [$1] 95 | 96 | reply whois user = {prefix-user} $T [$0@$1]: $2 97 | reply whowas user = {prefix-user} $T [$0@$1]: $2 98 | reply whois channel = {prefix-user} channels: $0 99 | reply whois regnick = {prefix-user} registered: $0 100 | reply whois operator = {prefix-user} ircop: $0 101 | reply whois idle = {prefix-user} idle: $0 signon: $1 102 | time = $7 days $2 hours $1 min $0 sec 103 | reply whois server = {prefix-user} server: $0 [$1] 104 | reply whois end = {prefix-user} $0 105 | 106 | error nosuchnick = {prefix-server} {hilight $T}: Nu exista canalul/nick-ul 107 | error nickinuse = {prefix-server} Nickname-ul $0 este ocupat, tasteaza /nick 'noul-tau_nick' pentru a folosi altul. 108 | 109 | irc close = {prefix-error} Deconectat de la IRC. (reconnect) 110 | 111 | 112 | bg = 00 113 | fg = 01 114 | 00 = #ffffff 115 | 01 = #000000 116 | 02 = #000080 117 | 03 = #008000 118 | 04 = #ff0000 119 | 05 = #800000 120 | 06 = #800080 121 | 07 = #ff6600 122 | 08 = #ffff00 123 | 09 = #00ff00 124 | 10 = #008080 125 | 11 = #00ffff 126 | 12 = #0000ff 127 | 13 = #ff00ff 128 | 14 = #808080 129 | 15 = #c0c0c0 130 | 131 | style = romanian 132 | -------------------------------------------------------------------------------- /formats/russian: -------------------------------------------------------------------------------- 1 | looking up = {prefix-client} Резолвим {server $0} 2 | connecting = {prefix-client} Соединяемся с {server $0} [$1] port {hilight $2} 3 | 4 | access denied = {prefix-client} Доступ закрыт: $0 5 | access server denied = {prefix-client} Доступ к серверу блокирован 6 | access channel denied = {prefix-client} Доступ к каналу блокирован 7 | command denied = {prefix-client} Использование данной команды запрещено 8 | session timeout = {prefix-client} Таймаут - ваша сессия была слишком долго не активна 9 | 10 | kill ok = {prefix-error} Вы получили kill от $1 ($2) 11 | kill wrong = {prefix-error} $1 Вам пытались сделать kill но ввели неверный пароль! ($2) 12 | 13 | command notparams = {prefix-client} Не достаточно параметров для команды 14 | command error = {prefix-client} Ошибка выполнения команды 15 | error = {prefix-error} Ошибка: $0 16 | not supported = {prefix-client} $0 пытается $3 к вам но CGI:IRC не поддерживает етой возможности ($2) 17 | 18 | cgiirc welcome = {prefix-client} Добро пожаловать в CGI:IRC - $VERSION 19 | 20 | join = {prefix-user} $0 {host $1} зашёл на канал {channel $T} 21 | nick = {prefix-user} $0 сменил(а) ник на $2 22 | quit = {prefix-user} $0 {host $1} покинул(а) канал {reason $2} 23 | part = {prefix-user} $0 покинул(а) {channel $T} {reason $2} 24 | user mode = {prefix-user} usermode/$0 $2 25 | mode = {prefix-user} mode/$T [$2] by $0 26 | topic = {prefix-user} $0 тема изменена на: $2 27 | invite = {prefix-user} $0 приглашает тебя присоединиться $2 28 | kick = {prefix-user} $2 выкинут с канала $T $0 {reason $3} 29 | 30 | prefix-error = %04***%n 31 | prefix-info = %03***%n 32 | prefix-user = %03***%n 33 | prefix-client = %02***%n 34 | prefix-server = %05***%n 35 | 36 | notice public = {notice-target $0 $T} {text $2} 37 | notice special = {notice-target $0 $2} {text $3} 38 | notice private = {notice-nick $0}{notice-host $1} {text $2} 39 | notice server = %05-$0%05-%n {text $2} 40 | notice public own = {notice-target $0 $T} {text $2} 41 | notice private own = [notice:$T] {text $2} 42 | 43 | notice-target = %05-$0:$1%05-%n 44 | notice-nick = %03$0%n 45 | notice-host = [$0] 46 | 47 | message public = {message-nick $0} {text $2} 48 | message public hilight = {message-nick-hilight $0} {text $2} 49 | message private window = {message-nick $0} {text $2} 50 | message private = [$0($1)] {text $2} 51 | message special = <$0:$2> {text $3} 52 | 53 | message-nick = %02<%n$0%02>%n 54 | message-nick-own = %03<%n$0%03>%n 55 | message-nick-hilight = %02<%07$0%02>%n 56 | 57 | message public own = {message-nick-own $0} {text $2} 58 | message private window own = {message-nick-own $0} {text $2} 59 | message private own = [msg->$T] {text $2} 60 | 61 | action-nick = %_*%_ $0 62 | action public = {action-nick $0} {text $2} 63 | action private = {action-nick $0} {text $2} 64 | 65 | action public own = {action-nick $0} {text $2} 66 | action private own = {action-nick $0} {text $2} 67 | 68 | ctcp own msg = {prefix-user} CTCP к $T: $1 69 | ctcp msg = {prefix-user} $1 запрос CTCP %_$3%_ от $0: $4 70 | ctcp reply = {prefix-user} CTCP %_$2%_ ответ от $0: $3 71 | 72 | text = $0 73 | channel = %_$0%_ 74 | reason = [$0] 75 | 76 | server = %_$0%_ 77 | hilight = %_$0%_ 78 | host = [$0] 79 | 80 | default = {prefix-server} $0- 81 | 82 | ignore list = {prefix-client} Ignore-список: $0- 83 | ignored = {prefix-client} Игнорирован: $0- 84 | unignored = {prefix-client} Деигнорирован: $0- 85 | 86 | reply away = {prefix-user} $T Отсутствует: $0 87 | reply nowaway = {prefix-server} Вы сейчас помечены как "отсутствует" 88 | reply unaway = {prefix-server} Вы больше не помечены как "отсутствует" 89 | 90 | reply channel time = {prefix-server} Канал создан $0 91 | reply notopic = {prefix-server} Нет темы канала 92 | reply topic = {prefix-server} Тема канала: $0 93 | reply topicwhotime = {prefix-server} Тема установлена $0 [$1] 94 | 95 | reply whois user = {prefix-user} $T [$0@$1]: $2 96 | reply whowas user = {prefix-user} $T [$0@$1]: $2 97 | reply whois channel = {prefix-user} каналов: $0 98 | reply whois regnick = {prefix-user} зарегистрирован: $0 99 | reply whois operator = {prefix-user} ircop: $0 100 | reply whois idle = {prefix-user} время: $0 с момента входа: $1 101 | time = $7 days $2 hours $1 min $0 sec 102 | reply whois server = {prefix-user} сервер: $0 [$1] 103 | reply whois end = {prefix-user} $0 104 | 105 | error nosuchnick = {prefix-server} %_$0%_ Нет такого ника/канала 106 | error nickinuse = {prefix-server} Ник $0 уже используется, наберите /nick новый_ник для смены ника. 107 | 108 | irc close = {prefix-error} Потеря связи с IRC (reconnect) 109 | 110 | bg = 00 111 | fg = 01 112 | 00 = #ffffff 113 | 01 = #000000 114 | 02 = #000080 115 | 03 = #008000 116 | 04 = #ff0000 117 | 05 = #800000 118 | 06 = #800080 119 | 07 = #ff6600 120 | 08 = #ffff00 121 | 09 = #00ff00 122 | 10 = #008080 123 | 11 = #00ffff 124 | 12 = #0000ff 125 | 13 = #ff00ff 126 | 14 = #808080 127 | 15 = #c0c0c0 128 | 129 | -------------------------------------------------------------------------------- /images/actmsg.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/actmsg.wav -------------------------------------------------------------------------------- /images/actsound.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/actsound.gif -------------------------------------------------------------------------------- /images/angry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/angry.gif -------------------------------------------------------------------------------- /images/cgiirc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/cgiirc.gif -------------------------------------------------------------------------------- /images/cheesy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/cheesy.gif -------------------------------------------------------------------------------- /images/closedn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/closedn.gif -------------------------------------------------------------------------------- /images/closeup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/closeup.gif -------------------------------------------------------------------------------- /images/confused.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/confused.gif -------------------------------------------------------------------------------- /images/cool.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/cool.gif -------------------------------------------------------------------------------- /images/cry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/cry.gif -------------------------------------------------------------------------------- /images/embarassed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/embarassed.gif -------------------------------------------------------------------------------- /images/entry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/entry.gif -------------------------------------------------------------------------------- /images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/favicon.ico -------------------------------------------------------------------------------- /images/flat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/flat.gif -------------------------------------------------------------------------------- /images/font.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/font.gif -------------------------------------------------------------------------------- /images/grin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/grin.gif -------------------------------------------------------------------------------- /images/happy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/happy.gif -------------------------------------------------------------------------------- /images/happycry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/happycry.gif -------------------------------------------------------------------------------- /images/helpdn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/helpdn.gif -------------------------------------------------------------------------------- /images/helpup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/helpup.gif -------------------------------------------------------------------------------- /images/hmmm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/hmmm.gif -------------------------------------------------------------------------------- /images/join.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/join.wav -------------------------------------------------------------------------------- /images/joinsound.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/joinsound.gif -------------------------------------------------------------------------------- /images/kiss.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/kiss.gif -------------------------------------------------------------------------------- /images/love.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/love.gif -------------------------------------------------------------------------------- /images/notsure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/notsure.gif -------------------------------------------------------------------------------- /images/optionsdn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/optionsdn.gif -------------------------------------------------------------------------------- /images/optionsup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/optionsup.gif -------------------------------------------------------------------------------- /images/scrollback.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/scrollback.gif -------------------------------------------------------------------------------- /images/sleep.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/sleep.gif -------------------------------------------------------------------------------- /images/smile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/smile.gif -------------------------------------------------------------------------------- /images/sorry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/sorry.gif -------------------------------------------------------------------------------- /images/surprised.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/surprised.gif -------------------------------------------------------------------------------- /images/taras/angry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/angry.gif -------------------------------------------------------------------------------- /images/taras/cheesy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/cheesy.gif -------------------------------------------------------------------------------- /images/taras/closedn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/closedn.gif -------------------------------------------------------------------------------- /images/taras/closeup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/closeup.gif -------------------------------------------------------------------------------- /images/taras/confused.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/confused.gif -------------------------------------------------------------------------------- /images/taras/cool.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/cool.gif -------------------------------------------------------------------------------- /images/taras/cry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/cry.gif -------------------------------------------------------------------------------- /images/taras/embarassed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/embarassed.gif -------------------------------------------------------------------------------- /images/taras/entry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/entry.gif -------------------------------------------------------------------------------- /images/taras/flat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/flat.gif -------------------------------------------------------------------------------- /images/taras/font.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/font.gif -------------------------------------------------------------------------------- /images/taras/grin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/grin.gif -------------------------------------------------------------------------------- /images/taras/happy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/happy.gif -------------------------------------------------------------------------------- /images/taras/helpdn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/helpdn.gif -------------------------------------------------------------------------------- /images/taras/helpup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/helpup.gif -------------------------------------------------------------------------------- /images/taras/love.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/love.gif -------------------------------------------------------------------------------- /images/taras/notsure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/notsure.gif -------------------------------------------------------------------------------- /images/taras/optionsdn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/optionsdn.gif -------------------------------------------------------------------------------- /images/taras/optionsup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/optionsup.gif -------------------------------------------------------------------------------- /images/taras/smile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/smile.gif -------------------------------------------------------------------------------- /images/taras/surprised.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/surprised.gif -------------------------------------------------------------------------------- /images/taras/time.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/time.gif -------------------------------------------------------------------------------- /images/taras/tongue.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/tongue.gif -------------------------------------------------------------------------------- /images/taras/unhappy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/unhappy.gif -------------------------------------------------------------------------------- /images/taras/wink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/taras/wink.gif -------------------------------------------------------------------------------- /images/time.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/time.gif -------------------------------------------------------------------------------- /images/tongue.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/tongue.gif -------------------------------------------------------------------------------- /images/unhappy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/unhappy.gif -------------------------------------------------------------------------------- /images/what.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/what.gif -------------------------------------------------------------------------------- /images/wink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dgl/cgiirc/f54402cccf28d2bade05f37a7f41c1a80628b1f9/images/wink.gif -------------------------------------------------------------------------------- /interfaces/.gitignore: -------------------------------------------------------------------------------- 1 | ie.pm 2 | opera7.pm 3 | konqueror.pm 4 | mozilla.pm 5 | -------------------------------------------------------------------------------- /interfaces/default.pm: -------------------------------------------------------------------------------- 1 | package default; 2 | use vars qw/$standardheader/; 3 | use strict; 4 | $standardheader = <<'EOF'; 5 | 9 | EOF 10 | 11 | sub new { 12 | return bless {}; 13 | } 14 | 15 | sub exists { 16 | return 1 if defined &{__PACKAGE__ . '::' . $_[1]}; 17 | } 18 | 19 | sub makeline { 20 | my($self, $type, $target, $html) = @_; 21 | return "$html
\n"; 22 | } 23 | 24 | sub lines { 25 | my($self, @lines); 26 | unless(print @lines) { 27 | $::needtodie++; 28 | } 29 | } 30 | 31 | sub header { 32 | print "\n"; 33 | } 34 | 35 | sub keepalive { 36 | unless(print "\r\n") { 37 | $::needtodie++; 38 | } 39 | } 40 | 41 | sub error { 42 | my($self, $error) = @_; 43 | $self->line({}, '', $error); 44 | } 45 | 46 | sub form { 'DUMMY' } 47 | 48 | sub add { 'DUMMY' } 49 | 50 | sub del { 'DUMMY' } 51 | 52 | sub clear { 'DUMMY' } 53 | 54 | sub end { 'DUMMY' } 55 | 56 | sub options { 'DUMMY' } 57 | 58 | sub setoption { 'DUMMY' } 59 | 60 | # not supported by default interface 61 | sub ctcpping { 0 } 62 | sub ping { 0 } 63 | 64 | sub login { 65 | my($self, $this, $interface, $copy, $config, $order, $items, $adv) = @_; 66 | my $notsupported = 0; 67 | # Seems to work on Safari 2 (WebKit >=4xx): 68 | # http://developer.apple.com/internet/safari/uamatrix.html 69 | if ($ENV{HTTP_USER_AGENT} =~ /konqueror.2|Mozilla\/4.\d+ \[|OmniWeb|Safari\/(\d{2}|[1-3]\d{2})(\D|$)|Mozilla\/4.\d+ .*Mac_PowerPC/i) { 70 | $notsupported++; 71 | } 72 | 73 | print < 76 | 77 | 78 | 130 | CGI:IRC Login 131 | 132 | 133 | EOF 134 | if($notsupported) { 135 | print "This web-based IRC interface probably won't work well or at all with your browser.\n
You could try a non web-based IRC client or a browser such as Mozilla Firefox.

\n"; 136 | } 137 | print < 139 | EOF 140 | print "\n"; 142 | print < 144 | CGI:IRC 145 | Login 146 | EOF 147 | for(@$order) { 148 | my $item = $$items{$_}; 149 | next unless defined $item; 150 | print "$_"; 152 | if(ref $item eq 'ARRAY') { 153 | s/ /_/g; 154 | print "\n\n"; 167 | }elsif($item eq '-PASSWORD-') { 168 | print ""; 169 | }else{ 170 | my $tmp = ''; 171 | if($item =~ s/^-DISABLED- //) { 172 | $tmp = " disabled=\"1\""; 173 | } 174 | print ""; 175 | } 176 | print "\n"; 177 | } 178 | print < 180 | EOF 181 | if($adv) { 182 | print <Advanced.. 184 | EOF 185 | } 186 | print < 188 | 189 | 190 | 191 | $copy 192 | 193 | EOF 194 | } 195 | 196 | sub reconnect { 197 | my($self, $url, $text) = @_; 198 | return "$text"; 199 | } 200 | 201 | 1; 202 | -------------------------------------------------------------------------------- /interfaces/interface-make/fform.pm: -------------------------------------------------------------------------------- 1 | my($self, $cgi, $config) = @_; 2 | print < 5 | 6 | 7 | 203 | 204 | 205 | 206 |
207 | 208 | 213 |
214 | EOF 215 | .$not konqueror 216 | if($ENV{HTTP_USER_AGENT} !~ /Mac_PowerPC/ && (!exists $config->{disable_format_input} || !$config->{disable_format_input})) { 217 | print < 219 | 220 | 221 | EOF 222 | if(exists $config->{smilies_popup} && $config->{smilies_popup}) { 223 | print ':)'; 224 | } 225 | print < 227 | 228 | EOF 229 | for(sort {$a <=> $b} keys %colours) { 230 | print "\n"; 231 | } 232 | print < 234 | 235 | EOF 236 | } 237 | .$end 238 | print < 240 | 241 | EOF 242 | -------------------------------------------------------------------------------- /interfaces/interface-make/fmain.pm: -------------------------------------------------------------------------------- 1 | my($self, $cgi, $config) = @_; 2 | 3 | # evil. 4 | sub regexp_parse { 5 | my $have_entities = eval { require HTML::Entities; }; 6 | 7 | my $string = shift; 8 | 9 | $string =~ s/(? 22 | 23 | EOF 24 | 25 | if($::config->{smilies_popup}) { 26 | my $smilies = ::parse_config($::config->{smilies}); 27 | my %smilies; 28 | for(keys %$smilies) { 29 | $smilies{regexp_parse($_)} = $smilies->{$_}; 30 | } 31 | $smilies = _outputhash(\%smilies); 32 | 33 | $config->{smilies_perrow} = 5 unless exists $config->{smilies_perrow}; 34 | 35 | print < 37 | var swin; 38 | function smilies() { 39 | if(!swin) { 40 | swin = document.createElement("table"); 41 | swin.className = "main-smilies"; 42 | var smilies = $smilies; 43 | 44 | var c = 0, tr; 45 | for(var i in smilies) { 46 | if((c++ % $config->{smilies_perrow}) == 0) { 47 | tr = document.createElement("tr"); 48 | swin.appendChild(tr); 49 | } 50 | var cont = document.createElement("td"); 51 | cont.width = "@{[int(100 / $config->{smilies_perrow})]}%"; 52 | var p = document.createElement("img"); 53 | p.title = i; 54 | p.src = "$config->{image_path}/" + smilies[i] + ".gif"; 55 | cont.appendChild(p); 56 | cont.onclick = function() { 57 | parent.fform.append(this.firstChild.title + " "); 58 | this.parentNode.parentNode.style.display = 'none'; 59 | } 60 | tr.appendChild(cont); 61 | } 62 | document.body.appendChild(swin); 63 | } 64 | swin.style.display = ''; 65 | } 66 | 67 | EOF 68 | } 69 | print < 71 |
77 | EOF 78 | -------------------------------------------------------------------------------- /interfaces/interface-make/fuserlist.pm: -------------------------------------------------------------------------------- 1 | my($self, $cgi, $config) = @_; 2 | print < 5 | 6 | 69 | 70 | 71 | 72 | 73 | 74 |
75 | 76 | 77 | 78 | 79 |
No channel
80 | 81 |
82 | 83 |
84 | 85 | 90 | 91 |
92 | 93 | 94 | 95 | EOF 96 | -------------------------------------------------------------------------------- /interfaces/interface-make/main.pm: -------------------------------------------------------------------------------- 1 | # NOTE -- This file is generated by running make-js-interfaces.pl 2 | package **BROWSER; 3 | 4 | use strict; 5 | use vars qw/@ISA $standardheader/; 6 | $standardheader = < 9 | == Released under the GNU GPL 10 | --> 11 | EOF 12 | 13 | if(defined $::config->{javascript_domain}) { 14 | $standardheader .= "\n"; 17 | } 18 | 19 | use default; 20 | @ISA = qw/default/; 21 | my %colours = ( 22 | '00' => '#FFFFFF', '01' => '#000000', '02' => '#0000FF', 23 | '03' => '#008000', '04' => '#FF0000', '05' => '#800000', 24 | '06' => '#800080', '07' => '#FF6600', '08' => '#FFFF00', 25 | '09' => '#00FF00', '10' => '#008080', '11' => '#00FFFF', 26 | '12' => '#0000FF', '13' => '#FF00FF', '14' => '#808080', 27 | '15' => '#C0C0C0'); 28 | 29 | my %options = ( 30 | timestamp => { 31 | type => 'toggle', 32 | info => 'Display a timestamp next to each message', 33 | img => 'time.gif' 34 | }, 35 | font => { 36 | type => 'select', 37 | options => [qw/serif sans-serif fantasy cursive monospace/, 38 | 'Arial Black', 'Comic Sans MS', 'Fixedsys', 39 | 'Tahoma', 'Verdana'], 40 | info => 'The font that messages are displayed in', 41 | img => 'font.gif' 42 | }, 43 | shownick => { 44 | type => 'toggle', 45 | info => 'Show your nickname next to the text entry box', 46 | img => 'entry.gif' 47 | }, 48 | smilies => { 49 | type => 'toggle', 50 | info => 'Convert smilies into pictures', 51 | img => 'smile.gif' 52 | }, 53 | scrollback => { 54 | type => 'toggle', 55 | info => 'Store all scrollback data (uses more memory)', 56 | img => 'scrollback.gif', 57 | }, 58 | 'actsound' => { 59 | type => "toggle", 60 | info => "Play a sound when activity directed at you occurs", 61 | img => 'actsound.gif', 62 | }, 63 | 'joinsound' => { 64 | type => "toggle", 65 | info => "Play a sound when some one joins a channel", 66 | img => 'joinsound.gif', 67 | }, 68 | ); 69 | 70 | my(%output_status, %output_none, %output_active); 71 | 72 | sub new { 73 | my($class,$event, $timer, $config, $icookies) = @_; 74 | my $self = bless {}, $class; 75 | tie %$self, 'IRC::UniqueHash'; 76 | if(defined $config->{javascript_domain}) { 77 | _out("document.domain = " . _escapejs($config->{javascript_domain}) . ";"); 78 | } 79 | my $tmp=''; 80 | for(keys %$icookies) { 81 | $tmp .= "$_: " . _escapejs($icookies->{$_}) . ', '; 82 | } 83 | $tmp =~ s/, $//; 84 | _out('document.onreadystatechange = function() { if(this.readyState == "complete") parent.disconnected(); }'); 85 | _out('parent.options = { ' . $tmp . '};'); 86 | $event->add('user add', code => \&useradd); 87 | $event->add('user del', code => \&userdel); 88 | $event->add('user change nick', code => \&usernick); 89 | $event->add('user change', code => \&usermode); 90 | $event->add('user self', code => \&mynick); 91 | $event->add('user 005', code => sub { _func_out('prefix',$_[1])}); 92 | $event->add('user connected', code => sub { _out('parent.connected = 1;') 93 | }); 94 | $self->add('Status', 0); 95 | _func_out('witemnospeak', 'Status'); 96 | _func_out('fontset', $icookies->{font}) if exists $icookies->{font}; 97 | _func_out('enable_sounds') if ((exists $icookies->{actsound} || exists $icookies->{joinsound}) && ($icookies->{actsound} || $icookies->{joinsound})); 98 | 99 | if(exists $::config->{'output status'}) { 100 | @output_status{split /,\s*/, $::config->{'output status'}} = 1; 101 | } 102 | 103 | if(exists $::config->{'output none'}) { 104 | @output_none{split /,\s*/, $::config->{'output none'}} = 1; 105 | } 106 | 107 | if(exists $::config->{'output active'}) { 108 | @output_active{split /,\s*/, $::config->{'output active'}} = 1; 109 | } 110 | 111 | return $self; 112 | } 113 | 114 | sub end { 115 | _out('parent.connected = 0;'); 116 | } 117 | 118 | sub _out { 119 | unless(print "\r\n") { 120 | $::needtodie++; 121 | } 122 | } 123 | 124 | sub _func_out { 125 | my($func,@rest) = @_; 126 | @rest = map(ref $_ eq 'ARRAY' ? _outputarray($_) : _escapejs($_), @rest); 127 | if($func eq 'witemaddtext') { 128 | return 'parent.' . $func . '(' . _jsp(@rest) . ');'; 129 | } 130 | _out('parent.' . $func . '(' . _jsp(@rest) . ');'); 131 | } 132 | 133 | sub _escapejs { 134 | my $in = shift; 135 | return "''" unless defined $in; 136 | $in =~ s/\\/\\\\/g; 137 | $in =~ s/'/\\'/g; 138 | $in =~ s/<\/script/<\\\/\\script/g; 139 | if(defined $_[0]) { 140 | return "$_[0]$in$_[0]"; 141 | } 142 | return '\'' . $in . '\''; 143 | } 144 | 145 | sub _escapehtml { 146 | my $in = shift; 147 | return "''" unless defined $in; 148 | $in =~ s//>/g; 150 | $in =~ s/"/"/g; 151 | return $in; 152 | } 153 | 154 | # XXX: switch this to use a proper JSON library one day.. 155 | 156 | sub _jsp { 157 | return join(', ', @_); 158 | } 159 | 160 | sub _outputarray { 161 | my $array = shift; 162 | return '[' . _jsp(map(_escapejs($_), @$array)) . ']'; 163 | } 164 | 165 | sub _outputhash { 166 | my $hash = shift; 167 | return '{' . _jsp(map(_escapejs($_) . ":" . _escapejs($hash->{$_}), keys %$hash)) . '}'; 168 | } 169 | 170 | sub useradd { 171 | my($event, $nicks, $channel) = @_; 172 | _func_out('channeladdusers', $channel, $nicks); 173 | } 174 | 175 | sub userdel { 176 | my($event, $nick, $channels) = @_; 177 | _func_out('channelsdeluser', $channels, $nick); 178 | } 179 | 180 | sub usernick { 181 | my($event,$old,$new,$channels) = @_; 182 | _func_out('channelsusernick', $old, $new); 183 | } 184 | 185 | sub usermode { 186 | my($event,$nick, $channel, $action, $type) = @_; 187 | _func_out('channelusermode', $channel, $nick, $action, $type); 188 | } 189 | 190 | sub mynick { 191 | my($event, $nick) = @_; 192 | _func_out('mynick', $nick); 193 | } 194 | 195 | sub exists { 196 | return 1 if defined &{__PACKAGE__ . '::' . $_[1]}; 197 | } 198 | 199 | sub query { 200 | return 1; 201 | } 202 | 203 | sub style { 204 | my($self, $cgi, $config) = @_; 205 | my $style = $cgi->{style} || 'default'; 206 | $cgi->{style} =~ s/[^a-z]//gi; 207 | open(STYLE, "; 209 | close(STYLE); 210 | } 211 | 212 | sub makeline { 213 | my($self, $info, $html) = @_; 214 | my $target = defined $info->{target} ? $info->{target} : 'Status'; 215 | 216 | if(ref $target eq 'ARRAY') { 217 | my %tmp = %$info; 218 | my $text = ''; 219 | for(@$target) { 220 | $tmp{target} = $_; 221 | $text .= $self->makeline(\%tmp, $html) . "\r\n"; 222 | } 223 | return $text; 224 | } 225 | 226 | my $out = ""; 227 | if(not exists $self->{$target}) { 228 | if(defined $info && ref $info && exists $info->{create} && $info->{create}) { 229 | $self->add($target, $info->{type} eq 'join' ? 1 : 0); 230 | }elsif($target ne '-all') { 231 | $target = 'Status'; 232 | } 233 | }elsif($info->{type} eq 'join') { 234 | $out = "parent.joinsound();"; 235 | } 236 | 237 | $info->{type} =~ s/^(\w+ \w+) .*/$1/; 238 | return if exists $output_none{$info->{type}}; 239 | $target = "Status" if exists $output_status{$info->{type}}; 240 | $target = "-active" if exists $output_active{$info->{type}}; 241 | 242 | if($info->{style}) { 243 | $html = "{style}\">$html"; 244 | } 245 | return $out . _func_out('witemaddtext', $target, $html . '
', $info->{activity} || 0, 0); 246 | } 247 | 248 | sub lines { 249 | my($self, @lines) = @_; 250 | _out(join("\r\n", @lines)."\r\nparent.witemredraw();"); 251 | .$not ie 252 | print "\r\n"; 253 | .$end 254 | } 255 | 256 | sub header { 257 | my($self, $cgi, $config, $fg, $bg) = @_; 258 | _func_out('maincolor', $fg, $bg); 259 | } 260 | 261 | sub error { 262 | my($self,$message) = @_; 263 | $self->lines($self->makeline({ target => 'Status'}, $message)); 264 | _func_out('disconnected'); 265 | } 266 | 267 | sub add { 268 | my($self,$add,$channel) = @_; 269 | return if not defined $add; 270 | $self->{$add}++; 271 | _func_out('witemadd', $add, $channel); 272 | _func_out('witemchg', $add) if $channel; 273 | } 274 | 275 | sub del { 276 | my($self, $del) = @_; 277 | return if not defined $del; 278 | _func_out('witemdel', $del); 279 | return if not exists $self->{$del}; 280 | delete($self->{$del}); 281 | } 282 | 283 | sub clear { 284 | my($self, $window) = @_; 285 | _func_out('witemclear', $window); 286 | } 287 | 288 | sub active { 289 | my($self, $window) = @_; 290 | _func_out('witemchg', $window); 291 | } 292 | 293 | sub smilie { # js runs in fmain. (XXX: doesn't actually work?) 294 | return '' . $_[2] . ''; 295 | } 296 | 297 | sub link { 298 | shift; # object 299 | return "$_[1]"; 300 | } 301 | 302 | sub frameset { 303 | my($self, $scriptname, $config, $random, $out, $interface, $style) = @_; 304 | if($config->{balance_servers}) { 305 | my @balance_servers = split /,\s*/, $config->{balance_servers}; 306 | $scriptname = $balance_servers[rand @balance_servers] . "/$scriptname"; 307 | } 308 | print < 311 | 312 | CGI:IRC - Loading 313 | 314 | 315 | 322 | 323 | 330 | 332 | 333 | 335 | 338 | 339 | 342 | 344 | 345 | This interface requires a browser that supports frames and javascript. 346 | 347 | 348 | 349 | EOF 350 | } 351 | 352 | sub blank { 353 | return ''; 354 | } 355 | 356 | sub ctcpping { 357 | my($self, $nick, $params) = @_; 358 | _func_out('sendcmd',"/ctcpreply $nick PING $params"); 359 | 1; 360 | } 361 | 362 | sub ping { 363 | 1; 364 | } 365 | 366 | sub sendping { 367 | _func_out('sendcmd',"/noop"); 368 | } 369 | 370 | sub help { 371 | my($self,$config) = @_; 372 | my %helpmap = ( "russian" => ".ru" ); 373 | my $extra = $helpmap{$::formatname} || ""; 374 | 375 | open(HELP, "<" . $::help_path . "help$extra.html") or do { 376 | _func_out('doinfowin', '-Help', "Help file not found!"); 377 | return; 378 | }; 379 | eval { local $SIG{__DIE__}; binmode HELP, ':utf8'; }; 380 | local $/; 381 | my $help = ; 382 | close HELP; 383 | $help =~ s/[\n\r]/ /g; 384 | _func_out('doinfowin', '-Help', $help); 385 | } 386 | 387 | sub setoption { 388 | my($self, $name, $value) = @_; 389 | _func_out('setoption', $name, $value); 390 | $self->options({}, {}, $main::config) 391 | } 392 | 393 | sub options { 394 | my($self, $cgi, $irc, $config) = @_; 395 | $config = $irc unless ref $config; 396 | my $ioptions = $main::ioptions; 397 | 398 | my $out = "CGI:IRC Options

Options

These options affect the appearence of CGI:IRC, they will stay between sessions provided cookies are turned on.
"; 399 | 400 | for my $option(sort keys %options) { 401 | my $o = $options{$option}; 402 | my $value = defined $ioptions->{$option} ? $ioptions->{$option} : ''; 403 | 404 | $out .= ""; 418 | } 419 | 420 | $out .= " 421 |
" . (exists $o->{img} ? ""; 405 | if($o->{type} eq 'toggle') { 406 | $out .= ""; 408 | }elsif($o->{type} eq 'select') { 409 | $out .= ""; 414 | }else{ 415 | $out .= ""; 416 | } 417 | $out .= "
close 422 | "; 423 | $out =~ s/\n//g; 424 | _func_out('doinfowin', '-Options', $out); 425 | } 426 | 427 | sub say { 428 | my($self) = @_; 429 | return 'ok'; 430 | } 431 | 432 | sub reconnect { 433 | my($self, $url, $text) = @_; 434 | return "$text"; 435 | } 436 | 437 | .$sub fwindowlist 438 | .$sub fmain 439 | .$sub fuserlist 440 | .$sub fform 441 | 442 | 1; 443 | -------------------------------------------------------------------------------- /interfaces/interface-make/make-js-interfaces.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # CGI:IRC JavaScript Interface builder 3 | # Copyright (C) 2002 David Leadbeater (http://contact.dgl.cx/) 4 | # Licensed under the GPLv2 5 | use Symbol; 6 | use IO::Handle; 7 | 8 | my(%fd, %current); 9 | my @browsers = qw/ie mozilla konqueror opera7/; 10 | @current{@browsers} = @browsers; 11 | 12 | for(@browsers) { 13 | $fd{$_} = Symbol::gensym; 14 | open($fd{$_}, ">../$_.pm") or die "Out to ../$_.pm: $!"; 15 | #? $fd{$_}->autoflush(1); 16 | } 17 | 18 | open(IN, "main.pm"); 19 | my @in = ; # don't use while - bug in perl? 20 | close(IN); 21 | parse_line($_) for @in; 22 | 23 | close($fd{$_}) for @browsers; 24 | 25 | sub parse_line { 26 | $_ = $_[0]; 27 | if(/^\.\$?(\w+)(?: (.*))?/) { 28 | # The $ is so the variables get syntax hilighted :) 29 | my($cmd, $param) = ($1, $2); 30 | my @params = split(' ', $param); 31 | 32 | if($cmd eq 'include') { 33 | open(INC, $param) or die "$param: $!"; 34 | parse_line($_) while ; 35 | close(INC); 36 | }elsif($cmd eq 'sub') { 37 | out_cur("sub $param {\n"); 38 | open(SUB, "$param.pm") or die "$param: $!"; 39 | parse_line($_) while ; 40 | close(SUB); 41 | out_cur("}\n"); 42 | }elsif($cmd eq 'just') { 43 | for my $current (keys %current) { 44 | $current{$current} = 0; 45 | if(scalar(grep(/$current/, @params))) { 46 | $current{$current} = 1; 47 | } 48 | } 49 | }elsif($cmd eq 'not') { 50 | for my $current (keys %current) { 51 | $current{$current} = 1; 52 | if(scalar(grep(/$current/, @params))) { 53 | $current{$current} = 0; 54 | } 55 | } 56 | }elsif($cmd eq 'end') { 57 | @current{keys %current} = keys %current; 58 | }elsif($cmd eq 'else') { 59 | for(keys %current) { 60 | $current{$_} = $current{$_} ? 0 : 1; 61 | } 62 | }else{ 63 | print "urm? $cmd isn't valid\n"; 64 | } 65 | 66 | }else{ 67 | out_cur($_); 68 | } 69 | } 70 | 71 | sub out_cur { 72 | $_ = $_[0]; 73 | for my $b(keys %current) { 74 | my $x = $_; 75 | $x =~ s/\*\*BROWSER/$b/g; 76 | my $fh = $fd{$b}; # cry :( 77 | print $fh $x if $current{$b}; 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /interfaces/nonjs.pm: -------------------------------------------------------------------------------- 1 | package nonjs; 2 | use strict; 3 | use vars qw/@ISA $standardheader/; 4 | 5 | $standardheader = < 9 | == Released under the GNU GPL 10 | --> 11 | EOF 12 | 13 | # nonjs always uses first server.. 14 | if(defined $::config->{balance_servers}) { 15 | my @s = split /,\s*/, $::config->{balance_servers}; 16 | $::config->{script_form} = "$s[0]/$::config->{script_form}"; 17 | $::config->{script_nph} = "$s[0]/$::config->{script_nph}"; 18 | } 19 | 20 | use default; 21 | @ISA = qw/default/; 22 | my %output_none; 23 | 24 | sub new { 25 | my($class,$event,$timer, $config, $icookies) = @_; 26 | my $self = bless {}, $class; 27 | $timer->addforever(code => \&todo, data => $self, interval => 10); 28 | $event->add('user 005', code => sub { $self->{':_prefix'} = "$_[1] " } ); 29 | $self->{':_timestamp'} = 0; 30 | $self->{':_timestamp'}++ if exists $icookies->{timestamp} && 31 | $icookies->{timestamp}; 32 | if(exists $::config->{'output none'}) { 33 | @output_none{split /,\s*/, $::config->{'output none'}} = 1; 34 | } 35 | return $self; 36 | } 37 | 38 | sub _out { 39 | unless(print "$_[1]\r\n") { 40 | $::needtodie++; 41 | } 42 | } 43 | 44 | sub _reloadreal { 45 | my($w) = @_; 46 | print "\r\n"; 47 | } 48 | 49 | sub _escape { 50 | my($in) = @_; 51 | $in =~ s//>/g; 53 | $in =~ s/"/"/g; 54 | return $in; 55 | } 56 | 57 | sub reload { 58 | my($self, $w) = @_; 59 | $self->{':_reload'} = $w; 60 | } 61 | 62 | sub todo { 63 | my($timer, $self) = @_; 64 | if(defined $self->{':_reload'} && $self->{':_reload'}) { 65 | _reloadreal($self->{':_reload'}); 66 | delete($self->{':_reload'}); 67 | } 68 | } 69 | 70 | sub exists { 71 | return 0 if $_[1] =~ /^_/; 72 | return 0 if $_[1] eq 'header'; 73 | return 1 if defined &{__PACKAGE__ . '::' . $_[1]}; 74 | } 75 | 76 | sub query { 77 | return 0; 78 | } 79 | 80 | sub smilie { 81 | shift; 82 | return "\"$_[2]\""; 83 | } 84 | 85 | sub link { 86 | shift; 87 | return "$_[1]"; 88 | } 89 | 90 | sub header { 91 | my($self, $config, $cgi, $bg, $fg) = @_; 92 | print < 95 | CGI:IRC 96 | 108 | 109 | 110 | EOF 111 | } 112 | 113 | sub makeline { 114 | my($self, $info, $html) = @_; 115 | my $target = $info->{target}; 116 | $target ||= 'Status'; 117 | if(not exists $self->{lc $target} && $target ne 'Status') { 118 | if(defined $info && ref $info && exists $info->{create} && 119 | $info->{create}) { 120 | $self->add($target, $info->{type} eq 'join' ? 1 : 0); 121 | } 122 | }elsif($info->{type} eq 'join') { 123 | $self->reload('u'); 124 | } 125 | 126 | return if exists $output_none{$info->{type}}; 127 | 128 | if($self->{':_timestamp'}) { 129 | my($sec,$min,$hour) = localtime; 130 | $html = sprintf("[%02d:%02d] %s", $hour, $min, $html); 131 | } 132 | 133 | return $html . '
'; 134 | } 135 | 136 | sub lines { 137 | my($self, @lines) = @_; 138 | $self->_out($_) for @lines; 139 | } 140 | 141 | sub line { 142 | my($self, $line) = @_; 143 | $self->_out($self->makeline({}, $line)); 144 | } 145 | 146 | sub add { 147 | my($self, $name, $param) = @_; 148 | $self->{':_target'} ||= lc $name; 149 | $self->{lc $name} = $param; 150 | $self->_out(''); 151 | } 152 | 153 | sub del { 154 | my($self, $name) = @_; 155 | delete($self->{$name}); 156 | $self->reload('f'); 157 | } 158 | 159 | sub active { 160 | my($self, $name) = @_; 161 | $self->{':_target'} = $name; 162 | $self->reload('f'); 163 | } 164 | 165 | sub error { 166 | my($self,$message) = @_; 167 | $self->line($message); 168 | } 169 | 170 | sub help { 171 | my($self) = shift; 172 | $self->line("Full help can be found at http://cgiirc.org/docs/usage.php"); 173 | } 174 | 175 | sub frameset { 176 | my($self, $scriptname, $config, $random, $out, $interface) = @_; 177 | print < 180 | 181 | 182 | CGI:IRC 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | This interface requires a browser that supports frames such as internet 193 | explorer, netscape or mozilla. 194 | 195 | 196 | 197 | 198 | EOF 199 | } 200 | 201 | sub fuserlist { 202 | my($self, $cgi, $config) = @_; 203 | my $r = _escape($cgi->{R}); 204 | print < 207 | 208 | 209 | Loading.. 210 | 211 | EOF 212 | } 213 | 214 | sub _page { 215 | return '' . $_[0] 216 | . "\r\n"; 217 | } 218 | 219 | sub userlist { 220 | my($self, $input, $irc, $config) = @_; 221 | if(!defined $self->{':_target'} || !$irc->is_channel($self->{':_target'})) { 222 | return _page('No channel'); 223 | } 224 | 225 | my $channel = $irc->channel($self->{':_target'}); 226 | return _page('No channel') unless ref $channel; 227 | 228 | my $output = 'Users in ' . _escape($channel->{name}) . '
'; 229 | 230 | my @users = map($channel->get_umode($_) . $_, $channel->nicks); 231 | my $umap = '@%+ '; 232 | if($self->{':_prefix'}) { 233 | $umap = $self->{':_prefix'}; 234 | } 235 | 236 | for(sort { # (I think this is clever :-) 237 | my($am,$bm) = (substr($a, 0, 1), substr($b, 0, 1)); 238 | return $a cmp $b if ($am eq $bm); 239 | return index($umap, $am) <=> index($umap, $bm); 240 | } @users) { 241 | $output .= "{script_form}?R=$input->{R}&item=userlist&cmd=say&say=/query+" . substr($_, 1) . "\">$_
"; 242 | } 243 | 244 | return _page($output); 245 | } 246 | 247 | sub fform { 248 | my($self, $cgi, $config) = @_; 249 | print _form_out($cgi->{R}, $config->{script_form}, undef, {}); 250 | } 251 | 252 | sub form { 253 | my($self, $cgi, $irc, $config) = @_; 254 | if(defined $cgi->{target} && $cgi->{target} && $cgi->{target} ne $self->{':_target'}) { 255 | $self->{':_target'} = $cgi->{target}; 256 | $self->reload('u'); 257 | } 258 | return _form_out($cgi->{R}, $config->{script_form}, $self->{':_target'}, $self); 259 | } 260 | 261 | sub _form_out { 262 | my($rand, $script, $target, $targets) = @_; 263 | $rand = _escape($rand); 264 | 265 | my $out = < 267 | 268 | 269 | 276 | 277 | 278 | 279 |
280 | 281 | 282 | 283 | 296 | 297 |
298 | 299 | 300 | 301 | EOF 302 | 303 | return $out; 304 | } 305 | 306 | 1; 307 | -------------------------------------------------------------------------------- /interfaces/opera.pm: -------------------------------------------------------------------------------- 1 | package opera; 2 | use strict; 3 | use vars qw/@ISA $standardheader/; 4 | 5 | $standardheader = < 9 | == Released under the GNU GPL 10 | --> 11 | EOF 12 | 13 | use nonjs; 14 | @ISA = qw/nonjs/; 15 | 16 | sub _out { 17 | print "$_[1]\r\n"; 18 | } 19 | 20 | sub header { 21 | my($self, $config, $cgi) = @_; 22 | print < 25 | 47 | 48 | 51 | EOF 52 | } 53 | 54 | 1; 55 | -------------------------------------------------------------------------------- /interfaces/style-dark.css: -------------------------------------------------------------------------------- 1 | /* Thanks to Veritas - northstar networks for this style */ 2 | /* Copyright David Leadbeater 2002, Licensed under the GPL */ 3 | 4 | /* This CSS File controls nearly all the layout related options 5 | * and colours in CGI:IRC. 6 | * The exceptions are the main frame - where background colour is set 7 | * in formats. 8 | * 9 | * Also note this only affects decently javascript enabled browsers 10 | * for older browsers the nonjs.pm is used which has hardly any style 11 | * settings 12 | */ 13 | 14 | .userlist-body { 15 | margin: 0; 16 | scrollbar-base-color: #BBBBBB; 17 | scrollbar-darkshadow-color: #222222; 18 | scrollbar-face-color: #555555; 19 | scrollbar-highlight-color: #222222; 20 | scrollbar-shadow-color: #AAAAAA; 21 | scrollbar-track-color: #444444; 22 | background-color: #303030; 23 | border-left: 1px solid #999999; 24 | } 25 | 26 | .userlist-div { 27 | width: 100%; 28 | } 29 | 30 | .userlist-item { 31 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 32 | font-size: 10px; 33 | cursor: default; 34 | color: #808080; 35 | } 36 | 37 | .userlist-select { 38 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 39 | font-size: 10px; 40 | background-color: #707070; 41 | } 42 | 43 | .userlist-btn { 44 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 45 | font-size: 10px; 46 | background-color: #606060; 47 | color: #909090; 48 | cursor: default; 49 | border-bottom: 1px solid #505050; 50 | border-right: 1px solid #505050; 51 | border-top: 1px solid #404040; 52 | border-left: 1px solid #404040; 53 | } 54 | 55 | .userlist-form { 56 | float: right; 57 | } 58 | 59 | .userlist-hover { 60 | width: 95%; 61 | font-size: 10px; 62 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 63 | cursor: default; 64 | background-color: #808080; 65 | } 66 | 67 | .userlist-selected { 68 | width: 95%; 69 | font-size: 10px; 70 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 71 | background-color: #909090; 72 | } 73 | 74 | .userlist-table TR { 75 | vertical-align: top; 76 | margin-bottom: 5px; 77 | } 78 | 79 | 80 | .userlist-status { 81 | width: 14px; 82 | font-size: 10px; 83 | font-family: courier,monospace,fixed; 84 | text-align: center; 85 | } 86 | 87 | .userlist-item { 88 | width: 95%; 89 | font-size: 10px; 90 | } 91 | 92 | .userlist-op { 93 | color: #0000dd; 94 | background-color: #404040; 95 | border: 1px solid #0000dd; 96 | } 97 | 98 | .userlist-voice { 99 | color: #a0a0a0; 100 | background-color: #404040; 101 | border: 1px solid #a0a0a0; 102 | } 103 | 104 | .main-body { 105 | word-wrap: break-word; 106 | scrollbar-base-color: #BBBBBB; 107 | scrollbar-darkshadow-color: #222222; 108 | scrollbar-face-color: #555555; 109 | scrollbar-highlight-color: #222222; 110 | scrollbar-shadow-color: #AAAAAA; 111 | scrollbar-track-color: #444444; 112 | background-color: #303030; 113 | color: #909090; 114 | font-family: arial; 115 | font-size: 12px; 116 | } 117 | 118 | .main-span IMG { 119 | border: 0; 120 | } 121 | 122 | .main-link { 123 | color: #000099; 124 | text-decoration: underline; 125 | background-color: #303030; 126 | } 127 | 128 | .main-motd { 129 | font-family: monospace; 130 | } 131 | 132 | .main-item { 133 | margin-left: 15px; 134 | text-indent: -15px; 135 | } 136 | 137 | .form-body { 138 | border-top: 1px solid #404040; 139 | margin: 0; 140 | background-color: #303030; 141 | border: 1px 142 | color: #b0b0b0; 143 | } 144 | 145 | .form-form { 146 | display: inline; 147 | } 148 | 149 | .form-econtain { 150 | display: inline; 151 | position: absolute; 152 | right: 0; 153 | } 154 | 155 | .form-say { 156 | border: 0; 157 | outline: 0; 158 | font-size: 105%; 159 | width: 90%; 160 | padding-left: 4px; 161 | background-color: #505050; 162 | } 163 | 164 | .form-nickname { 165 | padding-left: 4px; 166 | background-color: #303030; 167 | color: #303030; 168 | } 169 | 170 | .form-extra { 171 | display: none; 172 | } 173 | 174 | .form-boldbutton { 175 | font-weight: bold; 176 | } 177 | 178 | .form-expand { 179 | border: 0; 180 | background-color: #303030; 181 | color: #909090; 182 | } 183 | 184 | .wlist-body { 185 | margin: 0px; 186 | background: #303030; 187 | cursor: default; 188 | } 189 | 190 | .wlist-chooser { 191 | border: 1px solid #f1f1f1; 192 | padding: 2px; 193 | margin: 2px; 194 | cursor: default; 195 | } 196 | 197 | .wlist-container { 198 | width: 100%; 199 | height: 100%; 200 | padding: 5px; 201 | cursor: default; 202 | } 203 | 204 | .wlist-mouseover { 205 | background-color: #505050; 206 | border: 1px solid #000000; 207 | padding: 2px; 208 | margin: 2px; 209 | cursor: default; 210 | } 211 | 212 | .wlist-active { 213 | background: #404040; 214 | border: 1px solid #909090; 215 | padding: 2px; 216 | margin: 2px; 217 | cursor: default; 218 | } 219 | 220 | .wlist-buttons { 221 | text-align: right; 222 | width: 30px; 223 | } 224 | 225 | .wlist-button { 226 | border: 0; 227 | cursor: default; 228 | } 229 | 230 | .wlist-container { 231 | } 232 | 233 | .wlist-table { 234 | width: 100%; 235 | height: 100%; 236 | border-bottom: 1px solid #999999; 237 | } 238 | 239 | .options-body {} 240 | .options-title {} 241 | .options-table {} 242 | .options-checkbox {} 243 | .options-select {} 244 | .options-option {} 245 | .options-input {} 246 | 247 | .options-close { /* http://www.tom.me.uk/scripting/links.asp */ 248 | text-decoration: underline; 249 | text-align: right; 250 | color: #00f; 251 | cursor: pointer; 252 | cursor: hand; 253 | } 254 | 255 | 256 | -------------------------------------------------------------------------------- /interfaces/style-default.css: -------------------------------------------------------------------------------- 1 | /* Copyright David Leadbeater 2002, Licensed under the GPL */ 2 | 3 | /* This CSS File controls nearly all the layout related options 4 | * and colours in CGI:IRC. 5 | * The exceptions are the main frame - where background colour is set 6 | * in formats. 7 | * 8 | * Also note this only affects decently javascript enabled browsers 9 | * for older browsers the nonjs.pm is used which has hardly any style 10 | * settings 11 | */ 12 | 13 | /* --- Userlist */ 14 | .userlist-body { 15 | margin: 0; 16 | scrollbar-face-color: #e8e8e8; 17 | scrollbar-shadow-color: #777; 18 | scrollbar-highlight-color: #777; 19 | scrollbar-3dlight-color: #fff; 20 | scrollbar-darkshadow-color: #ccc; 21 | scrollbar-track-color: #e8e8e8; 22 | scrollbar-arrow-color: #777; 23 | background-color: #f8f8f8; 24 | border-left: 1px solid #999999; 25 | height: 100%; 26 | } 27 | 28 | .userlist-div { 29 | width: 100%; 30 | } 31 | 32 | .userlist-item { 33 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 34 | font-size: 10px; 35 | cursor: default; 36 | } 37 | 38 | .userlist-select { 39 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 40 | font-size: 10px; 41 | background-color: #f1f1f1; 42 | } 43 | 44 | .userlist-btn { 45 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 46 | font-size: 10px; 47 | background-color: #f1f1f1; 48 | cursor: default; 49 | border-bottom: 1px solid #808080; 50 | border-right: 1px solid #808080; 51 | border-top: 1px solid #f3f3f3; 52 | border-left: 1px solid #f3f3f3; 53 | } 54 | 55 | .userlist-form { 56 | float: right; 57 | } 58 | 59 | .userlist-hover { 60 | width: 95%; 61 | font-size: 10px; 62 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 63 | cursor: default; 64 | background-color: #a0c0ff; 65 | } 66 | 67 | .userlist-selected { 68 | width: 95%; 69 | font-size: 10px; 70 | font-family: MS Sans Serif,arial,verdana,helvetica,sans serif,sans; 71 | background-color: #a0c0ff; 72 | } 73 | 74 | .userlist-table TR { 75 | vertical-align: top; 76 | margin-bottom: 5px; 77 | } 78 | 79 | 80 | .userlist-status { 81 | width: 14px; 82 | font-size: 10px; 83 | font-family: courier,monospace,fixed; 84 | text-align: center; 85 | } 86 | 87 | .userlist-item { 88 | width: 95%; 89 | font-size: 10px; 90 | } 91 | 92 | .userlist-op { 93 | color: #008000; 94 | background-color: #20ff50; 95 | border: 1px solid #30a030; 96 | } 97 | .userlist-voice { 98 | color: #808000; 99 | background-color: #ffff20; 100 | border: 1px solid #a0a030; 101 | } 102 | .userlist-halfop { 103 | color: #808000; 104 | background-color: #20ffff; 105 | border: 1px solid #30a0a0; 106 | } 107 | .userlist-other { 108 | color: #808000; 109 | background-color: #ff20ff; 110 | border: 1px solid #a030a0; 111 | } 112 | 113 | /* --- Main */ 114 | 115 | .main-body { 116 | word-wrap: break-word; 117 | scrollbar-face-color: #e8e8e8; 118 | scrollbar-shadow-color: #777; 119 | scrollbar-highlight-color: #777; 120 | scrollbar-3dlight-color: #fff; 121 | scrollbar-darkshadow-color: #ccc; 122 | scrollbar-track-color: #e8e8e8; 123 | scrollbar-arrow-color: #777; 124 | overflow: hidden; 125 | margin: 0; 126 | padding: 0; 127 | } 128 | 129 | .main-span { 130 | margin: 0; 131 | overflow: auto; 132 | overflow-y: scroll; 133 | width: 100%; 134 | height: 100%; 135 | box-sizing: border-box; 136 | padding-top: 1.5em; 137 | padding-bottom: 1.5em; 138 | padding: 0.5em; 139 | } 140 | 141 | .main-span IMG { 142 | border: 0; 143 | } 144 | 145 | .main-link { 146 | color: black; 147 | text-decoration: underline; 148 | } 149 | 150 | .main-item { 151 | margin-left: 15px; 152 | text-indent: -15px; 153 | } 154 | 155 | .main-smilies { 156 | border: 1px dashed #ccc; 157 | background: #ccf; 158 | position: absolute; 159 | bottom: 0; 160 | left: 62%; 161 | width: 20%; 162 | height: 55%; 163 | overflow: auto; 164 | } 165 | 166 | /* RawCommands.pm styles */ 167 | 168 | .main-motd { 169 | font-family: monospace; 170 | } 171 | 172 | /* --- Form */ 173 | 174 | .form-body { 175 | border-top: 1px solid #999999; 176 | margin: 0; 177 | } 178 | 179 | .form-form { 180 | display: inline; 181 | } 182 | 183 | .form-econtain { 184 | display: inline; 185 | position: absolute; 186 | right: 0; 187 | } 188 | 189 | .form-say { 190 | border: 0; 191 | outline: 0; 192 | font-size: 105%; 193 | width: 90%; 194 | padding-left: 4px; 195 | } 196 | 197 | .form-nickname { 198 | margin-left: 4px; 199 | background: #c0c0c0; 200 | } 201 | 202 | .form-extra { 203 | display: inline; 204 | } 205 | 206 | .form-boldbutton { 207 | font-weight: bold; 208 | } 209 | 210 | .form-expand { 211 | border: 0; 212 | background: #ffffff; 213 | } 214 | 215 | /* --- Window List (wlist) */ 216 | 217 | .wlist-body { 218 | margin: 0px; 219 | background: #f1f1f1; 220 | cursor: default; 221 | } 222 | 223 | .wlist-chooser { 224 | border: 1px solid #f1f1f1; 225 | padding: 2px; 226 | margin: 2px; 227 | cursor: default; 228 | } 229 | 230 | .wlist-container { 231 | width: 100%; 232 | height: 100%; 233 | padding: 5px; 234 | cursor: default; 235 | } 236 | 237 | .wlist-mouseover { 238 | background-color: #a0c0ff; 239 | border: 1px solid black; 240 | padding: 2px; 241 | margin: 2px; 242 | cursor: default; 243 | } 244 | 245 | .wlist-active { 246 | background: #cccccc; 247 | border: 1px solid #999999; 248 | padding: 2px; 249 | margin: 2px; 250 | cursor: default; 251 | } 252 | 253 | .wlist-buttons { 254 | text-align: right; 255 | width: 30px; 256 | } 257 | 258 | .wlist-button { 259 | border: 0; 260 | cursor: default; 261 | } 262 | 263 | .wlist-container { 264 | } 265 | 266 | .wlist-table { 267 | width: 100%; 268 | height: 100%; 269 | border-bottom: 1px solid #999999; 270 | } 271 | 272 | 273 | /* --- Options */ 274 | 275 | .options-body {} 276 | .options-title {} 277 | .options-table {} 278 | .options-checkbox {} 279 | .options-select {} 280 | .options-option {} 281 | .options-input {} 282 | 283 | .options-close { /* http://www.tom.me.uk/scripting/links.asp */ 284 | text-decoration: underline; 285 | text-align: right; 286 | color: #00f; 287 | cursor: pointer; 288 | cursor: hand; 289 | } 290 | 291 | 292 | -------------------------------------------------------------------------------- /interfaces/style-gothic.css: -------------------------------------------------------------------------------- 1 | 2 | /* CGI:IRC gothic theme by Ron van Daal (Syntonix) ron@within-temptation.com 3 | * 4 | * Please use this theme with font-family "verdana,tahoma" 5 | * and gray-colored toolbar buttons for the best effect. 6 | */ 7 | 8 | /* --- Userlist */ 9 | .userlist-body { 10 | margin: 0; 11 | scrollbar-track-color:black; 12 | scrollbar-base-color:black; 13 | scrollbar-shadow-color:gray; 14 | scrollbar-arrow-color:gray; 15 | background-color:black; 16 | border-left: 6x solid #555555; 17 | font-size: 12px; 18 | } 19 | 20 | .userlist-div { 21 | width: 100%; 22 | } 23 | 24 | .userlist-item { 25 | font-family: verdana,tahoma; 26 | font-size: 12px; 27 | cursor: default; 28 | color: #bbbbbb; 29 | } 30 | 31 | .userlist-select { 32 | margin-top: 10px; 33 | font-family: verdana,tahoma; 34 | font-size: 12px; 35 | background-color: black; 36 | color: #bbbbbb; 37 | } 38 | 39 | .userlist-btn { 40 | font-family: verdana,tahoma; 41 | font-size: 12px; 42 | background-color: black; 43 | color: gray; 44 | cursor: default; 45 | border: 1px solid gray; 46 | } 47 | 48 | .userlist-form { 49 | float: right; 50 | } 51 | 52 | .userlist-hover { 53 | width: 95%; 54 | font-family: verdana,tahoma; 55 | font-size: 12px; 56 | cursor: default; 57 | color: white; 58 | } 59 | 60 | .userlist-selected { 61 | width: 95%; 62 | font-family: verdana,tahoma; 63 | font-size: 12px; 64 | background-color: gray; 65 | color: black; 66 | } 67 | 68 | .userlist-table TR { 69 | vertical-align: top; 70 | margin-bottom: 5px; 71 | } 72 | 73 | 74 | .userlist-status { 75 | width: 12px; 76 | font-family: verdana,tahoma; 77 | font-size: 12px; 78 | text-align: center; 79 | } 80 | 81 | .userlist-item { 82 | width: 95%; 83 | font-size: 12px; 84 | } 85 | 86 | .userlist-op { 87 | color: red; 88 | background-color: black; 89 | } 90 | 91 | .userlist-voice { 92 | color: purple; 93 | background-color: black; 94 | } 95 | 96 | /* --- Main */ 97 | 98 | .main-body { 99 | word-wrap: break-word; 100 | scrollbar-track-color:black; 101 | scrollbar-base-color:black; 102 | scrollbar-shadow-color:gray; 103 | scrollbar-arrow-color:gray; 104 | background: black; 105 | font-size: 12px; 106 | } 107 | 108 | .main-span IMG { 109 | border: 0; 110 | } 111 | 112 | .main-link { 113 | color: #999999; 114 | text-decoration: underline; 115 | } 116 | 117 | .main-item { 118 | margin-left: 15px; 119 | text-indent: -15px; 120 | } 121 | 122 | /* RawCommands.pm styles */ 123 | 124 | .main-motd { 125 | font-family: monospace; 126 | } 127 | 128 | /* --- Form */ 129 | 130 | .form-body { 131 | border-top: 6px solid #555555; 132 | background: black; 133 | margin: 5px; 134 | } 135 | 136 | .form-form { 137 | display: inline; 138 | } 139 | 140 | .form-econtain { 141 | display: inline; 142 | position: absolute; 143 | right: 0; 144 | } 145 | 146 | .form-say { 147 | border: 0; 148 | outline: 0; 149 | width: 90%; 150 | padding-left: 4px; 151 | background: #222222; 152 | color: white; 153 | font-family: verdana,tahoma; 154 | font-size: 12px; 155 | } 156 | 157 | .form-nickname { 158 | padding-left: 4px; 159 | padding-right: 4px; 160 | color: gray; 161 | font-family: verdana,tahoma; 162 | font-size: 12px; 163 | } 164 | 165 | .form-extra { 166 | display: none; 167 | } 168 | 169 | .form-boldbutton { 170 | font-weight: bold; 171 | } 172 | 173 | .form-expand { 174 | border: 0; 175 | background: gray; 176 | } 177 | 178 | /* --- Window List (wlist) */ 179 | 180 | .wlist-body { 181 | margin: 0px; 182 | background: black; 183 | cursor: default; 184 | } 185 | 186 | .wlist-chooser { 187 | border: 1px solid #999999; 188 | padding: 2px; 189 | margin: 2px; 190 | cursor: default; 191 | background: #333333; 192 | font-family: verdana,tahoma; 193 | font-size: 12px; 194 | } 195 | 196 | .wlist-container { 197 | width: 100%; 198 | height: 100%; 199 | padding: 5px; 200 | cursor: default; 201 | font-family: verdana,tahoma; 202 | font-size: 12px; 203 | } 204 | 205 | .wlist-mouseover { 206 | background-color: gray; 207 | border: 1px solid white; 208 | padding: 2px; 209 | margin: 2px; 210 | cursor: default; 211 | font-family: verdana,tahoma; 212 | font-size: 12px; 213 | } 214 | 215 | .wlist-active { 216 | background: gray; 217 | border: 1px solid #999999; 218 | padding: 2px; 219 | margin: 2px; 220 | cursor: default; 221 | font-family: verdana,tahoma; 222 | font-size: 12px; 223 | } 224 | 225 | .wlist-buttons { 226 | text-align: right; 227 | width: 30px; 228 | } 229 | 230 | .wlist-button { 231 | border: 0; 232 | cursor: default; 233 | } 234 | 235 | .wlist-container { 236 | } 237 | 238 | .wlist-table { 239 | width: 100%; 240 | height: 100%; 241 | border-bottom: 6px solid #555555; 242 | } 243 | 244 | 245 | /* --- Options */ 246 | 247 | .options-body {} 248 | .options-title {} 249 | .options-table {} 250 | .options-checkbox {} 251 | .options-select {} 252 | .options-option {} 253 | .options-input {} 254 | 255 | .options-close { /* http://www.tom.me.uk/scripting/links.asp */ 256 | text-decoration: underline; 257 | text-align: right; 258 | color: #00f; 259 | cursor: pointer; 260 | cursor: hand; 261 | } 262 | 263 | 264 | -------------------------------------------------------------------------------- /interfaces/style-mirc.css: -------------------------------------------------------------------------------- 1 | /* Copyright David Leadbeater 2002, Licensed under the GPL */ 2 | 3 | /* This CSS File controls nearly all the layout related options 4 | * and colours in CGI:IRC. 5 | * The exceptions are the main frame - where background colour is set 6 | * in formats. 7 | * 8 | * Also note this only affects decently javascript enabled browsers 9 | * for older browsers the nonjs.pm is used which has hardly any style 10 | * settings 11 | */ 12 | 13 | .userlist-body { 14 | margin: 0; 15 | scrollbar-face-color: #e8e8e8; 16 | scrollbar-shadow-color: #777; 17 | scrollbar-highlight-color: #777; 18 | scrollbar-3dlight-color: #fff; 19 | scrollbar-darkshadow-color: #ccc; 20 | scrollbar-track-color: #e8e8e8; 21 | scrollbar-arrow-color: #777; 22 | background-color: #fff; 23 | border-left: 1px solid #999999; 24 | } 25 | 26 | .userlist-div { 27 | width: 100%; 28 | } 29 | 30 | .userlist-item { 31 | font-family: Fixedsys,fixed,system,monospace; 32 | font-size: 10px; 33 | cursor: default; 34 | } 35 | 36 | .userlist-select { 37 | font-family: Fixedsys,fixed,system,monospace; 38 | font-size: 10px; 39 | background-color: #000080; 40 | color: #fff; 41 | } 42 | 43 | .userlist-btn { 44 | font-family: Fixedsys,fixed,system,monospace; 45 | font-size: 10px; 46 | background-color: #f1f1f1; 47 | cursor: default; 48 | border-bottom: 1px solid #808080; 49 | border-right: 1px solid #808080; 50 | border-top: 1px solid #f3f3f3; 51 | border-left: 1px solid #f3f3f3; 52 | } 53 | 54 | .userlist-form { 55 | float: right; 56 | } 57 | 58 | .userlist-hover { 59 | width: 95%; 60 | font-size: 10px; 61 | font-family: Fixedsys,fixed,system,monospace; 62 | cursor: default; 63 | background-color: #000080; 64 | color: #fff; 65 | } 66 | 67 | .userlist-selected { 68 | width: 95%; 69 | font-size: 10px; 70 | font-family: Fixedsys,fixed,system,monospace; 71 | background-color: #000080; 72 | color: #fff; 73 | } 74 | 75 | .userlist-table TR { 76 | vertical-align: top; 77 | margin-bottom: 5px; 78 | } 79 | 80 | 81 | .userlist-status { 82 | width: 14px; 83 | font-size: 10px; 84 | font-family: courier,monospace,fixed; 85 | text-align: center; 86 | } 87 | 88 | .userlist-item { 89 | width: 95%; 90 | font-size: 10px; 91 | } 92 | 93 | .userlist-op { 94 | color: #000000; 95 | background-color: #fff; 96 | border: 0px; 97 | font-family: Fixedsys,system,monospace; 98 | } 99 | 100 | .userlist-voice { 101 | color: #000000; 102 | background-color: #fff; 103 | border: 0px; 104 | font-family: Fixedsys,system,monospace; 105 | } 106 | 107 | .main-body { 108 | word-wrap: break-word; 109 | scrollbar-face-color: #e8e8e8; 110 | scrollbar-shadow-color: #777; 111 | scrollbar-highlight-color: #777; 112 | scrollbar-3dlight-color: #fff; 113 | scrollbar-darkshadow-color: #ccc; 114 | scrollbar-track-color: #e8e8e8; 115 | scrollbar-arrow-color: #777; 116 | } 117 | 118 | .main-span IMG { 119 | border: 0; 120 | } 121 | 122 | .main-link { 123 | color: black; 124 | text-decoration: underline; 125 | } 126 | 127 | .main-item { 128 | margin-left: 15px; 129 | text-indent: -15px; 130 | } 131 | 132 | /* RawCommands.pm styles */ 133 | 134 | .main-motd { 135 | font-family: Fixedsys,fixed,system,monospace; 136 | } 137 | 138 | /* --- */ 139 | 140 | .form-body { 141 | border-top: 1px solid #999999; 142 | margin: 0; 143 | font-family: Fixedsys,fixed,system,monospace; 144 | } 145 | 146 | .form-form { 147 | display: inline; 148 | } 149 | 150 | .form-econtain { 151 | display: inline; 152 | position: absolute; 153 | right: 0; 154 | } 155 | 156 | .form-say { 157 | border: 0; 158 | outline: 0; 159 | font-size: 105%; 160 | width: 90%; 161 | padding-left: 4px; 162 | } 163 | 164 | .form-nickname { 165 | padding-left: 4px; 166 | background: #c0c0c0; 167 | font-family: Fixedsys,fixed,system,monospace; 168 | } 169 | 170 | .form-extra { 171 | display: none; 172 | } 173 | 174 | .form-boldbutton { 175 | font-weight: bold; 176 | } 177 | 178 | .form-expand { 179 | border: 0; 180 | background: #ffffff; 181 | } 182 | 183 | .wlist-body { 184 | margin: 0px; 185 | background: #f1f1f1; 186 | cursor: default; 187 | } 188 | 189 | .wlist-chooser { 190 | border: 1px solid #f1f1f1; 191 | padding: 2px; 192 | margin: 2px; 193 | cursor: default; 194 | } 195 | 196 | .wlist-container { 197 | width: 100%; 198 | height: 100%; 199 | padding: 5px; 200 | cursor: default; 201 | } 202 | 203 | .wlist-mouseover { 204 | background-color: #a0c0ff; 205 | border: 1px solid black; 206 | padding: 2px; 207 | margin: 2px; 208 | cursor: default; 209 | } 210 | 211 | .wlist-active { 212 | background: #cccccc; 213 | border: 1px solid #999999; 214 | padding: 2px; 215 | margin: 2px; 216 | cursor: default; 217 | } 218 | 219 | .wlist-buttons { 220 | text-align: right; 221 | width: 30px; 222 | } 223 | 224 | .wlist-button { 225 | border: 0; 226 | cursor: default; 227 | } 228 | 229 | .wlist-container { 230 | } 231 | 232 | .wlist-table { 233 | width: 100%; 234 | height: 100%; 235 | border-bottom: 1px solid #999999; 236 | } 237 | 238 | .options-body {} 239 | .options-title {} 240 | .options-table {} 241 | .options-checkbox {} 242 | .options-select {} 243 | .options-option {} 244 | .options-input {} 245 | 246 | .options-close { /* http://www.tom.me.uk/scripting/links.asp */ 247 | text-decoration: underline; 248 | text-align: right; 249 | color: #00f; 250 | cursor: pointer; 251 | cursor: hand; 252 | } 253 | 254 | 255 | -------------------------------------------------------------------------------- /ipaccess.example: -------------------------------------------------------------------------------- 1 | # CGI:IRC example ipaccess file. (For CGI:IRC versions from 0.5.3). 2 | # To use this rename the file to ipaccess and in the CGI:IRC configuration 3 | # set ip_access_file = ipaccess 4 | 5 | # This file allows and disallows access to CGI:IRC based on IP address 6 | # and/or hostname. 7 | # It can be used to limit access to CGI:IRC to a certain IP range 8 | # or to limit the number of connections from particular IPs. 9 | 10 | # The file is read downwards and the first match for a particular mask is 11 | # used so if *.*.*.* is the first line then all connections would be allowed. 12 | 13 | # Format: 14 | # ipmask limit 15 | # ipmask is an IP address or mask (address containing *) 16 | # Note: An * in ipmask matches only numbers so it must contain three dots. 17 | # limit is optional - it is the number of connections to allow from a 18 | # specific IP address that matches this mask, 0 allows no connections, 19 | # and so bans connections from the address. 20 | 21 | # It is also possible to use hostnames, this is much the same as an IP address. 22 | # The format is: 23 | # hostmask limit 24 | # The only difference is subnet masks are not possible and the * matches any 25 | # character (even a dot). 26 | 27 | # Examples (remove first # to enable) 28 | #192.168.1.* 0 # Ban access from 192.168.1.* 29 | #192.168.2.* 5 # Limit access from 192.168.2.* to 5 connections per IP address 30 | #192.168.3.0/24 0 # Ban access from 192.168.3.0/24 31 | #127.0.0.1 # Allow 127.0.0.1 (without any connection limit) 32 | #*.example.com 0 # Ban all connections from example.com 33 | #*.*.*.* 2 # Allow all connections but limit to 2 connections per IP address 34 | 35 | # Remember you must add at least one allow line if you enable ip_access to 36 | # allow clients to connect. 37 | 38 | -------------------------------------------------------------------------------- /irc.cgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # CGI:IRC - http://cgiirc.org/ 3 | # Copyright (C) 2000-2007 David Leadbeater 4 | # vim:set ts=3 expandtab shiftwidth=3 cindent: 5 | 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | 20 | # Uncomment this if the server doesn't chdir (Boa). 21 | # BEGIN { (my $dir = $0) =~ s|[^/]+$||; chdir($dir) } 22 | 23 | use strict; 24 | use vars qw($VERSION $config $config_path); 25 | use lib qw/modules interfaces/; 26 | no warnings 'uninitialized'; 27 | 28 | ($VERSION = 29 | '0.5.13 $Id: 7efb2e1ff70a93875b5a419ab4ce9b8beeec46a2 $' 30 | ) =~ s/^.*?(\d\S+) .*?([0-9a-f]{4}).*/$1 . (index($1, "g") > 0 ? "$2" : "")/e; 31 | 32 | require 'parse.pl'; 33 | 34 | my $cgi = cgi_read(); 35 | 36 | for('', '/etc/cgiirc/', '/etc/') { 37 | last if -r ($config_path = $_) . 'cgiirc.config'; 38 | } 39 | 40 | $config = parse_config($config_path . 'cgiirc.config'); 41 | 42 | if(!parse_cookie()) { 43 | my $cookie_domain = $config->{javascript_domain}; 44 | if(defined $cookie_domain) { 45 | $cookie_domain = ";domain=.$cookie_domain"; 46 | } else { 47 | $cookie_domain = ""; 48 | } 49 | print "Set-cookie: cgiircauth=". random(25) .";path=/$cookie_domain\r\n"; 50 | } 51 | print join("\r\n", 52 | # Hack to make sure we print the correct type for stylesheets too.. 53 | 'Content-type: text/' . (ref $cgi && defined $cgi->{item} && 54 | $cgi->{item} eq 'style' ? 'css' : 'html') 55 | # We need this for some JavaScript magic that detects the character set. 56 | # Basically don't send a character set for the login page.. 57 | . (ref $cgi && ($cgi->{item} || $cgi->{Nickname}) ? '; charset=utf-8' : ''), 58 | 'Pragma: no-cache', 59 | 'Cache-control: must-revalidate, no-cache', 60 | 'Expires: -1') . "\r\n"; 61 | 62 | # Please leave this. 63 | my $copy = <CGI:IRC $VERSION
65 | EOF 66 | 67 | my $scriptname = $config->{script_login} || 'irc.cgi'; 68 | 69 | my $interface = ref $cgi && defined $cgi->{interface} ? $cgi->{interface} : 'default'; 70 | $interface =~ /^([a-z0-9]+)/; 71 | $interface = $1; 72 | require($interface . '.pm'); 73 | 74 | if(ref $cgi && defined $cgi->{item}) { 75 | print "\r\n"; # send final header 76 | error('Communication socket name is invalid') if $cgi->{R} =~ /[^A-Za-z0-9]/; 77 | my $name = $cgi->{item}; 78 | exit unless $interface->exists($name); 79 | $interface->$name($cgi, $config, 0); 80 | }elsif(ref $cgi && defined $cgi->{Nickname}) { 81 | print "\r\n"; # send final header 82 | my $r = random(); 83 | my($format, $style); 84 | 85 | my %p = ( 86 | Nickname => 'nick', 87 | Channel => 'chan', 88 | Port => 'port', 89 | Server => 'serv', 90 | Realname => 'name', 91 | interface => 'interface', 92 | Password => 'pass', 93 | Format => 'format', 94 | 'Character_set' => 'charset', 95 | ); 96 | my $out; 97 | for(keys %p) { 98 | if(exists $cgi->{"${_}_text"}) { 99 | if(!defined $cgi->{$_} or $cgi->{$_} eq '') { 100 | $cgi->{$_} = $cgi->{"${_}_text"}; 101 | } 102 | } 103 | next unless exists $cgi->{$_}; 104 | $out .= cgi_encode($p{$_}) . '=' . cgi_encode($cgi->{$_}) . '&'; 105 | } 106 | 107 | $format = exists $cgi->{Format} 108 | ? $cgi->{Format} 109 | : $config->{format} || 'default'; 110 | $format =~ s/[^a-z]//gi; 111 | $format = parse_config($config_path . "formats/$format"); 112 | $style = exists $format->{style} ? $format->{style} : 'default'; 113 | 114 | $out .= "R=$r"; 115 | 116 | if(defined $config->{'login secret'}) { 117 | require Digest::MD5; 118 | my $t = time; 119 | my $token = Digest::MD5::md5_hex($t . $config->{'login secret'} . $r); 120 | $out .= "&token=$token&time=$t"; 121 | } 122 | 123 | $interface->frameset($scriptname, $config, $r, $out, $interface, $style); 124 | 125 | }elsif(defined $config->{form_redirect}) { 126 | print join("\r\n", 127 | "Status: 302", 128 | "Location: $config->{form_redirect}", 129 | "", 130 | $config->{form_redirect}); 131 | }else{ 132 | print "\r\n"; # send final header 133 | 134 | my $have_entities = 0; 135 | eval { require HTML::Entities; $have_entities = 1; }; 136 | 137 | my(%items,@order); 138 | 139 | my $server = dolist($config->{default_server}); 140 | my $channel = dolist($config->{default_channel}); 141 | my $port = dolist($config->{default_port}); 142 | my $nickname = $ENV{REMOTE_USER} || $config->{default_nick}; 143 | 144 | my $charset = [ $config->{'irc charset'} || 'Unicode (UTF-8)' ]; 145 | 146 | # Add some useful suggestions for character sets: 147 | for my $set('Western (ISO-8859-1)', 'Cyrillic (ISO-8859-5)', 148 | 'Cyrillic (KOI8-R)', 'Japanese (ShiftJIS)', 'Chinese (Big5)', 149 | 'Chinese (GB2312)', 'Korean (EUC-KR)') { 150 | push @$charset, $set unless grep { $set =~ /$_/i } @$charset 151 | } 152 | 153 | if(defined $ENV{HTTP_ACCEPT_CHARSET}) { 154 | for my $set(split ',', $ENV{HTTP_ACCEPT_CHARSET}) { 155 | next if $set =~ /;q=0($|\.0$)/ or $set =~ /\*/; 156 | $set =~ s/;.*//; 157 | push @$charset, $set unless grep { /$set/i } @$charset; 158 | } 159 | } 160 | 161 | if(ref $cgi && $cgi->{chan}) { 162 | $channel = $cgi->{chan}; 163 | } 164 | 165 | if(ref $cgi && $cgi->{nick}) { 166 | $nickname = $cgi->{nick}; 167 | } 168 | 169 | if(!defined $config->{allow_non_default} || !$config->{allow_non_default}) { 170 | add_disabled($server); 171 | add_disabled($channel); 172 | add_disabled($port); 173 | }else{ 174 | add_disabled($server) unless defined $config->{access_server}; 175 | add_disabled($port) unless defined $config->{access_port}; 176 | add_disabled($channel) unless defined $config->{access_channel}; 177 | } 178 | 179 | opendir(FORMATS, $config_path . "formats"); 180 | my @formats; 181 | for(sort readdir FORMATS) { 182 | next unless !/^\./ && -f $config_path . "formats/$_"; 183 | if($_ eq ($config->{format} || 'default')) { 184 | unshift(@formats, $_); 185 | }else{ 186 | push(@formats, $_); 187 | } 188 | } 189 | closedir(FORMATS); 190 | 191 | %items = ( 192 | Nickname => $nickname, 193 | Channel => $channel, 194 | Server => $server, 195 | Port => $port, 196 | Password => '-PASSWORD-', 197 | Realname => $config->{default_name}, 198 | Format => \@formats, 199 | 'Character set' => $charset 200 | ); 201 | 202 | my $func = \&escape_html; 203 | $func = \&HTML::Entities::encode_entities if $have_entities; 204 | @items{keys %items} = map { ref $_ 205 | ? [map { $func->($_) } @$_] 206 | : $func->($_) } 207 | values %items; 208 | 209 | $items{Nickname} =~ s/\?/int rand 10/eg; 210 | 211 | if(ref $cgi && $cgi->{adv}) { 212 | if($config->{'login advanced'}) { 213 | @order = split(/,\s*/, $config->{'login advanced'}); 214 | }else{ 215 | @order = qw/Nickname Realname Server Port Channel Password Format/; 216 | push @order, 'Character set'; 217 | } 218 | }else{ 219 | if($config->{'login basic'}) { 220 | @order = split(/,\s*/, $config->{'login basic'}); 221 | }else{ 222 | @order = qw/Nickname Server Channel/; 223 | } 224 | } 225 | $interface->login($scriptname, $interface, $copy, $config, 226 | \@order, \%items, 227 | (ref $cgi && $cgi->{adv} ? 0 : 1)); 228 | } 229 | 230 | sub random { 231 | return join('',map(('a'..'z','0'..'9')[int rand 36], 0..($_[0] || 15))); 232 | } 233 | 234 | sub dolist { 235 | my($var) = @_; 236 | my @tmp = split(/,\s*/, $var); 237 | return [@tmp] if $#tmp > 0; 238 | return $var; 239 | } 240 | 241 | sub add_disabled { 242 | if(ref $_[0]) { 243 | unshift @{$_[0]}, "-DISABLED-"; 244 | } else { 245 | $_[0] = "-DISABLED- $_[0]"; 246 | } 247 | } 248 | 249 | sub cgi_read { 250 | return unless defined $ENV{REQUEST_METHOD}; 251 | if($ENV{REQUEST_METHOD} eq 'GET' && $ENV{QUERY_STRING}) { 252 | return parse_query($ENV{QUERY_STRING}); 253 | }elsif($ENV{REQUEST_METHOD} eq 'POST' && $ENV{CONTENT_LENGTH}) { 254 | my $tmp; 255 | read(STDIN, $tmp, $ENV{CONTENT_LENGTH}); 256 | return parse_query($tmp); 257 | } 258 | } 259 | 260 | sub cgi_encode { # from CGI.pm 261 | my $toencode = shift; 262 | $toencode=~s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg; 263 | return $toencode; 264 | } 265 | 266 | sub error { 267 | die(@_); 268 | } 269 | -------------------------------------------------------------------------------- /modules/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | -------------------------------------------------------------------------------- /modules/Command.pm: -------------------------------------------------------------------------------- 1 | package Command; 2 | use strict; 3 | my($package, $event, $irc, $command, $target, $params, $config, $interface); 4 | 5 | my %commands = ( 6 | noop => sub { 7 | 0; 8 | }, 9 | msg => sub { 10 | my($target, $text) = split(' ', $params, 2); 11 | return 2 unless(defined $text && defined $target); 12 | main::irc_send_message($target, $text); 13 | }, 14 | m => 'msg', 15 | privmsg => 'msg', 16 | say => sub { 17 | return 2 unless defined $params; 18 | main::irc_send_message($target, $params); 19 | }, 20 | wi => 'whois', 21 | whois => sub { 22 | $params = $irc->{nick} unless $params; 23 | $irc->out("WHOIS $params"); 24 | }, 25 | j => 'join', 26 | 'join' => sub { 27 | my($channels, $keys) = split(' ', $params, 2); 28 | my @channels = split /,/, $channels; 29 | for(@channels) { 30 | $_ = "#$_" unless $irc->is_channel($_); 31 | next if main::access_configcheck('channel', $_); 32 | message('access channel denied', $_); 33 | return; 34 | } 35 | $irc->join(join(',', @channels) . (defined $keys ? " $keys" : '')); 36 | }, 37 | l => 'part', 38 | part => sub { 39 | if(!$params) { 40 | $irc->part($target); 41 | }else{ 42 | my($atarget, $text) = split(' ', $params, 2); 43 | if($irc->is_channel($atarget)) { 44 | $irc->part($atarget, $text); 45 | }else{ 46 | $irc->part($target, $atarget . ' ' . $text); 47 | } 48 | } 49 | }, 50 | nick => sub { 51 | return 1 unless defined $params; 52 | $irc->nick($params); 53 | }, 54 | quit => sub { 55 | $irc->quit($params ? $params : (defined $config->{quit_message} ? 56 | $config->{quit_message} : "CGI:IRC $::VERSION")); 57 | }, 58 | names => sub { 59 | $irc->out("NAMES " . ($params ? $params : $target)); 60 | }, 61 | mode => sub { 62 | return 2 unless defined $params; 63 | my($atarget, $text) = split(' ', $params, 2); 64 | if($atarget =~ /^[+-]/) { 65 | $irc->mode($target, $params); 66 | }else{ 67 | $irc->mode($atarget, $text); 68 | } 69 | }, 70 | umode => sub { 71 | return 2 unless defined $params; 72 | $irc->mode($irc->{nick}, $params); 73 | }, 74 | usermode => 'umode', 75 | op => sub { 76 | return 2 unless defined $params; 77 | $irc->mode($target, '+' . ('o' x scalar @{[split ' ', $params]}) ." $params"); 78 | }, 79 | halfop => sub { 80 | return 2 unless defined $params; 81 | $irc->mode($target, '+' . ('h' x scalar @{[split ' ', $params]}) ." $params"); 82 | }, 83 | voice => sub { 84 | return 2 unless defined $params; 85 | $irc->mode($target, '+' . ('v' x scalar @{[split ' ', $params]}) ." $params"); 86 | }, 87 | deop => sub { 88 | return 2 unless defined $params; 89 | $irc->mode($target, '-' . ('o' x scalar @{[split ' ', $params]}) ." $params"); 90 | }, 91 | dehalfop => sub { 92 | return 2 unless defined $params; 93 | $irc->mode($target, '+' . ('h' x scalar @{[split ' ', $params]}) ." $params"); 94 | }, 95 | devoice => sub { 96 | return 2 unless defined $params; 97 | $irc->mode($target, '-' . ('v' x scalar @{[split ' ', $params]}) ." $params"); 98 | }, 99 | t => 'topic', 100 | topic => sub { 101 | my($atarget, $text) = split(' ', $params, 2); 102 | if(!$params) { 103 | $irc->topic($target); 104 | }elsif($irc->is_channel($atarget)) { 105 | $irc->topic($atarget, $text); 106 | }else{ 107 | $irc->topic($target, $params); 108 | } 109 | }, 110 | invite => sub { 111 | my($atarget, $text) = split(' ', $params, 2); 112 | if($text) { 113 | $irc->invite($atarget, $text); 114 | }else{ 115 | $irc->invite($params, $target); 116 | } 117 | }, 118 | k => 'kick', 119 | kick => sub { 120 | my($atarget, $tnick, $text) = split(' ', $params, 3); 121 | if($irc->is_channel($atarget)) { 122 | $irc->kick($atarget, $tnick, $text); 123 | }else{ 124 | $irc->kick($target, $atarget, $tnick .(defined $text ? " $text" : '')); 125 | } 126 | }, 127 | ban => sub { 128 | return 2 unless defined $params; 129 | my $chan = $irc->channel($target); 130 | if($params =~ /\@/) { 131 | $irc->mode($target, "+b $params"); 132 | }elsif(ref $chan && ref $chan->nick($params)) { 133 | my $host = $chan->nick($params)->{host}; 134 | if($host =~ /\d$/) { 135 | $host =~ s/^\W([^\@]+)\@(.*?)\.\d+$/*!*$1\@$2.*/; 136 | }else{ 137 | $host =~ s/^\W([^\@]+)\@[^\.]+\.(.*)$/*!*$1\@*.$2/; 138 | } 139 | $irc->mode($target, "+b $host"); 140 | }else{ 141 | return 1; 142 | } 143 | }, 144 | ignore => sub { 145 | if($params) { 146 | $params =~ s/[!@].*//; 147 | $irc->ignore($params); 148 | message('ignored', $params); 149 | }else{ 150 | for($irc->ignores) { 151 | message('ignore list', $_); 152 | } 153 | } 154 | return 0; 155 | }, 156 | unignore => sub { 157 | return 2 unless defined $params; 158 | $irc->unignore($params); 159 | message('unignored', $params); 160 | return 0; 161 | }, 162 | notice => sub { 163 | my($target, $text) = split(' ', $params, 2); 164 | my $display = $target; 165 | $display =~ s/^[+@]+//; 166 | $event->handle('notice ' . 167 | ($irc->is_channel($display) ? 'public' : 'private') . ' own', 168 | { target => $display }, $irc->{nick}, $irc->{myhost}, $text); 169 | 170 | $irc->notice($target,$text); 171 | }, 172 | ctcp => sub { 173 | my($target, $text) = split(' ', $params, 2); 174 | $event->handle('ctcp own msg', 175 | { target => $target }, $irc->{nick}, $irc->{myhost}, $text); 176 | $irc->ctcp($target,$text); 177 | }, 178 | ctcpreply => sub { 179 | my($target, $type, $text) = split(' ', $params, 3); 180 | $irc->ctcpreply($target, $type, $text); 181 | }, 182 | ping => sub { 183 | $target = $params if $params; 184 | $event->handle('ctcp own msg', 185 | { target => $target }, $irc->{nick}, $irc->{myhost}, 'PING'); 186 | $irc->ctcp($target, 'PING ' . time); 187 | }, 188 | me => sub { 189 | $event->handle('action ' . 190 | ($irc->is_channel($target) ? 'public' : 'private') . ' own', 191 | { target => $target }, $irc->{nick}, $irc->{myhost}, $params); 192 | $irc->ctcp($target, 'ACTION ' . $params); 193 | }, 194 | action => sub { 195 | my($target, $text) = split(' ', $params, 2); 196 | $event->handle('action ' . 197 | ($irc->is_channel($target) ? 'public' : 'private') . ' own', 198 | { target => $target }, $irc->{nick}, $irc->{myhost}, $params); 199 | $irc->ctcp($target, 'ACTION ' . $params); 200 | }, 201 | quote => sub { 202 | $irc->out($params) if $params; 203 | }, 204 | version => sub { 205 | if($params) { 206 | $irc->out("VERSION $params"); 207 | }else{ 208 | message('default',"CGI:IRC $main::VERSION - David Leadbeater - http://cgiirc.sf.net/"); 209 | $irc->out('VERSION'); 210 | } 211 | }, 212 | winclose => sub { 213 | my $c = $params ? $params : $target; 214 | $irc->part($c) if $irc->is_channel($c) && $irc->channel($c); 215 | $interface->del($c); 216 | return 0; 217 | }, 218 | 'close' => 'winclose', 219 | 'unquery' => 'winclose', 220 | 'query' => sub { 221 | return 2 unless $params; 222 | my($target, $text) = split(' ', $params, 2); 223 | $interface->add($target); 224 | $interface->active($target); 225 | if(defined $text and $text) { 226 | main::irc_send_message($target, $text); 227 | } 228 | return 0; 229 | }, 230 | clear => sub { 231 | $interface->clear($params ? $params : $target); 232 | return 0; 233 | }, 234 | help => sub { 235 | $interface->help($config); 236 | return 0; 237 | }, 238 | charset => sub { 239 | if(!$::ENCODE) { 240 | message('default', 'Encode module is not loaded, character set conversion not available'); 241 | }else{ 242 | if(!$params) { 243 | message('default', "Current encoding is: " . $config->{'irc charset'}); 244 | }else{ 245 | if(Encode::find_encoding($params)) { 246 | message('default', "Encoding changed to $params"); 247 | $config->{'irc charset'} = $params; 248 | }else{ 249 | message('default', 'Encoding not found'); 250 | } 251 | } 252 | } 253 | return 0; 254 | }, 255 | ); 256 | 257 | my %lcs; 258 | @lcs{qw/nickserv memoserv chanserv statserv cs ms ns ss away/} = 1; 259 | 260 | sub expand { 261 | ($package, $command) = @_; 262 | $command = lc $command; 263 | if(exists $commands{$command}) { 264 | $command = _find_command($command); 265 | return $command; 266 | } 267 | return $command; 268 | } 269 | 270 | sub run { 271 | ($package, $event, $irc, $command, $target, $params, $config, $interface) = @_; 272 | 273 | if(exists $commands{$command}) { 274 | my $error = $commands{$command}->(); 275 | return $error ? $error : 100; 276 | }elsif(exists $lcs{$command}) { 277 | $irc->out(uc($command) . ' :' . $params); 278 | return 100; 279 | }elsif($command =~ /^:/) { 280 | ($command,$params) = $params =~ /^([^ ]+) ?(.*)$/; 281 | return 1 unless exists $commands{lc $command}; 282 | my $error = $commands{lc $command}->(); 283 | return $error ? $error : 100; 284 | }else{ 285 | $irc->out(uc($command) . ' ' . $params); 286 | return 100; 287 | } 288 | 289 | return 1; 290 | } 291 | 292 | sub message { 293 | main::message(@_); 294 | } 295 | 296 | sub _find_command { 297 | my($fcommand) = @_; 298 | return '' unless exists $commands{$fcommand}; 299 | return $fcommand if ref $commands{$fcommand}; 300 | $fcommand = $commands{$fcommand}; 301 | return _find_command($fcommand); 302 | } 303 | 304 | 1; 305 | -------------------------------------------------------------------------------- /modules/Event.pm: -------------------------------------------------------------------------------- 1 | # $Id: Event.pm,v 1.1 2002/03/05 16:34:19 dgl Exp $ 2 | package Event; 3 | use strict; 4 | my($currentevent,$currenteventid,$stop); 5 | 6 | sub new { 7 | my $self = bless { }, shift; 8 | %$self = @_; 9 | return $self; 10 | } 11 | 12 | sub add { 13 | my($self,$event,%option) = @_; 14 | return unless $event; 15 | $self->{$event} ||= [ ]; 16 | 17 | push(@{$self->{$event}}, bless ( { 18 | priority => $option{priority} || 5, 19 | code => $option{code}, 20 | data => $option{data}, 21 | 'package' => (caller)[0], 22 | _self => $self, 23 | } ) ); 24 | $self->sortpri($event); 25 | } 26 | 27 | sub delete { 28 | my($self,$event,%option) = @_; 29 | if(defined $currentevent) { 30 | $self = $self->{_self}; 31 | splice( @{ $self->{$currentevent} }, $currenteventid, 1); 32 | $self->sortpri($currentevent); 33 | } else { 34 | my $count = 0; 35 | for my $item(@{ $self->{$event} } ) { 36 | if((exists $option{code} && $item->{code} eq $option{code}) || (exists $option{data} && $item->{data} eq $option{data})) { 37 | splice( @{ $self->{$event} }, $count, 1); 38 | } 39 | $count++; 40 | } 41 | $self->sortpri($event); 42 | } 43 | } 44 | 45 | sub remove_package { 46 | my($self, $package) = @_; 47 | for my $event (keys %$self) { 48 | next unless ref $self->{$event}; 49 | my $count = 0; 50 | for my $item(@{ $self->{$event} } ) { 51 | if($item->{package} eq $package) { 52 | splice( @{ $self->{$event} }, $count, 1); 53 | } 54 | $count++; 55 | } 56 | } 57 | } 58 | 59 | # Make sure the array for the event is sorted on priority 60 | sub sortpri { 61 | my($self,$event) = @_; 62 | return unless $event; 63 | 64 | if($#{$self->{$event}} == -1) { 65 | delete($self->{$event}); 66 | } else { 67 | @{$self->{$event}} = (sort {$a->{priority} <=> $b->{priority}} @{$self->{$event}}); 68 | } 69 | } 70 | 71 | sub handle { 72 | my($self,$event,@param) = @_; 73 | print("Event: $event, @param\n") if $self->{_DEBUG}; 74 | $currentevent = $event; 75 | $currenteventid = 0; 76 | for my $item(@{$self->{$event}} ) { 77 | my($tmpevent,$tmpid) = ($currentevent,$currenteventid); 78 | $item->{code}->($item,@param); 79 | ($currentevent,$currenteventid) = ($tmpevent,$tmpid); 80 | $currenteventid++; 81 | if($stop) { 82 | $stop = 0; 83 | last; 84 | } 85 | } 86 | if(!scalar @{$self->{$event}} && $event ne "unhandled") { 87 | $self->handle('unhandled', $event, @param); 88 | } 89 | $currenteventid = $currentevent = undef; 90 | } 91 | 92 | sub stop { 93 | my($self) = @_; 94 | $stop = 1 if defined $currentevent; 95 | } 96 | 97 | sub getevent { 98 | my($self) = @_; 99 | return defined $currentevent ? $currentevent : undef; 100 | } 101 | 102 | sub exists { 103 | my($self,$event) = @_; 104 | return 1 if exists $self->{$event}; 105 | 0; 106 | } 107 | 108 | 1; 109 | -------------------------------------------------------------------------------- /modules/IRC.pm: -------------------------------------------------------------------------------- 1 | # $Id: IRC.pm,v 1.14 2006/06/06 18:41:35 dgl Exp $ 2 | package IRC; 3 | use strict; 4 | use IRC::UniqueHash; 5 | use IRC::Util; 6 | use IRC::Channel; 7 | use IRC::RawCommands; 8 | 9 | sub new { 10 | my $class = shift; 11 | my $self = bless {}, $class; 12 | %$self = @_; 13 | return undef unless $self->{event} and $self->{timer}; 14 | 15 | $self->{_channels} = { }; 16 | tie %{$self->{_channels}}, 'IRC::UniqueHash'; 17 | 18 | $self->{ignore} = { }; 19 | tie %{$self->{ignore}}, 'IRC::UniqueHash'; 20 | 21 | $self->{_tmp} = { }; 22 | $self->{fh} ||= 1; 23 | $self->{mode} ||= '+'; 24 | 25 | $self->{_rawcmd} = IRC::RawCommands->new($self,$self->{event}); 26 | 27 | if($self->{nick}) { 28 | $self->connect(@_); 29 | } 30 | 31 | return $self; 32 | } 33 | 34 | sub in { 35 | my($self,$line) = @_; 36 | $line =~ s/(\015\012|\012|\015)$//; 37 | 38 | if($line =~ /^(PING|NOTICE|ERROR) /i){ 39 | if($line =~ /^PING (.*)$/i) { 40 | $self->out("PONG $1"); 41 | }elsif($line =~ /^NOTICE ([^ ]+) :?(.*)$/i) { 42 | $self->{event}->handle('notice server', {target => $1}, 43 | , $self->{server}, $self->{server}, $2); 44 | }elsif($line =~ /^ERROR :([^:]+):(.*)$/i) { 45 | $self->{event}->handle('disconnect', {target => 'Status'}, $1, $2); 46 | } 47 | }elsif( 48 | my($host,$params,$text) = $line =~ /^:([^ ]+) +((?:[^ ]+(?: +)?)+?)(?:(?<= ):(.*))?$/) { 49 | $params =~ s/^ +//; 50 | my @params = split(/ /,$params); 51 | $self->{event}->handle('raw ' . lc $params[0], $self, { 52 | host => fullhost2host($host), 53 | nick => fullhost2nick($host), 54 | params => [ @params ], 55 | text => $text 56 | } ); 57 | }else{ 58 | warn "Parse error in: '$line'"; 59 | } 60 | } 61 | 62 | sub out { 63 | my($self,$line) = @_; 64 | $self->{event}->handle('irc out',$self->{fh}, $line); 65 | } 66 | 67 | sub find_nick_channels { 68 | my($self,$nick) = @_; 69 | my @tmp; 70 | for my $channel(keys %{$self->{_channels}}) { 71 | next unless ref $self->{_channels}->{$channel} eq "IRC::Channel"; 72 | push @tmp, $channel if $self->{_channels}->{$channel}->nick($nick); 73 | } 74 | return @tmp; 75 | } 76 | 77 | sub connect { 78 | my($self,%connect) = @_; 79 | $connect{server} =~ s/://g; 80 | $self->{alternick} ||= $connect{alternick} || $connect{nick} . '_'; 81 | $self->out($self->{preconnect}) if $self->{preconnect}; 82 | $self->out("PASS $self->{password}") if $self->{password}; 83 | $self->out('NICK '.($connect{nick} || $ENV{IRC_NICK} || $ENV{USER})); 84 | $self->out('USER '.($connect{user} || $ENV{USER}) . ' ' 85 | . ($connect{host} || 'localhost') . ' ' . ($connect{server} || 'irc') 86 | . ' :' . ($connect{realname} || 'unknown')); 87 | } 88 | 89 | sub channel { 90 | my($self,$channel) = @_; 91 | return $self->{_channels}->{$channel}; 92 | } 93 | 94 | sub channels { 95 | my $self = shift; 96 | return values %{$self->{_channels}}; 97 | } 98 | 99 | sub is_channel { 100 | my($self,$channel) = @_; 101 | if(exists $self->{capab}->{chantypes}) { 102 | return 1 if $channel =~ /^[$self->{capab}->{chantypes}]/; 103 | return 0; 104 | } 105 | return is_valid_channel($channel); 106 | } 107 | 108 | sub is_nickname { 109 | my($self,$nick) = @_; 110 | return 0 if $self->is_channel($nick); 111 | return is_valid_nickname($nick); 112 | } 113 | 114 | sub sync_channel { 115 | my($self,$channel) = @_; 116 | $self->channel($channel)->{mode_sync} = 1; 117 | $self->out("MODE $channel"); 118 | $self->channel($channel)->{who_sync} = 1; 119 | $self->out("WHO $channel"); 120 | } 121 | 122 | sub ignore { 123 | my($self, $ignore) = @_; 124 | $self->{ignore}->{$ignore} = 1; 125 | } 126 | 127 | sub ignores { 128 | my($self) = @_; 129 | return keys %{$self->{ignore}}; 130 | } 131 | 132 | sub unignore { 133 | my($self, $ignore) = @_; 134 | delete($self->{ignore}->{$ignore}); 135 | } 136 | 137 | sub join { 138 | my($self, $channel, $key) = @_; 139 | return unless $channel; 140 | $self->out('JOIN ' . (ref $channel ? $channel->{name} : $channel) . ($key ? ' ' . $key : '')); 141 | } 142 | 143 | sub part { 144 | my($self, $channel, $reason) = @_; 145 | $self->out('PART ' . $channel . ($reason ? " :$reason" : '')); 146 | } 147 | 148 | sub nick { 149 | my($self,$nick) = @_; 150 | $self->out("NICK $nick"); 151 | } 152 | 153 | sub quit { 154 | my($self,$reason) = @_; 155 | $self->out("QUIT :$reason"); 156 | } 157 | 158 | sub mode { 159 | my($self, $channel, $mode) = @_; 160 | $channel = $channel->{name} if ref $channel; 161 | $self->out("MODE $channel $mode"); 162 | } 163 | 164 | sub topic { 165 | my($self, $channel, $message) = @_; 166 | $channel = $channel->{name} if ref $channel; 167 | $self->out("TOPIC $channel" . (defined $message ? " :$message" : '')); 168 | } 169 | 170 | sub invite { 171 | my($self, $channel, $nick) = @_; 172 | $channel = $channel->{name} if ref $channel; 173 | $self->out("INVITE $channel $nick"); 174 | } 175 | 176 | sub kick { 177 | my($self, $channel, $nick, $message) = @_; 178 | $channel = $channel->{name} if ref $channel; 179 | $self->out("KICK $channel $nick :$message"); 180 | } 181 | 182 | sub notice { 183 | my($self, $channel, $message) = @_; 184 | $channel = $channel->{name} if ref $channel; 185 | $self->out("NOTICE $channel :$message"); 186 | } 187 | 188 | sub msg { 189 | my($self, $channel, $message) = @_; 190 | $self->privmsg(@_[1..3]); 191 | } 192 | 193 | sub privmsg { 194 | my($self, $channel, $message) = @_; 195 | $channel = $channel->{name} if ref $channel; 196 | $self->out("PRIVMSG $channel :$message"); 197 | } 198 | 199 | sub ctcp { 200 | my($self, $channel, $text) = @_; 201 | $channel = $channel->{name} if ref $channel; 202 | $self->out("PRIVMSG $channel :\001$text\001"); 203 | } 204 | 205 | sub ctcpreply { 206 | my($self, $channel, $command, $text) = @_; 207 | $channel = $channel->{name} if ref $channel; 208 | $self->out("NOTICE $channel :\001$command $text\001"); 209 | } 210 | 211 | 1; 212 | -------------------------------------------------------------------------------- /modules/IRC/Channel.pm: -------------------------------------------------------------------------------- 1 | # $Id: Channel.pm,v 1.3 2002/05/21 14:48:17 dgl Exp $ 2 | package IRC::Channel; 3 | use strict; 4 | use IRC::UniqueHash; 5 | use IRC::Util; 6 | use IRC::Channel::Nick; 7 | 8 | sub new { 9 | my $class = shift; 10 | my $self = bless {}, $class; 11 | %$self = @_; 12 | $self->{_nicks} = { }; 13 | tie %{$self->{_nicks}}, 'IRC::UniqueHash'; 14 | return $self; 15 | } 16 | 17 | sub addnick { 18 | my($self,$nick,%nick) = @_; 19 | return 0 if exists $self->{_nicks}->{$nick}; 20 | 21 | $self->{_nicks}->{$nick} = IRC::Channel::Nick->new( 22 | name => $nick, 23 | op => defined $nick{op} ? $nick{op} : 0, 24 | voice => defined $nick{voice} ? $nick{voice} : 0, 25 | halfop => defined $nick{halfop} ? $nick{halfop} : 0 26 | ); 27 | } 28 | 29 | sub delnick { 30 | my($self,$nick) = @_; 31 | return 0 unless exists $self->{_nicks}->{$nick}; 32 | return delete($self->{_nicks}->{$nick}); 33 | } 34 | 35 | sub chgnick { 36 | my($self,$nick,$newnick) = @_; 37 | return 0 unless exists $self->{_nicks}->{$nick}; 38 | $self->{_nicks}->{$newnick} = $self->{_nicks}->{$nick}; 39 | $self->{_nicks}->{$newnick}->{name} = $newnick; 40 | return $self->{_nicks}->{$newnick} if lc $newnick eq lc $nick; 41 | return delete($self->{_nicks}->{$nick}); 42 | } 43 | 44 | sub nick { 45 | my($self,$nick) = @_; 46 | return 0 unless exists $self->{_nicks}->{$nick}; 47 | return $self->{_nicks}->{$nick}; 48 | } 49 | 50 | sub nicks { 51 | my($self) = @_; 52 | return keys %{$self->{_nicks}}; 53 | } 54 | 55 | sub is_nick { 56 | my($self,$nick) = @_; 57 | return 1 if $self->{_nicks}->{$nick}; 58 | 0; 59 | } 60 | 61 | sub is_voice { 62 | my($self, $nick) = @_; 63 | return 1 if $self->{_nicks}->{$nick}->{voice}; 64 | 0; 65 | } 66 | 67 | sub is_op { 68 | my($self, $nick) = @_; 69 | return 1 if $self->{_nicks}->{$nick}->{op}; 70 | 0; 71 | } 72 | 73 | sub get_umode { 74 | my($self, $nick) = @_; 75 | if($self->{_nicks}->{$nick}->{op}) { 76 | return '@'; 77 | }elsif($self->{_nicks}->{$nick}->{halfop}) { 78 | return '%'; 79 | }elsif($self->{_nicks}->{$nick}->{voice}) { 80 | return '+'; 81 | }else{ 82 | return ' '; 83 | } 84 | } 85 | 86 | sub has_mode { 87 | my($self,$mode) = @_; 88 | return 1 if check_mode($self->{mode},$mode); 89 | 0; 90 | } 91 | 92 | 1; 93 | -------------------------------------------------------------------------------- /modules/IRC/Channel/Nick.pm: -------------------------------------------------------------------------------- 1 | # $Id: Nick.pm,v 1.1 2002/03/05 16:34:19 dgl Exp $ 2 | package IRC::Channel::Nick; 3 | use strict; 4 | 5 | sub new { 6 | my $class = shift; 7 | my $self = bless { }, $class; 8 | %$self = @_; 9 | return $self; 10 | } 11 | 12 | # Maybe i'll add some functions here, one day... 13 | 14 | 1; 15 | -------------------------------------------------------------------------------- /modules/IRC/Event.pm: -------------------------------------------------------------------------------- 1 | # $Id: Event.pm,v 1.1 2002/03/05 16:34:19 dgl Exp $ 2 | package IRC::Event; 3 | 4 | AUTOLOAD { 5 | return unless defined $AUTOLOAD; 6 | my $name = $AUTOLOAD; 7 | $name =~ s/.*:://; 8 | return if $name eq 'DESTROY'; 9 | if($name && ref $_[0] && $_[0]->{server} && $_[0]->{channel}) { 10 | $_[0]->{server}->$name($_[0]->{channel}, @_[1..$#_]); 11 | } 12 | } 13 | 14 | sub new { 15 | my($class,$client) = (shift,shift); 16 | my $self = bless { }, $class; 17 | %$self = @_; 18 | $self->{server} = $client; 19 | return $self; 20 | } 21 | 22 | 1; 23 | -------------------------------------------------------------------------------- /modules/IRC/UniqueHash.pm: -------------------------------------------------------------------------------- 1 | # $Id: UniqueHash.pm,v 1.2 2002/04/27 19:21:54 dgl Exp $ 2 | #!/usr/bin/perl 3 | # from pircd, edited by david leadbeater.. 4 | # 5 | # IRCUniqueHash.pm 6 | # Created: Wed Apr 21 09:44:03 1999 by jay.kominek@colorado.edu 7 | # Revised: Wed Apr 21 09:59:55 1999 by jay.kominek@colorado.edu 8 | # Copyright 1999 Jay F. Kominek (jay.kominek@colorado.edu) 9 | # 10 | # Consult the file 'LICENSE' for the complete terms under which you 11 | # may use self file. 12 | # 13 | ##################################################################### 14 | # A hash class which enforces IRC-style unique name spaces 15 | ##################################################################### 16 | 17 | package IRC::UniqueHash; 18 | use strict; 19 | my(@tmp); 20 | 21 | sub TIEHASH { 22 | my $proto = shift; 23 | my $class = ref($proto) || $proto; 24 | my $self = { }; 25 | 26 | bless $self, $class; 27 | return $self; 28 | } 29 | 30 | sub FETCH { 31 | my($self,$key) = @_; 32 | 33 | return $self->{data}->{irclc($key)}->{value}; 34 | } 35 | 36 | sub STORE { 37 | my($self,$key,$value) = @_; 38 | 39 | my $name = irclc($key); 40 | $self->{data}->{$name}->{name} = $key; 41 | $self->{data}->{$name}->{value} = $value; 42 | } 43 | 44 | sub DELETE { 45 | my($self,$key) = @_; 46 | 47 | delete($self->{data}->{irclc($key)}); 48 | } 49 | 50 | sub CLEAR { 51 | my $self = shift; 52 | 53 | %$self = ( ); 54 | } 55 | 56 | sub EXISTS { 57 | my($self,$key) = @_; 58 | 59 | return exists $self->{data}->{irclc($key)}; 60 | } 61 | 62 | sub FIRSTKEY { 63 | my $self = shift; 64 | 65 | @{$self->{_tmp}} = keys %{$self->{data}}; 66 | 67 | return $self->{data}->{shift @{$self->{_tmp}}}->{name}; 68 | } 69 | 70 | sub NEXTKEY { 71 | my ($self,$lastkey) = @_; 72 | 73 | return undef unless @{$self->{_tmp}}; 74 | return $self->{data}->{shift @{$self->{_tmp}}}->{name}; 75 | } 76 | 77 | sub irclc { 78 | return lc $_[0]; 79 | } 80 | 81 | 1; 82 | -------------------------------------------------------------------------------- /modules/IRC/Util.pm: -------------------------------------------------------------------------------- 1 | # $Id: Util.pm,v 1.5 2006/04/30 12:51:55 dgl Exp $ 2 | package IRC::Util; 3 | use Exporter; 4 | @ISA = qw(Exporter); 5 | @EXPORT = qw(is_valid_channel is_valid_nickname is_valid_server make_lowercase check_mode match_mask fullhost2nick fullhost2host add_mode del_mode); 6 | 7 | use strict; 8 | 9 | sub is_valid_channel { 10 | return 0 if length $_[0] > 64; 11 | return 0 if $_[0] =~ /[ ,]/; 12 | return 1 if $_[0] =~ /^[#&]/; 13 | return 0; 14 | } 15 | 16 | sub is_valid_nickname { 17 | return 0 if length $_[0] > 32 or length $_[0] < 1; 18 | return 0 if $_[0] =~ / /; 19 | return 0 if $_[0] =~ /^[0-9#&]/; 20 | return 1; 21 | } 22 | 23 | sub is_valid_server { 24 | return 0 if $_[0] !~ /\./; 25 | return 0 if $_[0] =~ /[!@]/; 26 | return 0 if $_[0] =~ /[^-A-Za-z0-9\*\._]/; 27 | return 1; 28 | } 29 | 30 | sub make_lowercase{ 31 | my $lc = shift; 32 | $lc =~ tr/A-Z\[\]\\/a-z\{\}\|/; 33 | return $lc; 34 | } 35 | 36 | sub check_mode { 37 | my($mode,$bit) = @_; 38 | return 1 if $mode =~ /\S*\Q$bit\E/; 39 | } 40 | 41 | # should really split all the parts up... 42 | sub match_mask { 43 | my($check,$mask) = @_; 44 | $mask = quotemeta $mask; 45 | $mask =~ s/\\\?/./g; 46 | $mask =~ s/\\\*/.*?/g; 47 | return 1 if $check =~ /$mask/; 48 | 0; 49 | } 50 | 51 | sub fullhost2nick { 52 | my $host = shift; 53 | $host =~ s/!.*$//; 54 | return $host; 55 | } 56 | 57 | sub fullhost2host { 58 | my $host = shift; 59 | $host =~ s/^.*?!//; 60 | return $host; 61 | } 62 | 63 | sub add_mode{ 64 | my($mode,$bit) = @_; 65 | return $mode if $mode =~ /^\S*\Q$bit\E/; 66 | $mode =~ s/^(\S*)/$1$bit/; 67 | return $mode; 68 | } 69 | 70 | sub del_mode{ 71 | my($mode,$bit) = @_; 72 | return $mode if $mode !~ /^\S*\Q$bit\E/; 73 | $mode =~ s/^(\S*)$bit/$1/; 74 | return $mode; 75 | } 76 | 77 | 1; 78 | -------------------------------------------------------------------------------- /modules/Timer.pm: -------------------------------------------------------------------------------- 1 | # $Id: Timer.pm,v 1.1 2002/03/05 16:34:19 dgl Exp $ 2 | =head1 NAME 3 | 4 | Timer.pm 5 | 6 | =head1 EXAMPLES 7 | 8 | use Timer; 9 | $timer = Timer->new; 10 | 11 | $timer->addonce(code => \&somesub, data => 'moo', interval => 10); 12 | sub somesub { print shift } 13 | 14 | $timer->add(code => sub { 15 | my($timer,$data) = @_; 16 | print "Called $timer->{id} with $data\n"; 17 | }, data => 'oink', interval => 1, count => 10); 18 | 19 | # Obviously fit $timer->run into how your program needs to use it. 20 | sleep 1; 21 | sleep 1 while $timer->run; 22 | 23 | =head1 METHODS 24 | 25 | =head2 add 26 | 27 | add( code => \&codref, # \&code, sub { print blah..} etc.. 28 | data => 'data', # This data is passed back to the coderef when run 29 | interval => num, # Time between being run.. 30 | count => [num | undef ], # number of times to run, undef == forever 31 | ); 32 | 33 | =head2 addonce 34 | 35 | Wrapper to add, option count is already set to 1 36 | 37 | =head2 addforever 38 | 39 | Wrapper to add, option count is set to undef 40 | 41 | =head2 delete 42 | 43 | delete($id); 44 | 45 | =head2 get 46 | 47 | returns anon hash specified by $id 48 | 49 | =head2 run 50 | 51 | checks for timers that need running, returns number actually run. 52 | 53 | =head2 call 54 | 55 | used internally by run to call an timer when it needs running 56 | 57 | =head2 exists 58 | 59 | returns true if the timer exists 60 | 61 | =cut 62 | 63 | package Timer; 64 | use strict; 65 | 66 | sub new { 67 | my $class = shift; 68 | # notice it's an array, not a hash 69 | return bless [], $class; 70 | } 71 | 72 | sub add { 73 | my($self,%timer) = @_; 74 | my $id = $self->_newid; 75 | $$self[$id] = 76 | { 77 | code => $timer{code}, 78 | data => $timer{data}, 79 | interval => $timer{interval}, 80 | nextexec => $timer{interval} + time, 81 | count => $timer{count} || undef, 82 | 'package' => (caller)[0], 83 | id => $id 84 | }; 85 | return $id; 86 | } 87 | 88 | sub remove_package { 89 | my($self, $package) = @_; 90 | for my $id(0 .. $#$self) { 91 | next unless ref($$self[$id]) eq 'HASH'; 92 | if($$self[$id]->{package} eq $package) { 93 | splice(@$self, $id, 1); 94 | } 95 | } 96 | } 97 | 98 | # Finds the next free id (element) in the array 99 | sub _newid { 100 | my $self = shift; 101 | for my $id(0 .. $#$self) { 102 | return $id unless ref($$self[$id]) eq 'HASH'; 103 | } 104 | return scalar @$self; 105 | } 106 | 107 | sub addonce { 108 | my($self,%timer) = @_; 109 | $self->add(%timer,count => 1); 110 | } 111 | 112 | sub addforever { 113 | my($self,%timer) = @_; 114 | $self->add(%timer,count => undef); 115 | } 116 | 117 | sub delete { 118 | my($self,$id) = @_; 119 | return 0 unless $self->exists($id); 120 | $$self[$id] = undef; 121 | } 122 | 123 | sub get { 124 | my($self,$id) = @_; 125 | return $$self[$id]; 126 | } 127 | 128 | sub run { 129 | my $self = shift; 130 | my $time = time; 131 | my $num = 0; 132 | for my $id(0 .. $#$self) { 133 | next unless ref($$self[$id]) eq 'HASH'; 134 | if($time >= $$self[$id]->{nextexec}) { 135 | $self->call($id); 136 | $num++; 137 | } 138 | } 139 | return $num; 140 | } 141 | 142 | sub call { 143 | my($self,$id) = @_; 144 | my $timer = $self->get($id); 145 | 146 | $timer->{count}-- if defined $timer->{count}; 147 | $timer->{nextexec} = $timer->{interval} + time; 148 | 149 | # TODO: Make $timer into an object so things like $timer->delete work within 150 | # the timer. 151 | $timer->{code}->($timer,$timer->{data}); 152 | 153 | if(defined $timer->{count} && $timer->{count} <= 0) { 154 | $self->delete($id); 155 | return 0; 156 | } 157 | 1; 158 | } 159 | 160 | sub exists { 161 | my($self,$id) = @_; 162 | return 1 if ref($$self[$id]) eq 'HASH'; 163 | 0; 164 | } 165 | 166 | 1; 167 | -------------------------------------------------------------------------------- /modules/parse.pl: -------------------------------------------------------------------------------- 1 | #### Parsing Functions 2 | use strict; 3 | 4 | ## Reads a config file from the filename passed to it, returns a reference to 5 | ## a hash containing the name=value pairs in the file. 6 | sub parse_config { 7 | my %config; 8 | open(CONFIG, "<$_[0]") or error("Opening config file '$_[0]': $!"); 9 | eval { local $SIG{__DIE__}; binmode CONFIG, ':utf8'; }; 10 | while() { 11 | s/(\015\012|\012)$//; # Be forgiving for poor windows users 12 | next if /^\s*[#;]/; # Comments 13 | next if !/=/; 14 | 15 | my($key, $value); 16 | 17 | if(($key, $value) = $_ =~ /^"((?:[^"]+(?:(?<=\\)")?)+)"\s*=\s*(.*)$/) { 18 | $key =~ s/\\"/"/g; 19 | $key =~ s/\\(\d{1,3})/chr $1/eg; 20 | } else { 21 | ($key,$value) = split(/\s*=\s*/, $_, 2); 22 | } 23 | 24 | $config{$key} = defined $value ? $value : ''; 25 | } 26 | close(CONFIG); 27 | return \%config; 28 | } 29 | 30 | sub make_utf8 { 31 | # Use perl's unicode support assuming we have 5.6 and Encode 32 | return pack("U", hex($_[0])) if $] >= 5.006 && $::ENCODE; 33 | 34 | # From http://www1.tip.nl/~t876506/utf8tbl.html 35 | my $chr = unpack("n", pack("H*", shift)); 36 | return chr $chr if $chr < 0x7F; 37 | return chr(192 + int($chr / 64)) . chr(128 + $chr % 64) if $chr <= 0x7FF; 38 | return chr(224 + int($chr / 4096)) . chr(128 + int($chr / 64) % 64) . 39 | chr(128 + $chr % 64) if $chr <= 0xFFFF; 40 | return chr(240 + int($chr / 262144)) . chr(128 + int($chr / 4096) % 64) . 41 | chr(128 + int($chr / 64) % 64) . chr(128 + $chr % 64) if $chr <= 0x1FFFFF; 42 | return ""; 43 | } 44 | 45 | ## Parses a CGI input, returns a hash reference to the value within it. 46 | ## The clever regexp bit is from cgi-lib.pl 47 | ## This now also removes certain characters that might not be a good idea. 48 | ## $ext (bitmask): 1 to *NOT* remove \n etc, 2 to treat input as xmlhttp 49 | ## (different encoding for +). 50 | sub parse_query { 51 | my($query, $ext) = @_; 52 | return {} unless defined $query and length $query; 53 | 54 | return { 55 | map { 56 | s/\+/ /g unless defined $ext and $ext & 2; 57 | my($key, $val) = split(/=/,$_,2); 58 | $val = "" unless defined $val; 59 | 60 | $key =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge; 61 | $key =~ s/[\r\n\0\001]//g; 62 | 63 | # Modified from unescape as found in CGI::Util 64 | # (can't use CGI::Util due to + oddity from XMLHTTP). 65 | $val =~ s{%(?:([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))} { 66 | if(defined($1)) { 67 | if(defined($ext) && $ext & 2 and hex($1) > 0x7F) { 68 | make_utf8("00$1"); 69 | }else{ 70 | pack("C", hex($1)); 71 | } 72 | }else{ 73 | make_utf8($2); 74 | } 75 | }ge; 76 | 77 | if(defined $ext and $ext & 1) { 78 | $val =~ s/[\0\001]//g; 79 | }else{ 80 | $val =~ s/[\r\n\0\001]//g; 81 | } 82 | 83 | if($::ENCODE) { 84 | if($ext & 2) { 85 | # xmlhttp 86 | $val = Encode::decode_utf8($val); 87 | } else { 88 | # we don't really have enough information, but see if we can guess.. 89 | eval { 90 | local $SIG{__DIE__} = undef; 91 | $val = Encode::decode_utf8($val, Encode::FB_CROAK()); 92 | }; 93 | if ($@ && defined $::config->{'irc charset'}) { 94 | $val = Encode::decode($::config->{'irc charset'}, $val); 95 | } 96 | } 97 | } 98 | 99 | $key => $val; # Return a hash element to map. 100 | } split(/[&;]/, $query) 101 | }; 102 | } 103 | 104 | sub parse_cookie { 105 | if(exists $ENV{HTTP_COOKIE} && $ENV{HTTP_COOKIE} =~ /cgiircauth/) { 106 | for(split /;/, $ENV{HTTP_COOKIE}) { 107 | s/^\s+//; 108 | my($name,$value) = split(/=/,$_,2); 109 | return $value if $name eq "cgiircauth"; 110 | } 111 | } 112 | return 0; 113 | } 114 | 115 | sub parse_interface_cookie { 116 | my %tmp = ( ); 117 | if(exists $ENV{HTTP_COOKIE} && $ENV{HTTP_COOKIE} =~ /cgiirc/) { 118 | for(split /;/, $ENV{HTTP_COOKIE}) { 119 | s/^\s+//; 120 | my($name,$value) = split(/=/,$_,2); 121 | next if $name =~ /[^a-z]/i; 122 | next unless $name =~ s/^cgiirc//; 123 | next if $name eq 'auth'; 124 | $tmp{$name} = $value; 125 | } 126 | } 127 | return \%tmp; 128 | } 129 | 130 | sub escape_html { 131 | my($html) = @_; 132 | $html =~ s/&/&/g; 133 | $html =~ s/>/>/g; 134 | $html =~ s/