Initial commit of code released on 2002-07-15

This commit is contained in:
Brian Cline
2015-01-25 18:26:44 -06:00
commit feca086612
102 changed files with 22822 additions and 0 deletions

340
COPYING Normal file
View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

340
CS/COPYING Normal file
View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@@ -0,0 +1,74 @@
###################################################################
# Undernet Channel Service #
# Registration Form #
###################################################################
# Instructions: #
# o Read the Channel Service Committee Guidelines #
# This document can be obtained from: #
# ftp://ftp.undernet.org/pub/irc/docs/X/CSC-guidelines #
# /msg helpbot get CSC-guidelines #
# o Fill out this registration form completely #
# If you need help, ask in #cservice. #
# o Email completed form to cservice@undernet.org #
# Please be sure to include this form in the #
# BODY of your email, NOT as an attachment. #
# o If you do not receive acknowledgement of receipt of #
# this form within 2 weeks, please email it again, #
# stating that it is a second attempt. #
# o If your channel is not registered within 4 weeks, #
# you may email cservice@undernet.org to find out why #
###################################################################
-------------------------------------------------------------------
NOTE: Channel registration is not meant as a means to start a new
channel. It is meant for previously established channels
to have an opportunity to have some stability. If you are
first starting a new channel, then just start it, give it
some time to make sure you have a decent userbase, and then
consider registration. Thanks.
-------------------------------------------------------------------
A) Your Real Name :
B) The usual nick you use :
C) Your E-mail address :
D) The user@host that you use on irc :
{the address in your /whois on IRC}
{please try to include asterisks (*) wherever necessary}
E) Channel Name :
F) Purpose of channel :
{brief description}
G) Supporter's list :
This is a list of people who support you as channel
manager of this channel and who will frequent the channel.
You may want to CC them a copy of your application.
- Please do NOT include yourself as a supporter.
- Please do NOT use 2 (or more) different email addresses
of a user as being 2 (or more) different supporters.
Each entry in this list must be a different user.
---------------------------------------------------------------
Nickname | E-mail address
---------------------------------------------------------------
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
_______________________________________________________________
PLEASE NOTE -- You must have at least 10 supporters to register
a channel. You also may only register 1 channel.
_______________________________________________________________

BIN
HTTP/b_arrow.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

276
HTTP/chanopfaq.html Normal file
View File

@@ -0,0 +1,276 @@
<HTML>
<HEAD>
<TITLE>Undernet Channel Service: Channel Operators FAQ</TITLE>
<LINK REV="made" HREF:"mailto:marmi@soonernet.com">
<BODY BGCOLOR="#000000" TEXT="#ffff00" LINK="#ff0000" VLINK="#ff00ff">
<CENTER>
<p>
<hr>
<h1>Undernet Channel Service Committee</h1>
<h2>Channel Operator's FAQ</h2>
<hr>
</center>
<strong>
<blockquote>
Introduction: This FAQ has been put together by the Undernet Channel Service Committee for any and all users who have Channel Operator status on a Registered Channel on the Undernet.<br>
</blockquote>
<hr>
1) What is the Undernet Channel Service Committee?<br>
<img src="reddrop.gif">The Undernet Channel Service Committee is a sub committee of the Undernet User Committee (User-Com). The CSC (Channel Service Committee) is in charge of administrating the Channel Service and assisting users with its use.<p>
2) Who are X and W?<br>
<img src="reddrop.gif">X and W are the two Channel Service (CService) bots. They reside on Undernet's registered channels. Each registered channel has either X or W, but not both. They are exactly the same in the functions they can perform. The bots
hold separate user lists for each channel they reside on. These are lists of users for each channel who have access to certain functions on the bots depending on the level and settings of the user.<p>
3) What is a Channel Operator?<br>
<img src="reddrop.gif">A Channel Operator (ChanOp) is a user who has been given the privilege of helping the Channel Manager run the channel. ChanOps are expected to abide by all of the Channel Manager's rules, as well as CService's rules.<p>
4) What are the responsibilities of a ChanOp?<br>
<img src="reddrop.gif">A ChanOp is responsible for helping to maintain the atmosphere that the Channel Manager has set for his/her channel. This means ensuring that all users abide by the set channel rules and warning/removing users who do not abide by
them.<p>
5) Who is the Channel Manager?<br>
<img src="reddrop.gif">The Channel Manager is the person who registered the channel. There is generally only one Channel Manager, unless a special arrangement has been made with CService to have more than one. The Channel Manager makes the decisions on
how the channel is to be run. This is the person to go to first if you have a problem on your channel.<p>
<center>
To find out who the Channel Manager is:<br>
/msg x chaninfo #channel<br>
or<br>
/msg w chaninfo #channel<br>
Depending on which bot resides on that particular channel.<br>
<p>
</center>
*** All examples that follow will refer to X, but can be used with W as well.<p>
6) Can a user be a ChanOp even if s/he is not on the user list?<br>
<img src="reddrop.gif">Yes. A user can gain ops on a channel if they are given operator status from a current operator. This does not mean that just because someone makes you an op, you automatically have access to X/W. All it means is that you can pe
rform any operator commands that you can normally do on a non-registered channel.<p>
<blockquote>
Keep in mind that it is not a good idea to give ops to just anyone on the channel, though, since as an operator they have the ability to kick and ban anyone off the channel including X/W. Most forms of abuse of X/W are from users who do not know what X/
W are nor know and understand the CService rules. If you are going to give someone ops make sure that they will not be abusive and they will not try to kick/ban X/W off the channel. Also, some Channel Managers have their own rules about giving out ops
to users who are not on X/W's user list, so make sure you follow the Channel Manager's rules as well.</blockquote><p>
7) How do I know who is on the user list?<br>
<img src="reddrop.gif">You can find out if someone is on the user list for a channel by:<br>
<center>
/msg x access #channel nickname<p>
If the person is on the list for that channel, you will get a notice which looks like this:<p>
</center>
<blockquote>
-X- USER: teal (*!*erf103@*.psu.edu) ACCESS: ?450<br>
-X- CHANNEL: #Help -- AUTOOP: YES -- PROTECT: YES<br>
-X- LAST SEEN: 10 days, 19:42:16 ago<p>
Line 1: nickname, user@host mask and access level<br>
Line 2: channel name, autoop setting, protect setting<br>
Line 3: how long ago user was last seen on the channel<p>
</blockquote>
8) How do I get added to a channel's user list?<br>
<img src="reddrop.gif">Only ChanOps with ACCESS level 400 or higher can add users to the channel's user list. Who gets added is usually determined by the Channel Manager. Some channels may have a recommendation/voting process to add new ChanOps. Best
bet is to ask someone who is a ChanOp on that channel.<p>
9) What is this ACCESS level thing?<br>
<img src="reddrop.gif">A user's level determines what commands the user has access to on X or W. Users will have access to the commands for their level, plus all commands for any levels below them. For example, a level 75 user will have access to ban a
nd unban, plus the level 50 and level 0 commands.<p>
To find out what commands you have access to on a particular channel,<p>
<center>
/msg x showcommands #channelname<p>
</center>
<img src="reddrop.gif">Here are the commands for the all the different levels:<br>
<ul>
<ul>
<li>Level 500: set
<li>Level 450: addchan join part remchan
<li>Level 400: adduser clearmode modinfo remuser status
<li>Level 100: deop invite op suspend unsuspend
<li>Level 75: ban unban
<li>Level 50: kick topic
<li>Level 0: access banlist chaninfo deauth help lbanlist map motd newpass pass showcommands showignore verify<p>
</ul>
</ul>
<img src="reddrop.gif">Some Notes:<br>
<ul>
<ul>
<li>500........... Channel Manager.<p>
<li>450 & 400..... Trusted Administrators. These are ChanOps that the Channel Manager has allowed to help in administrative duties on the channel.<p>
<li>100........... These ChanOps can command X to perform all regular ChanOp commands, including some special X/W commands.<p>
<li>75 & 50....... These ChanOps can command X to perform most regular ChanOp commands (see above list) as well as some special ones.<p>
<li>0............. All users who are not on the bot's user list for that channel. Also, any ChanOp who has a password set, but has not yet msg'd the bot with his/her password will be seen as a level 0 user.<p>
</ul>
</ul>
<blockquote>
NOTE: For "regular" ChanOp commands (ie. kick, ban, unban, op, deop) these levels just allow for the ChanOp to command the bot to do them. Regardless of the ChanOp's level, these commands can still be performed manually by the ChanOp.<p>
</blockquote>
<pre>
For example:
A level 100 ChanOp can op another user either by:
/msg x op #channel nickname
or
/mode #channel +o nickname
A level 50 or level 75 ChanOp can op another user by:
/mode #channel +o nickname
BUT cannot /msg x op as the level 100 can.
</pre>
<p>
10) What does the ? next to a user's ACCESS level mean?<br>
<img src="reddrop.gif">The ? just means that the bot is not sure if the user is on-line. This could mean that either the user is not signed on, or has not given their password to identify themselves yet.<p>
11) What is AUTOOP?<br>
<img src="reddrop.gif">When AUTOOP is set to ON, you will be automatically opped by X upon entering the channel. If you have a password set though, then AUTOOP will only work if you /msg X with your password BEFORE you enter the channel.<p>
<blockquote>
If AUTOOP is set to OFF, you will need to /msg x op #channel yournick for X to op you. Again, if you have a password set, you will need to /msg x with your password before you ask it to op you.<p>
</blockquote>
12) What is PROTECT?<br>
<img src="reddrop.gif">When PROTECT is set to ON, you will be protected by X from other ops banning or deopping you. What this means is that if someone tries to ban or deop you, they will be deopped (even if they are protected also) and X will automatic
ally unban or reop you.<p>
13) Why would I use a password and how do I set one?<br>
<img src="reddrop.gif">A password gives more protection against someone faking your user@host and obtaining ops. If you have a password set, X/W will only recognize you if you have the correct user@host AND give the correct password.<p>
To set your password for the first time:<br>
<ul>
<ul>
<li>/msg x@channels.undernet.org newpass #channel yourpassword
<li>/msg w@channels2.undernet.org newpass #channel yourpassword
</ul>
</ul>
<p>
To change your password:<br>
<ul>
<ul>
<li>Identify yourself first:
<li>/msg x@channels.undernet.org pass #channel currentpassword
<li>/msg w@channels2.undernet.org pass #channel currentpassword
</ul>
</ul>
<p>
Then change it:<br>
<ul>
<ul>
<li>/msg x@channels.undernet.org newpass #channel newpassword
<li>/msg w@channels2.undernet.org newpass #channel newpassword
</ul>
</ul>
<p>
NOTES:<br>
<ul>
<ul>
<li>Once you have sent your password to X once, it will remember who you are until you signoff. Also, if you get caught on the opposite side of a netsplit from X, it will consider you as having signed off and it will forget who you are until you /msg y
our password again.
<li>x@channels.undernet.org and w@channels2.undernet.org are only needed when sending a newpass or a pass command. This was done to ensure that as long as you use the proper command, you will always be sure it is the real X or W when sending your passw
ord. There were too many problems with users taking the nick X or W when one was split, and being able to obtain passwords that way.
<li>If you IRC from a site with a lot of users, eg, a university or a large Internet Service Provider, it is wise to have a password to guard against other people imitating you and causing problems on your channel and with X/W and CService.
</ul>
</ul>
<p>
14) What happens if I can't remember my password?<br>
<img src="reddrop.gif">Your password will have to be reset by any 400 or higher level ChanOp on your channel. Speak to one of them. You can find out who these are by:<p>
<center>
/msg x access #channel -min 400<br>
or<br>
/msg x chaninfo #channel (tells you who the channel manager is)<p>
If you are the Channel Manager, then you will have to get a CService Admin to reset it for you. Ask in #cservice or email cservice@undernet.org
</center>
<p>
15) What is a Hack Script and why can't it be used?<br>
<img src="reddrop.gif">Hack scripts were written by EFnet users to prevent people from "hacking" ops on channels during netsplits. Since the Undernet uses new code for its servers which prevents users from getting ops during a netsplit, these scripts ar
e NOT necessary at all here.<p>
<blockquote>
The reason it can't be used with X or W on a channel is because X and W technically "hack" ops when they join a channel. If an op is running one of these scripts, it will detect this hack and then deop X or W.<p>
</blockquote>
16) What is a protect script and how can it cause problems?<br>
<img src="reddrop.gif">Protect scripts, such as the mIRC Friends List, work similarly to X/W's PROTECT function. CService asks that you please do NOT use these scripts on registered channels. If you have someone on your protect list, and for some reaso
n they get banned/deopped/kicked by X/W, then your script will try to ban/deop/kick (depending upon the script) X/W. This is considered abuse of the Channel Service.<p>
17) What exactly does CService consider abuse?<br>
<img src="reddrop.gif">Any time X or W is kicked, banned and/or deopped, this is considered abuse of the Channel Service. The CService bots are not to be played with. So-called "testing" of the bots is not allowed. Abusing the Channel Service could re
sult in you losing your ops or even being banned from the channel. The channel could also be placed in NoOp mode or even purged if necessary to prevent further abuse.<p>
18) What is NoOp mode?<br>
<img src="reddrop.gif">NoOp mode means that no one except X will be able to have ops on the channel and all kicks/bans must be done through X. Here is where the access level really determines what commands a user can perform.<p>
19) Where can I get more information about X/W and CService?<br>
<img src="reddrop.gif">Online, you can '/msg x help' for help with commands. You can also obtain help from someone in #cservice or any of the CService Admins who happen to be online. If you can't find someone online to help, you can email cservice@unde
rnet.org and someone will respond via email. Also, all CService documents can be obtained from ftp://ftp.undernet.org/pub/irc/docs/cservice/<p>
20) Who are the Channel Service Administrators?<br>
<img src="reddrop.gif">The Channel Service Administrators are users who have administrative access to the Channel Service bots. The CService Admins are volunteers who are committed to making sure the Channel Service is used as it was created to and that
the Channel Service is not abused. CService Admins represent the Undernet Channel Service, as well as the Undernet as a whole.<p>
<img src="reddrop.gif">Below is a list of Administrators as of the time this FAQ was written. If a user comes into your channel claiming to be a CService Administrator or a CService Helper, you may ask them to authenticate themselves to the bot, and the
n you can use:<p>
<center>
/msg x,w verify nickname<p>
</center>
If the user is a true Admin or Helper, you will get a notice from the bot that looks similar to:<p>
<center>
-X- Teal!~friedman@moscow.cse.psu.edu is a trusted CSERVICE admin<p>
If the user is not verifiable by either of the bots, then assume the user is not an Admin or Helper unless a verifiable person can vouch for them.<p>
<hr>
<h3>Current Cservice Administrators</h3>
</center>
** Creator of the Undernet Channel Service<p>
SeKs - <a href="mailto:seks@alias.undernet.org">seks@alias.undernet.org</a><p>
** Channel Service Coordinator<p>
Super - <a href="mailto:super@alias.undernet.org">super@alias.undernet.org</a><p>
** Channel Service Coders<p>
Kev - <a href="mailto:kev@alias.undernet.org">kev@alias.undernet.org</a><br>
WildThang - <a href="mailto:wildthang@alias.undernet.org">wildthang@alias.undernet.org</a><p>
** Channel Service is housed by:<p>
FootPrint - <a href="mailto:footprint@alias.undernet.org">footprint@alias.undernet.org</a> (X)<br>
WildThang - <a href="mailto:wildthang@alias.undernet.org">wildthang@alias.undernet.org</a>(W)<p>
** Senior Administrators<p>
Chaos - <a href="mailto:chaos@alias.undernet.org">chaos@alias.undernet.org</a><br>
Cowboy - <a href="mailto:cowboy@alias.undernet.org">cowboy@alias.undernet.org</a><br>
Footprint - <a href="mailto:footprint@alias.undernet.org">footprint@alias.undernet.org</a><br>
Jini - <a href="mailto:jini@alias.undernet.org">jini@alias.undernet.org</a><br>
Meredith - <a href="mailto:meredith@alias.undernet.org">meredith@alias.undernet.org</a><br>
Morrissey - <a href="mailto:jradford@npl.com">jradford@npl.com</a><br>
Striker - <a href="mailto:striker@alias.undernet.org">striker@alias.undernet.org</a><br>
Teal - <a href="mailto:teal@alias.undernet.org">teal@alias.undernet.org</a><p>
** Administrators<p>
AnElf - <a href="mailto:anelf@alias.undernet.org">anelf@alias.undernet.org</a><br>
BitBT - <a href="mailto:bitbt@alias.undernet.org">bitbt@alias.undernet.org</a><br>
Crip - <a href="mailto:crip@alias.undernet.org">crip@alias.undernet.org</a><br>
Jase - <a href="mailto:jase@alias.undernet.org">jase@alias.undernet.org</a><br>
MatthewA - <a href="mailto:matthewa@alias.undernet.org">matthewa@alias.undernet.org</a><br>
Signe - <a href="mailto:signe@alias.undernet.org">signe@alias.undernet.org</a><p>
<hr>
</center>
Closing Note: If there is anything in this document that needs to be fixed or anything that you feel should be added, please send suggestions to <a href="mailto:teal@alias.undernet.org">teal@alias.undernet.org</a><br>
<hr>
Thanks to the various CService Admins and Helpers for their suggestions.
<hr>
<center>
Undernet Channel Service Committee<br>
Channel Operator's FAQ<br>
Teal!friedman@cse.psu.edu<br>
Version 1.2<br>
3/22/96<p>
</center>
<P>
<HR>
<A HREF="/"><IMG SRC="/files/b_arrow.gif">Back to main page</A>

264
HTTP/cmfaq.html Normal file
View File

@@ -0,0 +1,264 @@
<HTML>
<HEAD><TITLE>Channel Managers' FAQ</TITLE></HEAD>
<BODY bgcolor=#000000 text=ffff00 link=ff0000 vlink=#ff00ff>
<FONT SIZE=4>
<CENTER><H1>Channel Managers FAQ</H1></CENTER>
<HR>
<B>IMPORTANT:</B> The channel service bot users an Undernet service called
Uworld to gain ops on channels. To some scripts/bots (such as Phoenix),
this is considered a nethack. Please ensure that no one uses nethack
protection or hack protection scripts. These scripts deop X/W and are
considered abuse of the Channel service. It is not possible to get ops
off of a netsplit on Undernet. DO NOT DO ANY "TESTING" WITH X/W.
If you have questions send mail or drop by #cservice and the Channel
Service Committee will answer your questions for you.
<P>
<HR><P>
Introduction: This FAQ is to answer general questions that channel
managers may have in regards to the Undernet Channel Service (UCS).
If you don'tknow what the UCS is you should get the Undernet Channel
Service FAQ fromftp.undernet.org in /pub/irc/docs/cservice. In all
examples, we will assume thatthe channel name is #foo, the nick is
foobar, the user@host is foo@test.com.For ease of documentation, X
will be used in all examples, but there are 2 channel service bots, X and W.
<P>
<DL>
<DD><A HREF="#1">I received my confirmation letter from the Channel Service
Committee (CSC), what does this mean?</A></DD>
<DD><A HREF="#2">What are my responsibilities as the channel manager?</A></DD>
<DD><A HREF="#3">How does X know that I am the right person.</A></DD>
<DD><A HREF="#4">So I have access to the the channel, what can I do?</A></DD>
<DD><A HREF="#5">What do you mean "hacked" user@host?</A></DD>
<DD><A HREF="#6">What happens if I have a password set.</A></DD>
<DD><A HREF="#7">I have my access, what now?</A></DD>
<DD><A HREF="#8">What are channel defaults?</A></DD>
<DD><A HREF="#9">X is on my channel, how do I configure it?</A></DD>
<DD><A HREF="#10">What is Massdeop, NickFlood, FloodPro?</A></DD>
<DD><A HREF="#11">What is NoOp and AlwaysOp mode?</A></DD>
<DD><A HREF="#12">How to I add other users to X's oplist?</A></DD>
<DD><A HREF="#13">What are the different levels?</A></DD>
<DD><A HREF="#14">How can I see my userlist?</A></DD>
<DD><A HREF="#15">How can I give someone AUTOOP?</A></DD>
<DD><A HREF="#16">How can I get a second 500 level user?</A></DD>
<DD><A HREF="#17">X used to respond to me, but now it is not, what happend?</A></DD>
<DD><A HREF="#18">I can't be on-line 24 hours a day, how will I know if someone is abusing X on my channel?</A></DD>
<DD><A HREF="#19">So is that it?</A></DD>
</DL>
<P>
<HR>
<P>
<A NAME="1">
<h2>1 - I received my confirmation letter from the Channel Service Committee (CSC), what does this
mean?</h2>
The confirmation letter means you have been added as the channel manager
of the channel that you applied for. If you are anxious and/or having mail
problems you can check if your channel has been added by doing a
/msg x,w chaninfo #channel. This will return a response from both channel
service bots to say wether your channel has been registered or not. Your
channel will only be registered on one of the two bots.
<P>
<HR>
<P><A NAME="2">
<h2>2 - What are my responsibilities as the channel manager?</h2>
As the channel manager, you are responsible for all activities of your
channel including its users and bots. It is recommended that you do not
run other bots on the channel besides X since there is no need for it. X
will always be there and maintains an oplist. You are also
responsible to ensure that none of your channel operators (including bots)
are not running hack protection scripts (such as phoenix). You are also to
ensure that none of your ops deop/kick/ban X. This is considered abuse and
will be dealt with severly and can result in the removal of X from the
channel. "Testing", such as seeing what will happen if X is deop'd,
is considered abuse.
<P>
<HR><P>
<A NAME="3">
<h2>3 - How does X know that I am the right person.</h2>
The Channel Service Committee has added the IRC address that you specified
in your application form to the UCS bot X. To check the user@host that
has been added you can type /msg X access #channel nick. For example:
/msg X access #foo foobar. If your user@host is not correct contact the
CSC by sending mail to cservice@undernet.org or drop by #cservice
and ask.
<P>
<HR><P>
<A NAME="4">
<h2>4 - So I have access to the the channel, what can I do?</h2>
To find out what commands you have access to do a /msg X showcommands #channel.
It is also a good idea to have a password, just in case someone is using
a hacked username and is able to replicate your user@host name.
<P>
<HR><P>
<A NAME="5">
<h2>5 - What do you mean "hacked" user@host?</h2>
Most users with PPP/SLIP access from your site or sites that do not run
identd can have hacked user@host. This means, the user can select the
userid of their choice at any time they wish. In general it is a good idea
to have a password. To setyour password type /msg X newpass password.
For example to make Foobar's password into FooPass1 it would be
/msg X newpass FooPass1.
<P>
<HR><P>
<A NAME="6">
<h2>6 - What happens if I have a password set.</h2>
If you have a password set, X will not recognize you until you send X
your password (even if you have AutoOp set on. You can identify yourself to
X using /msg X pass #channel password. For example: /msg X pass #foo FooPass1X
will return a confirmation message to say that your identification iscorrect.
If you have lost or forgotten your password, contact the CSC and askthem to
reset it for you. Once you have identified yourself once, you should not have
to do it until you log off of IRC. In some instances of netsplits and the
rare occurance that X needs to be restarted, you will need to resend your
password.
<P>
<HR><P>
<A NAME="7">
<h2>7 - I have my access, what now?</h2>
First thing you will want to do is move X onto your channel by sending X
a join message /msg X join #channel. For example: /msg X join #foobar.
To have X leave your channel do a /msg X part #channel. This will not remove
you from the channel service, it will just move X off of the channel. You
can bring X back at any time by sending the join message.
Now you will want to add your channel to X by /msg X addchan #channel.
For example: /msg X addchan #foobar. This will add #foobar to the list of
channels. This will add your channel to the channel database for X which
must be done before anything else.Also this will set up all of the channel's
defaults.
<P>
<HR><P>
<A NAME="8">
<h2>8 - What are channel defaults?</h2>
The channel defaults are X modes such as flood protection level, AlwaysOp,
NoOp, etc... To see what the X settings are for your channel type
/msg X status #channel.
<P>
<HR><P>
<A NAME="9">
<h2>9 - X is on my channel, how do I configure it?</h2>
When X is on the channel you can now configure X for the channel. The
variables the can be set are: MassDeop, NickFlood, FloodPro, NoOp, and AlwaysOp.
<P>
<HR><P>
<A NAME="10">
<h2>10 - What is Massdeop, NickFlood, FloodPro?</h2>
MassDeop is the maximum number of deops one user can do in a 15 second period.
This is an integer value and is set by /msg X set #channel MassDeop #.
For example: /msg X #foo MassDeop 5. NickFlood is the maximum number of
nick changes one user can do in a 15 second period.
This is an integer value and is set by /msg X set #channel NickFlood #.
For example /msg set #foo NickFlood 5. FloodPro is the limit of TOPIC, MODE,
and KICKS that one can send to a channel in a 15 secondperiod. This does
not cover public floods since X is deaf to all public messages to the channel.
This is an integer value set by /msg X set #channel FloodPro #. For example:
/msg X #foo Floodpro 20. Any user surpassing the set levels will be kicked
or deop'd by X.
<P>
<HR><P>
<A NAME="11">
<h2>11 - What is NoOp and AlwaysOp mode?</h2>
NoOp is a special mode where X is the only channel operator. This is an
on/off value that can be set by /msg X set #channel NoOp on/off. AlwaysOp
is a mode that ensures that X will always be an operator. This canbe set
with a /msg X set #channel AlwaysOp on/off. The default for NoOp is Off and
AlwaysOp is On. If a user with access >= 450 deops X, AlwaysOp is turned off
automatically. If a user with access >= 450 kicks X, AlwaysOp is turned off
AND a remchan is issued, so X won't rejoin. NoOp mode can only be reset by the
channel manager.
<P>
<HR><P>
<A NAME="12">
<h2>12 - How to I add other users to X's oplist?</h2>
To add a user to X's oplist you must be at least a 400 level operator on
the channel. If you have the correct access, you can addsomeone by
/msg X adduser #channel nick *!*user@host level password.The pasword and
user@host fields are optional and you may only add someone to a lower level
than you are. For example, if I am foobar with level 500 (channel manager)
and I want to add foo2 who's irc address is foo2@my.own.server with a password
of foopass I would /msg X adduser #foo foo2 *!*foo2@*.own.server 400 foopass
By placing an extra * in the host name creates a larger host mask that will
cover differnet server names that the user may have. However a *!*@* would
be a really bad entry since that covers all users. Be very careful with your
use of the * on the userlist.If there are entries that pose a threat to
X it is considered abuse and will be removed and can result in the complete
removal of X from the channel. If the user is on Undernet at the time that
you are adding them, X will automatically add the wildcards to the user@host
if a /msg X adduser #foo nick level format is used.
<P>
<HR><P>
<A NAME="13">
<h2>13 - What are the different levels?</h2>
When adding someone you can give any level you wish as long as it is less
than your own and it is a positive integer value. However, a user must
have a certain level to gain certain access.
Level 500 - Channel Manager<BR>
>=450 - Trusted Admins (can remove X from the channel)<BR>
>=400 - List administrator, may add users to the userlist<BR>
>=100 - Channel Operator
<P>
<HR><P>
<A NAME="14">
<h2>14 - How can I see my userlist?</h2>
The user list for the channel can be received by/msg X access #channel *
the asterix will show all users that have access on the specified channel.
If you want to check a specific users access type /msg X access #channel nick.
<P>
<HR><P>
<A NAME="15">
<h2>15 - How can I give someone AUTOOP?</h2>
You can give someone autoops on the channel by adding them to the user list
at any level (that is less than yours) and using the modinfo command.
/msg X modinfo #channelname AUTOOP nick ON
This should get the channel service bot to respond and show you the person's
entry in the database reflecting the change. This also applies to PROTECT.
<P>
<HR><P>
<A NAME="16">
<h2>16 - How can I get a second 500 level user?</h2>
In general, there should only be one 500 level user. In some extreme cases
the CSC will allow a second channel manager. If there was more than one 500
level user there can be disputes with the 500 level users which will lead
to problems since all 500 level users have the same access. It is best to
choose one person to be the channel manager and have that person add the
others at level 499. The only command that the level 500 person has is the
set command which is rarely used.
<P>
<HR><P>
<A NAME="17">
<h2>17 - X used to respond to me, but now it is not, what happend?</h2>
One of three things may be occuring. You may have had your access
suspended. Your access can be suspended for deop'ing X, attempting to op
someone that is not allowed to be op'd (banned or suspended user),
banning/kicking X, etc... To see if you have been suspended type
/msg x access #channel mynick Your user@host may also be different. Just
/msg x access #channel mynick to check if your access is correct. Thirdly,
you may need to send X your password if you have one set. If you still
cannot get X to respond, contact the Channel Service Committee.
<P>
<HR><P>
<A NAME="18">
<h2>18 - I can't be on-line 24 hours a day, how will I know if someone is abusing X on my
channel?</h2>
If there is abuse of X and a CSC representative is available, they will join
the channel and warn the users and answer any questions they might have. If
the abuse problem is severe (repeated deop's of X), then the channel will
be placed in NoOp mode and the channel topic will be changed to reflect this.
Only the channel manager can reset this mode. If you find the channel you
manage in NoOp mode, you can assume that there was abuse. This is also a
warning for the channel manager to ensure that their users will not abuse X
in the future.
<P>
<HR><P>
<A NAME="19">
<h2>19 - So is that it?</h2>
No. These are the basics. There are a lot of things in here but there is
still a lot to learn. Managing a channel is not an easy task. Managing
a popular channel is even harder. If you are unsure, please ask.
<P>
<HR>
<A HREF="/"><IMG SRC="/files/b_arrow.gif">Back to main page</A>

400
HTTP/faq.html Normal file
View File

@@ -0,0 +1,400 @@
<HTML>
<HEAD><TITLE>Undernet Channel Service: FAQ</TITLE></HEAD>
<BODY bgcolor=#000000 text=#ffff00 link=#ff0000 vlink=#ff00ff>
<FONT SIZE=4>
<CENTER><H1>Channel Service Frequently Asked Questions</H1></CENTER>
<HR>
<H2>Introduction:</H2>
This file answers some of the most frequently asked questions
regarding the Undernet Channel Service and the X and W bots. If your
question is not answered here, check the sources found in Section 5. If
there is a question that you feel should be in here, send it to
<A HREF="mail:signe@alias.undernet.org">Signe@alias.undernet.org</A>.<P>
<HR>
<H2>Section 1: General UCS/CSC questions</H2><UL>
<LI>1.1 -- <A HREF="#11">What is the UCS/CSC?</A>
<LI>1.2 -- <A HREF="#12">Who owns the UCS/CSC?</A>
<LI>1.3 -- <A HREF="#13">Where is the CSC's office? What is the CSC's phone number?</A>
<LI>1.4 -- <A HREF="#14">Who pays for the CSC? How does the CSC make a profit?</A>
<LI>1.5 -- <A HREF="#15">How can I become a CSC helper/admin?</A>
<LI>1.6 -- <A HREF="#16">How can I tell if someone really is a CSC helper/admin?</A>
<LI>1.7 -- <A HREF="#17">Who are the admins?</A>
</UL>
<H2>Section 2: General X/W Questions</H2><UL>
<LI>2.1 -- <A HREF="#21">What are X and W? What do X and W do?</A>
<LI>2.2 -- <A HREF="#22">How does this differ from any other bot?</A>
<LI>2.3 -- <A HREF="#23">How do X and W differ from each other?</A>
<LI>2.4 -- <A HREF="#24">Why is X so slow sometimes? Why do W and X disappear sometimes?</A>
<LI>2.5 -- <A HREF="#25">Why doesn't the CSC put X/W on a better system?</A>
</UL>
<H2>Section 3: Registration Information</H2><UL>
<LI>3.1 -- <A HREF="#31">Why would I want to register my channel?</A>
<LI>3.2 -- <A HREF="#32">What channels can get X/W onto it?</A>
<LI>3.3 -- <A HREF="#33">How do I get X/W on to a channel?</A>
<LI>3.4 -- <A HREF="#34">Why does the application require supporters?</A>
<LI>3.5 -- <A HREF="#35">Can I have more than one manager?</A>
<LI>3.6 -- <A HREF="#36">What is the registration process?</A>
<LI>3.7 -- <A HREF="#37">Why does registration take so long?</A>
<LI>3.8 -- <A HREF="#38">How can I check to see if my channel has been added?</A>
<LI>3.9 -- <A HREF="#39">It's been more than a month since I sent in my application, and I haven't heard anything from CSC, what should I do?</A>
<LI>3.10 -- <A HREF="#310">What if I have problems (such as a takeover) before my channel is added to X/W?</A>
<LI>3.11 -- <A HREF="#311">My channel is added, what do I do now?</A>
<LI>3.12 -- <A HREF="#312">Can I register more than one channel?</A>
<LI>3.13 -- <A HREF="#313">What if I want to switch channel names?</A>
</UL>
<H2>Section 4: Complaints and Channel Problems</H2><UL>
<LI>4.1 -- <A HREF="#41">How can I complain about X/W being on a channel?</A>
<LI>4.2 -- <A HREF="#42">I don't like the content of a channel with X/W on it, what can I do?</A>
<LI>4.3 -- <A HREF="#43">I was kicked/banned from a channel with X/W on it for no reason, who can I complain to?</A>
<LI>4.4 -- <A HREF="#44">I tried to deop/kick X/W, but I got this message that says I can't do that. Why?</A>
<LI>4.5 -- <A HREF="#45">I deopped/kicked X/W, why did people get on my case about doing that?</A>
<LI>4.6 -- <A HREF="#46">Admins/Helpers say that I deopped/kicked X/W, but I didn't!</A>
<LI>4.7 -- <A HREF="#47">A CSC helper/admin was very rude to me, what can I do?</A>
</UL>
<H2>Section 5: Getting More Help</H2><UL>
<LI>5.1 -- <A HREF="#51">How can I get help for X/W on IRC?</A>
<LI>5.2 -- <A HREF="#52">How can I get a copy of the manager's FAQ?</A>
<LI>5.3 -- <A HREF="#53">How can I get a copy of the Op FAQ?</A>
<LI>5.4 -- <A HREF="#54">Where are the CSC WWW pages?</A>
<LI>5.5 -- <A HREF="#55">What if I have other questions?</A>
</UL>
<H2><A HREF="#60">Section 6: FAQ Credits</A></H2>
<HR><HR>
<CENTER><H2>SECTION 1: General UCS/CSC Questions</H2></CENTER>
<A NAME="11"></A><H2>Question 1.1: What is the UCS/CSC?</H2>
The Undernet Channel Service (UCS), aka the Channel Service
Committee (CSC), is the Undernet committee responsible for the registration
of channels and for handling problems with those channels. It is comprised
of unpaid volunteers who want to help out.<P>
<A NAME="12"></A><H2>Question 1.2: Who owns the UCS/CSC?</H2>
The CSC is not owned by any one person. It is an organization
chartered by the Undernet administrators, and run by the CSC administrators
(see <A HREF="#17">1.7</A>). Currently David Low, aka Super, oversees the CSC.<P>
<A NAME="13"></A><H2>Question 1.3: Where is the CSC's office? What is the CSC's phone number?</H2>
The CSC does not have a physical office or phone number. Some
helpers and admins can be found in channel #cservice on Undernet. All
correspondances should be emailed to cservice@undernet.org<P>
<A NAME="14"></A><H2>Question 1.4: Who pays for the CSC? How does the CSC make a profit?</H2>
The CSC relies solely on the donation of time, disk space, and
services by Undernet administrators. The CSC helpers and admins are not
paid for their time. The disk space and computer time to run X/W are
donated by the respective system administrators. The CSC does not charge
for channel registrations, and therefore does not turn a profit.<P>
<A NAME="15"></A><H2>Question 1.5: How can I become a CSC helper/admin?</H2>
Generally, CSC helpers are people who hang around on #cservice and
help out answering questions. Trusted helpers are those who have been
around for a while, and are trusted by the admins. CSC admins are chosen by
the current administrators, usually from the trusted helpers. If you want
to help out, just join #cservice and start answering questions.<P>
<A NAME="16"></A><H2>Question 1.6: How can I tell if someone really is a CSC helper/admin?</H2>
Trusted helpers and admins can be verified through X/W with one of
the following commands:
/msg X verify nickname
/msg W verify nickname
Sometimes helpers may not be verifiable by this method. You should then ask
#cservice if they are truly a helper. If you have the slightest doubt about
someone's claim to be a helper or admin, do not hesitate to check it out. If
you find that someone is impersonating a CSC admin, please report it to
#cservice.<P>
<A NAME="17"></A><H2>Question 1.7: Who are the admins?</H2>
Currently, the list of CSC admins is as follows: Super, Seks, cowboy,
meredith, Morrissey, Chaos, Teal, jini, Jase, Signe, and AnElf<P>
<HR>
<CENTER><H2>SECTION 2: General X/W Questions</H2></CENTER>
<A NAME="21"></A><H2>Question 2.1: What are X and W? What do X and W do?</H2>
X and W are the CSC bots, written by Seks. One of these is assigned
to each registered channel. For each channel, these bots maintain a
userlist, which specifies who has what access and who should be opped, and a
banlist, which specifies who to ban from joining the channel (or from
getting ops), and for how long. They are designed to keep a channel open 24
hours a day, and prevent channel takeovers.<P>
<A NAME="22"></A><H2>Question 2.2: How does this differ from any other bot?</H2>
X and W are actually each servers, not just bots. They are allowed
to work this way because they are run by the Undernet administration. This
allows them to do several special functions, such as regaining ops if ops
are lost. Also, each bot is on a large number of channels. By having one
bot for many channels, this reduces the load on the Undernet network that
would be caused by having one separate bot on each channel.<P>
<A NAME="23"></A><H2>Question 2.3: How do X and W differ from each other?</H2>
There is no difference between X and W as far as the commands and
services availible is concerned. The only differences are that X and W each
run on separate computer systems and networks, and each one handles a
different list of channels. The bots are assigned to registered channels at
random.<P>
<A NAME="24"></A><H2>Question 2.4: Why are X/W slow sometimes? Why do X/W disappear sometimes?</H2>
Just like any other bot or user on Undernet, X and W are subject to
lag and netsplits caused by bad connections between Undernet servers. This
can cause X and W to slow down drastically (sometimes up to 5 minutes lag),
and even disappear. If this happens, please be patient. Be assured that
Undernet and CSC admins are working to get them back to normal as quickly as
possible in the event of a problem.<P>
<A NAME="25"></A><H2>Question 2.5: Why doesn't the CSC put X/W on a better system?</H2>
X and W each require a lot of disk space and computer resources.
And on top of this, they need to be run on a machine that is an Undernet
server. Currently, the system administrators of irc.ucdavis.edu
(davis.ca.us.undernet.org) and irc.wildstar.net (okc.ok.us.undernet.org)
are donating the neccessary resources. While it is possible to move X and
W, it is not feasible, as there is not another system to move one of them to
right now, and moving them involves a lot of time and work.<P>
<HR>
<CENTER><H2>SECTION 3: Registration Information</H2></CENTER>
<A NAME="31"></A><H2>Question 3.1: Why would I want to register my channel?</H2>
Registration not only provides you with the ability to keep your
channel open 24 hours a day, it also gives the channel stability. In the
case of a channel takeover, the manager always has ultimate control to
regain the channel. Also, it provides you with a way to have users
auto-op'd, and a more permanent banlist.<P>
<A NAME="32"></A><H2>Question 3.2: What channels can get X/W onto it?</H2>
Almost any Undernet channel can be registered. The only types of
channels that are currently excluded are warez-type channels, and channels
dealing with child pornography, although the CSC admins do reserve the right
to reject any channel registration for any reason that they deem valid. Do
not try to change the name of one of these types of channels, or try and
conceal the channel activity, as CSC has many ways of finding out the true
uses of a channel.<P>
<A NAME="33"></A><H2>Question 3.3: How do I get X/W on to a channel?</H2>
To get X/W onto your channel, the channel must be registered. In
order to do this, you must first have some consensus on the channel as to
who will be the channel manager. Then you must have 10 supporters.
Supporters are people who frequent your channel (not neccessarily ops), and
want you to register it. Once you have these two things, you need to fill
out the registration form, which you can get <A
HREF="/files/X_registration_form.txt">on WWW</A> or on IRC by doing:
"/msg Helpbot get XForm" Once you have filled out the application, email it
to cservice@undernet.org
<A NAME="34"></A><H2>Question 3.4: Why does the application require supporters?</H2>
Supporters are required because the CSC only registers established,
well used channels. By requiring supporters, CSC can know that there are at
least 10 people who use this channel. It also prevents users with malicious
intents from taking over a channel by registering it out from under the true
users of the channel.<P>
<A NAME="35"></A><H2>Question 3.5: Can I have more than one manager?</H2>
The CSC frowns greatly on multiple channel managers. This is
because in the case of a dispute between channel managers, there is no way
for CSC to mediate. Multiple managers are only allowed in extreme
circumstances, and to have more than one manager you must petition
cservice@undernet.org with the reasons.<P>
<A NAME="36"></A><H2>Question 3.6: What is the registration process?</H2>
After your registration form is received by the CSC, it is grouped
together with all the applications that come in withing the same 1 or 2 week
span as it. These are compiled into a pre-registration list which is then
posted to the cservice mailing list, and the alt.irc.undernet newsgroup.
This is the posting period, and it lasts for 1 week. During this time CSC
watches for any objections to the registration. If there are some, they are
evaluated by CSC, and if deemed valid, the registration is rejected. If
there are no objections, your channel goes into a list of channels waited to
be added to X/W. At this point you are emailed saying that your
registration has been accepted, and you are also sent a copy of the
manager's FAQ. Within 1 to 1 1/2 weeks after you receive your acceptance
letter, you channel will be added to X/W, and you may begin configuring
whichever one you are assigned.<P>
<A NAME="37"></A><H2>Question 3.7: Why does registration take so long?</H2>
Every week, there are many registrations to be processed. Some
weeks there are over 250 applications. Each of these applications must be
checked for completeness, checked to see if it is already registered, and
then compiled into the pre-registration list. Then the posting period must
pass, objections must be evaluated, and a final registration list compiled.
All of this work is done by one CSC admin, who is a volunteer who has other
things to do, such as work or school. After this final list is compiled, it
must be reviewed by the admins, and then they must make time to add all the
channels, which is a time consuming task. This is why the registration
process takes so long.<P>
<A NAME="38"></A><H2>Question 3.8: How can I check to see if my channel has been added?</H2>
You can check to see if your channel has been added to X or W by
typing the following commands to check both bots:<UL>
<LI>/msg X chaninfo #yourchannel
<LI>/msg W chaninfo #yourchannel</UL><P>
<A NAME="39"></A><H2>Question 3.9: It's been more than a month since I sent in my application, and I haven't heard anything from CSC, what should I do?</H2>
If you do not hear anything from CSC, one of several things may have
happened:<UL>
<LI>1) Your application may never have arrived, or may have been lost
<LI>2) There could be some backups on registrations causing them to take longer than a month
<LI>3) Your channel could have been rejected and you missed the email telling you this.</UL>
So if a month has passed, and you have not heard anything, your best bet is
to resend your application, and put a note at the top stating that the
application was submitted over a month ago, and you have not heard anything
back from CSC, so could someone kindly tell you what the status of your
application is.<P>
<A NAME="310"></A><H2>Question 3.10: What if I have problems (such as a takeover) before my channel is added to X/W?</H2>
Because your channel is not technically a registered channel until
it is actually added to X or W, there is nothing that CSC or #cservice can
do to help you with channel problems at this point. You need to talk to an
IRCOp, which you can find on #wasteland, and ask them if they will help you
out.<P>
<A NAME="311"></A><H2>Question 3.11: My channel is added, what do I do now?</H2>
Congratulations, you are now a channel manager. The channel
manager's FAQ, which you will have received by email before now, will tell
you how to set up the channel and userlist. Please read the manager's FAQ
thoroughly.<P>
<A NAME="312"></A><H2>Question 3.12: Can I register more than one channel?</H2>
Each user is allowed to register one channel. They may, in addition
to this channel, register a help channel that provides assistance to users
for things such as: Software products, Internet services, Internet Service
Providers. If you are unsure if you channel falls under this category,
email cservice@undernet.org and ask. ("Each user" is defined as a person,
not as an email address. If you have multiple email addresses, you may not
register multiple channels. One channel, and optionally one help channel,
per person)
<A NAME="313"></A><H2>Question 3.13: What if I want to switch channel names?</H2>
Since the registration is for the channel, there is no provision for
changing channel names. If you wish to do this, you must fill out a new
application for the new channel and submit it, following the normal
registration process. At the top of your application, write a note saying
that your are the channel manager of #youroldchannel and would like to have
it purged from the registered channels list in order to register a different
channel.<P>
<HR>
<CENTER><H2>SECTION 4: Complaints and Channel Problems</H2></CENTER>
<A NAME="41"></A><H2>Question 4.1: How can I complain about X/W being on a channel?</H2>
If you think you have a valid reason why X/W should not be on a
registered channel (see <A HREF="42">4.2</A>), such as the manager is never
around, or it is a warez or child pornography channel, you can email your
complaint to <A HREF="mail:cservice@undernet.org">cservice@undernet.org</A>.
If there is a lot of support for your complaint, please include the email
addresses and nicks of those who support you in your letter (do NOT have
everyone send a separate letter). The CSC admins will evaluate your
complaint, and if it is valid, action will be taken.<P>
<A NAME="42"></A><H2>Question 4.2: I don't like the content of a channel with X/W on it, what can I do?</H2>
Because CSC does not consider content during the registration
process, excepting warez and child porn channels, there is nothing you can
do about this. The CSC specifically disclaims responsibility for the
content of a channel, and the way the manager chooses to run the channel, as
it would be an overwhelming task for CSC to police every registered
channel.<P>
<A NAME="43"></A><H2>Question 4.3: I was kicked/banned from a channel with X/W on it for no reason, who can I complain to?</H2>
As stated in 4.2 above, the CSC has no reponsibility for, nor say
over how a manager, and those he gives operator status to, choose to run the
channel. A channel operator can kick and/or ban someone for any reason they
choose, or no reason at all. Therefore there is noone taht you can complain
to about this except the people who run that specific channel (the
manager).<P>
<A NAME="44"></A><H2>Question 4.4: I tried to deop/kick X/W, but I got this message that says I can't do that. Why?</H2>
Because X and W are Undernet services that exist to provide
stability to registered channels, the Undernet and CSC admins have chosen to
modify the Undernet servers to make it so that X and W cannot be kicked or
deopped. By doing this, the stability of registered channels is greatly
increased, and the load on the Undernet IRC network is decreased. This
modification is in effect on some, but not all, Undernet servers at this
point in time.<P>
<A NAME="45"></A><H2>Question 4.5: I deopped/kicked X/W, why did people get on my case about doing that?</H2>
As stated in 4.4 above, X and W exist to provide channel stability.
When they are deopped or kicked, their ability to maintain the channel is
disrupted, in addition to the fact that this places an extra load on the
Undernet network. For this reason, these actions are responded to by CSC
admins and/or helpers so that it will not happen again. If X/W is
repeatedly deopped and kicked on a channel, that channel can be removed from
the registered channels list, and X/W removed from the channel.<P>
<A NAME="46"></A><H2>Question 4.6: Admins/Helpers say that I deopped/kicked X/W, but I didn't!</H2>
If a CSC admin or helper comes onto a channel and says that you
kicked or deopped X/W, they are going to be right 99% of the time. It is
possible that you are running scripts or remotes that have deopped or kicked
X/W without your knowledge. If this is the case, explain to the admin or
helper that you did not deop/kick X/W consciously, and they will probably be
able to help you fix your script or remote so that it does not happen
again.<P>
<A NAME="47"></A><H2>Question 4.7: A CSC helper/admin was very rude to me, what can I do?</H2>
If you think an admin or helper was unnecessarily rude or abusive
towards you, please make sure you have a log of the incident. Email this
log, and a note explaining the situation, to cservice@undernet.org. The
admins will read and evaluate the situation, and respond accordingly.<P>
<HR>
<CENTER><H2>SECTION 5: Getting More Help</H2></CENTER>
<A NAME="51"></A><H2>Question 5.1: How can I get help for X/W on IRC?</H2>
The CSC maintains a help channel on Undernet called #cservice.
There are helpers and/or admins on this channel almost all the time.
However, please make sure you have checked this FAQ, and the Op FAQ before
asking a question there. If there is noone there to answer your question,
you can email it to <A
HREF="mail:cservice@undernet.org">cservice@undernet.org</A>.<P>
<A NAME="52"></A><H2>Question 5.2: How can I get a copy of the manager's FAQ?</H2>
The manager's FAQ is availible several ways:<UL>
<LI>1) On IRC: The Manager's FAQ is availible via DCC from Helpbot. Just
type: "/msg Helpbot get Xfaq.manager"
<LI>2) On WWW: The Manager's FAQ is availible <A
HREF="/files/cmfaq.html">here</A>
<LI>3) By FTP: The Manager's FAQ is availible on the Undernet FTP server at
<A HREF="ftp://ftp.undernet.org/pub/irc/docs/cservice/Xfaq.managers">
ftp.undernet.org</A>, or its mirror at
<A HREF="ftp://ftp2.undernet.org/pub/irc/docs/cservice/Xfaq.managers">
ftp2.undernet.org</A>.</UL>
<A NAME="53"></A><H2>Question 5.3: How can I get a copy of the Op FAQ?</H2>
The Op FAQ is availible several ways:<UL>
<LI>1) On IRC: The Op FAQ is availible via DCC from Helpbot. Just type:
"/msg Helpbot get Xfaq.op"
<LI>2) On WWW: The Op FAQ is availible <A HREF="files/opfaq.html">here</A>
<LI>3) By FTP: The Op FAQ is availible on the Undernet FTP server at
<A HREF="ftp://ftp.undernet.org/pub/irc/docs/cservice/Xfaq.op">
ftp.undernet.org</A>, or its mirror at
<A HREF="ftp://ftp2.undernet.org/pub/irc/docs/cservice/Xfaq.op">
ftp2.undernet.org</A>.</UL>
<A NAME="54"></A><H2>Question 5.4: Where are the CSC WWW pages?</H2>
CSC maintains 2 WWW pages, one for X, and one for W. On these
pages, besides getting information about CSC and X/W, you can access channel
userlists, banlists, chaninfo, and perform a whois search on Undernet.
These pages are located at:<UL>
<LI>X -- <A HREF="http://irc.ucdavis.edu:7357">http://irc.ucdavis.edu:7357</A>
<LI>W -- <A HREF="http://irc.wildstar.net:7357">http://irc.wildstar.net:7357</A></UL>
<A NAME="55"></A><H2>Question 5.5: What if I have other questions?</H2>
If none of these methods work, and you still have questions, feel
free to email them to <A HREF="mail:cservice@undernet.org">cservice@undernet.org</A><P>
<HR>
<A NAME="60"></A><CENTER><H2>SECTION 6: FAQ Credits</H2></CENTER>
This FAQ was composed by Todd Palino (Signe). Some of the questions were
gathered from the original Xfaq.general.<P>
All comments, quips, quotes, and additions should be sent to
<A HREF="mail:signe@alias.undernet.org">Signe@alias.undernet.org</A>
<HR>
<A HREF="/"><IMG SRC="/files/b_arrow.gif">Back to main page</A>

228
HTTP/guidelines.html Normal file
View File

@@ -0,0 +1,228 @@
<html>
<head><title>Undernet Channel Service: Guidelines</title></head>
<body bgcolor=#000000 text=#ffff00 link=#ff0000 vlink=#ff00ff>
<font size=4>
<CENTER><H1>The Undernet Channel Service Guidelines</H1></Center>
<pre>
Revised: May 12, 1995
</pre>
<HR><HR><P>
<H2> History & Ethos of The Channel Service</H2>
Thanks to a lot of work by Seks and the rest of the Undernet IRCops,
Undernet now has a channel service. This service will allow users to run a
channel without running a bot. This service replaces the need for a bot on
a channel.<P>
This channel service gives the opportunity to users to manage a channel.
This is *not* ownership because the service will only be placed on the
channel if that there is a general demand for. It cannot be used in
channel wars/op wars or in an attempt to end "take over" a channel.
<P>
The Channel Service works the same way that a bot works. It can control
all channel modes (including ops). One advantage that the service has is
if ops are lost either due to someone messing up and deop'ing everyone (or
a flooder/hacker doing it intentionally) then the bot can use Uworld
(special Undernet service) and regain ops.
<P>
The Channel Service has many different modes. AlwaysOp will ensure that
the bot always has ops. If ops are ever lost or the bot is unable to join
the channel then the bot will use Uworld to gain access. NoOp mode will
make it so the Channel Service is the only Op on the channel. All kicks,
bans, topic, etc have to be made through the bot. Mode changes still need
to be done manually. The bot also has flood protection against nick, kick,
topic and mode changes to ensure that channel flooders are not a problem.
<P>
The Channel Service retains a userlist for every channel that it is
registered on. The manager of the channel (person who registered the
channel) controls the list for that particular channel.
<P>
<HR><P>
<center><h2> Committee Guidelines</h2></center>
<h3> Structure of committee, and general aims</h3>
<DL>
<DD>(i) The Channel Service committee is a sub committee of User-com (Undernet
user committee).</DD>
<DD> (ii) The CSC (Channel Service Committee) are in charge of administrating
the channel service</DD>
<DD> (iii) The CSC Will (a) NOT enter into discussions on how a channel is run
(b) mediate upon discussions of channel managers.</DD>
<DD> (iv) The CSC will only register 1 channel per USER (this means user, not
account or e-mail address). This rule may be relaxed at the
discretion of the committee for special channels which provide a
service, such as help channels.</DD>
</DL>
<HR><P>
<h3> Committee Procedure</h3>
<DL>
<DD><h4> Standard Registration:</h4></DD>
<DL>
<DD>(i) Applications are review once per week by the CSC to ensure the
proper information has been included. A response letter is sent
to the applicant acknowledging the application when it is
reviewed.</DD>
<DD> (ii) The committee will send a weekly posting to alt.irc.undernet of
registration requests, for public viewing.</DD>
<DD> (iii) Provided there is no objections the channel service will be moved into
place on a trial basis, of 14 days. After which it will be
permanent, subject to the standard review procedures. The CSC will
post an FAQ to the manager.</DD>
<DD> (iv) The CSC will add the channel to the listing of channels that are
covered by the Channel service (ftp site ca.undernet.org in
pub/undernet) and changes to the document will be posted to cservice
on a regular basis.</DD>
</DL>
<DD><h4> Objections</h4></DD>
<DL>
<DD>(i) Users have 14 days in which to make an objection to the Channel
Service being placed on a channel</DD>
<DD> (ii) All objections will be considered by the committee. The CSC chall
invoke the following procedures:<BR><DL>
<DD> (a) remove the bot from the channel while discussions take
place</DD>
<DD>(b) attempt mediation between the objectors and the registered
owner.</DD><DL>
<DD>(i) by trying to put them into contact with each
other</DD>
<DD> (ii) by helping if requested to with discussions.</DD>
</DL>
<DD> (c) if mediation fails, the BOT will NOT be placed on the Channel.</DD><DL>
<DD> - a new application may be made in 2 months, but will not be
considered before then.</DD>
<DD> - the committee will suggest that a channel under a different
name be registered.</DD>
</DL></DL></DD>
<DD> (iii) if an objection is received after that time; the CSC will consider
it if:<DL>
<DD> (a) it is supported by a reasonable number of users (min. 10 - more
for larger channels)</DD>
<DD> (b) has reasonable grounds.
A valid objection will be dealt with in the same way as for (ii)
above; but with the presumption that if the objector cannot
substantiate the claim sufficiently, then the bot will
>tay.</DD></DL></DD>
<DD> (iv) The decision of the CSC in all these matters is Final.</DD>
<P>
</DL></DL>
<HR><P>
<h3> Registering a channel</h3>
<DL>
<DD>(i) Make sure that you have read these guidelines carefully, and are
willing to use the channel service (X) in conjunction with the
rules of use.</DD>
<DD> (ii) Fill out the form below (copy available by anonymous ftp to:
ca.undernet.org:/pub/undernet/CS</DD>
<DD> (iii) Post this to cservice@undernet.org</DD>
<pre>
###########################################################################
## E-MAIL COMPLETED FORM TO cservice@undernet.org ##
###########################################################################
1) Your Name :
2) The usual nick you use :
3) Your E-mail address :
4) The user@host that you use on irc :
{if different from your e-mail address}
5) Channel Name:
6) Purpose of channel:
{brief description}
7) Supporter's list:
-------------------------------------------------------------------------
Nickname | E-mail address
-------------------------------------------------------------------------
1)
2)
3)
4)
5)
6)
7)
8)
9)
10)
Please note, to register your channel, you need 10 supporters
###########################################################################
</pre>
</DL>
<HR><P>
<h3> Rules:</h3>
<DL>
<DD>(i) All e-mail addresses that are used on IRC and at least one mail
address that the applicant can be reached at should be included. If a
hacked user@host is used on IRC, a valid mail address is necessary.</DD>
<DD> (ii) At least 10 supporters are needed for the request to be processed.
The supporters need to be included on the application with nick and
e-mail addresses. </DD>
<DD> (iii) Any abuse of the channel service by the channel manager will result
in the immediate removal of the service. Any abuse of other users will
result in their refusal of the service to that user. The above includes
anyone "testing". If testing is required, there is a test network of
Undernet servers that can be used. If a CSC administrator finds
that the Channel Service is being abused in any way, they may remove
the channel service from the channel immediately and relay any
necessary information to other CSC members and contact the manager
of the channel immediately with the reason for the removal. The
removal will be open to immediate review by the CSC to ensure that
the service was abused and to decide if the Channel Service should
be returned the channel or not. </DD>
<DD> (iv) Please ensure that channel operators and/or bots on the registered
channel are not running netsplit hack protection because they will
get into an opwar with X. This is considered abuse and can result in
the removal of the channel service. X will always win in an
opwar.</DD>
<DD> (v) The registered channel manager must appear on the channel once every 3
weeks. If the CSC is notified of a prolonged absence a the channel
- managing may be transferred for the intermittant period. Any abuse
of the Channel Service done by the temporary channel manager will be
both the responsibility of the channel manager and the temporary
manager.</DD>
<DD> (vi) The Channel Service will be removed from any channel that has low
traffic. Channel not being used or only has less than 5 regular
users (open to discretion).</DD>
</DL>
<HR><P>
<h3> Disclaimer</h3>
The Channel Service will not be responsible for any activity that occurs
on the channel. Anything that occurs on the channel are the
resposibilities of the people involved and has nothing to do with the
Channel Service, its administrators and the Undernet as a whole, including
the Operators that run it. The guidelines may change without notice.<P>
- Original CSC Guidelines<BR>
- Amended by Super<BR>
- This Draft #Ox.1<BR>
- html by striker<BR>
<HR>
<A HREF="/"><IMG SRC="/files/b_arrow.gif">Back to main page</A>

BIN
HTTP/hline.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

105
HTTP/index.html.dist Normal file
View File

@@ -0,0 +1,105 @@
<HEAD>
<TITLE>Undernet Channel Service</TITLE>
</HEAD>
<BODY BGCOLOR=#000000 TEXT=#FFFF00 LINK=#FF0000 VLINK=#FF00FF>
<FONT SIZE=4>
<CENTER><H1>The Undernet Channel Service Page</H1>
<IMG SRC="/files/hline.gif"
ALT="===================================================================="><P>
<B><I>Welcome! This page provides Undernet users of the Channel
Service bot with a familiar, easy to use WWW interface to its
databases. It is still in construction, and more services will be
added to it as time goes by, but you may find it useful
already.</I></B><P></CENTER>
<HR>
To access X's database, use <A HREF="http://irc.direct.ca:7357/">http://irc.direct.ca:7357/</A><BR>
To access W's database, use <A HREF="http://www.wildstar.net:7357/">http://www.wildstar.net:7357/</A><BR>
<HR>
<H2>General information</H2>
<DL>
<DD><IMG SRC="/files/reddrop.gif" ALT="*">
<A HREF="/files/guidelines.html">The Channel Service Committee Guidelines</A>
</DD>
<DD><IMG SRC="/files/reddrop.gif" ALT="*">
<A HREF="/files/faq.html">The Channel Service FAQ</a>
</DD>
<DD><IMG SRC="/files/reddrop.gif" ALT="*">
<A HREF="/files/cmfaq.html">The Channel Managers' FAQ</a>
</DD>
<DD><IMG SRC="/files/reddrop.gif" ALT="*">
<A HREF="/files/chanopfaq.html">The Channel Operators FAQ</a>
<DD><IMG SRC="/files/reddrop.gif" ALT="*">
<A HREF="/files/X_registration_form.txt">Channel Service Application Form</a>
</DD>
<DD><IMG SRC="/files/reddrop.gif" ALT="*">
<A HREF="mailto:cservice@undernet.org">Send Email to the Channel Service Mailing List</A>
</DD>
</DL>
<HR>
<H2>User list management</H2>
Manage or consult your channel's user list from the comfort of your
favorite WWW-browser. This feature will allow you to view the complete
list of users on the channel you specify. Just enter the channel name
into the blank and click on "Go baby!"<P>
<FORM METHOD="POST" ACTION="/userlist/">
<B>Enter the channel name: </B><INPUT NAME="CHANNEL" TYPE="TEXT" SIZE=30 MAXLENGTH=80>
<INPUT TYPE="SUBMIT" VALUE="Go baby!">
</FORM>
<HR>
<H2>Ban list management</H2>
Same as the above, but this time for the ban list. Just enter the channel
name into the blank and click on the "Go baby!"<P>
<FORM METHOD="POST" ACTION="/banlist/">
<B>Enter the channel name: </B><INPUT NAME="CHANNEL" TYPE="TEXT" SIZE=30 MAXLENGTH=80>
<INPUT TYPE="SUBMIT" VALUE="Go baby!">
</FORM>
<HR>
<H2>Channel information</H2>
Obtain the information X/W has stored in its databases with regards to
the channel you specify. This is an interesting way to find out
whether your channel has been registered. :) Again, just enter the
channel name in the blank field and click on "Go Baby!".<P>
<FORM METHOD="post" ACTION="/chaninfo/">
<B>Enter the channel name: </B><INPUT NAME="CHANNEL" TYPE="TEXT" SIZE=30 MAXLENGTH=80>
<INPUT TYPE="SUBMIT" VALUE="Go baby!">
</FORM>
<HR>
<H2>/WHOIS on the web!</H2>
Find out if your friends (or enemies) are currently signed on to
Undernet IRC. This works just like the IRC /WHOIS command. Just
supply a nick and click on "Go Baby!"<P>
<FORM METHOD="post" ACTION="/whois/">
<B>Please enter a nick: </B><INPUT NAME="NICK" TYPE="TEXT" SIZE=30 MAXLENGTH=80>
<INPUT TYPE="SUBMIT" VALUE="Go Baby!">
</FORM>
<HR>
<H2>Online HELP files!</H2>
You can access the channel service HELP files from this page. All you
have to do is enter a command and then click on "Go Baby!"<P>
<FORM METHOD="post" ACTION="/HELP/">
<B>Please enter a command: </B><INPUT NAME="ARG" TYPE="TEXT" SIZE=30 MAXLENGHT=80>
<INPUT TYPE="SUBMIT" VALUE="Go Baby!">
</FORM>
<HR>
<H2>Undernet Resources</H2>
Undernet offers several services via the World Wide Web. These few
sites offer a good jumping off point to several of them.<P>
<DL>
<DD><IMG SRC="/files/reddrop.gif" ALT="*"><A
HREF="http://www2.undernet.org:8080/~cs93jtl/Undernet.html">The Official
Undernet Page</A></DD>
<DD><IMG SRC="/files/reddrop.gif" ALT="*"><A
HREF="http://undernet.infowest.com/index.html">Aaron Gifford's Undernet
Page</A></DD>
<DD><IMG SRC="/files/reddrop.gif" ALT="*"><A
HREF="http://aslan.pr.mala.bc.ca/~warren/usercom.html">The Undernet
User Committee Home Page</a></DD>
<DD><IMG SRC="/files/reddrop.gif" ALT="*"><A
HREF="/files/links.html">Links to other pages</A></DD>
</DL>
<HR>
<FONT SIZE=3>
<I>This page is brought to you by the administrators of the <a
href="mailto:cservice@undernet.org">Undernet Channel Service
Committee</a>.</I>
</BODY>

40
HTTP/links.html Normal file
View File

@@ -0,0 +1,40 @@
<HEAD>
<TITLE>Undernet Channel Service: Links</TITLE>
</HEAD>
<BODY BGCOLOR=#000000 TEXT=#FFFF00 LINK=#FF0000 VLINK=#FF00FF>
<FONT SIZE=4>
<CENTER><H1>Links to other pages</H1></CENTER>
<I>If you would like to add links on this page, please contact
<a href="mailto:seks@alias.undernet.org">seks@alias.undernet.org</a></I>
<P>
<B>Not responsible for content!</B>
<HR>
<A HREF="http://www.lookup.com/homepages/82867/home.html">Alpine's Page</A><BR>
<A HREF="http://www.geocities.com/siliconvalley/2894">Amy's Homepage on the WWW!</A><BR>
<A HREF="http://www.calweb.com/~blakice/bworld.html">BlackWorld HomePage</A><BR>
<A HREF="http://w3.one.net/~fostbt/">Brent Foster's Home Page</A><BR>
<A HREF="http://www.cse.psu.edu/~friedman/">Elise's Home Page</A><BR>
<A HREF="http://www.voyageur.ca/~emcintyre">Erin's page of Junk</A><BR>
<A HREF="http://www.pla-net.net/~reaper/ircnewbies/">#ircnewbies Channel Web Page</A><BR>
<A HREF="http://web.mit.edu/klmitch/www/home.html">Kevin Mitchell's Home Page</A><BR>
<A HREF="http://www.vt.com/~ozz/">Land Of Ozz</A><BR>
<A HREF="http://www.kluge.net/~godboy">#MacUnderground Home page</A><BR>
<A HREF="http://www.infomatch.com/~phillip/newbies.html">#Newbies Channel Web Page</A><BR>
<A HREF="http://soho.ios.com/~capjanwy/capt.html">#ReadyRoom Home Page</A><BR>
<A HREF="http://www.undergrad.math.uwaterloo.ca/~dglow/">Super's Home Page!!!!</A><BR>
<A HREF="http://www.voyageur.ca/~emcintyre/teen/">#Teen Channel Web Page</A><BR>
<A HREF="http://www.voicenet.com/~terabyte/">Terrabyte's Homepage</A><BR>
<A HREF="http://www.cloud9.net/aolsucks/">Why AOL Sucks</A><BR>
<A HREF="http://antietam.nssl.uoknor.edu/mosaic_files/mitchell/">WildThang's Personal Home Page</A><BR>
<A HREF="http://www.mindspring.com/~phiend">(Untitled)</A><BR>
<A HREF="http://www.azstarnet.com/~bluedog/bestbet/">#13-17BestBet Homepage</A><BR>
<A HREF="http://users.twave.net/bmrbeal/">#13-17Regz Homepage</A><BR>
<P>
<A HREF="http://www.yahoo.com/Computers_and_Internet/Internet/Chatting/IRC/Undernet/">
Yahoo - Computer and Internet:Internet:Chatting:IRC:Undernet</A><BR>
<A HREF="http://guide-p.infoseek.com/WW/NS/Titles?qt=IRC+UNDERNET&col=WW">
InfoSeek Guide Search: IRC UNDERNET</A><BR>
<HR>
<A HREF="/"><IMG SRC="/files/b_arrow.gif">Back to main page</A>
</BODY>

BIN
HTTP/reddrop.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

97
Makefile Normal file
View File

@@ -0,0 +1,97 @@
# Undernet Channel Service (X)
# Copyright (C) 1995-2002 Robin Thellend
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# The author can be contact by email at <csfeedback@robin.pfft.net>
#
# Please note that this software is unsupported and mostly
# obsolete. It was replaced by GNUworld/CMaster. See
# http://gnuworld.sourceforge.net/ for more information.
#
CC = gcc
RM = /bin/rm
CFLAGS = -Wall -g -O0
#CFLAGS = -O6
#DEFINES = -DDEBUG
#DEFINES = -DBACKUP
#DEFINES = -DDEBUG_MALLOC -DHISTORY
#DEFINES= -DHISTORY
DEFINES=
# necessary for Solaris
#LIBS = -lsocket -lnsl
OBJECTS = bans.o buffer.o channels.o chat.o conf.o connect.o dbio.o debug.o \
defchan.o events.o floodpro.o help.o http.o ignore.o kicks.o \
match.o modes.o nick.o opcom.o ops.o patch.o privmsg.o \
replies.o servers.o shitlist.o socketio.o special.o userlist.o \
users.o version.o
SOURCES = bans.c buffer.c channels.c chat.c conf.c connect.c dbio.c debug.c \
defchan.c events.c floodpro.c help.c http.c ignore.c kicks.c \
match.c modes.c nick.c opcom.c ops.c patch.c privmsg.c \
replies.c servers.c shitlist.c socketio.c special.c userlist.c \
users.c version.c
MAKE = make -f Sources.mak 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'DEFINES=${DEFINES}'\
'LIBS=${LIBS}' 'SOURCES=${SOURCES}' 'OBJECTS=${OBJECTS}'\
'RM=${RM}'
all: cs fixdb showdb show_old_managers
@echo 'All Done! :)'
cs: dummy
@echo "Making cs..."
@if [ -f cs ] ; then \
mv -f cs cs.old; \
sleep 1; \
fi
@cd Sources; ${MAKE}; cd ..;
list: dummy
@echo "Making list..."
@cd Sources; ${MAKE} list; cd ..;
listall: dummy
@echo "Making listall"
@cd Sources; ${MAKE} listall; cd ..;
fixdb: dummy
@echo "Making fixdb"
@cd Sources; ${MAKE} fixdb; cd ..;
showdb: dummy
@echo "Making showdb"
@cd Sources; ${MAKE} showdb; cd ..;
show_old_managers: dummy
@echo "Making show_old_managers"
@cd Sources; ${MAKE} show_old_managers; cd ..;
clean: dummy
@cd Sources; ${MAKE} clean; cd ..;
$(RM) -f core cs list listall cs.log *.bak
depend: dummy
@cd Sources; ${MAKE} depend; cd ..;
love:
-@echo "With you?? dream on! :P"
dummy:

50
README Normal file
View File

@@ -0,0 +1,50 @@
Undernet Channel Service (X)
Copyright (C) 1995-2002 Robin Thellend
This is the original Channel Service software that was used
on Undernet from 1995 to 2001.
For copying and licensing information, please see COPYING in
this directory.
This software is mostly obsolete now. It has been replaced
by GNUworld/CMaster, which can be found at:
http://gnuworld.sourceforge.net/
This software is unsupported, which means I have no intention
of ever releasing a new version. It is provided mainly for
educational and historical purposes.
I used this code on many different platforms, including
Solaris (sparc and x86), Linux, Freebsd, and OSF/1. As far as
I know, it should still compile and run fine on any of them with
a few minor adjustments.
<ob-disclaimer>
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
</ob-disclaimer>
To compile:
$ cp config.h.dist config.h
$ vi config.h # set everything correctly
$ cp cs.conf.dist cs.conf
$ vi cs.conf # set everything correctly
$ make
To run:
$ ./cs -f cs.conf
You can reach me at <csfeedback@robin.pfft.net> for questions or comments,
but I reserve the right to completely ignore you if I feel like it.
Enjoy!
/Robin

27
Sources/Makefile Normal file
View File

@@ -0,0 +1,27 @@
# Undernet Channel Service (X)
# Copyright (C) 1995-2002 Robin Thellend
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# The author can be contact by email at <csfeedback@robin.pfft.net>
#
# Please note that this software is unsupported and mostly
# obsolete. It was replaced by GNUworld/CMaster. See
# http://gnuworld.sourceforge.net/ for more information.
#
all:
@cd ..; make; cd Sources;

72
Sources/Sources.mak Normal file
View File

@@ -0,0 +1,72 @@
# Undernet Channel Service (X)
# Copyright (C) 1995-2002 Robin Thellend
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# The author can be contact by email at <csfeedback@robin.pfft.net>
#
# Please note that this software is unsupported and mostly
# obsolete. It was replaced by GNUworld/CMaster. See
# http://gnuworld.sourceforge.net/ for more information.
all: ../cs
.c.o:
${CC} ${CFLAGS} ${DEFINES} -c $<
../cs: ver ${OBJECTS} cksum.o cksum
${CC} ${CFLAGS} ${DEFINES} ${LIBS} -o ../cs main.c cksum.o ${OBJECTS} -DBINCKSUM1=0 -DBINCKSUM2=0
${CC} ${CFLAGS} ${DEFINES} ${LIBS} -o ../cs main.c cksum.o ${OBJECTS} `./cksum ../cs`
ver:
@chmod +x version.SH
@./version.SH
cksum: cksum.c
${CC} ${CFLAGS} -o cksum cksum.c -DMAIN
list: ../list
../list: list.c
${CC} -o ../list list.c
listall: ../listall
../listall: listall.c
${CC} -o ../listall listall.c
fixdb: match.o
${CC} fixdb.c match.o -DMAIN -o ../fixdb
showdb: match.o
${CC} -Wall showdb.c match.o -DMAIN -o ../showdb
show_old_managers: match.o
${CC} -Wall -o ../show_old_managers show_old_managers.c match.o -DMAIN
clean:
$(RM) -f *.o *.bak
depend:
-gcc -MM ${CFLAGS} ${SOURCES} > make.dep
backup: ${SOURCES} list.c listall.c
-cd ..; backups/backup
love:
-@echo "With you?? dream on! :P"
include make.dep

427
Sources/bans.c Normal file
View File

@@ -0,0 +1,427 @@
/* @(#)$Id: bans.c,v 1.12 1999/04/04 17:00:03 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
void ban(char *source, char *chan, char *nicklist)
{
char buffer[300];
char OneNick[NICK_LENGTH];
char channel[CHANNELNAME_LENGTH];
register auser *user;
register aluser *luser;
register achannel *ch;
register int i = 0;
if (*nicklist == '#')
{
GetWord(0, nicklist, channel);
nicklist = ToWord(1, nicklist);
}
else
{
strcpy(channel, chan);
GuessChannel(source, channel);
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: ban <channel> <nick1|addr1> [nick2|addr2] [...]");
return;
}
#ifdef DEBUG
printf("BAN REQUEST FOR %s\nON CHANNEL %s\nBY %s (%d)\n",
nicklist, channel, source, Access(channel, source));
#endif
if (*source && Access(channel, source) < BAN_LEVEL)
{
notice(source, "Your Access on this channel is too low");
return;
}
ch = ToChannel(channel);
/* I'm not on this channel.. so screw it! */
if (ch == NULL || !ch->on)
{
notice(source, "I'm NOT on that channel!");
return;
}
if (!ch->AmChanOp)
{
notice(source, "I'm not channel operator!");
return;
}
if (!*nicklist)
{
notice(source, "SYNTAX: ban <channel> <nick1|addr1> [nick2|addr2] [...]");
return;
}
GetWord(0, nicklist, OneNick);
while (*OneNick)
{
luser = ToLuser(OneNick);
if (luser)
sprintf(buffer, "%s!%s@%s", luser->nick,
luser->username, luser->site);
if (luser)
{
sprintf(buffer, "I BAN %s!%s@%s ON %s", luser->nick,
luser->username, luser->site, channel);
log(buffer);
user = ToUser(channel, OneNick);
if (user && user->chanop)
{
changemode(channel, "-o", user->N->nick, 0);
}
MakeBanMask(luser, buffer);
changemode(channel, "+b", buffer, 0);
}
GetWord(++i, nicklist, OneNick);
}
flushmode(channel);
}
void mban(char *source, char *ch, char *args)
{
char buffer[200];
char channel[80];
register int found = 0;
register achannel *chan;
register auser *user;
if (*args == '#')
{
GetWord(0, args, channel);
args = ToWord(1, args);
}
else
{
strcpy(channel, ch);
GuessChannel(source, channel);
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: mban <channel> <nick!username@hostname>");
return;
}
if ((chan = ToChannel(channel)) == NULL || !chan->on)
{
if (*source)
notice(source, "I'm NOT on that channel!");
return;
}
if (!chan->AmChanOp)
{
if (*source)
notice(source, "I am NOT channel operator!");
return;
}
if (*source && Access(channel, source) < MASS_BAN_LEVEL)
{
notice(source, "Your Access on this channel is too low!");
return;
}
if (!*args)
{
notice(source, "SYNTAX: mban <channel> <nick!username@hostname>");
return;
}
user = chan->users;
while (user)
{
sprintf(buffer, "%s!%s@%s",
user->N->nick, user->N->username, user->N->site);
if (match(buffer, args))
{
sprintf(buffer, "I BAN %s!%s@%s on %s (%s)", user->N->nick,
user->N->username, user->N->site, channel, args);
log(buffer);
if (user->chanop)
{
changemode(channel, "-o", user->N->nick, 0);
user->chanop = 0;
}
/*MakeBanMask(user->N,buffer); */
if (!found)
changemode(channel, "+b", args, 0);
found = 1;
}
user = user->next;
}
if (found)
flushmode(channel);
else if (*source)
{
notice(source, "No match.");
}
}
void unban(char *source, char *ch, char *list)
{
register aban *bans;
register aluser *luser;
register achannel *chan;
char channel[CHANNELNAME_LENGTH];
char buffer[512];
char one[200];
register int found;
register int i, exact;
if (*list == '#')
{
GetWord(0, list, channel);
list = ToWord(1, list);
}
else
{
strcpy(channel, ch);
GuessChannel(source, channel);
}
chan = ToChannel(channel);
if (chan == NULL || !chan->on)
{
notice(source, "I am NOT on that channel!");
return;
}
if (!chan->AmChanOp)
{
notice(source, "I am not channel operator!");
return;
}
if (*source && Access(channel, source) < BAN_LEVEL)
{
notice(source, "You're Access on this channel is too low");
return;
}
if (!*list)
{
notice(source, "SYNTAX: unban [#channel] <nick1|addr1> [<nick2|addr2>] [...]");
return;
}
i = 0;
GetWord(0, list, one);
while (*one)
{
found = 0;
luser = ToLuser(one);
if (luser != NULL)
{
sprintf(one, "%s!%s@%s", luser->nick, luser->username,
luser->site);
exact = 0;
}
else
{
exact = 1;
}
bans = chan->bans;
while (bans != NULL)
{
if ((!exact && match(one, bans->pattern)) ||
(exact && !strcasecmp(one, bans->pattern)))
{
sprintf(buffer, "I UNBAN %s ON %s",
bans->pattern, chan->name);
log(buffer);
changemode(channel, "-b", bans->pattern, 0);
RemBan(channel, bans->pattern);
bans = chan->bans;
found = 1;
if (exact)
break;
}
else
bans = bans->next;
}
if (*source && !found)
{
sprintf(buffer, "%s is not in %s's banlist!",
one, channel);
notice(source, buffer);
}
GetWord(++i, list, one);
}
flushmode(channel);
}
void showbanlist(char *source, char *ch, char *args)
{
char buffer[200];
char channel[80];
register achannel *chan;
register aban *curr;
if (*args == '#')
{
GetWord(0, args, channel);
}
else
{
strcpy(channel, ch);
GuessChannel(source, channel);
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: banlist <channel>");
return;
}
/* user must be on a channel to see the ban list
*/
if (ToUser(channel, source) == NULL)
{
sprintf(buffer, "%s: You are not on that channel", channel);
notice(source, buffer);
return;
}
chan = ToChannel(channel);
curr = chan->bans;
if (curr == NULL)
{
sprintf(buffer, "%s: ban list is empty.", channel);
notice(source, buffer);
return;
}
while (curr != NULL)
{
notice(source, curr->pattern);
curr = curr->next;
}
sprintf(buffer, "%s: End of ban list", channel);
notice(source, buffer);
}
void MakeBanMask(aluser * luser, char *output)
{
register int isip = 1;
register int i, j;
int a1, a2, a3, a4;
char hostmask[200];
register char *ptr;
if (luser == NULL)
{
/* Don't do anything */
return;
}
/* check if hostname is a numeric IP address
*/
for (i = 0; luser->site[i] != '\0' && isip; i++)
{
if (!isdigit(luser->site[i]) && luser->site[i] != '.')
isip = 0;
}
if (isip)
{
sscanf(luser->site, "%d.%d.%d.%d", &a1, &a2, &a3, &a4);
if (a1 <= 127)
{ /* class A */
/*sprintf(hostmask,"%d.*",a1); *shrugs* */
sprintf(hostmask, "%d.%d.*", a1, a2);
}
else if (a1 <= 191)
{ /* class B */
sprintf(hostmask, "%d.%d.*", a1, a2);
}
else
{ /* class C */
sprintf(hostmask, "%d.%d.%d.*", a1, a2, a3);
}
}
else
{ /* not numeric address */
ptr = luser->site + strlen(luser->site);
i = 0;
if (!strcasecmp(luser->site + strlen(luser->site) - 3, ".AU") ||
!strncasecmp(luser->site + strlen(luser->site) - 7, ".NET.", 4) ||
!strncasecmp(luser->site + strlen(luser->site) - 7, ".COM.", 4) ||
!strncasecmp(luser->site + strlen(luser->site) - 7, ".EDU.", 4) ||
!strncasecmp(luser->site + strlen(luser->site) - 6, ".AC.", 3))
j = 3;
else
j = 2;
while (i != j && ptr != luser->site)
{
if (*ptr == '.')
i++;
ptr--;
}
if (i == j)
ptr += 2;
if (ptr == luser->site)
strcpy(hostmask, ptr);
else
sprintf(hostmask, "*.%s", ptr);
}
if (!strncasecmp(luser->username, "^wld", 4))
{
/* special case for telnet users */
sprintf(output, "*!^wld*@%s", hostmask);
}
else
{
ptr = luser->username;
while (strlen(ptr) == 10 || *ptr == '~')
ptr++;
sprintf(output, "*!*%s@%s", ptr, hostmask);
}
}

288
Sources/buffer.c Normal file
View File

@@ -0,0 +1,288 @@
/* @(#)$Id: buffer.c,v 1.3 1996/11/13 00:40:34 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
/* These routines were first developed for the telnet3d project.
* Special thanks to Danny Mitchell (wildthang@irc) for his help
*/
#include "h.h"
static struct buffer_block *avail=NULL;
/*static unsigned long MEM_buffers=0;*/
static unsigned long NB_avail_buffer_blocks=0;
static unsigned long NB_alloc_buffer_blocks=0;
/* get_buffer_block() by SeKs <intru@step.polymtl.ca>
* returns a ptr to an empty buffer_block or NULL if malloc()
* returns an error.
*/
struct buffer_block *get_buffer_block(void)
{
register struct buffer_block *block;
/* I would like to move this to the GetMemory
** and linklist functions as soon as we get them
** finished. Mainly for use in keeping track
** of overall memory usage, and such.
** just a reminder. --DVM
*/
if(avail==NULL){
block=(struct buffer_block *)malloc(sizeof(struct buffer_block));
block->next=NULL;
}else{
block=avail;
avail=avail->next;
NB_avail_buffer_blocks--;
}
block->offset_read=0;
block->offset_write=0;
block->next=NULL;
NB_alloc_buffer_blocks++;
return block;
}
/* return_buffer_block() by SeKs <intru@step.polymtl.ca>
* returns the given "block" to the "system". Blocks are not
* free()'d. They are kept in order to be re-allocated by
* get_buffer_block().
*/
void return_buffer_block(struct buffer_block *block)
{
block->next=avail;
avail=block;
NB_avail_buffer_blocks++;
NB_alloc_buffer_blocks--;
}
/* copy_from_buffer() by SeKs <intru@step.polymtl.ca>
* copies characters from the buffer starting at the buffer_block
* '*block' into 'string' until a char in 'stop' is encountered or
* 'max' bytes are read.
* Blocks that are completely copied are returned to the system with
* return_buffer_block().
* Returns the number of characters that were copied.
*/
int
copy_from_buffer(struct buffer_block **block,char *string,char stop,int max)
{
register struct buffer_block *tmp;
register int count=0;
if(block==NULL || *block==NULL || string==NULL)
return -1;
while(count<max && *block!=NULL){
if((*block)->offset_read == (*block)->offset_write){
tmp=*block;
*block=(*block)->next;
return_buffer_block(tmp);
break;
}
count++;
*string=(*block)->buf[(*block)->offset_read++];
if((*block)->offset_read == BUFFER_BLOCK_SIZE){
tmp=*block;
*block=(*block)->next;
return_buffer_block(tmp);
}
string++;
if(stop!='\0' && stop==*(string-1))
break;
}
*string='\0';
return count;
}
/* look_in_buffer() by SeKs <intru@step.polymtl.ca>
* Same as copy_from_buffer() except that the buffer remains unchanged
* when the function returns.
* ** Added offset counter otherwise offset_read IS changed when returned -DVM
*/
int
look_in_buffer(struct buffer_block **block,char *string,char stop,int max)
{
register int count=0;
register int offset=0; /* added DVM */
if(block==NULL || *block==NULL || string==NULL)
return -1;
if((*block)->offset_read == (*block)->offset_write){
return_buffer_block(*block);
*block=NULL;
}
while(count<max && *block!=NULL){
if((*block)->offset_read+offset == (*block)->offset_write)
break;
count++;
*string=(*block)->buf[(*block)->offset_read+offset];
offset++;
if((*block)->offset_read+offset == BUFFER_BLOCK_SIZE){
block=&(*block)->next;
offset=0;
}
string++;
if(stop!='\0' && stop==*(string-1))
break;
}
*string='\0';
return count;
}
/* copy_to_buffer() by SeKs <intru@step.polymtl.ca>
* adds a string to the specified buffer.
* New buffer_blocks are requested when necessary.
* Returns the number of characters in the buffer after the
* new string is added.
* arguments are:
* ( struct buffer_block **block, char *format, args... )
*/
long copy_to_buffer(struct buffer_block **block, char *string,int length)
{
register long count=0;
if(block==NULL || length<=0)
return -1;
if(*block==NULL)
*block=get_buffer_block();
while((*block)->next!=NULL){
count+=(BUFFER_BLOCK_SIZE)-(*block)->offset_read;
block=&(*block)->next;
}
count+=(*block)->offset_write-(*block)->offset_read;
while(length--){
count++;
(*block)->buf[(*block)->offset_write++]=*(string++);
if((*block)->offset_write == BUFFER_BLOCK_SIZE){
(*block)->offset_write=-1;
(*block)->next=get_buffer_block();
block=&(*block)->next;
if(*block==NULL){
break;
}
}
}
return count;
}
/* zap_buffer() by SeKs <intru@step.polymtl.ca>
* clears the buffer starting at the buffer_block '*block'
* return -1 if block is NULL
* 0 otherwise
*/
int zap_buffer(struct buffer_block **block)
{
struct buffer_block *tmp;
if(block==NULL)
return -1;
while((tmp=*block)!=NULL){
*block=(*block)->next;
return_buffer_block(tmp);
}
return 0;
}
/* find_char_in_buffer() by SeKs <intru@step.polymtl.ca>
* returns 1 if any character of string 'findit' is present within the first
* 'max' characters of the buffer.
* returns 0 otherwise.
*/
int find_char_in_buffer(struct buffer_block **block, char findit,int max)
{
register int offset;
register int count=0;
if( (block == NULL) || (*block == NULL))
return 0; /* DVM */
offset=(*block)->offset_read;
loop:
if(offset == (*block)->offset_write)
return 0;
if(findit == (*block)->buf[offset])
return 1;
if(++count > max)
return 0;
if(++offset == BUFFER_BLOCK_SIZE){
block=&(*block)->next;
if(*block == NULL)
return 0;
offset=0;
}
goto loop;
}
/* skip_char_in_buffer() by SeKs <intru@step.polymtl.ca>
* flushes the first 'n' characters in buffer starting at
* buffer_block '*block'
*/
int skip_char_in_buffer(struct buffer_block **block, int n)
{
register struct buffer_block *tmp;
register int count=0;
while(count<n){
if((*block)->offset_read == (*block)->offset_write){
tmp=*block;
*block=(*block)->next;
return_buffer_block(tmp);
break;
}
count++;
(*block)->offset_read++;
if((*block)->offset_read == BUFFER_BLOCK_SIZE){
tmp=*block;
*block=(*block)->next;
return_buffer_block(tmp);
if(*block==NULL)
break;
}
}
return count;
}

185
Sources/change_byte_order.c Normal file
View File

@@ -0,0 +1,185 @@
/* @(#)$Id: change_byte_order.c,v 1.3 1996/11/13 00:40:34 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <netinet/in.h>
#include "defines.h"
#include "struct.h"
#include "version.h"
#include "../config.h"
typedef struct DiskUser {
char realname[80];
char match[80];
int Access;
char passwd[20];
char channel[80];
unsigned long flags;
char reserved[20];
time_t suspend;
time_t lastseen;
} DiskUser;
typedef struct ShitDisk {
time_t time;
time_t expiration;
char match[80];
char from[80];
char reason[200];
char channel[50];
int level;
} ShitDisk;
void main(void)
{
FILE *in;
FILE *out;
DiskUser olduser;
DiskUser user;
adefchan oldchan;
adefchan chan;
ShitDisk oldshit,shit;
time_t now;
char swap, *ptr;
if(chdir(HOMEDIR)<0){
perror(HOMEDIR);
exit(1);
}
now=time(NULL);
out=fopen("userlist.dat.new","w");
if(out==NULL){
perror("userlist.dat.new");
exit(1);
}
in=fopen(USERFILE,"r");
if(in==NULL){
perror(USERFILE);
return;
}
while(fread(&user,sizeof(DiskUser),1,in)>0){
ptr=(char *)&user.Access;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&user.flags;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&user.suspend;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&user.lastseen;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
fwrite(&user,sizeof(DiskUser),1,out);
}
fclose(in);
fclose(out);
out=fopen("channellist.dat.new","w");
if(out==NULL){
perror("channellist.dat.new");
exit(1);
}
in=fopen(DEFAULT_CHANNELS_FILE,"r");
if(in==NULL){
perror(DEFAULT_CHANNELS_FILE);
exit(1);
}
while(fread(&chan,sizeof(adefchan),1,in)>0){
ptr=(char *)&chan.MassDeopPro;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&chan.NickFloodPro;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&chan.MsgFloodPro;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&chan.TS;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&chan.flags;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&chan.uflags;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
fwrite(&chan,sizeof(adefchan),1,out);
}
fclose(in);
fclose(out);
out=fopen("shitlist.dat.new","w");
if(out==NULL){
perror("shitlist.dat.new");
exit(1);
}
in=fopen(SHITLIST_FILE,"r");
if(in==NULL){
perror(SHITLIST_FILE);
exit(1);
}
while(fread(&shit,sizeof(ShitDisk),1,in)>0){
ptr=(char *)&shit.time;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&shit.expiration;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
ptr=(char *)&shit.level;
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
fwrite(&shit,sizeof(ShitDisk),1,out);
}
fclose(in);
fclose(out);
}

1833
Sources/channels.c Normal file

File diff suppressed because it is too large Load Diff

266
Sources/chat.c Normal file
View File

@@ -0,0 +1,266 @@
/* @(#)$Id: chat.c,v 1.10 2000/09/09 15:38:13 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#ifdef DOHTTP
struct chat_user
{
char user[10];
char host[80];
aluser *luser;
};
void chat_sendtoall(char *from, char *msg)
{
register http_socket *scan = HttpList;
while (scan != NULL)
{
if (scan->status == HTTP_CHAT && ((struct chat_user *)scan->hook)->luser)
{
if (from)
sendto_http(scan, "<%s> %s\n", from, msg);
else
sendto_http(scan, "%s\n", msg);
}
scan = scan->next;
}
}
static void login_ok(struct http_socket *hsock, RegUser * reg)
{
char buffer[512], nick[15];
struct chat_user *cu = (struct chat_user *)hsock->hook;
register http_socket *scan;
int count = 0;
sprintf(buffer, "1 %ld %s %s %s", now, cu->user + 1, cu->host, VirtualServer.name);
strcpy(nick, cu->user);
while (ToLuser(nick) != NULL)
sprintf(nick, "+%d%s", ++count, cu->user + 1);
nick[9] = '\0';
onnick(VirtualServer.name, nick, buffer);
cu->luser = ToLuser(nick);
cu->luser->valchan = (avalchan *) MALLOC(sizeof(avalchan));
cu->luser->valchan->name = (char *)MALLOC(strlen(reg->channel) + 1);
strcpy(cu->luser->valchan->name, reg->channel);
cu->luser->valchan->reg = reg;
reg->inuse++;
reg->lastseen = now;
reg->modified = 1;
cu->luser->valchan->next = NULL;
sendto_http(hsock, "Welcome to %s's chat line\n", mynick);
count = 0;
sprintf(buffer, "*** Currently on: ");
for (scan = HttpList; scan != NULL; scan = scan->next)
{
if (scan->status != HTTP_CHAT || ((struct chat_user *)scan->hook)->luser == NULL)
continue;
if (strlen(buffer) > 70)
{
sendto_http(hsock, "%s\n", buffer);
sprintf(buffer, "*** ");
}
strcat(buffer, ((struct chat_user *)scan->hook)->luser->nick + 1);
strcat(buffer, " ");
}
sendto_http(hsock, "%s\n", buffer);
sprintf(buffer, "*** JOIN: %s@%s", cu->luser->nick + 1, cu->host);
chat_sendtoall(NULL, buffer);
}
static void
chat_login_callback(int *fd, off_t off, int action, void *hook1, void *hook2,
dbuser * dbu, int count)
{
extern RegUser *load_dbuser(off_t, dbuser *);
register RegUser *reg;
struct http_socket *hsock = (struct http_socket *)hook1;
struct chat_user *cu;
char userhost[200];
if (dbu != NULL)
{
cu = (struct chat_user *)hsock->hook;
reg = load_dbuser(off, dbu);
sprintf(userhost, "%s!%s@%s", cu->user, cu->user + 1, cu->host);
if (reg != NULL && *reg->match == '+' && match(userhost, reg->match))
{
#ifdef DEBUG
printf("login_ok: %s %s\n", userhost, reg->match);
#endif
login_ok(hsock, reg);
}
else
{
sendto_http(hsock, "Authentication failed!\n");
hsock->status = HTTP_ENDING;
}
}
else
{
if (count == 0)
{
sendto_http(hsock, "Authentication failed!\n");
hsock->status = HTTP_ENDING;
hsock->dbio = 0;
}
}
}
void chat_login(struct http_socket *hsock, char *user, char *password)
{
char userhost[200], channel[] = "*", buffer[200];
struct chat_user *cu;
register RegUser *ruser;
cu = (struct chat_user *)malloc(sizeof(struct chat_user));
sprintf(buffer, "+%s", user);
strncpy(cu->user, buffer, 9);
cu->user[9] = '\0';
strcpy(cu->host, inet_ntoa(hsock->peer.sin_addr));
cu->luser = NULL;
hsock->hook = (void *)cu;
sprintf(userhost, "%s!%s@%s", cu->user, cu->user + 1, cu->host);
ruser = UserList[ul_hash(channel)];
while (ruser != NULL)
{
if (!strcasecmp(ruser->channel, channel) &&
*ruser->match == '+' && match(userhost, ruser->match) &&
!strcmp(ruser->passwd, password))
break;
ruser = ruser->next;
}
if (ruser == NULL)
{ /* ok.. not in memory.. send db query */
db_fetch(channel, DBGETUHPASS, userhost, password, 0,
hsock, NULL, chat_login_callback);
hsock->dbio = 1;
}
else
{
#ifdef DEBUG
printf("login_ok: %s %s\n", userhost, ruser->match);
#endif
login_ok(hsock, ruser);
}
}
void chat_notice(char *user, char *msg)
{
register http_socket *scan = HttpList;
register struct chat_user *cu;
#ifdef DEBUG
printf("chat: ->%s %s\n", user, msg);
#endif
while (scan != NULL)
{
cu = (struct chat_user *)scan->hook;
if (scan->status == HTTP_CHAT && cu->luser &&
!strcasecmp(cu->luser->nick, user))
{
sendto_http(scan, "-%s- %s\n", mynick, msg);
break;
}
scan = scan->next;
}
}
void parse_chat(struct http_socket *hsock, char *line)
{
char buffer[200], global[] = "*", *ptr;
if (hsock == NULL || hsock->hook == NULL ||
((struct chat_user *)hsock->hook)->luser == NULL)
return;
if ((ptr = strpbrk(line, "\r\n")) != NULL)
*ptr = '\0';
#ifdef DEBUG
printf("chat: <%s> %s\n", ((struct chat_user *)hsock->hook)->luser->nick + 1, line);
#endif
if ((*line == '/') || (*line == '.'))
{
sprintf(buffer, "%s@%s", mynick, SERVERNAME);
parse_command(((struct chat_user *)hsock->hook)->luser->nick,
buffer, global, line + 1);
}
else
chat_sendtoall(((struct chat_user *)hsock->hook)->luser->nick + 1, line);
}
void chat_close(http_socket * hsock, char *comment)
{
char buffer[512];
struct chat_user *cu = (struct chat_user *)hsock->hook;
if (cu->luser)
{
sprintf(buffer, "*** LEAVE: %s@%s", cu->luser->nick + 1, cu->host);
chat_sendtoall(NULL, buffer);
onquit(cu->luser->nick);
}
}
void DccMe(char *source, char *arg)
{
char global[] = "*", buffer[512];
if(Access(global, source) >= 600)
{
unsigned long addr = inet_addr(BINDADDR);
addr = ntohl(addr);
sprintf(buffer, ":%s PRIVMSG %s :\001DCC CHAT chat %u %u\001\n",
mynick, source, addr, HTTP_PORT);
sendtoserv(buffer);
}
}
#endif

100
Sources/cksum.c Normal file
View File

@@ -0,0 +1,100 @@
/* $Id: cksum.c,v 1.1 1997/06/30 03:48:05 cvs Exp $
*/
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
void cksum(char *file, unsigned int *sum1, unsigned int *sum2)
{
int fd=-1, size;
unsigned char buffer[1024];
if(strchr(file,'/') != NULL)
{
fd = open(file,O_RDONLY);
}
else /* check path */
{
char *tok,*path = getenv("PATH");
if(path == NULL)
return;
for(tok=strtok(path,":"); tok!=NULL; tok=strtok(NULL,":"))/* mangles PATH*/
{
strncpy(buffer,tok,1023);
strncat(buffer,"/",1023);
strncat(buffer,file,1023);
buffer[1023] = '\0';
fd = open(buffer,O_RDONLY);
if(fd >= 0)
break;
}
}
if(fd<0)
{
return;
}
*sum1 = *sum2 = 0;
while((size=read(fd,buffer,1023))>0)
{
while(size--)
{
*sum1 += buffer[size];
*sum2 += (size&1)?-buffer[size]:buffer[size];
}
}
close(fd);
}
#ifdef MAIN
int main(int argc, char **argv)
{
unsigned int sum,pro;
if(argc != 2)
{
fprintf(stderr,"usage: %s file\n",argv[0]);
exit(1);
}
cksum(argv[1],&sum,&pro);
printf("-DBINCKSUM1=0x%x -DBINCKSUM2=0x%x\n",sum,pro);
exit(0);
}
#endif

241
Sources/conf.c Normal file
View File

@@ -0,0 +1,241 @@
/* @(#)$Id: conf.c,v 1.5 1998/01/22 09:36:11 chaos Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
void read_conf(char *conf)
{
FILE *fp;
char buffer[1024], *ptr;
fp = fopen(conf, "r");
if (fp == NULL)
{
perror(conf);
exit(1);
}
while (fgets(buffer, 1024, fp) != NULL)
{
if (*buffer == '#' || *buffer == '\0')
continue;
if ((ptr = strchr(buffer, '\n')) != NULL)
*ptr = '\0';
if (!strncasecmp(buffer, "NICKNAME ", 9))
{
strncpy(mynick, buffer + 9, NICK_LENGTH);
mynick[NICK_LENGTH - 1] = '\0';
}
else if (!strncasecmp(buffer, "USERNAME ", 9))
{
strncpy(myuser, buffer + 9, USERNAME_LENGTH);
myuser[USERNAME_LENGTH - 1] = '\0';
}
else if (!strncasecmp(buffer, "HOSTNAME ", 9))
{
strncpy(mysite, buffer + 9, SITE_LENGTH);
mysite[SITE_LENGTH - 1] = '\0';
}
else if (!strncasecmp(buffer, "REALNAME ", 9))
{
strncpy(myrealname, buffer + 9, REALNAME_LENGTH);
myrealname[REALNAME_LENGTH - 1] = '\0';
}
else if (!strncasecmp(buffer, "UPLINK ", 7))
{
strncpy(server, buffer + 7, SERVER_NAME_LENGTH);
server[SERVER_NAME_LENGTH - 1] = '\0';
}
else if (!strncasecmp(buffer, "PORT ", 5))
{
DEFAULT_PORTNUM = atoi(buffer + 5);
}
else if (!strncasecmp(buffer, "UMODE ", 6))
{
strncpy(UMODE, buffer + 6, 10);
UMODE[9] = '\0';
}
else if (!strncasecmp(buffer, "SERVERNAME ", 11))
{
strncpy(SERVERNAME, buffer + 11, 80);
SERVERNAME[79] = '\0';
}
else if (!strncasecmp(buffer, "SERVERINFO ", 11))
{
strncpy(SERVERINFO, buffer + 11, 80);
SERVERINFO[79] = '\0';
}
else if (!strncasecmp(buffer, "PASSWORD ", 9))
{
strncpy(PASSWORD, buffer + 9, 80);
PASSWORD[79] = '\0';
}
else if (!strncasecmp(buffer, "HOMEDIR ", 8))
{
strncpy(HOMEDIR, buffer + 8, 256);
HOMEDIR[255] = '\0';
}
else if (!strncasecmp(buffer, "UMASK ", 6))
{
sscanf(buffer + 6, "%d", &UMASK);
}
else if (!strncasecmp(buffer, "EXEC ", 5))
{
strncpy(EXEC_FILE, buffer + 5, 256);
EXEC_FILE[255] = '\0';
}
else if (!strncasecmp(buffer, "MOTD ", 5))
{
strncpy(MOTD_FILE, buffer + 5, 256);
MOTD_FILE[255] = '\0';
}
else if (!strncasecmp(buffer, "LOG ", 4))
{
strncpy(LOGFILE, buffer + 4, 256);
LOGFILE[255] = '\0';
}
else if (!strncasecmp(buffer, "LOGBAK ", 7))
{
strncpy(LOGFILEBAK, buffer + 7, 256);
LOGFILEBAK[255] = '\0';
}
else if (!strncasecmp(buffer, "PID ", 4))
{
strncpy(PIDFILE, buffer + 4, 256);
PIDFILE[255] = '\0';
}
else if (!strncasecmp(buffer, "HELPDIR ", 8))
{
strncpy(HELP_DIR, buffer + 8, 256);
HELP_DIR[255] = '\0';
}
else if (!strncasecmp(buffer, "MASTER_NICK ", 12))
{
strncpy(MASTER_REALNAME, buffer + 12, 80);
MASTER_REALNAME[79] = '\0';
}
else if (!strncasecmp(buffer, "MASTER_MASK ", 12))
{
strncpy(MASTER_MATCH, buffer + 12, 80);
MASTER_MATCH[79] = '\0';
}
else if (!strncasecmp(buffer, "MASTER_PASSWD ", 14))
{
strncpy(MASTER_PASSWD, buffer + 14, 20);
MASTER_PASSWD[19] = '\0';
}
else if (!strncasecmp(buffer, "BROADCAST ", 10))
{
strncpy(BROADCAST_CHANNEL, buffer + 10, 80);
BROADCAST_CHANNEL[79] = '\0';
}
else if (!strncasecmp(buffer, "VERIFYID ", 9))
{
strncpy(VERIFY_ID, buffer + 9, 256);
VERIFY_ID[255] = '\0';
}
else if (!strncasecmp(buffer, "UWORLD_NICK ", 12))
{
strncpy(UWORLD, buffer + 12, 10);
UWORLD[9] = '\0';
}
else if (!strncasecmp(buffer, "UWORLD_HOST ", 12))
{
strncpy(UWORLD_HOST, buffer + 12, 80);
UWORLD_HOST[79] = '\0';
}
else if (!strncasecmp(buffer, "UWORLD_SERVER ", 14))
{
strncpy(UWORLD_SERVER, buffer + 14, 80);
UWORLD_SERVER[79] = '\0';
}
else if (!strncasecmp(buffer, "UWORLD2_NICK ", 13))
{
strncpy(UWORLD2_NICK, buffer + 13, 10);
UWORLD2_NICK[9] = '\0';
}
else if (!strncasecmp(buffer, "UWORLD2_HOST ", 13))
{
strncpy(UWORLD2_HOST, buffer + 13, 80);
UWORLD2_HOST[79] = '\0';
}
else if (!strncasecmp(buffer, "UWORLD2_SERVER ", 15))
{
strncpy(UWORLD2_SERVER, buffer + 15, 80);
UWORLD2_SERVER[79] = '\0';
}
else if (!strncasecmp(buffer, "CALMDOWNTOPIC ", 14))
{
strncpy(CALMDOWNTOPIC, buffer + 14, 512);
CALMDOWNTOPIC[511] = '\0';
}
else if (!strncasecmp(buffer, "NSERV_NICK ", 11))
{
#ifdef NICKSERV
strncpy(NSERV_NICK, buffer + 11, 10);
NSERV_NICK[9] = '\0';
#endif
}
else if (!strncasecmp(buffer, "NSERV_USER ", 11))
{
#ifdef NICKSERV
strncpy(NSERV_USER, buffer + 11, 10);
NSERV_USER[9] = '\0';
#endif
}
else if (!strncasecmp(buffer, "NSERV_HOST ", 11))
{
#ifdef NICKSERV
strncpy(NSERV_HOST, buffer + 11, 80);
NSERV_HOST[79] = '\0';
#endif
}
else if (!strncasecmp(buffer, "NSERV_INFO ", 11))
{
#ifdef NICKSERV
strncpy(NSERV_INFO, buffer + 11, 200);
NSERV_INFO[199] = '\0';
#endif
}
else if (!strncasecmp(buffer, "NSERV_STAT ", 11))
{
#ifdef NICKSERV
if (!strncmp(buffer + 11, "on", 2))
NServ_status = 1;
else if (!strncmp(buffer + 11, "off", 3))
NServ_status = 0;
else
fprintf(stderr, "NSERV_STAT: Unknown value. Must be ON or OFF\n");
#endif
}
else
{
fprintf(stderr, "%s: Unknown keyword \"%s\"\n", conf, buffer);
}
}
fclose(fp);
}

696
Sources/connect.c Normal file
View File

@@ -0,0 +1,696 @@
/* @(#)$Id: connect.c,v 1.12 1998/01/25 18:35:42 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#ifndef FD_ZERO
#define FD_ZERO(set) (((set)->fds_bits[0]) = 0)
#define FD_SET(s1, set) (((set)->fds_bits[0]) |= 1 << (s1))
#define FD_ISSET(s1, set) (((set)->fds_bits[0]) & (1 << (s1)))
#define FD_SETSIZE 30
#endif
int read_from_server(int);
int write_to_server(irc_socket *);
int connection(char *serv)
{
char buffer[200];
int portnum;
char *ptr;
struct sockaddr_in socketname;
#ifdef BINDADDR
struct sockaddr_in myname;
#endif
struct hostent *remote_host;
if ((ptr = strchr(serv, ':')) != NULL)
{
*(ptr++) = 0;
sscanf(ptr, "%d", &portnum);
#ifdef DEBUG
printf("Server: %s\nPort: %d\n", serv, portnum);
#endif
}
else
{
portnum = DEFAULT_PORTNUM;
}
sprintf(buffer, "CONNECTING TO %s ON PORT %d", serv, portnum);
log(buffer);
if (Irc.outbuf)
zap_buffer(&Irc.outbuf);
if (Irc.inbuf)
zap_buffer(&Irc.inbuf);
read_from_server(1); /* reset input buffer */
now = time(NULL);
/* open an inet socket */
if ((Irc.fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
#ifdef DEBUG
fprintf(stderr, "ERROR: Can't assign fd for socket, darn!\n");
#endif
log("ERROR ASSIGNING FD FOR SOCKET");
exit(1);
}
#ifdef BINDADDR
memset(&myname, 0, sizeof(myname));
myname.sin_family = AF_INET;
myname.sin_port = 0;
myname.sin_addr.s_addr = inet_addr(BINDADDR);
if (bind(Irc.fd, (struct sockaddr *)&myname, sizeof(myname)) < 0)
{
#ifdef DEBUG
fprintf(stderr, "ERROR: Can't bind local address %s\n", BINDADDR);
#endif
log("Can't bind local address");
log(BINDADDR);
exit(1);
}
#endif
/* make it non-blocking */
fcntl(Irc.fd, F_SETFL, O_NONBLOCK);
/* lookup host */
socketname.sin_family = AF_INET;
if ((remote_host = gethostbyname(serv)) == NULL)
{
#ifdef DEBUG
fprintf(stderr, "ERROR: Host %s is unknown, wtf?\n", serv);
#endif
log("ERROR: BULLSHIT HOST!");
exit(1);
}
memcpy((void *)&socketname.sin_addr, (void *)remote_host->h_addr, remote_host->h_length);
socketname.sin_port = htons(portnum);
/* connect socket */
if (connect(Irc.fd, (struct sockaddr *)&socketname, sizeof(socketname)) < 0
&& errno != EINPROGRESS)
{
close(Irc.fd);
Irc.fd = -1;
#ifdef DEBUG
printf("ERROR: connect() %d: %s\n", errno, strerror(errno));
#endif
log("ERROR: COULDN'T CONNECT");
return (1);
}
TSconnect = Irc.TS = now = time(NULL);
errno = 0;
return 0;
}
int wait_msg(void)
{
fd_set readfds, writefds;
struct timeval timeout;
static int pingflag = 0;
int maxfd = -1;
int to;
#ifdef DOHTTP
void http_log(char *fmt,...);
register http_socket *hsock, *hsocktmp;
register http_file_pipe *fpipe, *fpipetmp;
#endif
#ifdef UPGRADE
register misc_socket *msock, *msocktmp;
#endif
register dbquery **dq, *dqtmp;
register dbsync **ds, *dstmp;
/* initialize the fd_sets
*/
FD_ZERO(&readfds);
FD_ZERO(&writefds);
/* set timeout
*/
if (EventList != NULL)
{
to = EventList->time - now;
if (to < PING_FREQ)
timeout.tv_sec = (to > 0) ? to : 0;
else
timeout.tv_sec = PING_FREQ;
}
else
{
timeout.tv_sec = PING_FREQ;
}
timeout.tv_usec = 0;
/* Check the DBQuery list before the server fd because
* end_db_read() might writing something in the server's
* buffer.
*/
dq = &DBQuery;
while (*dq)
{
if ((*dq)->fd < 0)
{
dqtmp = *dq;
*dq = (*dq)->next;
end_db_read(dqtmp);
free(dqtmp);
}
else
{
if ((*dq)->fd > maxfd)
maxfd = (*dq)->fd;
FD_SET((*dq)->fd, &readfds);
dq = &(*dq)->next;
}
}
ds = &DBSync;
while (*ds)
{
if ((*ds)->fd < 0)
{
dstmp = *ds;
*ds = (*ds)->next;
end_db_sync(dstmp);
free(dstmp);
}
else
{
if ((*ds)->fd > maxfd)
maxfd = (*ds)->fd;
if ((*ds)->status == SYNC_PENDWRITE)
FD_SET((*ds)->fd, &writefds);
else
FD_SET((*ds)->fd, &readfds);
ds = &(*ds)->next;
}
}
/* check if the uplink's socket is ready for reading..
*/
FD_SET(Irc.fd, &readfds);
/* check if the uplink's socket is ready for writing only if
* we have something to write
*/
if (Irc.outbuf != NULL)
FD_SET(Irc.fd, &writefds);
if (Irc.fd > maxfd)
maxfd = Irc.fd;
#ifdef DOHTTP
fpipe = FilePipes;
while (fpipe != NULL)
{
if (fpipe->fd > maxfd)
maxfd = fpipe->fd;
FD_SET(fpipe->fd, &readfds);
fpipe = fpipe->next;
}
hsock = HttpList;
while (hsock != NULL)
{
if (hsock->fd < 0 || hsock->status == HTTP_ERROR)
{
hsock = hsock->next; /* am I an idiot or what? -Kev */
continue; /* you should see the logs from below! -Kev */
}
if (hsock->fd > maxfd)
maxfd = hsock->fd;
if (hsock->status != HTTP_LISTEN &&
hsock->status != HTTP_CHAT &&
hsock->since + 2 * HTTP_TIMEOUT < now)
{
http_log("ERROR: absolute timeout for fd %d (%d)",
hsock->fd, hsock->status);
close(hsock->fd);
hsock->fd = -1;
hsock->status = HTTP_ERROR;
}
if (hsock->status != HTTP_LISTEN &&
hsock->status != HTTP_CHAT &&
hsock->TS + HTTP_TIMEOUT < now)
{
close(hsock->fd);
hsock->fd = -1;
hsock->status = HTTP_ERROR;
}
if (hsock->status == HTTP_ENDING &&
hsock->outbuf == NULL)
{
close(hsock->fd);
hsock->fd = -1;
hsock->status = HTTP_ERROR;
}
if (hsock->status != HTTP_ERROR)
{
if (hsock->status != HTTP_ENDING &&
hsock->status != HTTP_PIPE)
FD_SET(hsock->fd, &readfds);
if (hsock->outbuf != NULL)
FD_SET(hsock->fd, &writefds);
}
hsock = hsock->next;
}
#endif
#ifdef UPGRADE
msock = MiscList;
while (msock != NULL)
{
if (msock->fd > maxfd)
maxfd = msock->fd;
if (msock->TS + MISC_TIMEOUT < now)
{
close(msock->fd);
msock->fd = -1;
msock->status = MISC_ERROR;
notice(msock->link, "connection timeout!");
}
if (msock->status != MISC_ERROR)
{
FD_SET(msock->fd, &readfds);
if (msock->outbuf != NULL)
FD_SET(msock->fd, &writefds);
}
msock = msock->next;
}
#endif
/* Wait till the socket is ready for reading
* and/or writing and/or a timeout
*/
if (select(maxfd + 1, &readfds, &writefds, NULL, &timeout) < 0)
{
log("ERROR: select()");
log((char *)sys_errlist[errno]);
return (-1);
}
now = time(NULL);
/* The uplink's socket is ready for reading... */
if (FD_ISSET(Irc.fd, &readfds))
{
if (read_from_server(0) < 0)
{
log("ERROR: in read_from_server()");
return (-1);
}
pingflag = 0;
Irc.TS = now;
}
/* The uplink's socket is ready for writing... */
if (FD_ISSET(Irc.fd, &writefds))
{
if (write_to_server(&Irc) < 0)
{
log("ERROR: in write_to_server()");
return (-1);
}
}
#ifdef DOHTTP
fpipe = FilePipes;
while (fpipe != NULL)
{
fpipetmp = fpipe;
fpipe = fpipe->next;
if (FD_ISSET(fpipetmp->fd, &readfds))
{
readfrom_file(fpipetmp);
}
}
hsock = HttpList;
while (hsock != NULL)
{
while (hsock != NULL && hsock->status == HTTP_ERROR)
{
hsocktmp = hsock;
hsock = hsock->next;
remove_httpsock(hsocktmp);
}
if (hsock == NULL)
break;
if (hsock->fd >= 0 && FD_ISSET(hsock->fd, &readfds))
{
if (hsock->status == HTTP_LISTEN)
{
http_accept(hsock->fd);
}
else
{
readfrom_http(hsock);
hsock->TS = now;
}
}
if (hsock->fd >= 0 && FD_ISSET(hsock->fd, &writefds))
{
if (flush_http_buffer(hsock) != -1)
hsock->TS = now;
if (hsock->status == HTTP_ENDING && hsock->outbuf == NULL)
{
close(hsock->fd);
hsock->fd = -1;
hsock->status = HTTP_ERROR;
}
}
hsock = hsock->next;
}
#endif
#ifdef UPGRADE
msocktmp = NULL;
msock = MiscList;
while (msock != NULL)
{
while (msock != NULL && msock->status == MISC_ERROR)
{
if (msocktmp == NULL)
{
MiscList = msock->next;
free(msock);
msock = MiscList;
}
else
{
msocktmp->next = msock->next;
free(msock);
msock = msocktmp->next;
}
}
if (msock == NULL)
break;
if (msock->fd >= 0 && FD_ISSET(msock->fd, &readfds))
{
readfrom_misc(msock);
msock->TS = now;
}
if (msock->fd >= 0 && FD_ISSET(msock->fd, &writefds))
{
if (flush_misc_buffer(msock) != -1)
msock->TS = now;
}
msocktmp = msock;
msock = msock->next;
}
#endif
dqtmp = DBQuery;
while (dqtmp)
{
if (FD_ISSET(dqtmp->fd, &readfds))
read_db(dqtmp);
dqtmp = dqtmp->next;
}
dstmp = DBSync;
while (dstmp)
{
if (FD_ISSET(dstmp->fd, &readfds) || FD_ISSET(dstmp->fd, &writefds))
db_sync_ready(dstmp);
dstmp = dstmp->next;
}
if (EventList != NULL && now >= EventList->time)
CheckEvent();
/* send a PING to the server if nothing is received within
* PING_FREQ seconds... if yet nothing arrives within 3 * PING_FREQ
* seconds it's a ping timeout and the connection should be closed
*/
if ((now - Irc.TS) >= (3 * PING_FREQ + 1))
{
log("Errr PING TIMEOUT");
#ifdef DEBUG
printf("Ping timeout..\n");
#endif
sendtoserv("ERROR :Connection timeout\n");
return (-1);
}
else if (pingflag == 0 && (now - Irc.TS) >= (PING_FREQ - 1))
{
sendtoserv("PING :");
sendtoserv(SERVERNAME);
sendtoserv("\n");
pingflag = 1;
}
if (DB_Save_Status != -1)
do_cold_sync_slice();
return 0;
}
void sendtoserv(char *msg)
{
#ifdef DEBUG
printf("#OUT#%s", msg);
#endif
CurrentSendQ = copy_to_buffer(&Irc.outbuf, msg, strlen(msg));
if (CurrentSendQ > MAX_SENDQ)
{
log("ERROR: Reached MAX_SENDQ!!!");
zap_buffer(&Irc.outbuf);
close(Irc.fd);
exit(-1);
}
}
void dumpbuff(void)
{
if (Irc.fd < 0)
return;
/* remove the O_NONBLOCK flag */
fcntl(Irc.fd, F_SETFL, 0);
write_to_server(&Irc);
if (Irc.fd >= 0)
/* reset the O_NONBLOCK flag */
fcntl(Irc.fd, F_SETFL, O_NONBLOCK);
}
int read_from_server(int reset)
{
static char inbuff[1025] = "";
static char source[SERVER_NAME_LENGTH] = "";
static char function[10] = "";
static char target[513] = "";
static char body[513] = "";
static int in_pos = 0;
static int in_offset = 0;
static int length = 0;
char *inchar;
int end;
#ifdef HISTORY
char buffer[600];
#endif
if (reset)
{
*inbuff = *source = *function = *target = *body = '\0';
in_pos = in_offset = length = 0;
return 0;
}
#ifdef DEBUG
printf("#IN#");
#endif
end = 1;
while (end > 0)
{
errno = 0;
if ((length = read(Irc.fd, inbuff, 1024)) <= 0)
{
if (errno == EWOULDBLOCK || errno == EAGAIN || length == 0)
{
end = 0;
}
else
{
end = -1;
in_pos = in_offset = 0;
*source = *function = *target = *body = '\0';
#ifdef DEBUG
printf("Read error.. not EWOULDBLOCK!\n");
#endif
}
return (end);
}
TTLREADBYTES += length;
inchar = inbuff;
while (length--)
{
#ifdef DEBUG
putchar(*inchar);
#endif
if (*inchar != '\n' && *inchar != '\r')
{
if (*inchar == ' ' && in_pos < 3)
{
switch (in_pos)
{
case 0:
source[in_offset] = '\0';
break;
case 1:
function[in_offset] = '\0';
break;
case 2:
target[in_offset] = '\0';
break;
default:
exit(1);
}
in_pos++;
in_offset = 0;
}
else
{
switch (in_pos)
{
case 0:
if (in_offset == 0 && *inchar != ':')
{
source[0] = '\0';
in_pos++;
function[in_offset++] = *inchar;
}
else
source[in_offset++] = *inchar;
break;
case 1:
function[in_offset++] = *inchar;
break;
case 2:
target[in_offset++] = *inchar;
break;
case 3:
body[in_offset++] = *inchar;
break;
default: /*shouldn't happen */
exit(1);
}
}
}
if (*inchar == '\n')
{
if (in_pos >= 3)
body[in_offset] = '\0';
else
{
body[0] = '\0';
switch (in_pos)
{
case 2:
target[in_offset] = '\0';
break;
case 1:
function[in_offset] = '\0';
break;
case 0:
source[in_offset] = '\0';
default:
break;
}
}
/* parse the received line */
#ifdef HISTORY
sprintf(buffer, "%s %s %s %s", source, function, target, body);
History(buffer);
#endif
proc(source, function, target, body);
in_pos = in_offset = end = 0;
*source = *function = *target = *body = '\0';
}
inchar++;
} /* while */
} /*while */
return 1;
}
int write_to_server(irc_socket * isock)
{
char buf[1024];
int length;
int count;
if (isock == NULL || isock->outbuf == NULL)
return -1;
while ((count = look_in_buffer(&isock->outbuf, buf, '\0', 1023)) > 0)
{
if ((length = write(isock->fd, buf, count)) <= 0)
{
if (errno == EWOULDBLOCK || errno == EAGAIN)
{
return 0;
}
else
{
close(isock->fd);
isock->fd = -1;
return -1;
}
}
else
{
TTLSENTBYTES += length;
CurrentSendQ -= length;
skip_char_in_buffer(&isock->outbuf, length);
}
}
return 0;
}

755
Sources/dbio.c Normal file
View File

@@ -0,0 +1,755 @@
/* @(#)$Id: dbio.c,v 1.12 1998/01/02 18:30:08 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
char *make_dbfname(char *channel)
{
static char fname[600];
char tmp[600];
register char *ptr;
strcpy(tmp, channel);
for (ptr = tmp; *ptr; ptr++)
{
if (*ptr == '/')
*ptr = ' ';
else
*ptr = tolower(*ptr);
}
sprintf(fname, "db/channels/%04X/%s", ul_hash(channel), tmp);
return fname;
}
/* db_query()
* This is used to *retreive* information from the database.
* The arguments are:
* channel := channel name (null terminated string)
* type := query type, either of:
* DBGETNICK (Get entry by nick)
* DBGET1STUH (Get first matching userhost)
* DBGETALLUH (Get all matching userhosts)
* DBCOUNTUH (Count the number of matching userhosts)
* ...
* info := Either a nick or a userhost depending on type
* action := value passed to the callback function
* hook1 := pointer passed to the callback function
* hook2 := pointer passed to the callback function
* callback := callback function
*
* Since the database is accessed asychronously, 'hook' should not point to
* a structure that can be free()'d by a function other than callback,
* e.g. a pointer to a luser structure.
*/
int db_fetch(char *channel, unsigned int type, char *info, char *passwd,
int action, void *hook1, void *hook2, DBCALLBACK(callback))
{
dbquery *new;
int fd;
if ((fd = open(make_dbfname(channel), O_RDONLY | O_NONBLOCK)) < 0)
{
callback(&fd, (off_t) 0, action, hook1, hook2, NULL, 0);
return -1; /* caller can check errno to see want happened */
}
new = (dbquery *) malloc(sizeof(dbquery));
new->fd = fd;
new->offset = (off_t) 0;
new->time = now;
new->type = type;
new->action = action;
new->count = 0;
new->callback = callback;
new->buf = NULL;
new->hook1 = hook1;
new->hook2 = hook2;
strcpy(new->info, info);
strncpy(new->channel, channel, 79);
new->channel[79] = '\0';
if (passwd)
strcpy(new->passwd, passwd);
else
new->passwd[0] = '\0';
new->next = DBQuery;
DBQuery = new;
return 0;
}
/* fix_db()
* Remove db entries that are not in the right file.
*/
static void fix_db(char *channel, off_t offset)
{
register RegUser *reg;
register int idx;
idx = ul_hash(channel);
/* check if already taken care of */
reg = UserList[idx];
while (reg != NULL && (reg->offset != offset || strcasecmp(reg->channel, channel)))
reg = reg->next;
if (reg) /* already there.. disregard */
return;
reg = (RegUser *) MALLOC(sizeof(RegUser));
memset(reg, 0, sizeof(RegUser));
reg->realname = (char *)MALLOC(6);
strcpy(reg->realname, "!DEL!");
reg->passwd = (char *)MALLOC(1);
*reg->passwd = '\0';
reg->match = (char *)MALLOC(6);
strcpy(reg->match, "!DEL!");
reg->channel = (char *)MALLOC(strlen(channel) + 1);
strcpy(reg->channel, channel);
reg->modif = (char *)MALLOC(1);
*reg->modif = '\0';
reg->modified = 1;
reg->offset = offset;
reg->next = UserList[idx];
UserList[idx] = reg;
}
/* read_db()
* This should be called from the select() loop. Data is read sequentially
* and the query is processed according to 'type'.
*/
void read_db(dbquery * query)
{
struct dbuser buffer[11];
int size, status, end = 0;
size = read(query->fd, buffer, 10 * sizeof(dbuser));
if (size <= 0)
{
if (errno != EAGAIN && errno != EWOULDBLOCK)
{
close(query->fd);
query->fd = -1;
}
return;
}
copy_to_buffer(&query->buf, (char *)buffer, size);
while (!end && look_in_buffer(&query->buf, (char *)buffer, '\0', sizeof(dbuser))
== sizeof(dbuser))
{
if (buffer[0].header[0] == 0xFF && buffer[0].header[1] == 0xFF &&
buffer[0].footer[0] == 0xFF && buffer[0].footer[1] == 0xFF)
{
status = 1; /* block is used */
}
else if (buffer[0].header[0] == 0x00 && buffer[0].header[1] == 0x00 &&
buffer[0].footer[0] == 0x00 && buffer[0].footer[1] == 0x00)
{
status = 0; /* block is free */
}
else
{
status = -1; /* block has been written to while reading it */
}
if (status == 1 && strcasecmp(query->channel, buffer[0].channel))
{
fix_db(query->channel, query->offset);
skip_char_in_buffer(&query->buf, sizeof(dbuser));
query->offset += sizeof(dbuser);
continue;
}
#ifdef DEBUG
printf("hdr: %X%X nick: %s match: %s passwd: %s channel: %s "
"modif: %s access: %d flags: %ld susp: %ld last: %ld ftr: %X%X"
"sta: %d\n",
buffer[0].header[0], buffer[0].header[1], buffer[0].nick, buffer[0].match, buffer[0].passwd,
buffer[0].channel, buffer[0].modif, buffer[0].access, buffer[0].flags, buffer[0].suspend,
buffer[0].lastseen, buffer[0].footer[0], buffer[0].footer[1], status);
#endif
switch (query->type)
{
case DBGETNICK:
if (status == 1 && !strcasecmp(buffer[0].nick, query->info))
{
close(query->fd);
query->fd = -1;
query->count++;
query->callback(&query->fd, query->offset, query->action, query->hook1,
query->hook2, buffer, query->count);
end = 1;
}
break;
case DBGET1STUH:
if (status == 1 && match(query->info, buffer[0].match))
{
close(query->fd);
query->fd = -1;
query->count++;
query->callback(&query->fd, query->offset, query->action, query->hook1,
query->hook2, buffer, query->count);
end = 1;
}
break;
case DBGETALLUH:
if (status == 1 && match(query->info, buffer[0].match))
{
query->count++;
query->callback(&query->fd, query->offset, query->action, query->hook1,
query->hook2, buffer, query->count);
}
break;
case DBGETUHPASS:
if (status == 1 && match(query->info, buffer[0].match) &&
!strcmp(query->passwd, buffer[0].passwd))
{
close(query->fd);
query->fd = -1;
query->count++;
query->callback(&query->fd, query->offset, query->action, query->hook1,
query->hook2, buffer, query->count);
end = 1;
}
break;
case DBCOUNTUH:
if (status == 1 && match(query->info, buffer[0].match))
{
query->count++;
}
break;
case DBGET1STCMP:
if (status == 1 && (!*query->info || compare(query->info, buffer[0].match)))
{
close(query->fd);
query->fd = -1;
query->count++;
query->callback(&query->fd, query->offset, query->action, query->hook1,
query->hook2, buffer, query->count);
end = 1;
}
break;
case DBGETALLCMP:
if (status == 1 && (!*query->info || compare(query->info, buffer[0].match)))
{
query->count++;
query->callback(&query->fd, query->offset, query->action, query->hook1,
query->hook2, buffer, query->count);
}
break;
case DBCNTCMP:
if (status == 1 && (!*query->info || compare(query->info, buffer[0].match)))
{
query->count++;
}
break;
case DBGET1STFREE:
if (status == 0)
{
close(query->fd);
query->fd = -1;
query->count++;
query->callback(&query->fd, query->offset, query->action, query->hook1,
query->hook2, buffer, query->count);
end = 1;
}
break;
}
skip_char_in_buffer(&query->buf, sizeof(dbuser));
query->offset += sizeof(dbuser);
if (query->fd < 0)
end = 1;
}
}
void end_db_read(dbquery * query)
{
zap_buffer(&query->buf);
query->callback(&query->fd, query->offset, query->action, query->hook1,
query->hook2, NULL, query->count);
}
void make_dbuser(RegUser * reg, dbuser * dbu)
{
memset(dbu, 0, sizeof(dbuser));
if (reg->access != 0)
{
strncpy(dbu->nick, reg->realname, 79);
dbu->nick[79] = '\0';;
strncpy(dbu->match, reg->match, 79);
dbu->match[79] = '\0';
strncpy(dbu->channel, reg->channel, 49);
dbu->channel[49] = '\0';
strncpy(dbu->passwd, reg->passwd, 19);
dbu->passwd[19] = '\0';
strncpy(dbu->modif, reg->modif, 79);
dbu->modif[79] = '\0';
dbu->access = reg->access;
dbu->flags = reg->flags;
dbu->suspend = reg->suspend;
dbu->lastseen = reg->lastseen;
dbu->header[0] = 0xFF;
dbu->header[1] = 0xFF;
dbu->footer[0] = 0xFF;
dbu->footer[1] = 0xFF;
}
}
void sync_next_channel(void)
{
register syncchan *tmp;
if ((tmp = SyncChan) != NULL)
{
SyncChan = SyncChan->next;
db_sync(tmp->name);
free(tmp);
}
}
static void set_sync(dbsync * sync)
{
struct dbuser dbu;
if (*sync->reg == NULL)
{
close(sync->fd);
sync->fd = -1;
return;
}
if ((*sync->reg)->access == 0) /* delete */
{
make_dbuser(*sync->reg, &dbu);
zap_buffer(&sync->buf);
copy_to_buffer(&sync->buf, (char *)&dbu, sizeof(dbuser));
sync->type = SYNC_DELETE;
sync->status = SYNC_PENDWRITE;
sync->offset = (*sync->reg)->offset;
lseek(sync->fd, (*sync->reg)->offset, SEEK_SET);
}
else if ((*sync->reg)->offset != (off_t) - 1) /* update */
{
make_dbuser(*sync->reg, &dbu);
zap_buffer(&sync->buf);
copy_to_buffer(&sync->buf, (char *)&dbu, sizeof(dbuser));
sync->type = SYNC_UPDATE;
sync->status = SYNC_PENDWRITE;
sync->offset = (*sync->reg)->offset;
lseek(sync->fd, (*sync->reg)->offset, SEEK_SET);
}
else
/* add */
{
sync->type = SYNC_ADD;
sync->status = SYNC_SEEKFREE;
sync->offset = (off_t) 0;
lseek(sync->fd, 0L, SEEK_SET);
}
}
static void sync_next(dbsync * sync, char *channel)
{
register RegUser **reg = sync->reg;
if (*reg == NULL)
{
close(sync->fd);
sync->fd = -1;
return;
}
while (*reg != NULL && ((*reg)->modified == 0 || (*reg)->access == 1000 ||
strcasecmp((*reg)->channel, channel)))
{
if ((*reg)->inuse == 0 && (*reg)->lastused + CACHE_TIMEOUT < now)
free_user(reg);
else
reg = &(*reg)->next;
}
sync->time = now;
sync->reg = reg;
set_sync(sync);
}
void db_sync(char *channel)
{
register RegUser **reg, *tmp;
register char *ch;
register dbsync *sync;
struct stat st;
int fd;
#ifdef DEBUG
printf("SYNC: %s\n", channel);
#endif
if (DBSync != NULL && (DBSync->fd != -1 || DBSync->next != NULL))
{
log("ERROR: simultaneous syncs??");
return;
}
ch = make_dbfname(channel);
/* IF file does not exist.. remove all deletes and mark
* all other entries as new.
*/
if (stat(ch, &st) < 0)
{
/* remove all deletes */
reg = &UserList[ul_hash(channel)];
while (*reg)
{
(*reg)->offset = (off_t) - 1;
if ((*reg)->access == 0 && (*reg)->inuse == 0 &&
!strcasecmp((*reg)->channel, channel))
{
tmp = *reg;
*reg = (*reg)->next;
free_user(reg);
}
else
reg = &(*reg)->next;
}
fd = open(ch, O_RDWR | O_CREAT | O_EXCL | O_NONBLOCK, 0600);
}
else
{
fd = open(ch, O_RDWR | O_NONBLOCK);
}
/* create new sync struct
*/
sync = (dbsync *) malloc(sizeof(dbsync));
sync->fd = fd;
sync->reg = &UserList[ul_hash(channel)];
sync->buf = NULL;
sync->next = DBSync;
DBSync = sync;
sync_next(sync, channel);
}
void db_sync_ready(dbsync * sync)
{
struct dbuser buffer[10];
register RegUser **reg = sync->reg;
int size;
#ifdef DEBUG
printf("SYNC_READY: status= %d\n", sync->status);
#endif
if (sync->status == SYNC_PENDWRITE)
{
size = look_in_buffer(&sync->buf, (char *)buffer, '\0', sizeof(dbuser));
if (size == 0)
zap_buffer(&sync->buf);
if (sync->buf == NULL)
{
if ((*reg)->access == 0 && (*reg)->inuse == 0)
free_user(reg);
else
(*reg)->modified = 0;
sync_next(sync, (*reg)->channel);
return;
}
#ifdef DEBUG
printf("PENDWRITE: %d bytes to write...", size);
#endif
size = write(sync->fd, buffer, size);
#ifdef DEBUG
printf("%d written\n", size);
#endif
if (size <= 0)
{
if (errno != EWOULDBLOCK && errno != EAGAIN)
{
close(sync->fd);
sync->fd = -1;
}
return;
}
skip_char_in_buffer(&sync->buf, size);
}
else if (sync->status == SYNC_SEEKFREE)
{
size = read(sync->fd, buffer, 10 * sizeof(dbuser));
if (size <= 0)
{
if (errno != EAGAIN && errno != EWOULDBLOCK)
{
make_dbuser(*sync->reg, buffer);
zap_buffer(&sync->buf);
copy_to_buffer(&sync->buf, (char *)buffer, sizeof(dbuser));
sync->status = SYNC_PENDWRITE;
lseek(sync->fd, 0L, SEEK_END);
}
return;
}
copy_to_buffer(&sync->buf, (char *)buffer, size);
while (look_in_buffer(&sync->buf, (char *)buffer, '\0', sizeof(dbuser))
== sizeof(dbuser))
{
if (buffer[0].header[0] == 0x00 && buffer[0].header[1] == 0x00 &&
buffer[0].footer[0] == 0x00 && buffer[0].footer[1] == 0x00)
{
make_dbuser(*sync->reg, buffer);
zap_buffer(&sync->buf);
copy_to_buffer(&sync->buf, (char *)buffer, sizeof(dbuser));
sync->status = SYNC_PENDWRITE;
(*sync->reg)->offset = sync->offset;
lseek(sync->fd, sync->offset, SEEK_SET);
return;
}
skip_char_in_buffer(&sync->buf, sizeof(dbuser));
sync->offset += sizeof(dbuser);
}
}
}
void end_db_sync(dbsync * sync)
{
#ifdef DEBUG
printf("SYNC_END\n");
#endif
sync_next_channel();
return;
}
void cold_save_one(RegUser * reg)
{
struct stat st;
dbuser dbu;
char *fname;
register int fd;
off_t off;
fname = make_dbfname(reg->channel);
if (stat(fname, &st) < 0) /* file doesn't exist -- don't save delete */
{
if (reg->access == 0)
return;
fd = open(fname, O_RDWR | O_CREAT, 0600);
}
else
fd = open(fname, O_RDWR | O_EXCL);
if (fd < 0) /* hmmm? */
return;
if (reg->offset == (off_t) - 1) /* new ==> seek for empty slot */
{
lseek(fd, 0L, SEEK_SET);
off = (off_t) 0;
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
{
if (dbu.header[0] == 0x00 && dbu.header[1] == 0x00 &&
dbu.footer[0] == 0x00 && dbu.footer[1] == 0x00)
break; /* found empty slot */
off += sizeof(dbuser);
}
}
else
off = reg->offset;
lseek(fd, off, SEEK_SET); /* go to write position */
if (reg->access != 0)
make_dbuser(reg, &dbu);
else
memset(&dbu, 0, sizeof(dbuser));
write(fd, &dbu, sizeof(dbuser));
if (reg->access != 0)
reg->offset = off;
else
reg->offset = (off_t) - 1;
reg->modified = 0;
close(fd);
}
void do_cold_sync_slice(void)
{
register RegUser **reg;
if (DB_Save_Status < 0)
return;
reg = &UserList[DB_Save_Status];
while (*reg != NULL)
{
if ((*reg)->modified && (*reg)->access < 1000)
cold_save_one(*reg);
if ((*reg)->inuse == 0 && (*reg)->access < 1000 &&
((*reg)->access == 0 || (*reg)->lastused + CACHE_TIMEOUT < now))
free_user(reg);
else
reg = &(*reg)->next;
}
if (++DB_Save_Status == 1000)
{
DB_Save_Status = -1;
if (*DB_Save_Nick)
notice(DB_Save_Nick, "Userlist sync complete!");
}
}
void do_cold_sync(void)
{
register dbsync *sync;
register syncchan *schan;
register RegUser **reg;
register int i;
char buffer[200];
/* SET AWAY MESSAGE */
sprintf(buffer, ":%s AWAY :Busy saving precious user list\n", mynick);
sendtoserv(buffer);
dumpbuff();
/* First, cancel *all* sync requests */
while ((sync = DBSync) != NULL)
{
DBSync = DBSync->next;
if (sync->fd >= 0)
close(sync->fd);
zap_buffer(&sync->buf);
free(sync);
}
/* Also, clear *all* pending syncs */
while ((schan = SyncChan) != NULL)
{
SyncChan = SyncChan->next;
free(schan);
}
/* Now, go thru *all* the user entries in memory and save them
* to their respective files.
*/
for (i = 0; i < 1000; i++)
{
reg = &UserList[i];
while (*reg != NULL)
{
if ((*reg)->modified && (*reg)->access < 1000)
cold_save_one(*reg);
if ((*reg)->inuse == 0 && (*reg)->access < 1000 &&
((*reg)->access == 0 || (*reg)->lastused + CACHE_TIMEOUT < now))
free_user(reg);
else
reg = &(*reg)->next;
}
}
sprintf(buffer, ":%s AWAY\n", mynick);
sendtoserv(buffer);
}
#ifdef DEBUG
void db_test_callback(int *fd, off_t off, int action, void *hook1, void *hook2,
dbuser * dbu, int count)
{
char buffer[512];
sprintf(buffer, "off: %ld act: %d hook=%p cnt: %d", off, action, hook1, count);
notice((char *)hook1, buffer);
if (dbu)
{
sprintf(buffer, "hdr: %X%X nick: %s match: %s passwd: %s channel: %s "
"modif: %s access: %d flags: %ld susp: %ld last: %ld ftr: %X%X",
dbu->header[0], dbu->header[1], dbu->nick, dbu->match, dbu->passwd,
dbu->channel, dbu->modif, dbu->access, dbu->flags, dbu->suspend,
dbu->lastseen, dbu->footer[0], dbu->footer[1]);
notice((char *)hook1, buffer);
}
else
{
notice((char *)hook1, "End.");
free(hook1);
}
}
void db_test(char *source, char *chan, char *args)
{
char channel[80], type[80], info[80], *hook;
GetWord(0, args, channel);
GetWord(1, args, type);
GetWord(2, args, info);
hook = (char *)malloc(strlen(source) + 1);
strcpy(hook, source);
if (!strcmp(type, "nick"))
db_fetch(channel, DBGETNICK, info, NULL, 0, hook, NULL, db_test_callback);
else if (!strcmp(type, "alluh"))
db_fetch(channel, DBGETALLUH, info, NULL, 0, hook, NULL, db_test_callback);
else if (!strcmp(type, "1stuh"))
db_fetch(channel, DBGET1STUH, info, NULL, 0, hook, NULL, db_test_callback);
else if (!strcmp(type, "count"))
db_fetch(channel, DBCOUNTUH, info, NULL, 0, hook, NULL, db_test_callback);
else if (!strcmp(type, "1stcmp"))
db_fetch(channel, DBGET1STCMP, info, NULL, 0, hook, NULL, db_test_callback);
else if (!strcmp(type, "allcmp"))
db_fetch(channel, DBGETALLCMP, info, NULL, 0, hook, NULL, db_test_callback);
else if (!strcmp(type, "cntcmp"))
db_fetch(channel, DBCNTCMP, info, NULL, 0, hook, NULL, db_test_callback);
else if (!strcmp(type, "sync"))
db_sync(channel);
}
#endif

43
Sources/dbio.h Normal file
View File

@@ -0,0 +1,43 @@
/* @(#)$Id: dbio.h,v 1.3 1996/11/13 00:40:36 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#define DBGETNICK 0x00000001
#define DBGET1STUH 0x00000002
#define DBGETALLUH 0x00000004
#define DBCOUNTUH 0x00000008
#define DBGET1STCMP 0x00000010
#define DBGETALLCMP 0x00000020
#define DBCNTCMP 0x00000040
#define DBGETUHPASS 0x00000080
#define DBGET1STFREE 0x00000100
#define SYNC_UPDATE 0x00000001
#define SYNC_DELETE 0x00000002
#define SYNC_ADD 0x00000004
#define SYNC_PENDWRITE 0x00000001
#define SYNC_SEEKFREE 0x00000002

70
Sources/debug.c Normal file
View File

@@ -0,0 +1,70 @@
/* @(#)$Id: debug.c,v 1.3 1996/11/13 00:40:36 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#ifdef DEBUG_MALLOC
#include <stdarg.h>
#undef malloc
#undef free
static FILE *debug_malloc_file;
void open_debug_malloc(void)
{
debug_malloc_file=fopen("malloc.log","w");
}
void close_debug_malloc(void)
{
fclose(debug_malloc_file);
}
void log_malloc(char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
vfprintf(debug_malloc_file,fmt,ap);
va_end(ap);
}
void *debug_malloc(char *file, int line, size_t size)
{
register void *ptr;
ptr=malloc(size);
log_malloc("%s(%d):malloc(%ld)= %p\n",file,line,(long)size,ptr);
return ptr;
}
void debug_free(char *file, int line, void *ptr)
{
log_malloc("%s(%d):free(%p)\n",file,line,ptr);
free(ptr);
}
#endif

37
Sources/debug.h Normal file
View File

@@ -0,0 +1,37 @@
/* @(#)$Id: debug.h,v 1.3 1996/11/13 00:40:37 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#ifdef DEBUG_MALLOC
void open_debug_malloc(void);
void close_debug_malloc(void);
void *debug_malloc(char *,int,size_t);
void debug_free(char *,int,void *);
#define malloc(X) debug_malloc(__FILE__,__LINE__,X)
#define free(X) debug_free(__FILE__,__LINE__,X)
#endif

493
Sources/defchan.c Normal file
View File

@@ -0,0 +1,493 @@
/* @(#)$Id: defchan.c,v 1.7 1999/12/19 16:33:13 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#define FORMATNO 0x02
typedef struct adefchan0 {
char name[50];
char mode[80];
char reserved[20];
int MassDeopPro;
int NickFloodPro;
int MsgFloodPro;
time_t TS;
unsigned long flags;
unsigned long uflags;
struct adefchan *next;
} adefchan0;
typedef struct adefchan1 {
char name[50];
char mode[80];
int MassDeopPro;
int NickFloodPro;
int MsgFloodPro;
int lang;
time_t TS;
unsigned long flags;
unsigned long uflags;
struct adefchan *next;
} adefchan1;
static int active=0;
void SearchChan(char *source,char *ch,char *args)
{
char buffer[200],keylist[512];
char *tok[16];
adefchan *list[11];
register adefchan *curr;
register int found=0,i=0;
if(!*args){
notice(source,"SYNTAX: search <keywords>");
return;
}
strcpy(keylist,args);
tok[0]=strtok(keylist," ");
while(i<16 && (tok[++i]=strtok(NULL," "))!=NULL);
tok[i]=NULL;
for(curr=DefChanList; curr; curr=curr->next){
if((key_match(curr->name,tok)||key_match(curr->topic,tok)) &&
!IsSet(curr->name,'s',"") && !IsSet(curr->name,'p',"")){
list[found]=curr;
found++;
if(found>10){
sprintf(buffer,"There are more than 10 entries matching [%s]",args);
notice(source,buffer);
sprintf(buffer,"Please restrict your search mask");
notice(source,buffer);
return;
}
}
}
if(!found){
sprintf(buffer,"No matching entries for [%s]",args);
notice(source,buffer);
return;
}
for(i=0; i<found; i++){
sprintf(buffer,"%-15s - %s",list[i]->name,list[i]->topic);
notice(source,buffer);
}
}
void AddChan(char *source,char *ch,char *args)
{
char buffer[200];
char channel[80];
register adefchan *curr,**scan;
register achannel *chan;
register int found=0;
if(*args=='#'){
GetWord(0,args,channel);
}else{
strcpy(channel,ch);
GuessChannel(source,channel);
}
if(!strcmp(channel,"*")){
notice(source,"SYNTAX: addchan <channel>");
return;
}
chan=ToChannel(channel);
if(chan==NULL || !chan->on){
notice(source,replies[RPL_NOTONCHANNEL][L_DEFAULT]);
return;
}
if(Access(channel,source)<SET_DEFAULT_LEVEL){
ReplyNotAccess(source,channel);
return;
}
chan=ChannelList[cl_hash(channel)];
while(chan && !found){
if(!strcasecmp(chan->name,channel)){
/* look if the channel is already in the
* default channels list
*/
curr=DefChanList;
while(curr&&strcasecmp(curr->name,channel))
curr=curr->next;
/* The channel *IS NOT* in the list */
if(curr==NULL){
curr=(adefchan *)MALLOC(sizeof(adefchan));
scan=&DefChanList;
while(*scan && strcasecmp((*scan)->name,chan->name)<0)
scan=&(*scan)->next;
curr->next=*scan;
*scan=curr;
curr->url[0]='\0';
curr->topic[0]='\0';
}
strcpy(curr->name,chan->name);
strcpy(curr->mode,chan->mode);
curr->MassDeopPro=chan->MassDeopPro;
curr->NickFloodPro=chan->NickFloodPro;
curr->MsgFloodPro=chan->MsgFloodPro;
curr->lang=chan->lang;
curr->flags=chan->flags;
curr->uflags=chan->uflags;
curr->TS=chan->TS;
found=1;
}else
chan=chan->next;
}
sprintf(buffer,"I ADD DEFAULT CHANNEL %s",channel);
log(buffer);
if(found){
notice(source,replies[RPL_SETCHANDEFS][chan->lang]);
#ifdef BACKUP
notice(source,"This modification will not be permanent");
#endif
}else{
notice(source,replies[RPL_NOTONCHANNEL][L_DEFAULT]);
}
}
void RemChan(char *source, char *ch, char *arg)
{
char buffer[200];
char channel[80];
register adefchan *chan,*prev;
if(*arg=='#'){
GetWord(0,arg,channel);
}else{
strcpy(channel,ch);
GuessChannel(source,channel);
}
if(!strcmp(channel,"*")){
notice(source,"SYNTAX: remchan <channel>");
return;
}
if(*source && Access(channel,source)<SET_DEFAULT_LEVEL){
ReplyNotAccess(source,channel);
return;
}
prev=NULL;
for(chan=DefChanList;chan&&strcasecmp(channel,chan->name);chan=chan->next)
prev=chan;
if(!chan){
notice(source,replies[RPL_NOTDEF][L_DEFAULT]);
return;
}
if(prev)
prev->next=chan->next;
else
DefChanList=chan->next;
TTLALLOCMEM-=sizeof(adefchan);
free(chan);
sprintf(buffer,"I REMOVE DEFAULT CHANNEL %s",channel);
log(buffer);
if(*source){
notice(source,replies[RPL_REMDEF][L_DEFAULT]);
#ifdef BACKUP
notice(source,"This modification will not be permanent");
#endif
}
}
void SaveDefs(char *source)
{
register int file;
register adefchan *curr;
adefchan buff;
filehdr hdr;
char global[]="*";
char buffer[200];
if(*source&&Access(global,source)<SAVE_DEFAULTS_LEVEL){
notice(source,"Your admin Access is too low!");
return;
}
if(*source)
notice(source,"Saving defaults file...");
if(active)
return;
active=1;
sprintf(buffer,":%s AWAY :Busy saving precious channel list\n",mynick);
sendtoserv(buffer);
dumpbuff();
alarm(5); /* avoid NFS hangs */
file=open(DEFAULT_CHANNELS_FILE".new",O_WRONLY|O_CREAT|O_TRUNC,0600);
alarm(0);
if(file<0){
if(*source)
notice(source,"Error while opening file. Aborted!");
log("ERROR Saving defaults channels");
}else{
hdr.magic=0xff;
hdr.no=FORMATNO;
alarm(2);
if(write(file,&hdr,sizeof(hdr))<=0){
alarm(0);
close(file);
log("ERROR: Can't save channel list");
log((char *)sys_errlist[errno]);
alarm(2);
remove(DEFAULT_CHANNELS_FILE".new");
alarm(0);
active=0;
sprintf(buffer,":%s AWAY\n",mynick);
sendtoserv(buffer);
return;
}
alarm(0);
curr=DefChanList;
while(curr){
achannel *chan = ToChannel(curr->name);
buff = *curr;
if(chan)
buff.TS = chan->TS;
else
buff.TS = curr->TS;
buff.flags = curr->flags;
alarm(2);
if(write(file,&buff,sizeof(adefchan))<=0){
alarm(0);
close(file);
log("ERROR: Can't save channel list");
log((char *)sys_errlist[errno]);
alarm(2);
remove(DEFAULT_CHANNELS_FILE".new");
alarm(0);
active=0;
sprintf(buffer,":%s AWAY\n",mynick);
sendtoserv(buffer);
return;
}
alarm(0);
curr=curr->next;
}
close(file);
alarm(20);
rename(DEFAULT_CHANNELS_FILE".new",DEFAULT_CHANNELS_FILE);
alarm(0);
if(*source)
notice(source,"Done.");
}
active=0;
sprintf(buffer,":%s AWAY\n",mynick);
sendtoserv(buffer);
}
void LoadDefs(char *source)
{
register adefchan *curr,**scan;
adefchan buffer;
adefchan0 bufold0;
adefchan1 bufold1;
filehdr hdr;
register int file;
char global[]="*";
if(*source&&Access(global,source)<LOAD_DEFAULT_LEVEL){
notice(source,"Your admin Access is too low!");
return;
}
if(active)
return;
active=1;
file=open(DEFAULT_CHANNELS_FILE,O_RDONLY);
if(file<0){
if(*source) notice(source,"Error opening file! Aborted.");
log("ERROR Loading the default channels");
active=0;
return;
}
/* empty existing defaults */
while((curr=DefChanList)!=NULL){
DefChanList=DefChanList->next;
TTLALLOCMEM-=sizeof(adefchan);
free(curr);
}
/* find file format */
read(file,&hdr,sizeof(hdr));
if(hdr.magic!=0xff){
lseek(file,0L,SEEK_SET);
hdr.no=0x00;
}
if(hdr.no == FORMATNO){
scan=&DefChanList;
while(read(file,&buffer,sizeof(adefchan))>0){
#ifdef DEBUG
printf("DEFCHAN: %s %d %d %d %ld\n",buffer.name,
buffer.MassDeopPro,buffer.NickFloodPro,
buffer.MsgFloodPro,buffer.flags);
printf("TS: %lu\n",buffer.TS);
#endif
if(logTS==0||buffer.TS<logTS){
#ifdef DEBUG
printf("TS is older than %lu\n",logTS);
#endif
logTS=buffer.TS;
}
if(buffer.TS<0){
/* if the TS of a channel is negative
* the file is prolly corrupted!
*/
log("Channel file is corrupted");
quit("LoadDefs(): corrupted file!", 1);
}
curr=(adefchan *)MALLOC(sizeof(adefchan));
*curr=buffer;
curr->next=*scan;
*scan=curr;
scan=&(*scan)->next;
}
}else if(hdr.no == 0x01){
while(read(file,&bufold1,sizeof(adefchan1))>0){
#ifdef DEBUG
printf("DEFCHAN: %s %d %d %d %ld\n",bufold1.name,
bufold1.MassDeopPro,bufold1.NickFloodPro,
bufold1.MsgFloodPro,bufold1.flags);
printf("TS: %lu\n",bufold1.TS);
#endif
if(logTS==0||bufold1.TS<logTS){
#ifdef DEBUG
printf("TS is older than %lu\n",logTS);
#endif
logTS=bufold1.TS;
}
if(bufold1.TS<0){
/* if the TS of a channel is negative
* the file is prolly corrupted!
*/
log("Channel file is corrupted");
quit("LoadDefs(): corrupted file!", 1);
}
curr=(adefchan *)MALLOC(sizeof(adefchan));
strcpy(curr->name,bufold1.name);
strcpy(curr->mode,bufold1.mode);
curr->url[0]='\0';
curr->topic[0]='\0';
curr->MassDeopPro=bufold1.MassDeopPro;
curr->NickFloodPro=bufold1.NickFloodPro;
curr->MsgFloodPro=bufold1.MsgFloodPro;
curr->lang=bufold1.lang;
curr->TS=bufold1.TS;
curr->flags=bufold1.flags;
curr->uflags=bufold1.uflags;
scan=&DefChanList;
while(*scan && strcasecmp((*scan)->name,curr->name)<0)
scan=&(*scan)->next;
curr->next=*scan;
*scan=curr;
}
}else{ /* old file format */
while(read(file,&bufold0,sizeof(adefchan0))>0){
#ifdef DEBUG
printf("DEFCHAN: %s %d %d %d %ld\n",bufold0.name,
bufold0.MassDeopPro,bufold0.NickFloodPro,
bufold0.MsgFloodPro,bufold0.flags);
printf("TS: %lu\n",bufold0.TS);
#endif
if(logTS==0||bufold0.TS<logTS){
#ifdef DEBUG
printf("TS is older than %lu\n",logTS);
#endif
logTS=bufold0.TS;
}
if(bufold0.TS<0){
/* if the TS of a channel is negative
* the file is prolly corrupted!
*/
log("Channel file is corrupted");
quit("LoadDefs(): corrupted file!", 1);
}
curr=(adefchan *)MALLOC(sizeof(adefchan));
strcpy(curr->name,bufold0.name);
strcpy(curr->mode,bufold0.mode);
curr->url[0]='\0';
curr->topic[0]='\0';
curr->MassDeopPro=bufold0.MassDeopPro;
curr->NickFloodPro=bufold0.NickFloodPro;
curr->MsgFloodPro=bufold0.MsgFloodPro;
curr->lang=L_DEFAULT;
curr->TS=bufold0.TS;
curr->flags=bufold0.flags;
curr->uflags=bufold0.uflags;
scan=&DefChanList;
while(*scan && strcasecmp((*scan)->name,curr->name)<0)
scan=&(*scan)->next;
curr->next=*scan;
*scan=curr;
}
}
close(file);
if(*source)
notice(source,"Defaults file loaded!");
active=0;
}

141
Sources/defines.h Normal file
View File

@@ -0,0 +1,141 @@
/* @(#)$Id: defines.h,v 1.11 2000/06/04 16:54:16 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#define NICK_LENGTH 20
#define USERNAME_LENGTH 20
#define SITE_LENGTH 80
#define REALNAME_LENGTH 80
#define CHANNELNAME_LENGTH 80
#define SERVER_NAME_LENGTH 80
#define PASSWD_LENGTH 20
#define COMMAND_PREFIX "X "
#define MAX_MODE_PER_LINE 6
#define MAX_DEOP_RATE 3 /* deops within 15 seconds */
#define MASSDEOP_SUSPEND_TIME 600 /* seconds */
#define MASSDEOP_SHITLIST_TIME 1 /* hours */
#define MASSDEOP_SHITLIST_LEVEL 20
#define MAX_NICKCHANGE_RATE 5 /* nick change within 15 seconds */
#define NICK_FLOOD_SUSPEND_TIME 600 /* seconds */
#define MAX_PUBLIC_MSG_RATE 7 /* within 15 seconds */
#define PUBLIC_FLOOD_SUSPEND_TIME 600 /* seconds */
#define PUBLIC_FLOOD_SHITLIST_TIME 24 /* hour */
#define PUBLIC_FLOOD_SHITLIST_LEVEL 75
#define PRIVATE_FLOOD_RATE 10 /* messages per 30 seconds */
#define PRIVATE_FLOOD_SIZE 800 /* bytes per 30 seconds */
#define FLOOD_FLOOD_RATE 10 /* messages per 30 seconds */
#define FLOOD_FLOOD_SIZE 60 /* lines per 30 seconds */
#define MAX_IGNORE_PER_SITE 3 /* ignores per site */
#define IGNORE_TIME 3600 /* in seconds */
#define FLOOD_FLOOD_IGNORE 300 /* in seconds */
#define LEVEL_DIE 900
#define LEVEL_CORE 900
#define RUSAGE_ACCESS 900
#define LEVEL_UPGRADE 900
#define LEVEL_JOIN 450
#define LEVEL_PART 450
#define INVITE_LEVEL 100
#define OP_LEVEL 100
#define TOPIC_LEVEL 50
#define KICK_LEVEL 50
#define MASS_KICK_LEVEL 200
#define BAN_LEVEL 75
#define MASS_BAN_LEVEL 200
#define ADD_USER_LEVEL 400
#define SHOW_ACCESS_LEVEL 0
#define REMOVE_USER_LEVEL 400
#define MOD_USERINFO_LEVEL 400
#define LEVEL_SUSPEND 100
#define ADD_TO_SHITLIST_LEVEL 75
#define CLEAN_SHITLIST_LEVEL 200
#define SET_DEFAULT_LEVEL 450
#define LOAD_DEFAULT_LEVEL 999
#define SAVE_DEFAULTS_LEVEL 600
#define SAVE_SHITLIST_LEVEL 600
#define LOAD_SHITLIST_LEVEL 999
#define SAVE_USERLIST_LEVEL 600
#define LOAD_USERLIST_LEVEL 999
#define STATUS_ACCESS 1
#define STATUS_ACCESS_MODE 200
#define CH_FLOOD_LIMIT_LEVEL 500
#define CH_NICK_FLOOD_LIMIT_LEVEL 450
#define CH_MASSDEOP_LIMIT_LEVEL 450
#define CH_NOOP_LEVEL 500
#define CH_OPONLY_LEVEL 500
#define CH_AUTOTOPIC_LEVEL 450
#define CH_ALWAYSOP_LEVEL 450
#define CH_STRICTOP_LEVEL 500
#define CH_USERFLAGS_LEVEL 450
#define CH_LANG_LEVEL 500
#define CH_TOPIC_LEVEL 450
#define CH_URL_LEVEL 450
#define ACCESS_BAN_PRIORITY 450
#define ALWAYSOP_OVERRIDE_LEVEL 450
#define PROTECT_OVERRIDE_LEVEL 450
#define MASSDEOP_IMMUNE_LEVEL 450
#define CLEARMODE_LEVEL 400
#define XADMIN_LEVEL 750
#define AUTO_KICK_SHIT_LEVEL 75
#define NO_OP_SHIT_LEVEL 20
#define SHITLIST_DEFAULT_TIME (24*3) /* hours */
#define SUSPEND_TIME_FOR_OPPING_A_SHITLISTED_USER 600 /* seconds */
#define SUSPEND_TIME_FOR_BANNING_A_PROTECTED_USER 600 /* seconds */
#define DEOPME_SUSPEND_TIME 3600 /* seconds */
#define DEOP_SHITLIST_TIME 1 /* hours */
#define DEOP_SHITLIST_LEVEL 20
#define MAX_BAN 50
#define MIN_LASTSEEN (3*24*3600) /* 3 days */
#define HTTP_LISTEN 1
#define HTTP_ACTIVE 2
#define HTTP_ENDING 3
#define HTTP_RECV_POST 4
#define HTTP_PIPE 5
#define HTTP_CSRAW 6
#define HTTP_CHAT 7
#define HTTP_ERROR 0
#define MISC_GETPATCH 1
#define MISC_PIPE_PATCH 2
#define MISC_PIPE_MAKE 3
#define MISC_ERROR -1
#define MISC_CONNECTING 1
#define MISC_HANDSHAKE 2
#define MISC_RECV 3
#define BUFFER_BLOCK_SIZE 512
#define CACHE_TIMEOUT 4800 /* 1.5 hours */
#define AUTOTOPIC_FREQ 1800 /* 30 minutes*/

189
Sources/events.c Normal file
View File

@@ -0,0 +1,189 @@
/* @(#)$Id: events.c,v 1.6 1998/01/02 18:30:09 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
void InitEvent(void)
{
AddEvent(EVENT_SAVESHITLIST, now + SHITLIST_SAVE_FREQ + 300, "");
AddEvent(EVENT_SAVEDEFCHANNELS, now + DEFS_SAVE_FREQ + 600, "");
AddEvent(EVENT_SYNC, now + SYNC_FREQ + 900, "");
AddEvent(EVENT_CHECK_IDLE, now + CHECK_IDLE_FREQ, "");
AddEvent(EVENT_RENAME_LOGFILE, now + RENAME_LOGFILE_FREQ, "");
AddEvent(EVENT_SYNCDB, now + CACHE_TIMEOUT, "");
#ifdef CHANNEL_LOG
AddEvent(EVENT_LOG_CHANNEL, now + CHANNEL_LOG_FREQ, "");
#endif
#ifdef NICKSERV
AddEvent(EVENT_SAVENICKSERV, now + NSERV_SAVE_FREQ, "");
#endif
}
void AddEvent(int event, time_t time, char *param)
{
register anevent **curr = &EventList;
register anevent *new;
#ifdef DEBUG
printf("AddEvent( %d, %ld, %s)\n", event, time, param);
#endif
/* the events are store in ascending time order, so the new
* event is inserted before the first event with a greater
* time
*/
while (*curr && (*curr)->time < time)
curr = &(*curr)->next;
/* create a new event structure
*/
new = (anevent *) MALLOC(sizeof(anevent));
new->time = time;
new->event = event;
strncpy(new->param, param, 79);
new->param[79] = '\0';
/* link the new structure to the list
*/
new->next = *curr;
*curr = new;
}
void CheckEvent(void)
{
register anevent *curr;
register achannel *chan;
while (EventList != NULL && EventList->time <= now)
{
/* remove the event from the list */
curr = EventList;
EventList = EventList->next;
#ifdef DEBUG
printf("Scheduled event %d\n", curr->event);
#endif
switch (curr->event)
{
case EVENT_SAVEUSERLIST:
/* replaced by SYNCDB */
break;
case EVENT_SAVESHITLIST:
SaveShitList("", "");
AddEvent(EVENT_SAVESHITLIST,
now + SHITLIST_SAVE_FREQ, "");
break;
case EVENT_SAVEDEFCHANNELS:
SaveDefs("");
AddEvent(EVENT_SAVEDEFCHANNELS,
now + DEFS_SAVE_FREQ, "");
break;
case EVENT_CLEANSHITLIST:
CleanShitList("", curr->param);
break;
case EVENT_FLUSHMODEBUFF:
flushmode(curr->param);
break;
case EVENT_GETOPS:
chan = ToChannel(curr->param);
if (chan != NULL && chan->on &&
(IsOpless(curr->param) ||
((chan->flags & CFL_ALWAYSOP) &&
!chan->AmChanOp)))
GetOps(curr->param);
break;
case EVENT_SYNC:
sync();
AddEvent(EVENT_SYNC,
now + SYNC_FREQ, "");
break;
case EVENT_CLEAN_IGNORES:
CleanIgnores();
break;
case EVENT_CHECK_IDLE:
CheckIdleChannels();
AddEvent(EVENT_CHECK_IDLE, now + CHECK_IDLE_FREQ, "");
break;
case EVENT_RENAME_LOGFILE:
log("Closing log file");
close(logfile);
rename(LOGFILE, LOGFILEBAK);
logfile = open(LOGFILE, O_WRONLY | O_CREAT | O_APPEND, 0600); /* "a" in case rename() fails */
log("Opening log file");
AddEvent(EVENT_RENAME_LOGFILE, now + RENAME_LOGFILE_FREQ, "");
break;
case EVENT_SYNCDB:
if (DB_Save_Status == -1)
{
DB_Save_Status = 0;
*DB_Save_Nick = '\0';
}
/*SaveUserList("",""); */
/*
gather_sync_channels();
if(DBSync==NULL)
sync_next_channel();
sync_next_channel();
*/
AddEvent(EVENT_SYNCDB, now + CACHE_TIMEOUT, "");
break;
#ifdef CHANNEL_LOG
case EVENT_LOG_CHANNEL:
LogChan();
AddEvent(EVENT_LOG_CHANNEL, now + CHANNEL_LOG_FREQ, "");
break;
#endif
#ifdef NICKSERV
case EVENT_CHECKREGNICK:
nserv_checkregnick(curr->param);
break;
case EVENT_SAVENICKSERV:
nserv_save();
break;
#endif
default:
#ifdef DEBUG
printf("Err.. unknown event %d\n", curr->event);
#endif
break;
}
TTLALLOCMEM -= sizeof(anevent);
free(curr);
}
}

40
Sources/events.h Normal file
View File

@@ -0,0 +1,40 @@
/* @(#)$Id: events.h,v 1.4 1997/07/01 21:51:08 cvs Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#define EVENT_SAVEUSERLIST 1
#define EVENT_SAVESHITLIST 2
#define EVENT_SAVEDEFCHANNELS 3
#define EVENT_SYNC 4
#define EVENT_CLEANSHITLIST 5
#define EVENT_FLUSHMODEBUFF 6
#define EVENT_GETOPS 7
#define EVENT_CLEAN_IGNORES 8
#define EVENT_CHECK_IDLE 9
#define EVENT_RENAME_LOGFILE 10
#define EVENT_LOG_CHANNEL 11
#define EVENT_SYNCDB 12
#define EVENT_CHECKREGNICK 13
#define EVENT_SAVENICKSERV 14

203
Sources/fixdb.c Normal file
View File

@@ -0,0 +1,203 @@
/* @(#)$Id: fixdb.c,v 1.5 1998/01/12 20:02:17 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#include "dirent.h"
#define SPECFILE "special.log"
struct node
{
dbuser dbu;
struct node *next;
};
unsigned long ttlread = 0L, ttlwrite = 0L;
time_t now;
void SpecLog(char *text)
{
int fd;
char date[80], buffer[1024];
strcpy(date, ctime(&now));
*strchr(date, '\n') = '\0';
if ((fd = open(SPECFILE, O_WRONLY | O_CREAT | O_APPEND, 0600)) >= 0)
{
sprintf(buffer, "%s: %s\n", date, text);
write(fd, buffer, strlen(buffer));
close(fd);
}
}
void fix_user_file(char *file, char *channel)
{
char tmpfile[256], buffer[200];
struct node *List = NULL, *tmp;
dbuser dbu;
int fd;
fd = open(file, O_RDONLY);
if (fd < 0)
{
fprintf(stderr, "Can't open %s [%s]\n", file, sys_errlist[errno]);
return;
}
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
{
ttlread += sizeof(dbuser);
if (dbu.header[0] != 0xFF || dbu.header[1] != 0xFF ||
dbu.footer[0] != 0xFF || dbu.footer[1] != 0xFF)
{
continue;
}
if (strcasecmp(channel, dbu.channel))
continue;
if (!strcmp(dbu.match, "!DEL!"))
continue;
if (dbu.lastseen + USERLIST_EXP_TIME <= now)
{
sprintf(buffer, "Exp: %s [%s] (%d) on %s",
dbu.nick, dbu.match, dbu.access, dbu.channel);
SpecLog(buffer);
continue;
}
tmp = (struct node *)malloc(sizeof(struct node));
memcpy(&tmp->dbu, &dbu, sizeof(dbuser));
tmp->next = List;
List = tmp;
}
close(fd);
sprintf(tmpfile, "%s.new", file);
fd = open(tmpfile, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd < 0)
{
fprintf(stderr, "Can't open %s\n", tmpfile);
/* don't return.. need to free the list! */
}
while ((tmp = List) != NULL)
{
write(fd, &tmp->dbu, sizeof(dbuser));
ttlwrite += sizeof(dbuser);
List = List->next;
free(tmp);
}
close(fd);
if (fd >= 0)
rename(tmpfile, file);
}
void fix_user_db(void)
{
DIR *dp;
struct dirent *ent;
char dir[256], file[256], channel[80], *ptr;
int count;
for (count = 0; count < 1000; count++)
{
sprintf(dir, "db/channels/%04X", count);
dp = opendir(dir);
if (dp == NULL)
{
fprintf(stderr, "Can't read %s [%s]\n", dir, sys_errlist[errno]);
continue;
}
while ((ent = readdir(dp)) != NULL)
{
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
continue;
strcpy(channel, ent->d_name);
for (ptr = channel; *ptr; ptr++)
if (*ptr == ' ')
*ptr = '/';
sprintf(file, "db/channels/%04X/%s", count, ent->d_name);
/* If no comma in channel name, proceed with clean up */
if (strchr(channel, ',') == NULL)
fix_user_file(file, channel);
}
closedir(dp);
}
}
int main(void)
{
int pid = 0;
FILE *fp;
if (chdir(HOMEDIR) < 0)
{
perror(HOMEDIR);
exit(1);
}
if ((fp = fopen(PIDFILE, "r")) != NULL)
{
fscanf(fp, "%d", &pid);
fclose(fp);
if (!kill((pid_t) pid, 0))
{
fprintf(stderr, "Detected cs is running [pid %d]. Abort.\n", pid);
exit(1);
}
}
if (rename("cs", "cs.fixdb") < 0)
{
perror("rename");
exit(1);
}
if (symlink("/bin/true", "cs") < 0)
{
perror("symlink");
exit(1);
}
time(&now);
fix_user_db();
if (unlink("cs") < 0)
perror("unlink");
if (rename("cs.fixdb", "cs") < 0)
perror("rename");
printf("ttlread= %ld ttlwrite= %ld\n", ttlread, ttlwrite);
return 0;
}

36
Sources/flags.h Normal file
View File

@@ -0,0 +1,36 @@
/* @(#)$Id: flags.h,v 1.4 1996/11/13 00:40:39 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#define UFL_AUTOOP 1
/*#define UFL_PROTECT 2*/
#define CFL_NOOP 1
#define CFL_ALWAYSOP 2
#define CFL_OPONLY 4
#define CFL_STRICTOP 8
#define CFL_AUTOTOPIC 16
#define LFL_ISOPER 1

135
Sources/floodpro.c Normal file
View File

@@ -0,0 +1,135 @@
/* @(#)$Id: floodpro.c,v 1.4 1999/04/04 17:00:06 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
int CheckFlood(char *source, char *channel, int length)
{
char buffer[200];
register achannel *chan;
register auser *user;
register amsg *msg, *prev;
register int count = 0;
chan = ToChannel(channel);
user = ToUser(channel, source);
if (!chan || !chan->on || !user)
return 0;
/* BEGINNING OF FLOOD PROTECTION ROUTINE */
/* 1st clean msghist older than 15 seconds */
prev = NULL;
msg = user->msghist;
while (msg)
{
if (msg->time < (now - 15))
{
if (prev)
{
prev->next = msg->next;
TTLALLOCMEM -= sizeof(amsg);
free(msg);
msg = prev->next;
}
else
{
user->msghist = msg->next;
TTLALLOCMEM -= sizeof(amsg);
free(msg);
msg = user->msghist;
}
}
else
{
prev = msg;
msg = msg->next;
}
}
/* now add the current msg to the history */
msg = (amsg *) MALLOC(sizeof(amsg));
msg->time = now;
msg->length = length;
msg->next = user->msghist;
user->msghist = msg;
/* now count the number of entry in the history..
if it's greater than the max allowed... bite! */
count = 0;
for (msg = user->msghist; msg; msg = msg->next, count++);
if (chan->MsgFloodPro != 0 && count == chan->MsgFloodPro)
{
notice(source, "### FLOOD PROTECTION ACTIVATED ###");
sprintf(buffer, "%s!%s@%s %d", user->N->nick,
user->N->username, user->N->site, PUBLIC_FLOOD_SUSPEND_TIME);
suspend("", channel, buffer);
count = IsShit(channel, source, NULL, NULL);
#ifdef DEBUG
printf("Argh! %s has a shit level %d\n", source, count);
#endif
sprintf(buffer, "FLOODPRO ACTIVATED BY %s ON %s", source, channel);
log(buffer);
switch (count)
{
case 0:
case 1:
case 2:
case 3:
case 4:
log("First warning");
sprintf(buffer, "%s That was not very smart!", source);
break;
case 5:
case 6:
case 7:
case 8:
case 9:
log("Second warning");
sprintf(buffer, "%s You're pushing your luck too far!", source);
break;
default:
sprintf(buffer, "%s That was one time too many", source);
}
kick("", channel, buffer);
sprintf(buffer, "%s %d %d *** FLOOD ***",
user->N->nick,
PUBLIC_FLOOD_SHITLIST_TIME,
(count < 10) ? count + 5 :
PUBLIC_FLOOD_SHITLIST_LEVEL);
AddToShitList("", channel, buffer, 0);
return 1;
}
return 0;
}

105
Sources/globalvar.h Normal file
View File

@@ -0,0 +1,105 @@
/* @(#)$Id: globalvar.h,v 1.12 2000/10/24 15:15:53 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#if !defined(__FreeBSD__) && !defined(__linux__)
extern int errno;
extern char *sys_errlist[];
#endif
extern char mynick[NICK_LENGTH];
extern char myuser[USERNAME_LENGTH];
extern char mysite[SITE_LENGTH];
extern char myrealname[REALNAME_LENGTH];
extern char server[SERVER_NAME_LENGTH];
extern int logfile;
extern RegUser *UserList[1000];
extern ShitUser *ShitList[1000];
extern aluser *Lusers[1000];
extern achannel *ChannelList[1000];
extern adefchan *DefChanList;
extern anevent *EventList;
extern aserver *ServerList;
extern aserver VirtualServer;
extern dbquery *DBQuery;
extern dbsync *DBSync;
extern syncchan *SyncChan;
#ifdef DOHTTP
extern http_socket *HttpList;
extern http_file_pipe *FilePipes;
#endif
extern misc_socket *MiscList;
extern irc_socket Irc;
extern char *TmpPtr;
extern time_t now;
extern time_t logTS;
extern time_t TSoffset;
extern time_t TSonline;
extern time_t TSconnect;
extern unsigned long long TTLREADBYTES;
extern unsigned long long TTLSENTBYTES;
extern unsigned long TTLALLOCMEM;
extern unsigned long long HTTPTTLSENTBYTES;
extern alang Lang[NO_LANG];
extern char *replies[][NO_LANG];
#ifdef FAKE_UWORLD
extern int Uworld_status;
extern time_t UworldTS,UworldServTS;
#endif
#ifdef NICKSERV
extern int NServ_status;
#endif
extern unsigned long MEM_buffers;
extern unsigned long NB_avail_buffer_blocks;
extern unsigned long NB_alloc_buffer_blocks;
extern long CurrentSendQ;
extern int DB_Save_Status;
extern char DB_Save_Nick[NICK_LENGTH];
#define MALLOC(X) ((TmpPtr=(char *)malloc(X))? \
TmpPtr : (char *)quit("ERROR: malloc() failed", 1));\
TTLALLOCMEM+=X
#define close(X) if((X)>=0) close(X)
#define ABS(X) ((X>0)?(X):(-(X)))
/* I use '}' and ']' instead of 'z' and 'Z'
* in order to respect RFC-1459 (section 2.2)
*/
#undef toupper
#undef tolower
#if 0
#define toupper(X) ( ((X)>='a'&&(X)<='~') ? ((X)&223) : (X) )
#define tolower(X) ( ((X)>='A'&&(X)<='^') ? ((X)|32) : (X) )
#endif
#define toupper(X) ( ((X)>='a'&&(X)<='~') || ((unsigned char)(X)>=0xe0&&(unsigned char)(X)<=0xff&&(unsigned char)(X)!=0xf7)? ((X)&223) : (X) )
#define tolower(X) ( ((X)>='A'&&(X)<='^') || ((unsigned char)(X)>=0xc0&&(unsigned char)(X)<=0xdf&&(unsigned char)(X)!=0xd7)? ((X)|32) : (X) )
#define touppertmp(X) ( ((X)>='a'&&(X)<='~') || ((unsigned char)(X)>=0xe0&&(unsigned char)(X)<=0xff&&(unsigned char)(X)!=0xf7)? ((X)&223) : (X) )
#define tolowertmp(X) ( ((X)>='A'&&(X)<='^') || ((unsigned char)(X)>=0xc0&&(unsigned char)(X)<=0xdf&&(unsigned char)(X)!=0xd7)? ((X)|32) : (X) )
#define strcasecmp mycasecmp
#define strcmp mycasecmp

56
Sources/h.h Normal file
View File

@@ -0,0 +1,56 @@
/* @(#)$Id: h.h,v 1.3 1996/11/13 00:40:40 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/resource.h>
#include "../config.h"
#include "debug.h"
#include "defines.h"
#include "struct.h"
#include "lang.h"
#include "replies.h"
#include "prototypes.h"
#include "globalvar.h"
#include "events.h"
#include "flags.h"
#include "dbio.h"
#include "version.h"

761
Sources/help.c Normal file
View File

@@ -0,0 +1,761 @@
/* @(#)$Id: help.c,v 1.22 2000/10/02 00:55:13 lgm Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
static struct item
{
char *name;
int Access;
char *file;
}
commands[] =
{
{
"showcommands", 0, "SHOWCOMMANDS"
}
,
{
"status", STATUS_ACCESS, "STATUS"
}
,
{
"join", LEVEL_JOIN, "JOIN"
}
,
{
"invite", INVITE_LEVEL, "INVITE"
}
,
{
"part", LEVEL_PART, "JOIN"
}
,
{
"topic", TOPIC_LEVEL, "TOPIC"
}
,
{
"kick", KICK_LEVEL, "KICK"
}
,
{
"ban", BAN_LEVEL, "BAN"
}
,
{
"unban", BAN_LEVEL, "BAN"
}
,
{
"banlist", 0, "BAN"
}
,
{
"lbanlist", 0, "BAN"
}
,
{
"adduser", ADD_USER_LEVEL, "ADDUSER"
}
,
{
"access", SHOW_ACCESS_LEVEL, "ACCESS"
}
,
{
"verify", 0, "VERIFY"
}
,
{
"remuser", REMOVE_USER_LEVEL, "ADDUSER"
}
,
{
"modinfo", MOD_USERINFO_LEVEL, "ADDUSER"
}
,
{
"purge", XADMIN_LEVEL, "XADMIN"
}
,
{
"isreg", 0, "ISREG"
}
,
{
"set", CH_FLOOD_LIMIT_LEVEL, "SET"
}
,
{
"suspend", LEVEL_SUSPEND, "SUSPEND"
}
,
{
"unsuspend", LEVEL_SUSPEND, "SUSPEND"
}
,
{
"saveuserlist", SAVE_USERLIST_LEVEL, "SAVEUSERLIST"
}
,
{
"addchan", SET_DEFAULT_LEVEL, "DEFCHAN"
}
,
{
"remchan", SET_DEFAULT_LEVEL, "DEFCHAN"
}
,
{
"savedefs", SAVE_DEFAULTS_LEVEL, "DEFCHAN"
}
,
{
"loaddefs", LOAD_DEFAULT_LEVEL, "LOADDEFS"
}
,
{
"savebanlist", SAVE_SHITLIST_LEVEL, "SAVEBANLIST"
}
,
{
"loadbanlist", LOAD_SHITLIST_LEVEL, "LOADBANLIST"
}
,
{
"pass", 0, "PASSWORD"
}
,
{
"login", 0, "PASSWORD"
}
,
{
"newpass", 0, "PASSWORD"
}
,
{
"deauth", 0, "PASSWORD"
}
,
{
"die", LEVEL_DIE, "DIE"
}
,
{
"restart", LEVEL_DIE, "RESTART"
}
,
{
"core", LEVEL_CORE, "CORE"
}
,
{
"rusage", RUSAGE_ACCESS, "RUSAGE"
}
,
#ifdef UPGRADE
{
"upgrade", LEVEL_UPGRADE, "UPGRADE"
}
,
#endif
{
"op", OP_LEVEL, "OP"
}
,
{
"deop", OP_LEVEL, "OP"
}
,
{
"clearmode", CLEARMODE_LEVEL, "CLEARMODE"
}
,
{
"map", 0, "MAP"
}
,
{
"help", 0, "HELP"
}
,
{
"motd", 0, "MOTD"
}
,
{
"showignore", 0, "SHOWIGNORE"
}
,
{
"remignore", XADMIN_LEVEL, "REMIGNORE"
}
,
{
"chaninfo", 0, "CHANINFO"
}
,
{
NULL, -1, NULL
}
};
static int N = 0;
static void sort(void)
{
struct item tmp;
register int i, j, k;
/* sort the command list using a simple bubble sort algo.
* 1st sort the commands by decreasing access
*/
for (i = 0; i < N - 1; i++)
{
for (j = N - 1; j > i; j--)
{
if (commands[j - 1].Access < commands[j].Access)
{
tmp = commands[j - 1];
commands[j - 1] = commands[j];
commands[j] = tmp;
}
}
}
/* Then, sort the commands by alphabetical order
*/
i = k = 0;
while (k < N - 1)
{
while (commands[k].Access == commands[i].Access)
k++;
while (i < k - 1)
{
for (j = k - 1; j > i; j--)
{
if (strcmp(commands[j - 1].name, commands[j].name) > 0)
{
tmp = commands[j - 1];
commands[j - 1] = commands[j];
commands[j] = tmp;
}
}
i++;
}
i = k;
}
}
static void listinit(void)
{
static int sorted = 0;
/* count the number of commands
*/
if (N == 0)
{
for (N = 0; commands[N].name != NULL; N++);
N--;
}
/* sort the list if not already done
*/
if (!sorted)
{
sort();
sorted = 1;
}
}
void showcommands(char *source, char *chan, char *args)
{
char buffer[500];
char channel[80];
register aluser *luser;
register int useraccess;
register int i, j;
if (*args == '#' || *args == '*')
GetWord(0, args, channel);
else
{
strcpy(channel, chan);
GuessChannel(source, channel);
}
luser = ToLuser(source);
if (!luser)
return;
if (!strcmp(channel, "*") && !IsValid(luser, channel))
{
notice(source, "SYNTAX: showcommands <channel>");
return;
}
useraccess = LAccess(channel, luser);
listinit();
/* Now show the sorted command list to the user.
*/
i = useraccess;
sprintf(buffer, "Level%5d:", i);
for (j = 0; j < N + 1; j++)
{
if (commands[j].Access < i)
{
if (strlen(buffer) > 13)
notice(source, buffer);
i = commands[j].Access;
sprintf(buffer, "Level%5d:", i);
}
if (commands[j].Access <= useraccess)
{
strcat(buffer, " ");
strcat(buffer, commands[j].name);
}
}
notice(source, buffer);
}
void showhelp(char *source, char *chan, char *args)
{
struct buffer_block *dyn = NULL;
char buffer[512], word[80], *ptr;
int i, l, index = 0, found = 0, file, linecount = 0;
if (CurrentSendQ > HIGHSENDQTHRESHOLD)
{
notice(source, "Cannot process your request at this time. Try again later.");
return;
}
GetWord(0, args, word);
if (!*word)
strcpy(word, "help");
listinit();
/* find the command index */
for (i = 0; i <= N; i++)
{
if (!strcasecmp(word, commands[i].name))
{
found = 1;
index = i;
break;
}
else if (!strncasecmp(word, commands[i].name, strlen(word)))
{
found++;
index = i;
}
}
if (found > 1)
{
sprintf(buffer, "%s is ambiguous", word);
notice(source, buffer);
return;
}
else if (found == 0)
{
if (!strcasecmp(word, "INFO"))
{
sprintf(buffer, "%s/INFO", HELP_DIR);
}
else if (!strcasecmp(word, "FORM"))
{
sprintf(buffer, "%s/FORM", HELP_DIR);
}
else
{
sprintf(buffer, "No help on %s. Please use "
"showcommands to get a list of commands "
"available to you", word);
notice(source, buffer);
return;
}
}
else
{
sprintf(buffer, "%s/%s", HELP_DIR, commands[index].file);
}
alarm(2);
file = open(buffer, O_RDONLY);
alarm(0);
if (file < 0)
{
if (found)
sprintf(buffer, "The help file for command %s "
"is not available", commands[index].name);
else
sprintf(buffer, "This help file is not available");
notice(source, buffer);
return;
}
if (found)
{
sprintf(buffer,
" HELP on %-20s Minimum access: %4d ",
commands[index].name, commands[index].Access);
notice(source, buffer);
}
alarm(3);
while ((l = read(file, buffer, 511)) > 0)
{
copy_to_buffer(&dyn, buffer, l);
}
alarm(0);
close(file);
while (dyn != NULL)
{
copy_from_buffer(&dyn, buffer, '\n', 199);
if ((ptr = strchr(buffer, '\n')) != NULL)
*ptr = '\0';
else
continue;
if (*buffer == '\0')
strcpy(buffer, " ");
string_swap(buffer, 512, "$NICK", mynick);
string_swap(buffer, 512, "$SERVER", SERVERNAME);
notice(source, buffer);
linecount++;
}
if (linecount > 0)
CheckFloodFlood(source, linecount);
}
void showmotd(char *source)
{
struct buffer_block *dyn = NULL;
char buffer[512];
int fd, l;
alarm(3);
fd = open(MOTD_FILE, O_RDONLY);
if (fd < 0)
{
notice(source, "MOTD is empty");
return;
}
if (CurrentSendQ > HIGHSENDQTHRESHOLD)
{
notice(source, "Cannot process your request at this time. Try again later.");
return;
}
while ((l = read(fd, buffer, 511)) > 0)
{
copy_to_buffer(&dyn, buffer, l);
}
close(fd);
alarm(0);
while (dyn != NULL)
{
char *ptr;
copy_from_buffer(&dyn, buffer, '\n', 199);
if ((ptr = strchr(buffer, '\n')) != NULL)
*ptr = '\0';
else
continue;
if (*buffer == '\0')
strcpy(buffer, " ");
notice(source, buffer);
}
}
static void
chaninfo_callback(int *fd, off_t off, int action, void *hook1, void *hook2,
dbuser * dbu, int count)
{
char buffer[512];
register adefchan *def;
time_t t;
if (count == 1 && dbu != NULL)
{
sprintf(buffer, "%s is registered by:", (char *)hook2);
notice((char *)hook1, buffer);
}
if (dbu == NULL)
{
if (count == 0)
{
notice((char *)hook1, "That channel is not registered");
}
else
{
def = DefChanList;
while (def && strcasecmp(def->name, (char *)hook2))
def = def->next;
if (def)
{
if (*def->topic)
{
sprintf(buffer, "Desc: %s", def->topic);
notice((char *)hook1, buffer);
}
if (*def->url)
{
sprintf(buffer, "URL: %s", def->url);
notice((char *)hook1, buffer);
}
}
}
free(hook1);
free(hook2);
}
else if (dbu->access >= 500)
{
t = now - dbu->lastseen;
sprintf(buffer, "%s (%s) last seen: %s ago",
dbu->nick, dbu->match,
time_remaining(t));
notice((char *)hook1, buffer);
}
}
void ShowChanInfo(char *source, char *chan, char *args)
{
char channel[80], *hook1, *hook2;
if (*args == '#')
GetWord(0, args, channel);
else
{
strcpy(channel, chan);
GuessChannel(source, channel);
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: chaninfo <channel>");
return;
}
hook1 = (char *)malloc(strlen(source) + 1);
strcpy(hook1, source);
hook2 = (char *)malloc(strlen(channel) + 1);
strcpy(hook2, channel);
db_fetch(channel, DBGETALLCMP, "", NULL, 0, hook1, hook2, chaninfo_callback);
}
void isreg(char *source, char *chan, char *args)
{
char channel[80], buffer[512];
struct stat st;
if (*args == '#')
GetWord(0, args, channel);
else
{
strcpy(channel, chan);
GuessChannel(source, channel);
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: isreg <channel>");
return;
}
if (stat(make_dbfname(channel), &st) < 0)
sprintf(buffer, "%s is not registered.",channel);
else
sprintf(buffer, "%s is registered.",channel);
notice(source, buffer);
}
#ifdef DOHTTP
void http_show_help(http_socket * hsock, char *command)
{
char buffer[512], buffer2[200];
struct buffer_block *dyn = NULL;
register char *ptr, *ptr2;
register int i, index = 0, found = 0;
int file, l;
listinit();
/* find the command index */
for (i = 0; i <= N; i++)
{
if (!strcasecmp(command, commands[i].name))
{
found = 1;
index = i;
break;
}
else if (!strncasecmp(command, commands[i].name, strlen(command)))
{
found++;
index = i;
}
}
buffer[0] = '\0';
sendto_http(hsock, HTTP_HEADER, command);
sendto_http(hsock, HTTP_BODY);
sendto_http(hsock, "<H1>HELP ON %s</H1>\n", (*command) ? command : "COMMANDS");
sendto_http(hsock, "<PRE>\n");
if (found > 1)
{
if (*command)
sendto_http(hsock, "%s is ambiguous\n", command);
}
else if (found == 0)
{
if (!strcasecmp(command, "INFO"))
{
sprintf(buffer, "%s/INFO", HELP_DIR);
}
else if (!strcasecmp(command, "FORM"))
{
sprintf(buffer, "%s/FORM", HELP_DIR);
}
else
{
sendto_http(hsock, "No help on %s.\n", command);
}
}
else
{
sprintf(buffer, "%s/%s", HELP_DIR, commands[index].file);
}
if (buffer[0] != '\0')
{
alarm(2);
file = open(buffer, O_RDONLY);
if (file < 0)
{
alarm(0);
if (found)
sendto_http(hsock, "The help file for command %s "
"is not available\n", commands[index].name);
else
sendto_http(hsock, "This help file is not available\n");
}
else
{
alarm(2);
while ((l = read(file, buffer, 511)) > 0)
{
copy_to_buffer(&dyn, buffer, l);
}
alarm(0);
close(file);
while (dyn != NULL)
{
copy_from_buffer(&dyn, buffer, '\n', 199);
if ((ptr = strchr(buffer, '\n')) == NULL)
continue;
if ((ptr = strstr(buffer, "$NICK")) != NULL)
{
*ptr = '\0';
sprintf(buffer2, "%s%s%s", buffer, mynick, ptr + 5);
strcpy(buffer, buffer2);
}
/* Some nasty char quoting required.. */
ptr = buffer;
ptr2 = buffer2;
do
{
if (*ptr == '<')
{
ptr2[0] = '&';
ptr2[1] = 'l';
ptr2[2] = 't';
ptr2[3] = ';';
ptr2 += 4;
}
else if (*ptr == '>')
{
ptr2[0] = '&';
ptr2[1] = 'g';
ptr2[2] = 't';
ptr2[3] = ';';
ptr2 += 4;
}
else
{
ptr2[0] = ptr[0];
ptr2++;
}
}
while (*(ptr++) != '\0');
sendto_http(hsock, "%s", buffer2);
}
}
sendto_http(hsock, "</PRE>\n");
}
else
{ /* show list of commands */
sendto_http(hsock, "</PRE>\n<H2>List of commands:</H2>\n");
sendto_http(hsock, "<FONT SIZE=+1>\n");
for (i = 0; i < N + 1; i++)
{
if (commands[i].Access <= 500)
sendto_http(hsock, "<A HREF=\"/HELP/%s\">%s</A>\n",
commands[i].name, commands[i].name);
}
sendto_http(hsock, "</FONT><P>\n");
}
sendto_http(hsock, "<HR>%s\n", HTTP_FOOTER);
sendto_http(hsock, "</BODY></HTML>\n");
hsock->status = HTTP_ENDING;
}
#endif

1427
Sources/http.c Normal file

File diff suppressed because it is too large Load Diff

572
Sources/ignore.c Normal file
View File

@@ -0,0 +1,572 @@
/* @(#)$Id: ignore.c,v 1.19 2000/10/24 16:04:24 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
typedef struct aprivmsg
{
char user[200];
time_t time;
int length;
struct aprivmsg *next;
}
aprivmsg;
typedef struct aignore
{
char mask[200];
time_t time;
struct aignore *next;
}
aignore;
static aprivmsg *MessageList = NULL;
static aprivmsg *FloodList = NULL;
static aprivmsg *AddUserFloodList = NULL;
static aignore *IgnoreList = NULL;
void add_silence(char *, char *);
void rem_silence(char *);
int CheckPrivateFlood(char *source, int length, char *type)
{
char buffer[200];
char userhost[200];
char global[] = "*";
register aluser *user;
register aprivmsg *msg, *prev;
register int count, size;
if ((user = ToLuser(source)) == NULL)
{
sprintf(buffer, "ERROR! CheckPrivateFlood(): %s not found", source);
log(buffer);
return 1;
}
/* Don't check flood from admins */
if (IsValid(user, global) && Access(global, source) >= 1)
return 0;
if (!strcasecmp(user->username, DEFAULT_USERNAME) &&
!strcasecmp(user->site, DEFAULT_HOSTNAME))
{
return 0;
}
/* clean messages older than 30 seconds */
prev = NULL;
msg = MessageList;
while (msg != NULL)
{
if (msg->time < (now - 30))
{
if (prev)
{
prev->next = msg->next;
TTLALLOCMEM -= sizeof(aprivmsg);
free(msg);
msg = prev->next;
}
else
{
MessageList = msg->next;
TTLALLOCMEM -= sizeof(aprivmsg);
free(msg);
msg = MessageList;
}
}
else
{
prev = msg;
msg = msg->next;
}
}
/* now add the current message in the list */
sprintf(userhost, "%s@%s", user->username, user->site);
msg = (aprivmsg *) MALLOC(sizeof(aprivmsg));
strcpy(msg->user, userhost);
msg->time = now;
msg->length = length;
msg->next = MessageList;
MessageList = msg;
/* count how many messages were received from that user
* and also how many bytes
*/
count = size = 0;
for (msg = MessageList; msg != NULL; msg = msg->next)
{
if (compare(userhost, msg->user))
{
count++;
size += msg->length;
}
}
if (count >= PRIVATE_FLOOD_RATE || size >= PRIVATE_FLOOD_SIZE)
{
#ifdef DEBUG
printf("FLOODED by %s!%s\n", user->nick, userhost);
#endif
if (!IsIgnored(source))
{
sprintf(buffer, "%sFLOOD from %s!%s", type, user->nick, userhost);
log(buffer);
sprintf(buffer, "%sFLOOD from %s!%s (%s)", type,
user->nick, userhost, user->server->name);
broadcast(buffer, 1);
}
MakeBanMask(user, buffer);
AddIgnore(source, buffer, IGNORE_TIME);
return 1;
}
return 0;
}
void AddIgnore(char *source, char *mask, int t)
{
char buffer[200];
char *site;
aignore *curr;
int count;
if (IsIgnored(source))
return;
/* count number of ignores from the same site */
site = strchr(mask, '@') + 1;
count = 0;
curr = IgnoreList;
while (curr)
{
if (!mycasecmp(strchr(curr->mask, '@') + 1, site))
count++;
curr = curr->next;
}
/* add the entry in the list */
curr = (aignore *) MALLOC(sizeof(aignore));
curr->time = now + t;
curr->next = IgnoreList;
IgnoreList = curr;
strcpy(curr->mask, mask);
add_silence(source, curr->mask);
notice(source, "I don't like being flooded! "
"I will ignore you from now on.");
/* schedule ignore removal */
AddEvent(EVENT_CLEAN_IGNORES, curr->time, "");
/* If there are already too many ignores from this site
* ignore the whole site
*/
if (count >= (MAX_IGNORE_PER_SITE - 1))
{
curr = (aignore *) MALLOC(sizeof(aignore));
curr->time = now + 300;
curr->next = IgnoreList;
IgnoreList = curr;
#ifdef DEBUG
printf("TOO MANY IGNORES FROM THE SAME SITE\n");
#endif
log("Too many ignores.. ignoring the whole site");
sprintf(curr->mask, "*!*@%s", site);
sprintf(buffer, "Ignoring the whole site! (%s)", site);
broadcast(buffer, 1);
add_silence(source, curr->mask);
AddEvent(EVENT_CLEAN_IGNORES, curr->time, "");
}
}
void CleanIgnores(void)
{
char buffer[200];
aignore *curr, *prev;
prev = NULL;
curr = IgnoreList;
while (curr != NULL)
{
if (curr->time <= now)
{
sprintf(buffer, "Removing ignore for %s", curr->mask);
log(buffer);
rem_silence(curr->mask);
if (prev != NULL)
{
prev->next = curr->next;
TTLALLOCMEM -= sizeof(aignore);
free(curr);
curr = prev->next;
}
else
{
IgnoreList = curr->next;
TTLALLOCMEM -= sizeof(aignore);
free(curr);
curr = IgnoreList;
}
}
else
{
prev = curr;
curr = curr->next;
}
}
}
int IsIgnored(char *nick)
{
char userhost[200];
register aignore *curr;
register aluser *user;
register int found = 0;
if ((user = ToLuser(nick)) == NULL)
{
return 1;
}
sprintf(userhost, "%s!%s@%s", user->nick, user->username, user->site);
curr = IgnoreList;
while (curr != NULL && !found)
{
if (compare(userhost, curr->mask))
{
add_silence(nick, curr->mask);
found++;
}
curr = curr->next;
}
return (found);
}
void ShowIgnoreList(char *source, char *channel, char *args)
{
char buffer[200];
aignore *curr = IgnoreList;
time_t m;
if (curr == NULL)
{
notice(source, "Ignore list is empty");
}
else
{
notice(source, "Ignore list:");
while (curr != NULL)
{
m = (curr->time - now) / 60 + 1;
sprintf(buffer, "%s for %ld minute%s",
curr->mask, m, (m > 1) ? "s" : "");
notice(source, buffer);
curr = curr->next;
}
}
}
void add_silence(char *nick, char *mask)
{
char buffer[200];
sprintf(buffer, ":%s SILENCE %s :%s\n", mynick, nick, mask);
sendtoserv(buffer);
#ifdef FAKE_UWORLD
if (Uworld_status == 1)
{
sprintf(buffer, ":%s SILENCE %s :%s\n", UFAKE_NICK, nick, mask);
sendtoserv(buffer);
}
#endif
}
void rem_silence(char *mask)
{
char buffer[200];
sprintf(buffer, ":%s SILENCE * -%s\n", mynick, mask);
sendtoserv(buffer);
#ifdef FAKE_UWORLD
if (Uworld_status == 1)
{
sprintf(buffer, ":%s SILENCE * -%s\n", UFAKE_NICK, mask);
sendtoserv(buffer);
}
#endif
}
int CheckFloodFlood(char *source, int length)
{
char buffer[200];
char userhost[200];
char global[] = "*";
register aluser *user;
register aprivmsg *msg, *prev;
register int count, size;
if ((user = ToLuser(source)) == NULL)
{
sprintf(buffer, "ERROR! CheckFloodFlood(): %s not found", source);
log(buffer);
return 1;
}
/* Don't check flood from admins */
if (IsValid(user, global) && Access(global, source) >= 1)
return 0;
if (!strcasecmp(user->username, DEFAULT_USERNAME) &&
!strcasecmp(user->site, DEFAULT_HOSTNAME))
{
return 0;
}
/* clean messages older than 30 seconds */
prev = NULL;
msg = FloodList;
while (msg != NULL)
{
if (msg->time < (now - 30))
{
if (prev)
{
prev->next = msg->next;
TTLALLOCMEM -= sizeof(aprivmsg);
free(msg);
msg = prev->next;
}
else
{
FloodList = msg->next;
TTLALLOCMEM -= sizeof(aprivmsg);
free(msg);
msg = FloodList;
}
}
else
{
prev = msg;
msg = msg->next;
}
}
/* now add the current message in the list */
sprintf(userhost, "%s@%s", user->username, user->site);
msg = (aprivmsg *) MALLOC(sizeof(aprivmsg));
strcpy(msg->user, userhost);
msg->time = now;
msg->length = length;
msg->next = FloodList;
FloodList = msg;
/* count how many messages were received from that user
* and also how many bytes
*/
count = size = 0;
for (msg = FloodList; msg != NULL; msg = msg->next)
{
if (compare(userhost, msg->user))
{
count++;
size += msg->length;
}
}
if (count >= FLOOD_FLOOD_RATE || size >= FLOOD_FLOOD_SIZE)
{
if (!IsIgnored(source))
{
sprintf(buffer, "OUTPUT-FLOOD from %s!%s", user->nick, userhost);
log(buffer);
sprintf(buffer, "OUTPUT-FLOOD from %s!%s (%s)",
user->nick, userhost, user->server->name);
broadcast(buffer, 1);
}
MakeBanMask(user, buffer);
AddIgnore(source, buffer, FLOOD_FLOOD_IGNORE);
return 1;
}
return 0;
}
int CheckAdduserFlood(char *source, char *channel)
{
char buffer[200];
char userhost[200];
char global[] = "*";
register aluser *user;
register aprivmsg *msg, *prev;
register int count;
if ((user = ToLuser(source)) == NULL)
{
sprintf(buffer, "ERROR! CheckAdduserFlood(): %s not found", source);
log(buffer);
return 1;
}
/* Don't check flood from admins */
if (IsValid(user, global) && Access(global, source) >= 1)
return 0;
if (!strcasecmp(user->username, DEFAULT_USERNAME) &&
!strcasecmp(user->site, DEFAULT_HOSTNAME))
{
return 0;
}
/* clean messages older than 1 hour */
prev = NULL;
msg = AddUserFloodList;
while (msg != NULL)
{
if (msg->time < (now - 3600))
{
if (prev)
{
prev->next = msg->next;
TTLALLOCMEM -= sizeof(aprivmsg);
free(msg);
msg = prev->next;
}
else
{
AddUserFloodList = msg->next;
TTLALLOCMEM -= sizeof(aprivmsg);
free(msg);
msg = AddUserFloodList;
}
}
else
{
prev = msg;
msg = msg->next;
}
}
sprintf(userhost, "%s@%s", user->username, user->site);
/* now add the current message in the list */
msg = (aprivmsg *) MALLOC(sizeof(aprivmsg));
strcpy(msg->user, channel);
msg->time = now;
msg->length = 0;
msg->next = AddUserFloodList;
AddUserFloodList = msg;
/* count how many messages were received from that user
* and also how many bytes
*/
count = 0;
for (msg = AddUserFloodList; msg != NULL; msg = msg->next)
{
if (!strcmp(channel, msg->user))
{
count++;
}
}
if (count >= 20)
{
if (!IsIgnored(source))
{
sprintf(buffer, "ADDUSER-FLOOD from %s!%s [%s]", user->nick, userhost, channel);
log(buffer);
sprintf(buffer, "ADDUSER-FLOOD from %s!%s [%s] (%s)",
user->nick, userhost, channel, user->server->name);
broadcast(buffer, 1);
}
MakeBanMask(user, buffer);
AddIgnore(source, buffer, 120);
return 1;
}
return 0;
}
void AdminRemoveIgnore(char *source, char *ch, char *args)
{
char mask[200], global[] = "*";
char buffer[200];
aignore **curr, *tmp;
int change = 0;
if (Access(global, source) < XADMIN_LEVEL)
{
ReplyNotAccess(source, global);
return;
}
GetWord(0, args, mask);
if (!*mask)
{
notice(source, "SYNTAX: remignore <mask|all>");
return;
}
curr = &IgnoreList;
while (*curr != NULL)
{
if (!strcasecmp((*curr)->mask, mask) || !strcasecmp(mask, "all"))
{
change = 1;
sprintf(buffer, "removed %s", (*curr)->mask);
notice(source, buffer);
log(buffer);
rem_silence((*curr)->mask);
tmp = *curr;
*curr = tmp->next;
free(tmp);
TTLALLOCMEM -= sizeof(aignore);
}
else
{
curr = &(*curr)->next;
}
}
if (change)
{
sprintf(buffer, "%s removed ignore for [%s]", source, mask);
broadcast(buffer, 1);
}
}

148
Sources/kicks.c Normal file
View File

@@ -0,0 +1,148 @@
/* @(#)$Id: kicks.c,v 1.5 1997/07/18 07:55:04 cvs Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
void kick(char *source,char *chanarg,char *args)
{
char buffer[500];
char nick[80];
char channel[80];
char *comment;
int found=0;
achannel *chan;
auser *user;
if(*args=='#'){
GetWord(0,args,channel);
GetWord(1,args,nick);
comment=ToWord(2,args);
}else{
GetWord(0,args,nick);
comment=ToWord(1,args);
strcpy(channel,chanarg);
GuessChannel(source,channel);
}
if(strlen(comment)>200)
comment[200]='\0';
if(!strcmp(channel,"*") || !*nick){
notice(source,"SYNTAX: kick [#channel] <nick|pattern> [reason]");
return;
}
chan=ToChannel(channel);
if(!chan||!chan->on){
if(*source)
notice(source,replies[RPL_NOTONCHANNEL][L_DEFAULT]);
return;
}
if(*source && (chan->flags&CFL_OPONLY)){
notice(source,replies[RPL_OPONLY][chan->lang]);
return;
}
if(!chan->AmChanOp){
if(*source)
notice(source,replies[RPL_NOTCHANOP][chan->lang]);
return;
}
/* check whether there are wildcards or not.
* if there are wildcards, it's a masskick and nick is a match pattern
* otherwise, it's an ordinary kick and nick is the nick to kick
*/
if(!strpbrk(nick,"*?")){
#ifdef DEBUG
printf("KICK REQUEST (NO WILDCARDS)\nSOURCE %s\nCHANNEL %s\nTARGET %s\n",
source,channel,nick);
#endif
if(*source&&Access(channel,source)<KICK_LEVEL){
ReplyNotAccess(source,channel);
return;
}
user=ToUser(channel,nick);
if(!user) return;
if(*comment){
if(*source)
sprintf(buffer,":%s KICK %s %s :(%s) %s\n",
mynick,channel,nick,source,comment);
else
sprintf(buffer,":%s KICK %s %s :%s\n",
mynick,channel,nick,comment);
}else{
if(*source)
sprintf(buffer,":%s KICK %s %s :From %s\n",
mynick,channel,nick,source);
else
sprintf(buffer,":%s KICK %s %s :%s\n",
mynick,channel,nick,mynick);
}
sendtoserv(buffer);
sprintf(buffer,"I KICK %s OFF %s",nick,channel);
log(buffer);
}else{
#ifdef DEBUG
printf("KICK REQUEST (WITH WILDCARDS)\nSOURCE %s\nCHANNEL %s\nTARGET %s\n",
source,channel,nick);
#endif
if(*source&&Access(channel,source)<MASS_KICK_LEVEL){
ReplyNotAccess(source,channel);
return;
}
user=chan->users;
while(user){
sprintf(buffer,"%s!%s@%s",user->N->nick,user->N->username,user->N->site);
if(match(buffer,nick)&&(!*source||strcasecmp(user->N->nick,source))){
if(*comment){
if(*source)
sprintf(buffer,":%s KICK %s %s :(%s) %s\n",mynick,channel,user->N->nick,source,comment);
else
sprintf(buffer,":%s KICK %s %s :%s\n",mynick,channel,user->N->nick,comment);
}else{
if(*source)
sprintf(buffer,":%s KICK %s %s :From %s\n",
mynick,channel,user->N->nick,source);
else
sprintf(buffer,":%s KICK %s %s :%s\n",
mynick,channel,user->N->nick,mynick);
}
sendtoserv(buffer);
sprintf(buffer,"I KICK %s OFF %s",user->N->nick,channel);
log(buffer);
found=1;
}
user=user->next;
}
if(*source && !found)
notice(source,replies[RPL_NOMATCH][chan->lang]);
}
}

35
Sources/lang.h Normal file
View File

@@ -0,0 +1,35 @@
/* @(#)$Id: lang.h,v 1.5 1999/01/09 16:51:31 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#define NO_LANG 5
#define L_ENGLISH 0
#define L_DUTCH 1
#define L_FRENCH 2
#define L_SPANISH 3
#define L_GERMAN 4
#define L_DEFAULT L_ENGLISH

122
Sources/list.c Normal file
View File

@@ -0,0 +1,122 @@
/* @(#)$Id: list.c,v 1.3 1996/11/13 00:40:43 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <netinet/in.h>
#include "defines.h"
#include "struct.h"
#include "version.h"
#include "../config.h"
typedef struct DiskUser {
char realname[80];
char match[80];
int Access;
char passwd[20];
char channel[80];
unsigned long flags;
char reserved[20];
time_t suspend;
time_t lastseen;
} DiskUser;
void main(void)
{
FILE *in1,*in2;
FILE *out;
char *ptr;
adefchan channel;
DiskUser user;
time_t currtime;
if(chdir(HOMEDIR)<0){
perror(HOMEDIR);
exit(1);
}
out=fopen("Registered_Channels","w");
if(out==NULL){
fclose(in1);
perror("Registered_Channels");
exit(1);
}
currtime=time(NULL);
fprintf(out,
"%s\n"
"(c) 1995,1996 by Robin Thellend <intru@info.polymtl.ca>\n"
"\n"
"This is the list of currently registered channels on Undernet.\n"
"Note that secret and private channels are NOT showed here.\n"
"This file is updated every hour.\n"
"\n"
"Last update: %s"
"Montreal's local time is used.\n\n",
VERSION,ctime(&currtime));
in1=fopen(DEFAULT_CHANNELS_FILE,"r");
if(in1==NULL){
fprintf(out,"There are no registered channels\n");
return;
}
while(fread(&channel,sizeof(adefchan),1,in1)>0){
ptr=strchr(channel.mode,' ');
if(ptr!=NULL)
*ptr='\0';
/* don't show secret or private channel */
if(strpbrk(channel.mode,"sp"))
continue;
fprintf(out,"%s Created: %s",channel.name,ctime(&channel.TS));
in2=fopen(USERFILE,"r");
if(in2==NULL){
fprintf(out,"Can't open \"%s\"\n",USERFILE);
}else{
while(fread(&user,sizeof(DiskUser),1,in2)>0){
if(!strcasecmp(user.channel,channel.name)&&
user.Access>=SET_DEFAULT_LEVEL){
fprintf(out," %s %s Last seen: %s",
user.realname,user.match,
ctime(&user.lastseen));
}
}
fclose(in2);
}
fprintf(out,"\n");
}
fclose(in1);
fclose(out);
}

79
Sources/listall.c Normal file
View File

@@ -0,0 +1,79 @@
/* @(#)$Id: listall.c,v 1.3 1996/11/13 00:40:43 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <netinet/in.h>
#include "defines.h"
#include "struct.h"
#include "version.h"
#include "../config.h"
typedef struct DiskUser {
char realname[80];
char match[80];
char passwd[20];
char channel[80];
char modif[80];
int Access;
unsigned long flags;
time_t suspend;
time_t lastseen;
} DiskUser;
void main(void)
{
FILE *in1,*in2;
FILE *out;
char *ptr;
adefchan channel;
DiskUser user;
time_t currtime;
if(chdir(HOMEDIR)<0){
perror(HOMEDIR);
exit(1);
}
out=stdout;
currtime=time(NULL);
in2=fopen(USERFILE,"r");
while(fread(&user,sizeof(DiskUser),1,in2)>0){
for(ptr=user.channel;*ptr;ptr++)
*ptr=tolower(*ptr);
fprintf(out,"[%s] %s %s (%d) Last modif: %s, Last seen: %s",
user.channel,
user.realname,user.match,user.Access,
user.modif,ctime(&user.lastseen));
}
fclose(in2);
fclose(out);
}

1002
Sources/main.c Normal file

File diff suppressed because it is too large Load Diff

0
Sources/make.dep Normal file
View File

316
Sources/match.c Normal file
View File

@@ -0,0 +1,316 @@
/* @(#)$Id: match.c,v 1.10 1999/03/06 19:15:34 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#include <regex.h>
static int matchX(char *, char *);
int mycasecmp(char *s1, char *s2)
{
register unsigned char *c1 = (unsigned char *)s1, *c2 = (unsigned char *)s2;
register int d;
while (!(d = (toupper(*c1) - toupper(*c2))) && *c1)
{
c1++;
c2++;
}
return d;
}
char *strcasestr(register char *s1, char *s2)
{
register char *a, *b;
while (*s1)
{
a = s1;
b = s2;
while (*b && *a && toupper(*a) == toupper(*b))
{
a++;
b++;
}
if (!*b)
return s1;
s1++;
}
return NULL;
}
/* xmatch() returns 1 if both pat1 and pat2 can *possibly*
* match the same string. It returns 0 otherwise.
*/
int xmatch(char *pat1, char *pat2)
{
if (!strcmp(pat1, "*") || !strcmp(pat2, "*"))
return 1;
while (*pat1 && *pat2)
{
if (*pat1 == '*' && *pat2 == '*')
return (matchX(pat1 + 1, pat2 + 1) || matchX(pat2 + 1, pat1 + 1));
if (*pat1 == '*')
return matchX(pat1 + 1, pat2);
if (*pat2 == '*')
return matchX(pat2 + 1, pat1);
if (*pat1 == '?' || *pat2 == '?' || toupper(*pat1) == toupper(*pat2))
{
pat1++;
pat2++;
if ((!*pat1 && !strcmp(pat2, "*")) ||
(!*pat2 && !strcmp(pat1, "*")))
return 1;
}
else
return 0;
}
if (*pat1 || *pat2)
return 0;
return 1;
}
static int matchX(char *pat1, char *pat2)
{
do
{
if (xmatch(pat1, pat2))
return 1;
}
while (*pat2++);
return 0;
}
int match(register char *string, register char *mask)
{
char *stack[200][2] = {{NULL, NULL}};
register char type = 0;
register short quote, level = 0;
while (*string)
{
quote = 0;
switch (*mask)
{
case '*':
type = '*';
if (++level == 200)
return 0;
stack[level][0] = mask;
stack[level][1] = string;
while (*++mask == '*'); /* '*' eats any following '*' */
break;
case '\\':
quote++;
mask++;
/* no break! */
default:
if (toupper(*string) == toupper(*mask) || (*mask == '?' && !quote))
{
mask++;
}
else
{
while (stack[level][0] == NULL && --level > 0);
if (level <= 0)
return 0;
mask = stack[level][0];
string = stack[level][1];
level--;
}
string++;
}
}
while (*mask == '*') /* Skip everything that can */
mask++; /* match an empty string. */
return (*mask) ? 0 : 1;
}
/* compare() will return 1 if p1 and p2 can match the same
* nick!user@host. p1 and p2 are nick!user@host masks.
*/
int compare(char *p1, char *p2)
{
char tmp1[200], tmp2[200];
register char *s1 = tmp1, *s2 = tmp2;
register int ip1, ip2, in_uh = 0;
do
{
ip1 = ip2 = 1;
while (*p1 && *p1 != '!' && *p1 != '@')
{
if (ip1 && !isdigit(*p1) && *p1 != '.' && (*p1 != '*' || p1[1]) && (*p1 == '*' || s1 != tmp1))
ip1 = 0;
*(s1++) = *(p1++);
}
if (!in_uh && *p1 == '\0')
in_uh = 1;
while (*p2 && *p2 != '!' && *p2 != '@')
{
if (ip2 && !isdigit(*p2) && *p2 != '.' && (*p2 != '*' || p2[1]) && (*p2 == '*' || s2 != tmp2))
ip2 = 0;
*(s2++) = *(p2++);
}
*s2 = *s1 = '\0';
if (*p1 != *p2)
{
if (*p1 == '!')
{
s1 = tmp1;
if (*p1)
p1++;
while (*p1 && *p1 != '@')
{
if (ip1 && !isdigit(*p1) && *p1 != '.' && (*p1 != '*' || p1[1]) && (*p1 == '*' || s1 != tmp1))
ip1 = 0;
*(s1++) = *(p1++);
}
if (!in_uh && *p1 == '\0')
in_uh = 1;
}
else
{
s2 = tmp2;
if (*p2)
p2++;
while (*p2 && *p2 != '@')
{
if (ip2 && !isdigit(*p2) && *p2 != '.' && (*p2 != '*' || p2[1]) && (*p1 == '*' || s2 != tmp2))
ip2 = 0;
*(s2++) = *(p2++);
}
}
*s2 = *s1 = '\0';
}
if ((in_uh && ip1 != ip2) || !xmatch(tmp1, tmp2))
return 0;
if (*p1)
p1++;
if (*p2)
p2++;
s1 = tmp1;
s2 = tmp2;
}
while (*p1);
return 1;
}
int key_match(char *s, char *tok[])
{
register int k;
for (k = 0; tok[k] != NULL; k++)
{
if (!strcasestr(s, tok[k]))
return 0;
}
return 1;
}
void string_swap(char *buf, size_t size, char *orig, char *new)
{
char *ptr, *buf2;
buf2 = (char *)alloca(sizeof(char) * size);
while ((ptr = strstr((buf), orig)))
{
*ptr = '\0';
strncpy(buf2, buf, size - 1);
strncat(buf2, new, size - strlen(buf) - 1);
strncat(buf2, ptr + strlen(orig), size - strlen(buf) - strlen(new) - 1);
strcpy(buf, buf2);
}
}
/* regex_cmp() (stolen from RCSD)
* This function compares a regular expression (patern) with a string.
* Return value: 1 if there is a match
* 0 otherwise
*
* Note: if patern is NULL, the last patern that was passed to the
* function is used.
*/
#define HAVE_REGEXEC
int regex_cmp(char *patern, char *string)
{
#if defined(HAVE_REGEXEC)
static regex_t preg;
static int called_once = 0;
register int cmpv = 0, execv;
if (patern != NULL)
{
if (called_once)
regfree(&preg);
cmpv = regcomp(&preg, patern, REG_EXTENDED | REG_ICASE | REG_NOSUB);
}
called_once = 1;
if (cmpv == 0)
execv = regexec(&preg, string, 0, NULL, 0);
return cmpv ? 0 : execv ? 0 : 1;
#elif defined(HAVE_RE_EXEC)
register char *ptr;
ptr = re_comp(patern);
return ptr ? 0 : re_exec(string);
#else
#error neither re_exec() nor rexexec() :/
#endif
}
#ifdef MATCHALONE
void main(void)
{
char str1[80];
char str2[80];
puts("#1");
gets(str1);
puts("#2");
gets(str2);
printf("match: %d\n", match(str1, str2));
}
#endif

970
Sources/modes.c Normal file
View File

@@ -0,0 +1,970 @@
/* @(#)$Id: modes.c,v 1.10 1999/04/04 17:00:11 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
static void AddFlag(char *, char, char *);
static void RemFlag(char *, char);
void setchanmode(char *line)
{
register char *mode;
register achannel *chan;
if ((mode = strchr(line, ' ')) != NULL)
*(mode++) = 0;
chan = ToChannel(line);
if (!chan)
return;
strcpy(chan->mode, mode + 1); /* why +1 ???? coz I don't want the + */
}
void AddFlag(char *string, char flag, char *arg)
{
char newmode[15];
char newarg[200];
if (strchr(string, flag))
RemFlag(string, flag);
GetWord(0, string, newmode);
*(newmode + strlen(newmode) + 1) = 0;
*(newmode + strlen(newmode)) = flag;
strcpy(newarg, ToWord(1, string));
if (arg)
{
strcat(newarg, arg);
strcat(newarg, " ");
}
sprintf(string, "%s %s", newmode, newarg);
}
void RemFlag(char *string, char flag)
{
char newmode[15];
char newarg[200];
register char *ptr;
register char *curr = newmode;
register int count = 0;
GetWord(0, string, newmode);
strcpy(newarg, ToWord(1, string));
while (*curr)
{
ptr = strchr("lk", *curr);
if (*curr == flag)
{
strcpy(curr, curr + 1);
if (ptr)
strcpy(ToWord(count, newarg), ToWord(count + 1, newarg));
}
else
{
if (ptr)
count++;
curr++;
}
}
sprintf(string, "%s %s", newmode, newarg);
}
int IsSet(char *channel, char flag, char *param)
{
register achannel *chan;
register char *setmode;
char setflags[20];
char setparam[80];
register int out;
register int i, j;
chan = ToChannel(channel);
if (chan == NULL)
return 0;
setmode = chan->mode;
GetWord(0, setmode, setflags);
j = 0;
for (i = 0; setflags[i] != '\0' && setflags[i] != flag; i++)
{
if (setflags[i] == 'l' || setflags[i] == 'k')
j++;
}
if (setflags[i] != '\0')
{
if (flag == 'l' || flag == 'k')
{
GetWord(j + 1, setmode, setparam);
if (!strcmp(setparam, param))
out = 1;
else
out = 0;
}
else
{
out = 1;
}
}
else
{
out = 0;
}
#ifdef DEBUG
printf("IsSet(): +%c %s on %s (%d)\n", flag, param, channel, out);
#endif
return (out);
}
void bounce(char *channel, char *change, time_t TS)
{
char buffer[200];
char arg[200];
register char sign = '+';
register auser *user;
register achannel *chan;
register int pos = 1;
register int i;
chan = ToChannel(channel);
for (i = 0; change[i] != '\0' && change[i] != ' '; i++)
{
if (change[i] == '+')
sign = '+';
else if (change[i] == '-')
sign = '-';
else if (change[i] == 'o')
{
GetWord(pos++, change, arg);
user = ToUser(channel, arg);
if (user == NULL)
continue;
if (sign == '+')
{
if (!user->chanop)
{
changemode(channel, "-o", arg, 1);
user->chanop = 0;
}
}
else
{
if (user->chanop)
{
/*
changemode(channel,"+o",arg,1);
user->chanop=1;
*/
/* don't bounce -o */
user->chanop = 0;
}
}
}
else if (change[i] == 'v')
{
GetWord(pos++, change, arg);
if (sign == '+')
changemode(channel, "-v", arg, 1);
else
changemode(channel, "+v", arg, 1);
}
else if (change[i] == 'k')
{
GetWord(pos++, change, arg);
if (sign == '+')
{
if (!IsSet(channel, 'k', arg))
changemode(channel, "-k", arg, 1);
}
else
{
if (IsSet(channel, 'k', arg))
changemode(channel, "+k", arg, 1);
}
}
else if (change[i] == 'l')
{
pos++;
if (sign == '+' && !IsSet(channel, 'l', arg))
changemode(channel, "-l", "", 1);
}
else if ((IsSet(channel, change[i], "") && sign == '-') ||
(!IsSet(channel, change[i], "") && sign == '+'))
{
sprintf(buffer, "%c%c",
(sign == '+') ? '-' : '+',
change[i]);
changemode(channel, buffer, "", 1);
}
}
AddEvent(EVENT_FLUSHMODEBUFF, now + MODE_DELAY, channel);
}
void ModeChange(char *source, char *channel, char *change)
{
register char sign = '+';
char arg[200];
register char *ptr;
register achannel *chan;
register aluser *u;
register int count = 1;
int desync = 0;
#ifdef DEBUG
printf("ModeChange(%s, %s, %s)\n", source, channel, change);
#endif
chan = ToChannel(channel);
/* if chan == NULL at this point.. we're dealing with a
* user mode change
*/
if (chan != NULL)
chan->lastact = now;
u = ToLuser(source);
if (chan == NULL && u == NULL)
{
return; /* probably a lost MODE */
}
if (u == NULL)
{
/* This is a mode change from a server.. if it is not
* a +b, then the last argument is a TS
*/
for (ptr = change; *ptr != 'b' && *ptr != ' '; ptr++);
if (*ptr != 'b' && strcasecmp(UWORLD_SERVER, source)
#ifdef UWORLD2
&& strcasecmp(UWORLD2_SERVER, source)
#endif
#ifdef FAKE_UWORLD
&& strcasecmp(UFAKE_SERVER, source)
#endif
)
{
ptr = change + strlen(change);
while (*ptr != ' ')
ptr--;
*(ptr++) = '\0';
if (atol(ptr) > chan->TS && atol(ptr) != 0 && chan->on)
{
log(source);
log(channel);
log(change);
log(ptr);
bounce(channel, change, chan->TS);
return;
}
if (atol(ptr) != 0)
chan->TS = atol(ptr);
}
}
while (*change && *change != ' ')
{
if (*change == '+')
{
sign = '+';
}
else if (*change == '-')
{
sign = '-';
}
else
{
if (sign == '+')
{
if (chan != NULL)
{
ptr = strchr("blkov", *change);
if (ptr)
{
GetWord(count, change, arg);
if (strchr("lk", *change) && *arg)
AddFlag(chan->mode, *change, arg);
count++;
}
else
{
if (strchr("imntps", *change))
AddFlag(chan->mode, *change, NULL);
}
}
else
{
/* user mode change (+) */
if (*change == 'o')
{
u->mode |= LFL_ISOPER;
#ifdef DEBUG
printf("%s is now IRCOP\n", source);
#endif
}
}
}
else
{
if (chan != NULL)
{
ptr = strchr("bkov", *change);
if (strchr("ilkmntps", *change))
RemFlag(chan->mode, *change);
if (ptr)
{
GetWord(count, change, arg);
count++;
}
}
else
{
/* user mode change (-) */
if (*change == 'o')
{
u->mode &= ~LFL_ISOPER;
#ifdef DEBUG
printf("%s is no longer IRCOP\n", source);
#endif
}
}
}
/** other tests should go here **/
if (chan != NULL)
{
if (*change == 'o')
{
if (sign == '+')
onop(source, channel, arg);
else
ondeop(source, channel, arg, &desync);
}
else if (*change == 'b')
{
if (sign == '+')
onban(source, channel, arg);
else
onunban(source, channel, arg);
}
else if (*change == 'l')
{
if (sign == '+' && atoi(arg) < 2)
{
if (chan->on && chan->AmChanOp)
{
changemode(channel, "-l", "", 0);
RemFlag(chan->mode, *change);
}
}
}
}
}
change++;
if (*change == ' ')
{
change = ToWord(count, change);
count = 1;
}
}
if (chan != NULL)
{
if (desync)
{
part("", channel, "");
join("", channel, "");
}
CheckFlood(source, channel, 80);
flushmode(channel);
}
}
void onop(char *source, char *channel, char *target)
{
register auser *user;
register aluser *luser;
register achannel *chan;
char buffer[200];
chan = ToChannel(channel);
luser = ToLuser(source);
user = ToUser(channel, target);
if (!strcasecmp(mynick, target))
{
if (!chan)
{
log("ERROR: onop() channel not found!");
return;
}
chan->AmChanOp = 1;
}
else
{
#ifdef DEBUG
printf("OP for %s on %s\n", target, channel);
#endif
if (!user)
{
sprintf(buffer, "ERROR: onop() user not found (%s)",
target);
log(buffer);
return;
}
user->chanop = 1;
sprintf(buffer, "%s!%s@%s", user->N->nick, user->N->username, user->N->site);
if (luser && chan->on && (chan->flags & CFL_NOOP))
{
sprintf(buffer, "NoOp MODE! deopping %s and %s",
target, source);
log(buffer);
notice(target, replies[RPL_NOOP][chan->lang]);
notice(source, replies[RPL_NOOP][chan->lang]);
changemode(channel, "-o", target, 0);
changemode(channel, "-o", source, 0);
user->chanop = 0;
user = ToUser(channel, source);
if (user != NULL)
{
user->chanop = 0;
}
}
else if (luser && chan->on && (chan->flags & CFL_STRICTOP) &&
Access(channel, target) < OP_LEVEL)
{
sprintf(buffer, "StrictOp MODE! deopping %s and %s",
target, source);
log(buffer);
notice(target, "Only authenticated users may be op in StrictOp mode");
notice(source, "Only authenticated users may be op in StrictOp mode");
changemode(channel, "-o", target, 0);
user->chanop = 0;
if (Access(channel, source) < OP_LEVEL)
{
changemode(channel, "-o", source, 0);
user = ToUser(channel, source);
if (user != NULL)
{
user->chanop = 0;
}
}
}
else if (luser && chan->on && IsShit(channel, buffer, NULL, NULL) >= NO_OP_SHIT_LEVEL)
{
if (Access(channel, source) < ACCESS_BAN_PRIORITY)
{
sprintf(buffer, "%s is shitlisted (NO-OP LEVEL)!"
"Deopping %s and %s", target, target, source);
log(buffer);
notice(target, replies[RPL_CANTBEOP][chan->lang]);
notice(source, replies[RPL_CANTBEOPPED][chan->lang]);
changemode(channel, "-o", target, 0);
changemode(channel, "-o", source, 0);
user->chanop = 0;
user = ToUser(channel, source);
if (user != NULL)
user->chanop = 0;
sprintf(buffer, "%s %d", source, SUSPEND_TIME_FOR_OPPING_A_SHITLISTED_USER);
suspend("", channel, buffer);
}
else
{
unban(source, channel, target);
}
}
}
/** further tests should be put here **/
#ifdef NICKSERV
nserv_onop(channel, user);
#endif
}
void ondeop(char *source, char *channel, char *target, int *desync)
{
char buffer[200];
register auser *user1, *user2;
register achannel *chan;
register adeop *curr, *prec;
register int i;
chan = ToChannel(channel);
if (!chan)
{
log("ERROR: ondeop() channel not found!");
return;
}
user1 = ToUser(channel, source);
user2 = ToUser(channel, target);
if (chan->on && user1 == NULL)
{ /* desync! */
if (user2 != NULL)
{
user2->chanop = 0;
}
sprintf(buffer, "DESYNC detected! (%s deopped %s on %s)",
source, target, channel);
log(buffer);
/* part("",channel,"");
join("",channel,""); now doing this in ChangeMode */
*desync = 1;
return;
}
if (!strcasecmp(mynick, target))
{
if ((chan->flags & CFL_ALWAYSOP) &&
Access(channel, source) >= ALWAYSOP_OVERRIDE_LEVEL)
{
chan->flags &= ~CFL_ALWAYSOP;
sprintf(buffer, "AlwaysOp is turned off on %s (deopped by %s!%s@%s)",
channel, user1->N->nick, user1->N->username, user1->N->site);
log(buffer);
notice(source, replies[RPL_ALWAYSOPWASACTIVE][chan->lang]);
}
if (chan->flags & CFL_ALWAYSOP)
{
if (user1 != NULL)
{
sprintf(buffer, "DEOPPED by %s!%s@%s (%d) while AlwaysOp active on %s",
user1->N->nick, user1->N->username, user1->N->site,
Access(channel, source), channel);
log(buffer);
broadcast(buffer, 0);
i = IsShit(channel, source, NULL, NULL);
notice(source, replies[RPL_ALWAYSOP][chan->lang]);
switch (i)
{
case 0:
case 1:
case 2:
case 3:
case 4:
log("First warning");
notice(source, replies[RPL_DEOPPED1ST][chan->lang]);
changemode(channel, "-o", source, 0);
flushmode(channel);
user1->chanop = 0;
break;
case 5:
case 6:
case 7:
case 8:
case 9:
log("Second warning");
notice(source, replies[RPL_DEOPPED2ND][chan->lang]);
kick("", channel, source);
break;
default:
notice(source, "I warned you!");
changemode(channel, "-o", source, 0);
flushmode(channel);
user1->chanop = 0;
sprintf(buffer, "%s!%s@%s %d",
user1->N->nick, user1->N->username,
user1->N->site,
DEOPME_SUSPEND_TIME);
suspend("", channel, buffer);
sprintf(buffer, "Suspended %s!%s@%s on %s for repeatedly deopping me",
user1->N->nick, user1->N->username, user1->N->site, channel);
SpecLog(buffer);
broadcast(buffer, 0);
}
sprintf(buffer, "%s %d %d *** DEOP WHILE ALWAYSOP ACTIVE ***",
source, DEOP_SHITLIST_TIME,
(i < 10) ? i + 5 :
DEOP_SHITLIST_LEVEL);
AddToShitList("", channel, buffer, 0);
chan->AmChanOp = 0; /* to remove if I reop myself */
GetOps(channel);
}
}
else
{
chan->AmChanOp = 0;
if (IsOpless(channel))
onopless(channel);
}
}
/* massdeop protection does NOT apply to the bot itself!
if(!strcasecmp(source,mynick)) return; obsolete */
/* No protection against server deop :/
Hey! I'm not gonna /squit it just for doing a deop!! ;) */
if (!user1)
return;
if (user2)
user2->chanop = 0;
chan = ToChannel(channel);
if (!chan)
{
log("ERROR: ondeop() channel not found!");
return;
}
/* If not on channel.. do NOT check for massdeop
*/
if (!chan->on)
return;
curr = user1->deophist;
prec = NULL;
/* ok.. let's free the *old* deops from history */
while (curr)
{
if (curr->time < (now - 15) || !strcasecmp(curr->nick, target))
{
if (prec)
{
prec->next = curr->next;
TTLALLOCMEM -= sizeof(adeop);
free(curr);
curr = prec->next;
}
else
{
user1->deophist = curr->next;
TTLALLOCMEM -= sizeof(adeop);
free(curr);
curr = user1->deophist;
}
}
else
{
prec = curr;
curr = curr->next;
}
}
/* now store the deop in the user's deop history */
curr = (adeop *) MALLOC(sizeof(adeop));
strcpy(curr->nick, target);
curr->time = now;
curr->next = user1->deophist;
user1->deophist = curr;
/* now we count the number of deop in the user's history
if it's equal to the max number of deops per 15 seconds
interval.. activate the massdeop protection */
for (curr = user1->deophist, i = 0; curr; curr = curr->next, i++);
if (i == chan->MassDeopPro && chan->MassDeopPro != 0 && chan->on)
{
sprintf(buffer, "MASSDEOP from %s on %s", source, channel);
log(buffer);
notice(source, "### MASSDEOP PROTECTION ACTIVATED ###");
if (Access(channel, source) >= MASSDEOP_IMMUNE_LEVEL)
{
notice(source, "You are lucky your access is so high :P");
}
else
{
sprintf(buffer, "%s %d", source, MASSDEOP_SUSPEND_TIME);
suspend("", channel, buffer);
sprintf(buffer, "%s %d %d *** MASSDEOP ***", source,
MASSDEOP_SHITLIST_TIME,
MASSDEOP_SHITLIST_LEVEL);
AddToShitList("", channel, buffer, 0);
sprintf(buffer, "%s ### MASSDEOP PROTECTION ###", source);
kick("", channel, buffer);
}
}
}
void onban(char *nick, char *channel, char *pattern)
{
#ifdef DEBUG
printf("Wah! BAN FROM: %s\nON CHANNEL %s\nTARGET: %s\n",
nick, channel, pattern);
#endif
AddBan(channel, pattern);
}
void onunban(char *source, char *channel, char *pattern)
{
/*register achannel *chan; */
RemBan(channel, pattern);
/* mode -b no longer removes the ban from X's banlist
** it has to be removed with the 'unban' command.
chan=ToChannel(channel);
if(chan!=NULL && chan->on)
RemShitList(source,channel,pattern,1);
* */
}
void AddBan(char *channel, char *pattern)
{
register achannel *chan;
register aban *theban;
char buffer[200];
chan = ToChannel(channel);
if (chan == NULL)
{
sprintf(buffer, "ERROR: AddBan(): can't find %s", channel);
log(buffer);
return;
}
/* check if ban isn't already there */
for (theban = chan->bans; theban != NULL; theban = theban->next)
{
if (!strncasecmp(theban->pattern, pattern, 79))
{
return;
}
}
theban = (aban *) MALLOC(sizeof(aban));
strncpy(theban->pattern, pattern, 79);
theban->pattern[79] = '\0';
theban->next = chan->bans;
chan->bans = theban;
}
void RemBan(char *channel, char *pattern)
{
register achannel *chan;
register aban **b, *theban = NULL;
chan = ToChannel(channel);
b = &chan->bans;
while (*b != NULL)
{
if (!strncasecmp((*b)->pattern, pattern, 79))
{
theban = *b;
*b = theban->next;
TTLALLOCMEM -= sizeof(aban);
free(theban);
}
else
{
b = &(*b)->next;
}
}
#ifdef DEBUG
if (theban == NULL)
{
printf("WARNING: RemBan(): pattern NOT found!!\n");
}
#endif
}
void changemode(char *channel, char *flag, char *arg, int AsServer)
{
register achannel *chan;
register modequeue *mode, *curr;
#ifdef DEBUG
printf("Queueing mode change for channel %s %s %s %d\n", channel, flag, arg, AsServer);
#endif
chan = ToChannel(channel);
if (!AsServer && (!chan || !chan->on))
return; /* not on the channel.. ignore */
/* first, cancel previous contradicting mode changes..
ex.. mode #test +o-o+o-o+o .. the bot won't do that.. */
mode = chan->modebuff;
while (mode)
{
if (!strcmp(arg, mode->arg) && flag[1] == mode->flag[1] &&
((flag[0] == '+' && mode->flag[0] == '-') ||
(flag[0] == '-' && mode->flag[0] == '+')))
{
if (mode->prev)
mode->prev->next = mode->next;
else
chan->modebuff = mode->next;
if (mode->next)
mode->next->prev = mode->prev;
curr = mode;
TTLALLOCMEM -= sizeof(modequeue);
free(curr);
}
else if (!strcmp(arg, mode->arg) && flag[1] == mode->flag[1] &&
flag[0] == mode->flag[0])
return;
mode = mode->next;
}
curr = (modequeue *) MALLOC(sizeof(modequeue));
strcpy(curr->arg, arg);
strcpy(curr->flag, flag);
curr->AsServer = AsServer;
curr->next = NULL;
for (mode = chan->modebuff; mode && mode->next; mode = mode->next);
if (mode)
{
curr->prev = mode;
mode->next = curr;
}
else
{
chan->modebuff = curr;
curr->prev = NULL;
}
}
void flushmode(char *channel)
{
char buffer[500];
register achannel *chan;
register modequeue *mode, *tmp;
char flags[20] = "";
char args[500] = "";
register char lastsign;
register int AsServer;
register int count = 0;
#ifdef DEBUG
printf("Flushing mode change buffer.. for channel %s\n", channel);
#endif
/* gotta pass thru the list twice:
* the first time, check for Server mode changes
* the second time, check for user mode changes
*/
chan = ToChannel(channel);
if (chan == NULL)
return;
#ifdef FAKE_UWORLD
#define ASSERVERMAX 2
#else
#define ASSERVERMAX 1
#endif
for (AsServer = ASSERVERMAX; AsServer >= 0; AsServer--)
{
#undef ASSERVERMAX
lastsign = '\0';
mode = chan->modebuff;
while (mode != NULL)
{
if (!strcmp(mode->flag, "-b"))
{
RemBan(channel, mode->arg);
}
else if (!strcmp(mode->flag, "+b"))
{
AddBan(channel, mode->arg);
}
if (AsServer == mode->AsServer)
{
if (mode->arg[0] != '\0')
{
count++;
strcat(args, " ");
strcat(args, mode->arg);
}
if (lastsign != mode->flag[0])
{
strcat(flags, mode->flag);
lastsign = mode->flag[0];
}
else
{
strcat(flags, mode->flag + 1);
}
if (mode->prev)
mode->prev->next = mode->next;
else
chan->modebuff = mode->next;
if (mode->next)
mode->next->prev = mode->prev;
tmp = mode;
mode = mode->next;
TTLALLOCMEM -= sizeof(modequeue);
free(tmp);
}
else
{
mode = mode->next;
}
if (count == MAX_MODE_PER_LINE || !mode)
{
if (AsServer == 0 && chan->AmChanOp && *flags != '\0')
{
sprintf(buffer, ":%s MODE %s %s%s\n",
mynick, channel, flags, args);
sendtoserv(buffer);
}
else if (AsServer == 1 && *flags != '\0')
{
sprintf(buffer, ":%s MODE %s %s%s %ld\n",
SERVERNAME, channel,
flags, args, chan->TS);
sendtoserv(buffer);
}
#ifdef FAKE_UWORLD
else if (AsServer == 2 && Uworld_status == 1 && *flags != '\0')
{
sprintf(buffer, ":%s MODE %s %s%s\n",
UFAKE_SERVER, channel,
flags, args);
sendtoserv(buffer);
}
#endif
count = *args = *flags = 0;
lastsign = '+';
}
}
}
}

81
Sources/nick.c Normal file
View File

@@ -0,0 +1,81 @@
/* @(#)$Id: nick.c,v 1.3 1996/11/13 00:40:44 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
void NickInUse(void)
{
char buffer[200];
sprintf(buffer,":%s SQUIT %s 0 :Unexpected nick collision\n",
SERVERNAME,SERVERNAME);
sendtoserv(buffer);
dumpbuff();
close(Irc.fd);
Irc.fd=-1;
QuitAll();
if(reconnect(server)){
try_later(server);
}
#if 0
char *ptr;
achannel *chan;
int index=0;
do{
if(!strcmp(mynick,DEFAULT_NICKNAME)){
strcat(mynick,"1");
}else{
ptr = (mynick+strlen(mynick)-1);
(*ptr)++;
if(*ptr>'z') *ptr='0';
}
}while(ToLuser(mynick)!=NULL);
sprintf(buffer,
"ERROR: ARGH! Nick already in use! Changing to %s",mynick);
log(buffer);
for(index=0;index<1000;index++){
chan=ChannelList[index];
while(chan!=NULL){
chan->on=chan->AmChanOp=0;
chan=chan->next;
}
}
/*logTS=time(NULL);*/
signon();
joindefault();
#endif
}
void ChNick(char *newnick)
{
char buffer[80];
sprintf(buffer,":%s NICK %s :%ld\n",mynick,newnick,now);
sendtoserv(buffer);
strcpy(mynick,newnick);
}

763
Sources/opcom.c Normal file
View File

@@ -0,0 +1,763 @@
/* @(#)$Id: opcom.c,v 1.19 2000/10/24 16:07:33 lgm Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
void CalmDown(char *source, char *chan, char *args)
{
register aluser *user;
register achannel *ch;
char buffer[200], channel[80], global[] = "*";
if ((user = ToLuser(source)) == NULL)
{
log("ERROR: CalmDown() can't locate user!");
return;
}
if (*args == '#')
{
GetWord(0, args, channel);
args = ToWord(1, args);
}
else
{
strcpy(channel, chan);
GuessChannel(source, channel);
}
if (!(user->mode & LFL_ISOPER) && Access(global, source) < XADMIN_LEVEL)
{
notice(source, "This command is reserved for IRC Operators");
return;
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: calmdown [channel]");
return;
}
ch = ToChannel(channel);
if (ch == NULL || !ch->on)
{
notice(source, replies[RPL_NOTONCHANNEL][L_DEFAULT]);
return;
}
sprintf(buffer, ":%s WALLOPS :%s!%s@%s is asking me to calm down on %s\n",
SERVERNAME, user->nick, user->username, user->site, ch->name);
sendtoserv(buffer);
sprintf(buffer, "%s!%s@%s is asking me to calm down on %s\n",
user->nick, user->username, user->site, ch->name);
broadcast(buffer, 0);
sprintf(buffer, "CALMDOWN requested by %s!%s@%s on %s",
user->nick, user->username, user->site, ch->name);
SpecLog(buffer);
/*
part("",channel,"");
RemChan("",channel,"");
*/
ch->flags |= CFL_NOOP;
massdeop(channel);
#ifdef CALMDOWNTOPIC
topic("", channel, CALMDOWNTOPIC);
#endif
}
void OperJoin(char *source, char *chan, char *args)
{
register aluser *user;
register achannel *ch;
char buffer[200], channel[80];
if ((user = ToLuser(source)) == NULL)
{
log("ERROR: OperJoin() can't locate user!");
return;
}
if (*args == '#')
{
GetWord(0, args, channel);
args = ToWord(1, args);
}
else
{
strcpy(channel, chan);
GuessChannel(source, channel);
}
if (!(user->mode & LFL_ISOPER))
{
notice(source, "This command is reserved for IRC Operators");
return;
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: operjoin <channel>");
return;
}
if (!IsReg(channel))
{
notice(source, "That channel is not registered");
return;
}
ch = ToChannel(channel);
if (ch != NULL && ch->on)
{
notice(source, "I am already on that channel");
return;
}
sprintf(buffer, ":%s WALLOPS :%s!%s@%s is asking me to join channel %s\n",
SERVERNAME, user->nick, user->username, user->site, channel);
sendtoserv(buffer);
sprintf(buffer, "%s!%s@%s is asking me join channel %s\n",
user->nick, user->username, user->site, channel);
broadcast(buffer, 0);
sprintf(buffer, "OPERJOIN requested by %s!%s@%s on %s",
user->nick, user->username, user->site, channel);
SpecLog(buffer);
join("", channel, "");
}
void OperPart(char *source, char *chan, char *args)
{
register aluser *user;
register achannel *ch;
char buffer[200], channel[80];
if ((user = ToLuser(source)) == NULL)
{
log("ERROR: OperPart() can't locate user!");
return;
}
if (*args == '#')
{
GetWord(0, args, channel);
args = ToWord(1, args);
}
else
{
strcpy(channel, chan);
GuessChannel(source, channel);
}
if (!(user->mode & LFL_ISOPER))
{
notice(source, "This command is reserved for IRC Operators");
return;
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: operpart [channel]");
return;
}
ch = ToChannel(channel);
if (ch == NULL || !ch->on)
{
notice(source, "I am not on that channel");
return;
}
sprintf(buffer, ":%s WALLOPS :%s!%s@%s is asking me to leave channel %s\n",
SERVERNAME, user->nick, user->username, user->site, channel);
sendtoserv(buffer);
sprintf(buffer, "%s!%s@%s is asking me to leave channel %s\n",
user->nick, user->username, user->site, channel);
broadcast(buffer, 0);
sprintf(buffer, "OPERPART requested by %s!%s@%s on %s",
user->nick, user->username, user->site, channel);
SpecLog(buffer);
part("", channel, "");
}
void ClearMode(char *source, char *chan, char *args)
{
register aluser *user;
register achannel *ch;
register char *curr;
register int i;
char buffer[200], channel[80], arg[80];
if ((user = ToLuser(source)) == NULL)
{
log("ERROR: ClearMode() can't locate user!");
return;
}
if (*args == '#')
{
GetWord(0, args, channel);
args = ToWord(1, args);
}
else
{
strcpy(channel, chan);
GuessChannel(source, channel);
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: clearmode [channel]");
return;
}
if (Access(channel, source) < CLEARMODE_LEVEL)
{
if (user->mode & LFL_ISOPER)
{
sprintf(buffer, ":%s WALLOPS :%s is using clearmode on %s\n",
SERVERNAME, source, channel);
sendtoserv(buffer);
}
else
{
ReplyNotAccess(source, channel);
return;
}
}
if ((ch = ToChannel(channel)) == NULL)
{
notice(source, "No such channel!");
return;
}
if (!ch->on || !ch->AmChanOp)
{
notice(source, replies[RPL_NOTCHANOP][ch->lang]);
return;
}
sprintf(buffer, "CLEARMODE on %s requested by %s!%s@%s",
channel, user->nick, user->username, user->site);
log(buffer);
curr = ch->mode;
i = 1;
while (*curr && *curr != ' ')
{
if (strchr("kl", *curr))
{
GetWord(i++, ch->mode, arg);
if (*curr == 'k')
{
changemode(channel, "-k", arg, 0);
}
else
{
changemode(channel, "-l", "", 0);
}
}
else
{
sprintf(buffer, "-%c", *curr);
changemode(channel, buffer, "", 0);
}
curr++;
}
ch->mode[0] = '\0';
flushmode(channel);
}
void verify(char *source, char *arg)
{
aluser *luser;
char buffer[200], nick[80], global[] = "*", *oper;
int acc;
GetWord(0, arg, nick);
if (!*nick)
{
notice(source, "SYNTAX: verify <nick>");
return;
}
luser = ToLuser(nick);
if (luser == NULL)
{
sprintf(buffer, "No such nick: %s", nick);
notice(source, buffer);
return;
}
if (luser->mode & LFL_ISOPER)
{
oper = " and an IRC operator";
}
else
{
oper = "";
}
acc = Access(global, nick);
if (acc == 1000)
{
sprintf(buffer, "%s!%s@%s is my daddy%s",
luser->nick, luser->username, luser->site, oper);
}
else if (acc > 900)
{
sprintf(buffer, "%s!%s@%s is an Official %s coder%s",
luser->nick, luser->username, luser->site, VERIFY_ID, oper);
}
else if (acc == 900)
{
sprintf(buffer, "%s!%s@%s is my grandma%s",
luser->nick, luser->username, luser->site, oper);
}
else if (acc == 800)
{
sprintf(buffer, "%s!%s@%s is a Co-ordinator of %s%s",
luser->nick, luser->username, luser->site, VERIFY_ID, oper);
}
else if (acc > 500)
{
sprintf(buffer, "%s!%s@%s is an Official %s admin%s",
luser->nick, luser->username, luser->site, VERIFY_ID, oper);
}
else if (acc > 0)
{
sprintf(buffer, "%s!%s@%s is an Official %s helper%s",
luser->nick, luser->username, luser->site, VERIFY_ID, oper);
}
else if (acc < 0)
{
sprintf(buffer, "%s!%s@%s is a well-known TROUBLEMAKER%s",
luser->nick, luser->username, luser->site, oper);
}
else if (luser->mode & LFL_ISOPER)
{
sprintf(buffer, "%s!%s@%s is an IRC operator",
luser->nick, luser->username, luser->site);
}
else
{
sprintf(buffer, "%s!%s@%s is NOT an authenticated %s representative",
luser->nick, luser->username, luser->site, VERIFY_ID);
}
notice(source, buffer);
}
#ifdef FAKE_UWORLD
void Uworld_switch(char *source, char *ch, char *args)
{
char buffer[200];
aluser *user, *user2;
user = ToLuser(source);
if (!user || !(user->mode & LFL_ISOPER))
{
notice(source, "This command is reserved to IRC Operators");
return;
}
if (!strcasecmp(args, "ON"))
{
if (Uworld_status == 1)
{
sprintf(buffer, "%s is already active", UFAKE_NICK);
notice(source, buffer);
}
else
{
if ((user2 = ToLuser(UFAKE_NICK)) != NULL &&
!strcmp(user2->site, DEFAULT_HOSTNAME))
{
sprintf(buffer, "%s already present!", UFAKE_NICK);
notice(source, buffer);
return;
}
if (user2 != NULL)
{
onquit(UFAKE_NICK);
}
if (FindServer(&ServerList, UFAKE_SERVER) != NULL)
{
sprintf(buffer, "%s already present!", UFAKE_SERVER);
notice(source, buffer);
return;
}
sprintf(buffer, ":%s WALLOPS :%s activated %s\n",
SERVERNAME, source, UFAKE_NICK);
sendtoserv(buffer);
Uworld_status = 1;
IntroduceUworld();
sprintf(buffer, "%s activated by %s!%s@%s",
UFAKE_NICK, user->nick, user->username, user->site);
log(buffer);
}
}
else if (!strcasecmp(args, "OFF"))
{
if (Uworld_status == 0)
{
sprintf(buffer, "%s is not active", UFAKE_NICK);
notice(source, buffer);
}
else
{
sprintf(buffer, ":%s WALLOPS :%s deactivated %s\n",
SERVERNAME, source, UFAKE_NICK);
sendtoserv(buffer);
Uworld_status = 0;
sprintf(buffer, "Deactivated by %s!%s@%s",
user->nick, user->username, user->site);
KillUworld(buffer);
sprintf(buffer, "%s deactivated by %s!%s@%s",
UFAKE_NICK, user->nick, user->username, user->site);
log(buffer);
}
}
else
{
notice(source, "SYNTAX: uworld [ON|OFF]");
}
}
void parse_uworld_command(char *source, char *args)
{
char command[80];
GetWord(0, args, command);
args = ToWord(1, args);
if (!strcasecmp(command, "OPCOM"))
Uworld_opcom(source, args);
else if (!strcasecmp(command, "CLEARCHAN"))
ClearChan(source, args);
else if (!strcasecmp(command, "REOP"))
Uworld_reop(source, args);
}
void Uworld_opcom(char *source, char *args)
{
char buffer[512];
char command[80];
char channel[80];
aluser *user;
user = ToLuser(source);
if (!user || !(user->mode & LFL_ISOPER))
{
notice(source, "This command is reserved to IRC Operators");
return;
}
sprintf(buffer, "%s!%s@%s", user->nick, user->username, user->site);
if (IsOperSuspended(buffer))
{
notice(source, "Sorry, Your Uworld access is suspended");
return;
}
GetWord(0, args, command);
GetWord(1, args, channel);
args = ToWord(2, args);
if (!strcasecmp(command, "MODE"))
{
if (*channel != '#')
{
sprintf(buffer, ":%s NOTICE %s :bad channel name\n",
UFAKE_NICK, source);
sendtoserv(buffer);
return;
}
sprintf(buffer, ":%s WALLOPS :%s is using %s to: MODE %s %s\n",
UFAKE_SERVER, source, UFAKE_NICK, channel, args);
sendtoserv(buffer);
sprintf(buffer, ":%s MODE %s %s\n", UFAKE_SERVER, channel, args);
sendtoserv(buffer);
sprintf(buffer, "OPCOM MODE %s %s (%s!%s@%s)",
channel, args, user->nick, user->username, user->site);
log(buffer);
ModeChange(UFAKE_SERVER, channel, args);
}
else
{
sprintf(buffer, ":%s NOTICE %s :(yet) unsupported command (%s)\n",
UFAKE_NICK, source, command);
sendtoserv(buffer);
}
}
void ClearChan(char *source, char *args)
{
register aluser *user;
register auser *chanuser;
register achannel *ch;
register char *curr;
register aban *oneban;
register int i;
char buffer[200], channel[80], arg[80];
if ((user = ToLuser(source)) == NULL)
{
log("ERROR: ClearMode() can't locate user!");
return;
}
GetWord(0, args, channel);
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: clearmode [channel]");
return;
}
if (!user->mode & LFL_ISOPER)
{
sprintf(buffer, ":%s NOTICE %s :This command is reserved to IRC Operators\n",
UFAKE_NICK, source);
sendtoserv(buffer);
return;
}
sprintf(buffer, "%s!%s@%s", user->nick, user->username, user->site);
if (IsOperSuspended(buffer))
{
notice(source, "Sorry, Your Uworld access is suspended");
return;
}
if ((ch = ToChannel(channel)) == NULL)
{
sprintf(buffer, ":%s NOTICE %s :That channel does not exist\n",
UFAKE_NICK, source);
sendtoserv(buffer);
return;
}
sprintf(buffer, ":%s WALLOPS :%s is using %s to: CLEARCHAN %s\n",
UFAKE_SERVER, source, UFAKE_NICK, channel);
sendtoserv(buffer);
sprintf(buffer, "CLEARCHAN on %s requested by %s!%s@%s",
channel, user->nick, user->username, user->site);
log(buffer);
chanuser = ch->users;
while (chanuser != NULL)
{
if (chanuser->chanop)
{
changemode(channel, "-o", chanuser->N->nick, 2);
chanuser->chanop = 0;
}
chanuser = chanuser->next;
}
curr = ch->mode;
i = 1;
while (*curr && *curr != ' ')
{
if (strchr("kl", *curr))
{
GetWord(i++, ch->mode, arg);
if (*curr == 'k')
{
changemode(channel, "-k", arg, 2);
}
else
{
changemode(channel, "-l", "", 2);
}
}
else
{
sprintf(buffer, "-%c", *curr);
changemode(channel, buffer, "", 2);
}
curr++;
}
ch->mode[0] = '\0';
for (oneban = ch->bans; oneban != NULL; oneban = oneban->next)
{
changemode(channel, "-b", oneban->pattern, 2);
}
flushmode(channel);
}
void Uworld_reop(char *source, char *channel)
{
register aluser *user;
char buffer[200];
user = ToLuser(source);
if (user != NULL && !strcasecmp(user->username, DEFAULT_USERNAME) &&
!strcasecmp(user->site, DEFAULT_HOSTNAME))
{
sprintf(buffer, "%s called for REOP on %s", source, channel);
log(buffer);
changemode(channel, "+o", source, 2);
flushmode(channel);
}
}
void OperSuspend(char *source, char *args)
{
FILE *in, *out;
char Mask[200], strtimeout[80], global[] = "*", buffer[120], tmp[80],
*mask = Mask, *ptr;
time_t timeout;
int add = 1, count = 0;
if (Access(global, source) < 900)
{
notice(source, "You don't have access to that command");
return;
}
GetWord(0, args, mask);
GetWord(1, args, strtimeout);
if (!*mask)
{
notice(source, "SYNTAX: opersuspend [+/-]<mask> [timeout]");
return;
}
if (*mask == '+')
{
add = 1;
mask++;
}
else if (*mask == '-')
{
add = 0;
mask++;
}
if (add)
{
out = fopen("opersuspend.dat", "a");
if (!out)
{
notice(source, "Can't open file opersuspend.dat :(");
return;
}
timeout = atol(strtimeout);
if (timeout <= 0)
timeout = 1999999999;
else
timeout += now;
fprintf(out, "%s %ld\n", mask, timeout);
fclose(out);
notice(source, "1 entry added");
}
else
{
in = fopen("opersuspend.dat", "r");
if (!in)
{
notice(source, "Can't open file opersuspend.dat :(");
return;
}
out = fopen("opersuspend.dat.new", "w");
if (!in)
{
notice(source, "Can't open file opersuspend.dat.new :(");
return;
}
while (fgets(buffer, 120, in) != NULL)
{
if ((ptr = strchr(buffer, '\n')) != NULL)
*ptr = '\0';
GetWord(0, buffer, tmp);
if (strcasecmp(tmp, mask) && atol(ToWord(1, buffer)) > now)
fprintf(out, "%s\n", buffer);
else
count++;
}
fclose(in);
fclose(out);
rename("opersuspend.dat.new", "opersuspend.dat");
sprintf(buffer, "Removed %d entry(ies)", count);
notice(source, buffer);
}
}
int IsOperSuspended(char *userhost)
{
FILE *fp;
char buffer[120], mask[200], *ptr;
if ((fp = fopen("opersuspend.dat", "r")) == NULL)
return 0;
while (fgets(buffer, 120, fp) != NULL)
{
if ((ptr = strchr(buffer, '\n')) != NULL)
*ptr = '\0';
GetWord(0, buffer, mask);
if (atol(ToWord(1, buffer)) > now && match(userhost, mask))
{
fclose(fp);
return 1;
}
}
fclose(fp);
return 0;
}
#endif

266
Sources/ops.c Normal file
View File

@@ -0,0 +1,266 @@
/* @(#)$Id: ops.c,v 1.6 1999/04/04 17:00:13 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
void op(char *source, char *chan, char *nicklist)
{
char channel[80];
char nick[80];
char buffer[200];
register auser *user;
register achannel *ch;
register int i;
/* if the 1st arg is a channel name.. use it instead of 'chan' */
if (*nicklist == '#')
{
GetWord(0, nicklist, channel);
nicklist = ToWord(1, nicklist);
}
else
{
strncpy(channel, chan, 79);
channel[79] = '\0';
GuessChannel(source, channel);
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: op <channel> <nick1> [nick2] [nick3] [...]");
return;
}
/* Bad channel.. geez what am I supposed to do with it?? */
if ((ch = ToChannel(channel)) == NULL || !ch->on)
{
notice(source, replies[RPL_NOTONCHANNEL][L_DEFAULT]);
return;
}
if (!ch->AmChanOp)
{
notice(source, replies[RPL_NOTCHANOP][ch->lang]);
return;
}
if (*source && (ch->flags & CFL_OPONLY) &&
*nicklist && strcasecmp(nicklist, source))
{
notice(source, replies[RPL_OPSELFONLY][ch->lang]);
return;
}
if (*source && (ch->flags & CFL_NOOP))
{
notice(source, replies[RPL_NOOP][ch->lang]);
return;
}
#ifdef DEBUG
printf("OP requested....\nCHANNEL: %s\nNICKS: %s\n", channel, nicklist);
#endif
if (*source && Access(channel, source) < OP_LEVEL)
{
ReplyNotAccess(source, channel);
return;
}
if (!*nicklist)
{
strcpy(nick, source);
}
else
{
GetWord(0, nicklist, nick);
}
i = 0;
while (*nick)
{
user = ToUser(channel, nick);
#ifdef DEBUG
if (user)
{
printf("USER FOUND!\n");
printf("nick: %s\n", user->N->nick);
printf("Chanop: %s\n", (user->chanop) ? "YES" : "NO");
}
else
{
printf("USER %s NOT FOUND ON CHANNEL %s\n", nick, channel);
}
#endif
/* the user might be shitlisted.. */
if (user)
{
sprintf(buffer, "%s!%s@%s", user->N->nick, user->N->username, user->N->site);
if (ch->flags & CFL_STRICTOP && Access(channel, user->N->nick) < OP_LEVEL)
{
if (*source)
{
notice(source, "StrictOp is active and user is not authenticated");
}
}
else if (IsShit(channel, buffer, NULL, NULL) < NO_OP_SHIT_LEVEL)
{
if (user && !user->chanop)
{
user->chanop = 1;
changemode(channel, "+o", nick, 0);
if (*source && strcasecmp(source, nick))
{
sprintf(buffer, replies[RPL_YOUREOPPEDBY][ch->lang], source);
notice(nick, buffer);
}
}
}
else
{
sprintf(buffer, "%s: %s", nick, replies[RPL_CANTBEOPPED][ch->lang]);
notice(source, buffer);
}
}
else
{
sprintf(buffer, replies[RPL_USERNOTONCHANNEL][ch->lang], nick, channel);
notice(source, buffer);
}
GetWord(++i, nicklist, nick);
}
AddEvent(EVENT_FLUSHMODEBUFF, now + MODE_DELAY, channel);
}
void deop(char *source, char *ch, char *nicklist)
{
char channel[CHANNELNAME_LENGTH];
char nick[80];
char buffer[200];
register auser *user;
register achannel *chan;
register int i;
/* if the 1st arg is a channel name.. use it instead of 'channel' */
if (*nicklist == '#')
{
GetWord(0, nicklist, channel);
nicklist = ToWord(1, nicklist);
}
else
{
strncpy(channel, ch, CHANNELNAME_LENGTH);
GuessChannel(source, channel);
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: deop <channel> <nick1> [nick2] [nick3] [...]");
return;
}
#ifdef DEBUG
printf("DEOP requested....\nCHANNEL: %s\nNICKS: %s\n", channel, nicklist);
#endif
if ((chan = ToChannel(channel)) == NULL || !chan->on)
{
notice(source, replies[RPL_NOTONCHANNEL][L_DEFAULT]);
return;
}
if (*source && (chan->flags & CFL_OPONLY))
{
notice(source, replies[RPL_OPONLY][chan->lang]);
return;
}
if (!chan->AmChanOp)
{
notice(source, replies[RPL_NOTCHANOP][chan->lang]);
return;
}
if (*source && Access(channel, source) < OP_LEVEL)
{
ReplyNotAccess(source, channel);
return;
}
if (!*nicklist)
{
notice(source, "SYNTAX: deop [channel] <nick1> [nick2] [nick3] [...]");
return;
}
i = 0;
GetWord(i, nicklist, nick);
while (*nick)
{
user = ToUser(channel, nick);
if (user)
{
sprintf(buffer, "%s!%s@%s",
user->N->nick, user->N->username, user->N->site);
if (user && user->chanop)
{
user->chanop = 0;
changemode(channel, "-o", nick, 0);
if (*source && strcasecmp(source, nick))
{
sprintf(buffer, replies[RPL_YOUREDEOPPEDBY][chan->lang], source);
notice(nick, buffer);
}
}
}
GetWord(++i, nicklist, nick);
}
AddEvent(EVENT_FLUSHMODEBUFF, now + MODE_DELAY, channel);
}
void massdeop(char *channel)
{
achannel *chan;
auser *user;
chan = ToChannel(channel);
if (chan == NULL || !chan->on || !chan->AmChanOp)
return;
user = chan->users;
while (user != NULL)
{
if (user->chanop)
{
changemode(channel, "-o", user->N->nick, 0);
user->chanop = 0;
}
user = user->next;
}
flushmode(channel);
}

351
Sources/patch.c Normal file
View File

@@ -0,0 +1,351 @@
/* @(#)$Id: patch.c,v 1.3 1996/11/13 00:40:46 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#include <stdarg.h>
#ifdef UPGRADE
static void misc_closed_conn(misc_socket *);
void upgrade(char *source, char *args)
{
char global[]="*";
if(Access(global,source)<LEVEL_UPGRADE){
notice(source,"This command is not for you");
return;
}
open_patch_socket(source);
}
void open_patch_socket(char *source)
{
misc_socket *msock;
struct sockaddr_in socketname;
struct hostent *remote_host;
char pserver[80]=PATCH_SERVER, buffer[200], *ptr;
int port;
if((ptr=strchr(pserver,':'))==NULL){
notice(source,"PATCH_SERVER needs to be \"server:port\"!");
return;
}
*(ptr++)='\0';
sscanf(ptr,"%d",&port);
#ifdef DEBUG
printf("Connecting to patch server %s on port %d\n",pserver,port);
#endif
sprintf(buffer,"Connecting to patch server %s on port %d",pserver,port);
log(buffer);
notice(source,"Attempting to contact patch server...");
msock=(misc_socket *)MALLOC(sizeof(misc_socket));
msock->type=MISC_GETPATCH;
msock->status=MISC_CONNECTING;
msock->TS=now;
strcpy(msock->link,source);
msock->inbuf=NULL;
msock->outbuf=NULL;
if((msock->fd=socket(AF_INET,SOCK_STREAM,0))<0){
free(msock);
sprintf(buffer,"Can't assigned fd for socket: %s",sys_errlist[errno]);
notice(source,buffer);
return;
}
fcntl(msock->fd,F_SETFL,O_NONBLOCK);
socketname.sin_family=AF_INET;
if((remote_host=gethostbyname(pserver))==NULL){
sprintf(buffer,"gethostbyname() failed for %s: %s",pserver,sys_errlist[errno]);
notice(source,buffer);
close(msock->fd);
free(msock);
return;
}
memcpy((void *)&socketname.sin_addr,(void *)remote_host->h_addr,remote_host->h_length);
socketname.sin_port = htons(port);
if(connect(msock->fd,(struct sockaddr *)&socketname,sizeof(socketname))<0
&& errno != EINPROGRESS){
close(msock->fd);
sprintf(buffer,"Can't connect() to %s: %s",pserver,sys_errlist[errno]);
notice(source,buffer);
free(msock);
return;
}
msock->next=MiscList;
MiscList=msock;
send_misc_handshake(msock);
}
int readfrom_misc(misc_socket *msock)
{
void parse_misc(misc_socket *,char *);
char buf[1024];
int length;
if((length=read(msock->fd,buf,1023))<=0){
if(errno==EWOULDBLOCK || errno==EAGAIN){
return 0;
}else{
misc_closed_conn(msock);
close(msock->fd);
msock->fd=-1;
msock->status=MISC_ERROR;
return -1;
}
}
buf[length]='\0';
copy_to_buffer(&msock->inbuf,buf,length);
if(find_char_in_buffer(&msock->inbuf,'\n',1023)){
while(find_char_in_buffer(&msock->inbuf,'\n',1023)){
copy_from_buffer(&msock->inbuf,buf,'\n',1023);
parse_misc(msock,buf);
}
}
return 1;
}
int flush_misc_buffer(misc_socket *msock)
{
char buf[1024];
int length;
int count;
if(msock->status==MISC_CONNECTING){
msock->status=MISC_HANDSHAKE;
notice(msock->link,"Connected.");
}
if(msock==NULL || msock->outbuf==NULL)
return -1;
while((count = look_in_buffer(&msock->outbuf,buf,'\0',1023))>0){
if((length=write(msock->fd,buf,count))<=0){
if((errno==EWOULDBLOCK || errno==EAGAIN) && length!=0){
return 0;
}else{
misc_closed_conn(msock);
close(msock->fd);
msock->fd=-1;
msock->status=MISC_ERROR;
return -1;
}
}else{
skip_char_in_buffer(&msock->outbuf,length);
}
}
return 0;
}
long sendto_misc(misc_socket *msock, char *format, ...)
{
va_list args;
char string[1024];
va_start(args,format);
vsprintf(string,format,args);
#ifdef DEBUG
vprintf(format,args);
#endif
va_end(args);
return copy_to_buffer(&msock->outbuf,string,strlen(string));
}
void send_misc_handshake(misc_socket *msock)
{
struct stat stlast;
char tag[80], buffer[200];
FILE *fp;
if(msock->type==MISC_GETPATCH){
if(stat("lastupgrade",&stlast)<0){
sprintf(buffer,"lastupgrade: %s",
sys_errlist[errno]);
notice(msock->link,buffer);
close(msock->fd);
msock->status=MISC_ERROR;
}
fp=fopen("lastupgrade","r");
if(fp==NULL){
close(msock->fd);
msock->fd=-1;
msock->status=MISC_ERROR;
sprintf(buffer,"lastupgrade: %s",sys_errlist[errno]);
notice(msock->link,buffer);
return;
}
fgets(tag,80,fp);
fclose(fp);
sendto_misc(msock,"%s\n%s\n",GETPATCHPASS,tag);
}
}
static void misc_closed_conn(misc_socket *msock)
{
int pipefd[2],i;
char *ptr;
if(msock->type==MISC_GETPATCH){
if(msock->status==MISC_CONNECTING)
notice(msock->link,"Connection refused.");
else if(msock->status==MISC_HANDSHAKE)
notice(msock->link,"Handshake failed.");
else
notice(msock->link,"Connection closed.");
}else if(msock->type==MISC_PIPE_PATCH){
notice(msock->link,"patch process exited.");
pipe(pipefd);
switch(fork()){
case 0:
dup2(pipefd[1],1);
dup2(pipefd[1],2);
close(0);
for(i=3;i<MAX_CONNECTIONS;i++) close(i);
execl(MAKE,MAKE,(char *)0);
exit(-1);
case -1:
notice(msock->link,"fork() failed!");
/* socket already closed.. */
break;
default:
notice(msock->link,"Spawning make..");
close(pipefd[1]);
ptr=msock->link;
msock=(misc_socket *)MALLOC(sizeof(misc_socket));
msock->fd=pipefd[0];
msock->type=MISC_PIPE_MAKE;
msock->status=MISC_RECV;
msock->TS=now;
strcpy(msock->link,ptr);
msock->inbuf=NULL;
msock->outbuf=NULL;
msock->next=MiscList;
MiscList=msock;
break;
}
}else if(msock->type==MISC_PIPE_MAKE){
notice(msock->link,"make process exited.");
}else{
notice(msock->link,"Connection closed.");
}
}
void parse_misc(misc_socket *msock, char *line)
{
FILE *fp;
int fdpipe[2],i;
char *ptr;
if(msock->status==MISC_CONNECTING){
msock->status=MISC_HANDSHAKE;
notice(msock->link,"Connected!");
}
while((ptr=strpbrk(line,"\r\n"))!=NULL)
*ptr='\0';
if(!*line)
return;
if(msock->type==MISC_GETPATCH){
if(msock->status==MISC_HANDSHAKE){
if(strcmp(RECPATCHPASS,line)){
close(msock->fd);
msock->fd=-1;
msock->status=MISC_ERROR;
notice(msock->link,"Bad password!");
return;
}
msock->status=MISC_RECV;
}else if(msock->status==MISC_RECV){
fp=fopen("lastupgrade","w");
if(fp!=NULL){
fprintf(fp,"%s\n",line);
fclose(fp);
}
/* spawn patch */
pipe(fdpipe);
switch(fork()){
case 0:
fcntl(msock->fd,F_SETFL,0);
dup2(msock->fd,0);
dup2(fdpipe[1],1);
dup2(fdpipe[1],2);
for(i=3;i<MAX_CONNECTIONS;i++) close(i);
putenv("IFS="); /* I'm paranoid */
execl("/bin/sh","[patch script]","-c",
"tee upgrade.patch | "PATCH" -p1",
(char *)0);
exit(-1);
case -1:
notice(msock->link,"fork() failed");
close(msock->fd);
msock->fd=-1;
msock->status=MISC_ERROR;
break;
default:
notice(msock->link,"Spawning patch script..");
close(msock->fd);
while(msock->inbuf!=NULL){
char buf[512];
int l;
l=copy_from_buffer(&msock->inbuf,buf,'\0',511);
write(fdpipe[1],buf,l);
}
close(fdpipe[1]);
msock->fd=fdpipe[0];
msock->type=MISC_PIPE_PATCH;
zap_buffer(&msock->outbuf);
break;
}
}
}else if(msock->type==MISC_PIPE_PATCH || msock->type==MISC_PIPE_MAKE){
notice(msock->link,line);
}
}
#endif /* UPGRADE */

405
Sources/privmsg.c Normal file
View File

@@ -0,0 +1,405 @@
/* @(#)$Id: privmsg.c,v 1.22 2000/10/24 16:04:24 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
void privmsg(char *source, char *target, char *body)
{
register auser *user;
register achannel *chan;
register char *ptr;
char global[] = "*";
#ifdef DEBUG
printf("PRIVMSG from %s to %s\n", source, target);
#endif
if ((*target == '#' || *target == '$') && strchr(target, '*'))
{
#ifdef DEBUG
printf("Received WALL... ignoring.. \n");
#endif
return;
}
/* CTCP */
if (body[1] == '\001' && (ptr = strchr(body + 2, '\001')) != NULL)
{
if (*target == '#' || *target == '&')
{
if (CheckFlood(source, target, strlen(ToWord(1, body + 1))))
return;
}
*ptr = '\0';
if (!IsIgnored(source) &&
!CheckPrivateFlood(source, strlen(body), "CTCP-"))
parse_ctcp(source, target, body + 2);
}
/* PRIVMSG TO A CHANNEL */
else if (*target == '#' || *target == '&')
{
/* PRIVMSG #blah@channels.undernet.org ?? */
if (!(chan = ToChannel(target)))
return;
chan->lastact = now;
user = ToUser(target, source);
if (!user)
return; /* not on channel.. happens if not +n */
user->lastact = now;
if (CheckFlood(source, target, strlen(ToWord(1, body + 1))))
return;
if (!strncmp(body + 1, COMMAND_PREFIX, strlen(COMMAND_PREFIX)))
parse_command(source, target, target, body + strlen(COMMAND_PREFIX) + 1);
/* PRIVATE PRIVMSG */
}
else
{
if (!IsIgnored(source) && !CheckPrivateFlood(source, strlen(body), "MSG-"))
{
#ifdef FAKE_UWORLD
if (!strcasecmp(target, UFAKE_NICK))
{
parse_uworld_command(source, body + 1);
}
else
#endif
parse_command(source, target, global, body + 1);
}
}
}
void parse_command(char *source, char *target, char *channel, char *commandline)
{
char buffer[1024];
char command[80];
char global[] = "*";
register aluser *user;
GetWord(0, commandline, command);
#ifdef DEBUG
printf("PARSING COMMAND: %s\nCOMMAND: %s\nARGS: %s\nSOURCE: %s\n",
commandline, command, ToWord(1, commandline), source);
#endif
user = ToLuser(source);
/* all commands must come from a user */
if (user == NULL)
return;
if (strcasecmp(command, "pass") && strcasecmp(command, "login") &&
strcasecmp(command, "newpass"))
{
sprintf(buffer, "COMMAND FROM %s!%s@%s on %s: %s",
user->nick, user->username, user->site,
channel, commandline);
log(buffer);
}
else
{
sprintf(buffer, "COMMAND FROM %s!%s@%s on %s: %s XXXXXXX",
user->nick, user->username, user->site,
channel, command);
log(buffer);
}
if (!strcmp(command, "showcommands"))
showcommands(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "pass") || !strcmp(command, "login"))
validate(source, target, ToWord(1, commandline));
else if (!strcmp(command, "deauth"))
DeAuth(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "die") && Access(global, source) >= LEVEL_DIE)
quit(ToWord(1, commandline), 0);
else if (!strcmp(command, "restart") && Access(global, source) >= LEVEL_DIE)
restart(ToWord(1, commandline)); /* added by Kev; restarts */
else if (!strcmp(command, "search"))
SearchChan(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "join"))
join(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "part"))
part(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "op"))
op(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "deop"))
deop(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "banlist"))
showbanlist(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "kick"))
kick(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "invite"))
invite(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "topic"))
topic(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "adduser"))
AddUser(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "remuser"))
RemoveUser(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "modinfo"))
ModUserInfo(source, target, channel, ToWord(1, commandline));
else if (!strcmp(command, "newpass"))
ChPass(source, target, ToWord(1, commandline));
else if (!strcmp(command, "set"))
SetChanFlag(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "access"))
showaccess(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "suspend"))
suspend(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "unsuspend"))
unsuspend(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "saveuserlist"))
SaveUserList(source, channel);
else if (!strcmp(command, "lbanlist"))
ShowShitList(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "ban"))
AddToShitList(source, channel, ToWord(1, commandline), 0);
else if (!strcmp(command, "unban"))
RemShitList(source, channel, ToWord(1, commandline), 0);
else if (!strcmp(command, "cleanbanlist"))
CleanShitList(source, ToWord(1, commandline));
else if (!strcmp(command, "addchan"))
AddChan(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "remchan"))
RemChan(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "savedefs"))
SaveDefs(source);
else if (!strcmp(command, "loaddefs"))
LoadDefs(source);
else if (!strcmp(command, "saveshitlist"))
SaveShitList(source, channel);
else if (!strcmp(command, "loadshitlist"))
LoadShitList(source);
else if (!strcmp(command, "status"))
showstatus(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "map"))
showmap(source);
else if (!strcmp(command, "help"))
showhelp(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "chaninfo"))
ShowChanInfo(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "motd"))
showmotd(source);
else if (!strcmp(command, "isreg"))
isreg(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "core"))
dumpcore(source);
#ifdef RUSAGE_SELF
else if (!strcmp(command, "rusage"))
show_rusage(source);
#endif
else if (!strcmp(command, "showignore"))
ShowIgnoreList(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "remignore"))
AdminRemoveIgnore(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "calmdown"))
CalmDown(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "operjoin"))
OperJoin(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "operpart"))
OperPart(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "clearmode"))
ClearMode(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "purge"))
purge(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "verify"))
verify(source, ToWord(1, commandline));
#ifdef UPGRADE
else if (!strcmp(command, "upgrade"))
upgrade(source, ToWord(1, commandline));
#endif
else if (!strcmp(command, "random"))
RandomChannel(source);
else if (!strcmp(command, "say"))
Say(source, ToWord(1, commandline));
else if (!strcmp(command, "servnotice"))
ServNotice(source, ToWord(1, commandline));
else if (!strcmp(command, "fuck"))
notice(source, "This command is obsolete");
#ifdef DEBUG
else if (!strcmp(command, "db"))
db_test(source, channel, ToWord(1, commandline));
#endif
#ifdef DOHTTP
else if (!strcmp(command, "rehash"))
read_http_conf(source);
#endif
#ifdef FAKE_UWORLD
else if (!strcmp(command, "uworld"))
Uworld_switch(source, channel, ToWord(1, commandline));
else if (!strcmp(command, "opersuspend"))
OperSuspend(source, ToWord(1, commandline));
#endif
#ifdef DEBUG
else if (!strcmp(command, "showusers"))
showusers(ToWord(1, commandline));
else if (!strcmp(command, "showchannels"))
showchannels();
#endif
#ifdef NICKSERV
else if (!strcmp(command, "nickserv"))
nserv_nickserv(source, ToWord(1, commandline));
else if (!strcmp(command, "addnick"))
nserv_addnick(source, ToWord(1, commandline));
else if (!strcmp(command, "remnick"))
nserv_remnick(source, ToWord(1, commandline));
else if (!strcmp(command, "addmask"))
nserv_addmask(source, ToWord(1, commandline));
else if (!strcmp(command, "remmask"))
nserv_remmask(source, ToWord(1, commandline));
else if (!strcmp(command, "nickinfo"))
nserv_nickinfo(source, ToWord(1, commandline));
else if (!strcmp(command, "identify"))
nserv_identify(source, ToWord(1, commandline));
else if (!strcmp(command, "ghost"))
nserv_ghost(source, ToWord(1, commandline));
else if (!strcmp(command, "nicknewpass"))
nserv_nicknewpass(source, ToWord(1, commandline));
else if (!strcmp(command, "nicknewemail"))
nserv_nicknewemail(source, ToWord(1, commandline));
#endif
#ifdef DOHTTP
else if (!strcmp(command, "dccme"))
DccMe(source, ToWord(1, commandline));
#endif
}
void parse_ctcp(char *source, char *target, char *body)
{
char func[80];
char buffer[1024];
char tmp[80];
GetWord(0, body, func);
body = ToWord(1, body);
if (strcmp(func, "ACTION"))
{
sprintf(buffer, "CTCP %s from %s [%s]", func, source, body);
log(buffer);
}
if (match(func, "PING"))
{
sprintf(buffer, "\001PING %s\001", body);
notice(source, buffer);
}
else if (match(func, "TIME"))
{
strcpy(tmp, ctime(&now));
*strchr(tmp, '\n') = '\0';
sprintf(buffer, "\001TIME %s\001", tmp);
notice(source, buffer);
}
else if (match(func, "ITIME"))
{
sprintf(buffer, "\001ITIME @%03ld\001",
1000 * ((now + 3600) % 86400) / 86400);
notice(source, buffer);
}
else if (match(func, "VERSION"))
{
sprintf(buffer, "\001VERSION %s\001", VERSION);
notice(source, buffer);
}
else if (match(func, "GENDER"))
{
notice(source, "\001GENDER I'm a male bot! Are you a pretty young bottesse?\001");
}
}

271
Sources/prototypes.h Normal file
View File

@@ -0,0 +1,271 @@
/* @(#)$Id: prototypes.h,v 1.20 2000/10/24 15:15:53 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
void log(char *);
void SpecLog(char *);
void LogChan(void);
int connection(char *);
void try_later(char *);
void sendtoserv(char *);
int wait_msg(void);
void dumpbuff(void);
void rec_sigsegv(int);
void rec_sigbus(int);
void rec_sigterm(int);
void rec_sigint(int);
void dumpcore(char *);
void show_rusage(char *);
void regist(void);
void signon(void);
void onserver(char *,char *,char *);
void onsettime(char *,char *);
void onsquit(char *,char *,char *);
aserver *ToServer(char *);
aserver **FindServer(aserver **, char *);
char *ToWord(int,char *);
void GetWord(int,char *,char *);
char *time_remaining(time_t);
void proc(char *,char *, char *, char *);
void pong(char *);
void showversion(char *);
int reconnect(char *server);
int xmatch(char *, char *);
int compare(char *, char *);
int match(char *, char *);
int regex_cmp(char *patern, char *string);
int mycasecmp(char *,char *);
int key_match(char *,char *[]);
void string_swap(char *, size_t, char *, char *);
int quit(char *, int);
int restart(char *); /* added for restart function -Kev */
void showcommands(char *,char *,char *);
void showhelp(char *,char *,char *);
void showmotd(char *);
void ShowChanInfo(char *,char *,char *);
void isreg(char *,char *,char *);
void LoadUserList(char *);
void SaveUserList(char *,char *);
void DelChannel(char *);
void FreeUser(auser *);
void NewChannel(char *,time_t,int);
void QuitAll(void);
void privmsg(char *,char *,char *);
void parse_command(char *,char *,char *,char *);
int GuessChannel(char *, char *);
void try_find(char *,aluser *);
int LAccess(char *,aluser *);
int Access(char *,char *);
void verify(char *, char *);
RegUser *IsValid(aluser *,char *);
int IsShit(char *,char *,char *, char *);
void AddUser(char *,char *,char *);
void showaccess(char *,char *,char *);
void RemoveUser(char *,char *,char *);
void ModUserInfo(char *,char *,char *,char *);
void purge(char *,char *,char *);
void ChPass(char *,char *,char *);
void SetChanFlag(char *,char *,char *);
void free_user(RegUser **);
void validate(char *,char *,char *);
void DeAuth(char *, char *, char *);
void join(char *,char *,char *);
void joindefault(void);
void SendBurst(void);
void invite(char *,char *,char *);
void part(char *,char *,char *);
void oninvite(char *,char *);
void onjoin(char *,char *);
void onpart(char *,char *);
void onkick(char *,char *,char *);
void onop(char *,char *,char *);
void ondeop(char *,char *,char *,int *);
void GetOps(char *);
int IsOpless(char *);
void onopless(char *);
void onnick(char *,char *,char *);
void onban(char *,char *,char *);
void onunban(char *,char *,char *);
void showbanlist(char *,char *,char *);
void AddBan(char *,char *);
void RemBan(char *,char *);
void onwhois(char *,char *);
void UserQuit(char *);
achannel *ToChannel(char *);
auser *ToUser(char *,char *);
aluser *ToLuser(char *);
void onquit(char *);
void onkill(char *,char *,char *);
void onwho(char *);
void showusers(char *);
void showchannels(void);
void setchanmode(char *);
void ModeChange(char *,char *,char *);
void changemode(char *,char *,char *,int);
void flushmode(char *);
void bounce(char *,char *,time_t);
int IsSet(char *,char,char *);
void op(char *,char *,char *);
void deop(char *,char *,char *);
void massdeop(char *);
void MakeBanMask(aluser *, char *);
void ban(char *,char *,char *);
void mban(char *,char *,char *);
void unban(char *,char *,char *);
void kick(char *,char *,char *);
void topic(char *,char *,char *);
void notice(char *,char *);
void servnotice(char *,char *);
void broadcast(char *,int);
void NickInUse(void);
void ChNick(char *);
void AddToShitList(char *, char *, char *,int);
void RemShitList(char *,char *,char *,int);
void CleanShitList(char *,char *);
void suspend(char *, char *, char *);
void unsuspend(char *, char *, char *);
void ShowShitList(char *,char *,char *);
void LoadDefs(char *);
void SearchChan(char *,char *,char *);
void AddChan(char *,char *,char *);
void SaveDefs(char *);
void RemChan(char *, char *, char *);
int CheckFlood(char *,char *,int);
int CheckAdduserFlood(char *, char *);
void ontopic(char *,char *,char *);
void onnotice(char *,char *,char *);
void LoadShitList(char *);
void SaveShitList(char *,char *);
void parse_ctcp(char *,char *,char *);
void showstatus(char *,char *,char *);
void showmap(char *);
void showserv(char *,aserver *, int *);
void InitEvent(void);
void AddEvent(int, time_t, char *);
void CheckEvent(void);
void CleanIgnores(void);
void AddIgnore(char *,char *,int);
int CheckPrivateFlood(char *,int,char *);
int CheckFloodFlood(char *,int);
int IsIgnored(char *);
void ShowIgnoreList(char *,char *,char *);
void AdminRemoveIgnore(char *, char *, char *);
void CalmDown(char *,char *,char *);
void OperJoin(char *,char *,char *);
void OperPart(char *,char *,char *);
void ClearMode(char *, char *, char *);
void ReplyNotAccess(char *,char *);
void CheckIdleChannels(void);
void RandomChannel(char *);
void Say(char *,char *);
void RobinSay(char *,char *);
void ServNotice(char *,char *);
int IsReg(char *);
#ifdef FAKE_UWORLD
void IntroduceUworld(void);
void KillUworld(char *);
void Uworld_switch(char *,char *,char *);
void parse_uworld_command(char *,char *);
void Uworld_opcom(char *,char *);
void ClearChan(char *, char *);
void Uworld_reop(char *, char *);
void OperSuspend(char *, char *);
int IsOperSuspended(char *);
#endif
#ifdef NICKSERV
void IntroduceNickserv(void);
#endif
#ifdef DOHTTP
void open_http(void);
void remove_httpsock(http_socket *old);
void http_accept(int sock);
void parse_http(http_socket *hsock, char *buf);
void readfrom_file(http_file_pipe *fpipe);
void destroy_file_pipe(http_file_pipe *old);
void read_http_conf(char *);
long sendto_http(http_socket *sck, char *format, ...);
int readfrom_http(http_socket *);
int flush_http_buffer(http_socket *);
#endif
void upgrade(char *,char *);
void open_patch_socket(char *);
int readfrom_misc(misc_socket *);
int flush_misc_buffer(misc_socket *);
long sendto_misc(misc_socket *, char *, ...);
void send_misc_handshake(misc_socket *);
struct buffer_block *get_buffer_block(void);
void return_buffer_block(struct buffer_block *);
int copy_from_buffer(struct buffer_block **, char *, char, int);
int look_in_buffer(struct buffer_block **, char *, char, int);
long copy_to_buffer(struct buffer_block **, char *,int);
int zap_buffer(struct buffer_block **);
int find_char_in_buffer(struct buffer_block **, char,int);
int skip_char_in_buffer(struct buffer_block **, int);
char *make_dbfname(char *);
int db_fetch(char *,unsigned int,char *,char *,int,void *,void *,DBCALLBACK(x));
void read_db(dbquery *);
void end_db_read(dbquery *);
void db_sync(char *);
void db_sync_ready(dbsync *);
void end_db_sync(dbsync *);
void db_test(char *, char *,char *);
void gather_sync_channels(void);
void sync_next_channel(void);
void do_cold_sync(void);
void do_cold_sync_slice(void);
#ifdef HISTORY
void History(char *);
#endif
int ul_hash(char *);
int sl_hash(char *);
int lu_hash(char *);
int cl_hash(char *);
int su_hash(char *);
#ifdef NICKSERV
void IntroduceNickserv(void);
void KillNickserv(char *msg);
void nserv_nickserv(char *source, char *args);
void nserv_addnick(char *source, char *args);
void nserv_addmask(char *source, char *args);
void nserv_remnick(char *source, char *args);
void nserv_remmask(char *source, char *args);
void nserv_nickinfo(char *source, char *args);
void nserv_identify(char *source, char *args);
void nserv_ghost(char *source, char *args);
void nserv_nicknewpass(char *source, char *args);
void nserv_nicknewemail(char *source, char *args);
void nserv_save(void);
void nserv_load(void);
void nserv_checkregnick(char *nick);
void nserv_quit(aluser *user);
void nserv_nick(char *newnick, aluser *user);
void nserv_onop(char *channel, auser *user);
#endif
void DccMe(char *, char *);

614
Sources/replies.c Normal file
View File

@@ -0,0 +1,614 @@
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
/* Very appreciated contribution from: (just add your name here)
Stephan Mantler aka Step <smantler@atpibm6000.tuwien.ac.at>
Carlo Kid aka Run <carlo@tnrunaway.tn.tudelft.nl>
nirvana <nirvana@nil.fut.es>
*/
#include "h.h"
alang Lang[NO_LANG] =
{
{L_ENGLISH, "en", "english"},
{L_DUTCH, "nl", "dutch"},
{L_FRENCH, "fr", "fran<EFBFBD>ais"},
{L_SPANISH, "es", "espa<EFBFBD>ol"},
{L_GERMAN, "de", "deutsch"}
};
/* the %s will be expanded to the channel name
notaccessreply is only english for now */
char *notaccessreply[] =
{
"%s: Nice try. But I'm not a fool!",
"%s: Cheating is very bad you know!",
"%s: Do I know you?",
"You should come on %s more often",
"Ha! Ha! I don't think people on %s would like that!",
"%s: Pfft! Nice try!",
"%s: No, I don't think so.. you're not my type :P",
"go read the %s manual.. then I might consider it",
"I would.. but.. one teensy problem. You're not in %s's database",
"Oh.. are you trying to communicate with me?",
"You see, %s is some kinda private thing...",
NULL
};
void ReplyNotAccess(char *nick, char *channel)
{
static int index = 0;
register int i;
char buffer[200];
for (i = rand() % 5 + 1; i > 0; i--)
if (notaccessreply[++index] == NULL)
index = 0;
sprintf(buffer, notaccessreply[index], channel);
notice(nick, buffer);
}
void RandomChannel(char *source)
{
register int hash, offset;
register achannel *chan;
char buffer[200];
hash = rand() % 1000;
offset = rand() % 100;
chan = ChannelList[hash];
while (chan == NULL)
{
chan = ChannelList[(++hash) % 1000];
if (hash > 2000)
return;
}
while (offset > 0 && !chan->on)
{
chan = chan->next;
if (chan == NULL)
{
while (chan == NULL)
{
chan = ChannelList[(++hash) % 1000];
if (hash > 2000)
return;
}
}
offset--;
}
sprintf(buffer, "%s is cool!", chan->name);
notice(source, buffer);
}
void Say(char *source, char *args)
{
char buffer[1024], target[80], global[] = "*";
if (Access(global, source) < 900)
{
return; /*silently */
}
GetWord(0, args, target);
args = ToWord(1, args);
if (!*target || !*args)
{
notice(source, "Syntax: say [#channel] [whatever]");
return;
}
sprintf(buffer, ":%s PRIVMSG %s :%s\n", mynick, target, args);
sendtoserv(buffer);
}
void ServNotice(char *source, char *args)
{
char buffer[1024], target[80], global[] = "*";
if (Access(global, source) < 600)
{
return; /*silently */
}
GetWord(0, args, target);
args = ToWord(1, args);
if (!*target || !*args)
{
notice(source, "SYNTAX: servnotice [#channel] [whatever]");
return;
}
sprintf(buffer, "[Channel Service: %s] %s", source, args);
servnotice(target, buffer);
}
char *replies[][NO_LANG] =
{
/* RPL_NOTONCHANNEL */
{"I am not on that channel!", /* english */
"Ik zit niet op dat kanaal!", /* dutch */
"Je ne suis pas sur ce canal!", /* french */
"No estoy en ese canal!", /* spanish */
"Ich bin nicht auf diesem Kanal!" /* german */
},
/* RPL_NOTCHANOP */
{"I am not channel operator", /* english */
"Ik ben geen channel operator", /* dutch */
"Je ne suis pas op<6F>rateur de canal", /* french */
"No soy operador del canal", /* spanish */
"Ich bin kein Betreiber auf diesem Kanal" /* german */
},
/* RPL_OPONLY */
{"This channel is in OpOnly Mode", /* english */
"Dit kanaal is in OpOnly Mode", /* dutch */
"Ce canal est en mode OpOnly", /* french */
"Ese canal est<73> en modo OpOnly", /* spanish */
"Dieser Kanal is im OpOnly-Modus" /* german */
},
/* RPL_OPSELFONLY */
{"You can only op yourself in OpOnly mode", /* english */
"In OpOnly mode mag je alleen jezelf operator maken", /* dutch */
"Vous ne pouvez opper que vous-m<>me en mode OpOnly", /* french */
"Solo puedes ser operador en modo OpOnly", /* spanish */
"Sie koennen nur sich selbst zum Betreiber machen (Kanal im OpOnly-Modus)" /* german */
},
/* RPL_NOSUCHNICK */
{"No such nickname", /* english */
"Deze NICK is niet in gebruik", /* dutch */
"Ce nick n'existe pas", /* french */
"Ese nick no existe", /* spanish */
"Diesen Nickname gibt es nicht" /* german */
},
/* RPL_ALREADYONCHANNEL */
{"This user is already on channel", /* english */
"Deze persoon is al op dat kanaal", /* dutch */
"Cet usager est d<>j<EFBFBD> sur le canal", /* french */
"Ese usuario ya est<73> en el canal", /* spanish */
"Dieser Benutzer ist bereits auf dem Kanal" /* german */
},
/* RPL_IINVITED */
{"I invited %s to %s", /* english */
"%s is uitgenodigd naar %s te komen", /* dutch */
"J'ai invit<69> %s sur %s", /* french */
"Yo he invitado a %s en %s", /* spanish */
"Ich haben %s eingeladen, auf %s zu kommen" /* german */
},
/* RPL_YOUAREINVITED */
{"%s invites you to %s", /* english */
"%s vraagt of naar %s komt", /* dutch */
"%s vous invite sur %s", /* french */
"%s te invita en %s", /* spanish */
"%s laedt Sie ein, auf %s zu kommen" /* german */
},
/* RPL_ALWAYSOPWASACTIVE */
{"AlwaysOp was active! It's now deactivated", /* english */
"AlwaysOp was actief! Het is nu uitgeschakeld", /* dutch */
"AlwaysOp <20>tait actif! Il est maintenant d<>sactiv<69>", /* french */
"AlwaysOp estaba activado! Ahora ya esta desactivado", /* spanish */
"AlwaysOp war aktiv! Es wurde ausgeschalten" /* german */
},
/* RPL_ALWAYSOP */
{"This channel is in AlwaysOp mode!", /* english */
"Dit kanaal is in AlwaysOp mode!", /* dutch */
"Ce canal est en mode AlwaysOp!", /* french */
"Este canal est<73> en modo AlwaysOp!", /* spanish */
"Dieser Kanal is im AlwaysOp-Modus!" /* german */
},
/* RPL_KICK1ST */
{"You are not allowed to KICK me!", /* english */
"Het is niet toegestaan mij te KICKen!", /* dutch */
"Vous n'avez pas le droit de me kicker!", /* french */
"No estas autorizado para kickearme!", /* spanish */
"Sie duerfen mich nicht kicken!" /* german */
},
/* RPL_KICK2ND */
{"Please STOP kicking me!", /* english */
"STOP mij te KICKen!", /* dutch */
"Veuillez arr<72>ter de me kicker!", /* french */
"Por favor <20>para de kickearme!", /* spanish */
"Bitte hoeren Sie auf, mich zu kicken!" /* german */
},
/* RPL_CHANNOTEXIST */
{"That channel does not exist!", /* english */
"Dat kanaal bestaat niet!", /* dutch */
"Ce canal n'existe pas!", /* french */
"Ese canal no existe!", /* spanish */
"Diesen Kanal gibt es nicht!" /* german */
},
/* RPL_BADFLOODLIMIT */
{"value of FLOODPRO must be in the range [3-20] or 0 to turn it off",
"FLOODPRO moet een waarde hebben tussen 3 en 20 of 0 om het uit te schakelen",
"la valeur de FLOODPRO doit <20>tre entre 3 et 20 ou 0 pour le d<>sactiver",
"El valor de FLOODPRO tiene que estar entre 3 y 20 <20> 0 para desactivarlo",
"der Wert fon FLOODPRO muss im Bereich von 3 und 20 sein (oder 0 um es abzuschalten)"
},
/* RPL_SETFLOODLIMIT */
{"value of FLOODPRO is now %d", /* english */
"De waarde van FLOODPRO is nu %d", /* dutch */
"la valeur de FLOODPRO est maintenant %d", /* french */
"El valor de FLOOPRO est<73> ahora %d", /* spanish */
"FLOODPRO hat jetzt den Wert %d" /* german */
},
/* RPL_BADNICKFLOODLIMIT */
{"value of NICKFLOODPRO must be in the range [3-10] or 0 to turn it off",
"NICKFLOODPRO moet een waarde hebben tussen 3 en 10 of 0 om het uit te schakelen",
"la valeur de NICKFLOODPRO doit <20>tre entre 3 et 10 ou 0 pour le d<>sactiver",
"El valor de NICKFLOOPRO tiene que estar entre 3 y 10 <20> 0 para desactivarlo",
"Werte fuer NICKFLOODPRO muessen im Bereich von 3 bis 10 sein. Oder 0 um es abzuschalten"
},
/* RPL_SETNICKFLOODLIMIT */
{"value of NICKFLOODPRO is now %d", /* english */
"De waarde van NICKFLOODPRO is nu %d", /* dutch */
"la valeur de NICKFLOODPRO est maintenant %d", /* french */
"El valor de NICKFLOOPRO est<73> ahora en %d", /* spanish */
"der Wert fuer NICKFLOODPRO ist jetzt %d" /* german */
},
/* RPL_BADMASSDEOPLIMIT */
{"value of MASSDEOPPRO must be in the range [3-10] or 0 to turn it off",
"MASSDEOPPRO moet een waarde hebben tussen 3 en 10 of 0 om het uit te schakelen",
"la valeur de MASSDEOPPRO doit <20>tre entre 3 et 10 ou 0 pour le d<>sactiver",
"El valor de MASSDEOPPRO tiene que estar entre 3 y 10 <20> 0 para desactivarlo",
"der Wert von MASSDEOPPRO muss zwischen 3 und 10 liegen, oder 0 um es abzuschalten"
},
/* RPL_SETMASSDEOPLIMIT */
{"value of MASSDEOPPRO is now %d", /* english */
"De waarde van MASSDEOPPRO is nu %d", /* dutch */
"la valeur de MASSDEOPPRO est maintenant %d", /* french */
"El valor de MASSDEOPPRO est<73> ahora en %d", /* spanish */
"MASSDEOPPRO ist jetzt %d" /* german */
},
/* RPL_NOOPON */
{"value of NOOP is now ON", /* english */
"NOOP mode is nu ingeschakeld", /* dutch */
"la valeur de NOOP est maintenant ON", /* french */
"El valor de NOOP est<73> ahora en ON", /* spanish */
"NOOP hat jetzt den Wert EIN" /* german */
},
/* RPL_NOOPOFF */
{"value of NOOP is now OFF", /* english */
"NOOP mode is nu uit", /* dutch */
"la valeur de NOOP est maintenant OFF", /* french */
"El valor de NOOP est<73> ahora en OFF", /* spanish */
"NOOP hat jetzt den Wert AUS" /* german */
},
/* RPL_BADNOOP */
{"value of NOOP must be ON or OFF", /* english */
"Kies 'ON' of 'OFF' voor de waarde van NOOP", /* dutch */
"la valeur de NOOP doit <20>tre ON ou OFF", /* french */
"El valor de NOOP debe ser ON o OFF", /* spanish */
"NOOP kann nur EIN oder AUS sein" /* german */
},
/* RPL_ALWAYSOPON */
{"value of ALWAYSOP is now ON", /* english */
"ALWAYSOP mode is nu ingeschakeld", /* dutch */
"la valeur de ALWAYSOP est maintenant ON", /* french */
"El valor de ALWAYSOP es ahora ON", /* spanish */
"ALWAYSOP ist jetzt EIN" /* german */
},
/* RPL_ALWAYSOPOFF */
{"value of ALWAYSOP is now OFF", /* english */
"ALWAYSOP mode is nu uit", /* dutch */
"la valeur de ALWAYSOP est maintenant OFF", /* french */
"El valor de ALWAYSOP es ahora OFF", /* spanish */
"ALWAYSOP ist jetzt AUS" /* german */
},
/* RPL_BADALWAYSOP */
{"value of ALWAYSOP must be ON or OFF", /* english */
"Kies 'ON' of 'OFF' voor de waarde van ALWAYSOP", /* dutch */
"la valeur de ALWAYSOP doit <20>tre ON ou OFF", /* french */
"El valor de ALWAYSOP debe ser ON o OFF", /* spanish */
"Werte fuer ALWAYSOP sind EIN oder AUS" /* german */
},
/* RPL_OPONLYON */
{"value of OPONLY is now ON", /* english */
"OPONLY mode is nu ingeschakeld", /* dutch */
"la valeur de OPONLY est maintenant ON", /* french */
"El valor de OPONLY es ahora ON", /* spanish */
"der Wert fuer OPONLY ist jetzt EIN" /* german */
},
/* RPL_OPONLYOFF */
{"value of OPONLY is now OFF", /* english */
"OPONLY mode is nu uit", /* dutch */
"la valeur de OPONLY est maintenant OFF", /* french */
"El valor de OPONLY es ahora OFF", /* spanish */
"der Wert fuer OPONLY ist jetzt AUS" /* german */
},
/* RPL_BADOPONLY */
{"value of OPONLY must be ON or OFF", /* english */
"Kies 'ON' of 'OFF' voor de waarde van OPONLY", /* dutch */
"la valeur de OPONLY doit <20>tre ON ou OFF", /* french */
"El valor de OPONLY debe ser ON o OFF", /* spanish */
"Werte fuer OPONLY sind EIN oder AUS" /* german */
},
/* RPL_AUTOTOPICON */
{"value of AUTOTOPIC is now ON", /* english */
"AUTOTOPIC mode is nu ingeschakeld", /* dutch */
"la valeur de AUTOTOPIC est maintenant ON", /* french */
"El valor de AUTOTOPIC es ahora ON", /* spanish */
"der Wert fuer AUTOTOPIC ist jetzt EIN" /* german */
},
/* RPL_AUTOTOPICOFF */
{"value of AUTOTOPIC is now OFF", /* english */
"AUTOTOPIC mode is nu uit", /* dutch */
"la valeur de AUTOTOPIC est maintenant OFF", /* french */
"El valor de AUTOTOPIC es ahora OFF", /* spanish */
"der Wert fuer AUTOTOPIC ist jetzt AUS" /* german */
},
/* RPL_BADAUTOTOPIC */
{"value of AUTOTOPIC must be ON or OFF", /* english */
"Kies 'ON' of 'OFF' voor de waarde van AUTOTOPIC", /* dutch */
"la valeur de AUTOTOPIC doit <20>tre ON ou OFF", /* french */
"El valor de AUTOTOPIC debe ser ON o OFF", /* spanish */
"Werte fuer AUTOTOPIC sind EIN oder AUS" /* german */
},
/* RPL_STRICTOPON */
{"value of STRICTOP is now ON", /* english */
"value of STRICTOP is now ON", /* dutch */
"value of STRICTOP is now ON", /* french */
"El valor de STRICTOP es ahora ON", /* spanish */
"value of STRICTOP is now ON" /* german */
},
/* RPL_STRICTOPOFF */
{"value of STRICTOP is now OFF", /* english */
"value of STRICTOP is now OFF", /* dutch */
"value of STRICTOP is now OFF", /* french */
"El valor de STRICTOP es ahora OFF", /* spanish */
"value of STRICTOP is now OFF" /* german */
},
/* RPL_BADSTRICTOP */
{"value of STRICTOP must be ON or OFF", /* english */
"value of STRICTOP must be ON or OFF", /* dutch */
"value of STRICTOP must be ON or OFF", /* french */
"El valor de STRICTOP debe ser ON o OFF", /* spanish */
"value of STRICTOP must be ON or OFF" /* german */
},
/* RPL_BADUSERFLAGS */
{"New value can be 1-AUTOOP or 0-NO AUTOOP",
"De nieuwe waarde kan zijn 1-AUTOOP, 2-PROTECT ou 3-BOTH",
"La nouvelle valeur peut <20>tre 1-AUTOOP ou 0-PAS DE AUTOOP",
"El nuevo valor puede ser 1-AUTOOP o 0- NOAUTOOP", /* spanish */
"Der neue Wert kann 1-AUTOOP, 2-PROTECT oder 3-BEIDE sein."
},
/* RPL_SETUSERFLAGS */
{"value of USERFLAGS is now %d", /* english */
"de waarde van USERFLAGS is nu %d", /* dutch */
"la nouvelles valeur de USERFLAGS est %d", /* french */
"El nuevo valor de USERFLAGS es ahora %d", /* spanish */
"USERFLAGS ist jetzt %d" /* german */
},
/* RPL_KNOWNLANG */
{"Known languages are", /* english */
"De volgende talen zijn bekend", /* dutch */
"Je connais les langues", /* french */
"Yo hablo y escribo los siguientes idiomas", /* spanish */
"Folgende Sprachen sind bekannt" /* german */
},
/* RPL_SETLANG */
{"Default language is now %s (%s)", /* english */
"De default taal is nu %s (%s)", /* dutch */
"La langue par d<>faut est maintenant %s (%s)", /* french */
"El idioma configurado por defecto es ahora %s (%s)", /* spanish */
"Die neue Default-Sprache ist %s (%s)" /* german */
},
/* RPL_STATUS1 */
{"Channel %s has %d user%s (%d operator%s)", /* english */
"Kanaal %s heeft %d deelnemer%s (%d operator%s)", /* dutch */
"Canal %s a %d usager%s (%d op<6F>rateur%s)", /* french */
"El canal %s tiene %d usuarios%s (%d operadores%s)", /* spanish */
"Kanal %s hat %d Benutzer (%d Betreiber)" /* german */
/* ### NOTE the german version does not use plurals!
The code reflects this. */
},
/* RPL_STATUS2 */
{"Mode is +%s", /* english */
"Mode is +%s", /* dutch */
"Le mode est +%s", /* french */
"El modo es +%s", /* spanish */
"Der Modus ist +%s" /* german */
},
/* RPL_STATUS3 */
{"Default user flags%s", /* english */
"Default 'user flags'%s", /* dutch */
"Flags d'usager par d<>faut%s", /* french */
"Flags por defectos son %s", /* spanish */
"Default-Flags fuer Benutzer %s" /* german */
},
/* RPL_STATUS4 */
{"Default language is %s", /* english */
"Default taal is %s", /* dutch */
"Langue par d<>faut %s", /* french */
"Idioma por defecto %s", /* spanish */
"Default-Sprache ist %s" /* german */
},
/* RPL_STATUS5 */
{"Channel has been idle for %d second%s", /* english */
"Het kanaal is %d second%s idle", /* dutch */
"Le canal est inactif depuis %d seconde%s", /* french */
"El canal no est<73> activo desde hace %d segundos%s", /* spanish */
"Der Kanal ist seit %d Sekunden inaktiv." /* german */
},
/* RPL_SETCHANDEFS */
{"Channel defaults set.", /* english */
"Kanaal defaults geregistreerd.", /* dutch */
"L'<27>tat du canal est enregistr<74>", /* french */
"Los nuevos cambios han sido registrados", /* spanish */
"Default-Werte fuer den Kanal wurden gesetzt" /* german */
},
/* RPL_NOTDEF */
{"That channel is not in my default channel list", /* english */
"Dat kanaal staat niet in mijn default kanaal lijst", /* dutch */
"Ce canal n'est pas sur ma liste", /* french */
"Ese canal no est<73> en mi lista por defecto", /* spanish */
"Dieser Kanal ist nicht auf meiner Liste" /* german */
},
/* RPL_REMDEF */
{"Channel removed from default channel list", /* english */
"Het kanaal is van de default kanaal lijst verwijderd", /* dutch */
"Ce canal n'est plus sur ma liste", /* french */
"Canal eliminado de la lista por defecto", /* spanish */
"Der Kanal wurde aus meiner Liste entfernt" /* german */
},
/* RPL_NOMATCH */
{"No match.", /* english */
"Niet gevonden.", /* dutch */
"Introuvable", /* french */
"No se encuentra", /* spanish */
"Nicht gefunden." /* german */
},
/* RPL_NOOP */
{"Sorry. This channel is in NoOp mode!", /* english */
"Sorry. Dit kanaal is in NoOp mode!", /* dutch */
"D<EFBFBD>sol<EFBFBD>. Ce canal est en mode NoOp!", /* french */
"Lo siento, <20>Ese canal est<73> en modo NoOp!", /* spanish */
"Tut mir leid, aber dieser Kanal ist im NoOp-Modus!" /* german */
},
/* RPL_CANTBEOP */
{"Sorry. You are not allowed to be chanop", /* english */
"Sorry. Het is niet toegestaan dat u kanaal operator bent", /* dutch */
"D<EFBFBD>sol<EFBFBD>. Il ne vous est pas permis d'<27>tre op<6F>rateur", /* french */
"Lo siento. No estas autorizado para ser operador en el canal", /* spanish */
"Tut mir leid, aber Sie duerfen nicht Betreiber werden." /*german */
},
/* RPL_CANTBEOPPED */
{"This user is not allowed to be chanop", /* english */
"Deze gebruiker is het niet toegestaan kanaal operator te zijn", /* dutch */
"Cet usager n'a pas le droit d'<27>tre op<6F>rateur", /* french */
"Ese usuario no est<73> autorizado para ser operador en el canal", /* spanish */
"Dieser Benutzer darf nicht Betreiber werden." /* german */
},
/* RPL_DEOPPED1ST */
{"You are not allowed to DEOP me!", /* english */
"Je mag me niet deoppen!", /* dutch */
"Vous ne pouvez pas me deopper!", /* french */
"<EFBFBD>No me puedes quitar el op!", /* spanish */
"Sie duerfen mich nicht deoppen!" /* german */
},
/* RPL_DEOPPED2ND */
{"Please STOP deopping me!", /* english */
"STOP met me te de-oppen!", /* dutch */
"Veuillez arr<72>ter de me deopper!", /* french */
"Por favor, <20>para de quitarme el op!", /* spanish */
"Bitte hoeren Sie auf, mich zu deoppen!" /* german */
},
/* RPL_DEOPPED3RD */
{"I warned you!", /* english */
"Je was gewaarschuwd!", /* dutch */
"Je vous aurai pr<70>venu!", /* french */
"<EFBFBD>Te he hecho una advertencia!", /* spanish */
"Sie wurden gewarnt!" /* german */
},
/* RPL_USERISPROTECTED */
{"This user is protected", /* english */
"Deze gebruiker is beschermd", /* dutch */
"Cet usager est prot<6F>g<EFBFBD>", /* french */
"Este usuario est<73> protegido", /* spanish */
"Dieser Benutzer ist geschuetzt" /* german */
},
/* RPL_YOUREOPPEDBY */
{"You're opped by %s", /* english */
"U bent kanaal operator gemaakt door %s", /* dutch */
"Vous <20>tes opp<70> par %s", /* french */
"El %s te ha puesto de operador en el canal", /*spanish */
"Sie wurden von %s zum Betreiber gemacht." /* german */
},
/* RPL_USERNOTONCHANNEL */
{"User %s is not on channel %s!", /* english */
"%s bevindt zich niet op kanaal %s!", /* dutch */
"%s n'est pas sur %s!", /* french */
"El usuario %s no est<73> presente en el canal %s!", /* spanish */
"%s ist nicht auf dem Kanal %s!" /* german */
},
/* RPL_YOUREDEOPPEDBY */
{"You're deopped by %s", /* english */
"Het kanaal operatorschap is u ontnomen door %s", /* dutch */
"Vous <20>tes d<>opp<70> par %s", /* french */
"El %s te quit<69> el status de op%s", /* spanish */
"%s hat ihnen den Betreiberstatus entzogen" /* german */
}
};

83
Sources/replies.h Normal file
View File

@@ -0,0 +1,83 @@
/* @(#)$Id: replies.h,v 1.4 1996/11/13 00:40:47 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#define RPL_NOTONCHANNEL 0
#define RPL_NOTCHANOP 1
#define RPL_OPONLY 2
#define RPL_OPSELFONLY 3
#define RPL_NOSUCHNICK 4
#define RPL_ALREADYONCHANNEL 5
#define RPL_IINVITED 6
#define RPL_YOUAREINVITED 7
#define RPL_ALWAYSOPWASACTIVE 8
#define RPL_ALWAYSOP 9
#define RPL_KICK1ST 10
#define RPL_KICK2ND 11
#define RPL_CHANNOTEXIST 12
#define RPL_BADFLOODLIMIT 13
#define RPL_SETFLOODLIMIT 14
#define RPL_BADNICKFLOODLIMIT 15
#define RPL_SETNICKFLOODLIMIT 16
#define RPL_BADMASSDEOPLIMIT 17
#define RPL_SETMASSDEOPLIMIT 18
#define RPL_NOOPON 19
#define RPL_NOOPOFF 20
#define RPL_BADNOOP 21
#define RPL_ALWAYSOPON 22
#define RPL_ALWAYSOPOFF 23
#define RPL_BADALWAYSOP 24
#define RPL_OPONLYON 25
#define RPL_OPONLYOFF 26
#define RPL_BADOPONLY 27
#define RPL_AUTOTOPICON 28
#define RPL_AUTOTOPICOFF 29
#define RPL_BADAUTOTOPIC 30
#define RPL_STRICTOPON 31
#define RPL_STRICTOPOFF 32
#define RPL_BADSTRICTOP 33
#define RPL_BADUSERFLAGS 34
#define RPL_SETUSERFLAGS 35
#define RPL_KNOWNLANG 36
#define RPL_SETLANG 37
#define RPL_STATUS1 38
#define RPL_STATUS2 39
#define RPL_STATUS3 40
#define RPL_STATUS4 41
#define RPL_STATUS5 42
#define RPL_SETCHANDEFS 43
#define RPL_NOTDEF 44
#define RPL_REMDEF 45
#define RPL_NOMATCH 46
#define RPL_NOOP 47
#define RPL_CANTBEOP 48
#define RPL_CANTBEOPPED 49
#define RPL_DEOPPED1ST 50
#define RPL_DEOPPED2ND 51
#define RPL_DEOPPED3RD 52
#define RPL_USERISPROTECTED 53
#define RPL_YOUREOPPEDBY 54
#define RPL_USERNOTONCHANNEL 55
#define RPL_YOUREDEOPPEDBY 56

265
Sources/servers.c Normal file
View File

@@ -0,0 +1,265 @@
/* @(#)$Id: servers.c,v 1.9 1998/01/25 18:35:47 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
aserver **FindServer(aserver ** head, char *name)
{
register aserver **tmp;
if (head == NULL || *head == NULL)
return NULL;
while (*head != NULL)
{
if (!strcasecmp((*head)->name, name))
{
return head;
}
if ((tmp = FindServer(&(*head)->down, name)) != NULL)
{
return tmp;
}
else
{
head = &(*head)->next;
}
}
return NULL;
}
aserver *ToServer(char *name)
{
return (*FindServer(&ServerList, name));
}
void onserver(char *source, char *newserver, char *args)
{
register aserver *head;
register aserver *tmp;
register int i;
char TS[80];
if (source[0] != '\0')
{
head = ToServer(source);
}
else
{
head = NULL;
}
#ifdef BACKUP
if (!strcasecmp(newserver, MAIN_SERVERNAME))
{
quit(MAIN_NICK " is back", 0);
}
#endif
tmp = (aserver *) MALLOC(sizeof(aserver));
tmp->name = (char *)MALLOC(strlen(newserver) + 1);
strcpy(tmp->name, newserver);
GetWord(2, args, TS);
tmp->TS = atol(TS);
if (head == NULL)
{
tmp->next = ServerList;
ServerList = tmp;
TSoffset = tmp->TS - now;
#ifdef DEBUG
printf("New connection: my time: %ld others' time %ld (%ld)\n",
now, tmp->TS, TSoffset);
#endif
}
else
{
tmp->next = head->down;
head->down = tmp;
}
tmp->up = head;
tmp->down = NULL;
for (i = 0; i < 100; i++)
tmp->users[i] = NULL;
}
void onsquit(char *source, char *theserver, char *args)
{
register aserver *serv, **s;
register int i;
char TS[80];
#ifdef FAKE_UWORLD
if (!strcasecmp(theserver, UFAKE_SERVER) && Uworld_status == 1)
{
GetWord(0, args, TS);
if (atol(TS) == UworldServTS)
{
char buffer[200];
sprintf(buffer, "%s squitted", UFAKE_NICK);
log(buffer);
Uworld_status = 0;
}
return;
}
#endif
s = FindServer(&ServerList, theserver);
if (s == NULL)
{
char buffer[200];
sprintf(buffer, "ERROR: SQUIT unknown server %s (from %s)",
theserver, source);
log(buffer);
return;
}
serv = *s;
#ifdef DEBUG
printf("SQUIT: %s %s\n", source, theserver);
#endif
if (args != NULL)
{
GetWord(0, args, TS);
#ifdef DEBUG
if (s != NULL)
printf("ConnectTS: %ld SquitTS: %ld\n", serv->TS, atol(TS));
#endif
}
if (serv != ServerList && args != NULL && serv->TS != atol(TS))
{
#ifdef DEBUG
printf("TS's are different.. ignoring squit!\n");
#endif
return;
}
while (serv->down != NULL)
{
onsquit(NULL, serv->down->name, NULL);
}
for (i = 0; i < 100; i++)
{
while (serv->users[i] != NULL)
{
onquit(serv->users[i]->N->nick);
}
}
TTLALLOCMEM -= strlen(serv->name) + 1;
free(serv->name);
*s = serv->next;
TTLALLOCMEM -= sizeof(aserver);
free(serv);
}
void showmap(char *source)
{
int count = 0;
if (CurrentSendQ > HIGHSENDQTHRESHOLD)
{
notice(source, "Cannot process your request at this time. Try again later.");
return;
}
notice(source, SERVERNAME);
showserv(source, ServerList, &count);
CheckFloodFlood(source, count);
}
void showserv(char *source, aserver * server, int *count)
{
static char prefix[80] = "";
static int offset = 0;
char buffer[200];
register asuser *suser;
register int nbusers = 0, i;
if (server == NULL)
{
return;
}
(*count)++; /* number of servers */
/* count number of users */
for (i = 0; i < 100; i++)
{
suser = server->users[i];
while (suser != NULL)
{
nbusers++;
suser = suser->next;
}
}
if (server->next == NULL)
{
sprintf(buffer, "%s`-%s (%d client%s)", prefix, server->name, nbusers, (nbusers != 1) ? "s" : "");
}
else
{
sprintf(buffer, "%s|-%s (%d client%s)", prefix, server->name, nbusers, (nbusers != 1) ? "s" : "");
}
notice(source, buffer);
if (server->next != NULL)
strcpy(prefix + offset, "| ");
else
strcpy(prefix + offset, " ");
offset += 2;
showserv(source, server->down, count);
offset -= 2;
prefix[offset] = '\0';
showserv(source, server->next, count);
}
void onsettime(char *source, char *value)
{
char buffer[200];
TSoffset = atol(value) - now;
sprintf(buffer, "SETTIME from %s (%s) (%ld)", source, value, TSoffset);
log(buffer);
#ifdef DEBUG
puts(buffer);
#endif
}
void showversion(char *source)
{
char buffer[200];
sprintf(buffer, ":%s 351 %s . %s :%s\n", SERVERNAME, source, SERVERNAME, VERSION);
sendtoserv(buffer);
}

791
Sources/shitlist.c Normal file
View File

@@ -0,0 +1,791 @@
/* @(#)$Id: shitlist.c,v 1.12 2000/01/28 01:29:14 lgm Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
typedef struct ShitDisk
{
time_t time;
time_t expiration;
char match[80];
char from[80];
char reason[200];
char channel[50];
int level;
}
ShitDisk;
static int active = 0;
int sl_hash(char *channel)
{
register int i, j = 0;
for (i = 1; i < strlen(channel); i++)
j += (unsigned char)toupper(channel[i]);
return (j % 1000);
}
void AddToShitList(char *source, char *ch, char *args, int force)
{
char buffer[1024];
char srcuh[200];
char channel[80];
char pattern[200];
char strtime[80];
char strlevel[80];
char *reason;
time_t exp;
int shitlevel;
int srcAccess;
int exact;
register char *ptr1, *ptr2;
register aluser *luser;
register ShitUser *curr;
register achannel *chan;
if (*args == '#')
{
GetWord(0, args, channel);
args = ToWord(1, args);
}
else
{
strcpy(channel, ch);
GuessChannel(source, channel);
}
if (*source && force == 0)
{
chan = ToChannel(channel);
if (chan != NULL && (chan->flags & CFL_OPONLY))
{
notice(source, replies[RPL_OPONLY][chan->lang]);
return;
}
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: ban <#channel> <nick|address> "
"<duration in hours> <level> <reason>");
return;
}
if (!*source || force > 0)
srcAccess = (MASTER_ACCESS + 1);
else
srcAccess = Access(channel, source);
if (srcAccess < ADD_TO_SHITLIST_LEVEL)
{
ReplyNotAccess(source, channel);
return;
}
GetWord(0, args, pattern);
GetWord(1, args, strtime);
GetWord(2, args, strlevel);
reason = ToWord(3, args);
if (strlen(reason) > 200)
reason[199] = '\0';
if (!*pattern || (*strtime != '\0' && !isdigit(*strtime)))
{
notice(source, "SYNTAX: ban [#channel] <nick|address> "
"[duration in hours] [level] [reason]");
return;
}
if (!*strtime)
{
exp = SHITLIST_DEFAULT_TIME;
}
else
{
exp = atoi(strtime);
}
if (!*strlevel)
{
shitlevel = AUTO_KICK_SHIT_LEVEL;
}
else
{
shitlevel = atoi(strlevel);
}
exp *= 3600;
if (exp < 0 || exp > (MAX_BAN_DURATION * 24 * 3600))
{
sprintf(buffer, "Invalid duration (Max %d days)", MAX_BAN_DURATION);
notice(source, buffer);
return;
}
if (shitlevel < 1 || shitlevel > 1000)
{
notice(source, "Ban level must be in the range 1-1000");
return;
}
if (srcAccess < shitlevel)
{
notice(source, "Can't ban to a higher level than your access level.");
return;
}
exp += now;
if ((luser = ToLuser(source)) != NULL)
{
sprintf(srcuh, "%s!%s@%s", luser->nick, luser->username, luser->site);
}
else
{
strcpy(srcuh, source);
}
/* look if the user is on the channel, if so, take his address */
luser = ToLuser(pattern);
if (luser != NULL)
{
MakeBanMask(luser, pattern);
exact = 0;
}
else
{
if ((ptr2 = strchr(pattern, '@')) == NULL)
{
strcat(pattern, "@*");
ptr2 = strchr(pattern, '@');
}
if ((ptr1 = strchr(pattern, '!')) == NULL)
{
char tmp[200];
sprintf(tmp, "*!%s", pattern);
strncpy(pattern, tmp, 200);
pattern[199] = '\0';
ptr1 = pattern + 1;
}
if (ptr1 > ptr2)
{
notice(source, "Illegal ban mask");
return;
}
exact = 1;
}
/* count number of bans.. if it's > MAX_BAN.. refuse to add */
if (!force && *source && shitlevel > 0)
{
register int count = 0;
curr = ShitList[sl_hash(channel)];
while (curr)
{
if (!strcasecmp(curr->channel, channel))
count++;
curr = curr->next;
}
if (count > MAX_BAN)
{
notice(source, "Sorry, there are too many bans on"
" your channel. You'll have to remove some first.");
return;
}
}
/* Now, seek thru the ShitList if the pattern is already there.
if it is, only change the information already present */
curr = ShitList[sl_hash(channel)];
if (exact)
{
while (curr && (strcasecmp(curr->match, pattern) || strcasecmp(curr->channel, channel)))
{
curr = curr->next;
}
}
else
{
while (curr && (!match(pattern, curr->match) || strcasecmp(curr->channel, channel)))
{
curr = curr->next;
}
}
if (curr)
{
/* if the user is already on the shitlist.. */
/* if this is the result of a flood protection.. we have to
make sure the user is not already shitlisted for a longer
time.. */
if (shitlevel == 0 || curr->expiration < exp)
curr->expiration = exp;
curr->time = now;
/* if this is the result of a flood protection.. we have to
make sure the user is not already shitlisted at a higher
level.. */
if (shitlevel == 0 || curr->level < shitlevel)
curr->level = shitlevel;
TTLALLOCMEM -= strlen(curr->from) + 1;
free(curr->from);
curr->from = (char *)MALLOC(strlen(srcuh) + 1);
strcpy(curr->from, srcuh);
TTLALLOCMEM -= strlen(curr->reason) + 1;
free(curr->reason);
curr->reason = (char *)MALLOC(strlen(reason) + 1);
strcpy(curr->reason, reason);
}
else
{
#ifdef DEBUG
printf("TIME: %ld EXP: %ld LEVEL %d\n", now, exp, shitlevel);
#endif
/* if the user is NOT already on the shitlist */
/* first, create a new structure */
curr = (ShitUser *) MALLOC(sizeof(ShitUser));
curr->time = now;
curr->expiration = exp;
curr->level = shitlevel;
curr->match = (char *)MALLOC(strlen(pattern) + 1);
strcpy(curr->match, pattern);
curr->from = (char *)MALLOC(strlen(srcuh) + 1);
strcpy(curr->from, srcuh);
curr->reason = (char *)MALLOC(strlen(reason) + 1);
strcpy(curr->reason, reason);
curr->channel = (char *)MALLOC(strlen(channel) + 1);
strcpy(curr->channel, channel);
/* Then, link it to the list.. */
curr->next = ShitList[sl_hash(channel)];
ShitList[sl_hash(channel)] = curr;
}
/* schedule the removal of the entry..
*/
AddEvent(EVENT_CLEANSHITLIST, exp, channel);
if (*source && !force)
notice(source, "Ban list updated");
if (shitlevel >= AUTO_KICK_SHIT_LEVEL && !force)
{
#ifdef DEBUG
printf("Calling mban(\"\",%s,%s)\n", channel, pattern);
#endif
mban("", channel, pattern);
sprintf(buffer, "%s (%s) %s", pattern, source, reason);
kick("", channel, buffer);
}
/* Now, clean the shitlist */
if (!force)
CleanShitList("", channel);
}
void RemShitList(char *source, char *ch, char *args, int force)
{
char channel[80];
char pattern[2][200];
register aluser *luser;
register ShitUser *curr;
register achannel *chan;
int srcaccess, exact;
if (*args == '#')
{
GetWord(0, args, channel);
args = ToWord(1, args);
}
else
{
strcpy(channel, ch);
GuessChannel(source, channel);
}
if (*source && force == 0)
{
chan = ToChannel(channel);
if (chan != NULL && (chan->flags & CFL_OPONLY))
{
notice(source, replies[RPL_OPONLY][chan->lang]);
return;
}
}
if (!strcmp(channel, "*"))
{
notice(source, "SYNTAX: unban <#channel> <nick|address>");
return;
}
if (!*source || force > 0)
srcaccess = (MASTER_ACCESS + 1);
else
srcaccess = Access(channel, source);
if (srcaccess < ADD_TO_SHITLIST_LEVEL)
{
ReplyNotAccess(source, channel);
return;
}
GetWord(0, args, pattern[0]);
if (!*pattern[0])
{
notice(source, "SYNTAX: unban [#channel] <nick|address>");
return;
}
/* look if the user is on the channel, if so, take his address */
luser = ToLuser(pattern[0]);
if (luser != NULL)
{
sprintf(pattern[1], "%s!%s@%s",
luser->nick, luser->username, luser->site);
exact = 0;
}
else
{
exact = 1;
}
/* Now, seek thru the ShitList if the pattern is already there. */
curr = ShitList[sl_hash(channel)];
if (exact)
{
while (curr && (strcasecmp(curr->match, pattern[0]) || strcasecmp(curr->channel, channel) || srcaccess < curr->level))
{
curr = curr->next;
}
}
else
{
while (curr && (!match(pattern[1], curr->match) || strcasecmp(curr->channel, channel) || srcaccess < curr->level))
{
curr = curr->next;
}
}
if (curr)
{
curr->expiration = now - 1;
if (*source && !force)
notice(source, "Ban list updated");
CleanShitList("", channel);
}
else
{
unban("", channel, pattern[0]);
}
}
void CleanShitList(char *source, char *channel)
{
char buffer[200];
register ShitUser *curr, *prev;
register achannel *chan;
int i;
if (*source && Access(channel, source) < CLEAN_SHITLIST_LEVEL)
{
notice(source, "Your admin Access is too low");
return;
}
i = sl_hash(channel);
curr = ShitList[i];
prev = NULL;
while (curr)
{
chan = ToChannel(curr->channel);
if (chan == NULL || (curr->expiration <= now && !strcasecmp(channel, chan->name))
|| curr->level == 0)
{
if (chan != NULL && chan->on && chan->AmChanOp)
{
unban("", curr->channel, curr->match);
}
if (prev)
{
prev->next = curr->next;
TTLALLOCMEM -= strlen(curr->match) + 1;
free(curr->match);
TTLALLOCMEM -= strlen(curr->from) + 1;
free(curr->from);
TTLALLOCMEM -= strlen(curr->reason) + 1;
free(curr->reason);
TTLALLOCMEM -= strlen(curr->channel) + 1;
free(curr->channel);
TTLALLOCMEM -= sizeof(ShitUser);
free(curr);
curr = prev->next;
}
else
{
ShitList[i] = curr->next;
TTLALLOCMEM -= strlen(curr->match) + 1;
free(curr->match);
TTLALLOCMEM -= strlen(curr->from) + 1;
free(curr->from);
TTLALLOCMEM -= strlen(curr->reason) + 1;
free(curr->reason);
TTLALLOCMEM -= strlen(curr->channel) + 1;
free(curr->channel);
TTLALLOCMEM -= sizeof(ShitUser);
free(curr);
curr = ShitList[i];
}
}
else
{
prev = curr;
curr = curr->next;
}
}
if (*source)
notice(source, "Ban list is now up-to-date");
sprintf(buffer, "Cleaned banlist on %s", channel);
log(buffer);
}
int IsShit(char *channel, char *user, char *out, char *reason)
{
register ShitUser *curr;
register aluser *luser;
char uh[200];
if (strchr(user, '!') != NULL)
{
strcpy(uh, user);
}
else
{
luser = ToLuser(user);
sprintf(uh, "%s!%s@%s", luser->nick, luser->username, luser->site);
}
curr = ShitList[sl_hash(channel)];
#ifdef DEBUG
printf("IsShit(%s,%s,%s)\n", channel, user, out);
#endif
while (curr && (!match(channel, curr->channel) || !match(uh, curr->match)))
curr = curr->next;
#ifdef DEBUG
if (curr)
printf("Banlevel: %d\n", curr->level);
#endif
if (curr)
{
if (out != NULL)
strcpy(out, curr->match);
if (reason != NULL)
strcpy(reason, curr->reason);
return (curr->level);
}
else
{
return 0;
}
}
void ShowShitList(char *source, char *ch, char *args)
{
register ShitUser *curr;
struct tm *tp;
char buffer[1024], global[] = "*";
char channel[80];
int found = 0;
if (*args == '#')
{
GetWord(0, args, channel);
args = ToWord(1, args);
}
else
{
strcpy(channel, ch);
GuessChannel(source, channel);
}
if (!strcmp(channel, "*") || !*args)
{
notice(source, "SYNTAX: lbanlist [#channel] <search pattern>");
return;
}
if (!ToUser(channel, source) &&
Access(channel, source) < 500 && Access(global, source) < 500)
{
notice(source, "You are not on that channel");
return;
}
curr = ShitList[sl_hash(channel)];
while (curr)
{
if (!strcasecmp(channel, curr->channel) && match(curr->match, args))
{
found++;
}
curr = curr->next;
}
if ((found > 15) && (source[0] != '+'))
{
sprintf(buffer, "There are %d matching entries. Please use a userhost mask to narrow down the list.", found);
notice(source, buffer);
return;
}
if (found == 0)
{
sprintf(buffer, "*** No entry matching with %s ***", args);
notice(source, buffer);
return;
}
sprintf(buffer, "*** Ban List for channel %s ***", channel);
notice(source, buffer);
curr = ShitList[sl_hash(channel)];
while (curr)
{
if (!strcasecmp(channel, curr->channel) && match(curr->match, args))
{
sprintf(buffer, "%s %s Level: %d", curr->channel,
curr->match, curr->level);
notice(source, buffer);
sprintf(buffer, "ADDED BY: %s (%s)", curr->from,
(*curr->reason) ? curr->reason : "No reason given");
notice(source, buffer);
tp = gmtime(&curr->time);
sprintf(buffer, "SINCE: %sUCT", asctime(tp));
*strchr(buffer, '\n') = ' ';
notice(source, buffer);
sprintf(buffer, "EXP: %s", time_remaining(curr->expiration - now));
notice(source, buffer);
}
curr = curr->next;
}
notice(source, "*** END ***");
}
void SaveShitList(char *source, char *channel)
{
ShitDisk tmp;
register ShitUser *user;
register int file;
char buffer[200];
int i;
if (*source && Access(channel, source) < SAVE_SHITLIST_LEVEL)
{
notice(source, "Your admin Access is too low!");
return;
}
if (active)
return;
active = 1;
alarm(5); /* avoid NFS hangs */
file = open(SHITLIST_FILE ".new", O_WRONLY | O_CREAT | O_TRUNC, 0600);
alarm(0);
if (file < 0)
{
if (*source)
notice(source, "Error opening BanList file! Aborted.");
log("Error saving shitlist");
active = 0;
return;
}
sprintf(buffer, ":%s AWAY :Busy saving precious ban list\n", mynick);
sendtoserv(buffer);
dumpbuff();
for (i = 0; i < 1000; i++)
{
user = ShitList[i];
while (user)
{
tmp.time = user->time;
tmp.expiration = user->expiration;
strncpy(tmp.match, user->match, 79);
tmp.match[79] = '\0';
strncpy(tmp.from, user->from, 79);
tmp.from[79] = '\0';
strncpy(tmp.reason, user->reason, 199);
tmp.reason[199] = '\0';
strncpy(tmp.channel, user->channel, 49);
tmp.channel[49] = '\0';
tmp.level = user->level;
alarm(2);
if (write(file, &tmp, sizeof(ShitDisk)) <= 0)
{
alarm(0);
close(file);
log("ERROR: Can't save banlist");
log((char *)sys_errlist[errno]);
alarm(2);
remove(SHITLIST_FILE ".new");
alarm(0);
active = 0;
sprintf(buffer, ":%s AWAY\n", mynick);
sendtoserv(buffer);
return;
}
alarm(0);
user = user->next;
}
}
close(file);
alarm(20);
rename(SHITLIST_FILE ".new", SHITLIST_FILE);
alarm(0);
if (*source)
notice(source, "banlist saved.");
active = 0;
sprintf(buffer, ":%s AWAY\n", mynick);
sendtoserv(buffer);
}
void LoadShitList(char *source)
{
ShitDisk tmp;
ShitUser *user;
int file;
int i;
if (*source && Access("*", source) < LOAD_SHITLIST_LEVEL)
{
notice(source, "Your admin access is too low!");
return;
}
if (active)
return;
active = 1;
file = open(SHITLIST_FILE, O_RDONLY);
if (file < 0)
{
if (*source)
notice(source, "Error opening BanList file! Aborted.");
log("ERROR loading banlist");
active = 0;
return;
}
/* empty existing shitlist */
for (i = 0; i < 1000; i++)
{
while ((user = ShitList[i]) != NULL)
{
ShitList[i] = ShitList[i]->next;
TTLALLOCMEM -= strlen(user->match) + 1;
free(user->match);
TTLALLOCMEM -= strlen(user->from) + 1;
free(user->from);
TTLALLOCMEM -= strlen(user->reason) + 1;
free(user->reason);
TTLALLOCMEM -= strlen(user->channel) + 1;
free(user->channel);
TTLALLOCMEM -= sizeof(ShitUser);
free(user);
}
}
while (read(file, &tmp, sizeof(ShitDisk)) > 0)
{
if (tmp.expiration < now)
continue;
user = (ShitUser *) MALLOC(sizeof(ShitUser));
user->time = tmp.time;
user->expiration = tmp.expiration;
if (tmp.level > 500)
tmp.level = 500;
user->level = tmp.level;
user->match = (char *)MALLOC(strlen(tmp.match) + 1);
strcpy(user->match, tmp.match);
user->from = (char *)MALLOC(strlen(tmp.from) + 1);
strcpy(user->from, tmp.from);
user->reason = (char *)MALLOC(strlen(tmp.reason) + 1);
strcpy(user->reason, tmp.reason);
user->channel = (char *)MALLOC(strlen(tmp.channel) + 1);
strcpy(user->channel, tmp.channel);
user->next = ShitList[sl_hash(tmp.channel)];
ShitList[sl_hash(tmp.channel)] = user;
}
close(file);
if (*source)
notice(source, "BanList loaded!");
active = 0;
}

133
Sources/show_old_managers.c Normal file
View File

@@ -0,0 +1,133 @@
/* @(#)$Id: show_old_managers.c,v 1.2 1998/01/08 17:02:18 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#include "dirent.h"
time_t now;
#define HOWLONG (30*24*60*60) /* 30 days */
void fix_user_file(char *file, char *channel)
{
dbuser dbu;
int fd;
fd = open(file, O_RDONLY);
if (fd < 0)
{
fprintf(stderr, "Can't open %s [%s]\n", file, sys_errlist[errno]);
return;
}
/* Find at least one 500 seen within the last 30 days */
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
{
if (dbu.header[0] != 0xFF || dbu.header[1] != 0xFF ||
dbu.footer[0] != 0xFF || dbu.footer[1] != 0xFF)
{
continue;
}
if (!strcmp(dbu.match, "!DEL!"))
continue;
if (dbu.access == 500 && (now - dbu.lastseen) < HOWLONG)
{
close(fd);
return;
}
}
/* Ok.. at this point, there is no channel manager that was seen
* within 30 days. Show all of them.
*/
lseek(fd, 0L, SEEK_SET);
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
{
if (dbu.header[0] != 0xFF || dbu.header[1] != 0xFF ||
dbu.footer[0] != 0xFF || dbu.footer[1] != 0xFF)
{
continue;
}
if (!strcmp(dbu.match, "!DEL!"))
continue;
if (dbu.access != 500)
continue;
printf("%-14s %-9s %03d %-26s %.24s\n",
dbu.channel, dbu.nick, dbu.access, dbu.match, ctime(&dbu.lastseen));
}
close(fd);
}
void fix_user_db(void)
{
DIR *dp;
struct dirent *ent;
char dir[256], file[256], channel[80], *ptr;
int count;
for (count = 0; count < 1000; count++)
{
sprintf(dir, "db/channels/%04X", count);
dp = opendir(dir);
if (dp == NULL)
{
fprintf(stderr, "Can't read %s [%s]\n", dir, sys_errlist[errno]);
continue;
}
while ((ent = readdir(dp)) != NULL)
{
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
continue;
strcpy(channel, ent->d_name);
for (ptr = channel; *ptr; ptr++)
if (*ptr == ' ')
*ptr = '/';
sprintf(file, "db/channels/%04X/%s", count, ent->d_name);
fix_user_file(file, channel);
}
closedir(dp);
}
}
int main(void)
{
if (chdir(HOMEDIR) < 0)
{
perror(HOMEDIR);
exit(1);
}
time(&now);
fix_user_db();
return 0;
}

110
Sources/showdb.c Normal file
View File

@@ -0,0 +1,110 @@
/* @(#)$Id: showdb.c,v 1.6 1999/01/18 04:17:40 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#include "dirent.h"
time_t now;
void fix_user_file(char *file, char *channel)
{
dbuser dbu;
int fd;
fd = open(file, O_RDONLY);
if (fd < 0)
{
fprintf(stderr, "Can't open %s [%s]\n", file, sys_errlist[errno]);
return;
}
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
{
if (dbu.header[0] != 0xFF || dbu.header[1] != 0xFF ||
dbu.footer[0] != 0xFF || dbu.footer[1] != 0xFF)
{
continue;
}
if (!strcmp(dbu.match, "!DEL!"))
continue;
printf("%-14s %-9s %03d %-26s %.24s\n",
dbu.channel, dbu.nick, dbu.access, dbu.match, ctime(&dbu.lastseen));
}
close(fd);
}
void fix_user_db(void)
{
DIR *dp;
struct dirent *ent;
char dir[256], file[256], channel[80], *ptr;
int count;
for (count = 0; count < 1000; count++)
{
sprintf(dir, "db/channels/%04X", count);
dp = opendir(dir);
if (dp == NULL)
{
fprintf(stderr, "Can't read %s [%s]\n", dir, sys_errlist[errno]);
continue;
}
while ((ent = readdir(dp)) != NULL)
{
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
continue;
strcpy(channel, ent->d_name);
for (ptr = channel; *ptr; ptr++)
if (*ptr == ' ')
*ptr = '/';
sprintf(file, "db/channels/%04X/%s", count, ent->d_name);
fix_user_file(file, channel);
}
closedir(dp);
}
}
int main(int argc, char **argv)
{
if (chdir(HOMEDIR) < 0)
{
perror(HOMEDIR);
exit(1);
}
time(&now);
if (argc == 3)
{
fix_user_file(argv[1], argv[2]);
}
else
fix_user_db();
return 0;
}

183
Sources/socketio.c Normal file
View File

@@ -0,0 +1,183 @@
/* @(#)$Id: socketio.c,v 1.7 1998/06/23 23:35:08 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
/* These routines were first developed for the telnet3d project.
* Special thanks to Danny Mitchell (wildthang@irc) for his help.
*/
#include "h.h"
#ifdef DOHTTP
#include <stdarg.h>
extern void chat_close(http_socket *, char *);
int readfrom_http(http_socket * client)
{
void http_log(char *fmt,...);
char buf[1024];
int length;
if ((length = read(client->fd, buf, 1023)) <= 0)
{
if (errno == EWOULDBLOCK || errno == EAGAIN)
{
return 0;
}
else
{
if (client->status == HTTP_CHAT)
chat_close(client, "read error");
close(client->fd);
client->fd = -1;
client->status = HTTP_ERROR;
return -1;
}
}
buf[length] = '\0';
#ifdef DEBUG
printf("AA: |%s|\n", buf);
#endif
if (copy_to_buffer(&client->inbuf, buf, length) >= 4096)
{
http_log("ERROR: Recv'd more than 4K from client! (flood?)");
if (client->status == HTTP_CHAT)
chat_close(client, "Input packet too big");
client->status = HTTP_ERROR;
close(client->fd);
client->fd = -1;
return -1;
}
if (find_char_in_buffer(&client->inbuf, '\n', 1023))
{
while (find_char_in_buffer(&client->inbuf, '\n', 1023) &&
client->status != HTTP_PIPE &&
client->status != HTTP_ENDING &&
client->status != HTTP_ERROR)
{
copy_from_buffer(&client->inbuf, buf, '\n', 1023);
parse_http(client, buf);
}
/* Check for STUPID MSIE! who doesn't send a \n after post data
** so check for a = in the first 10 chars, assume *ugh* it's post data
*/
if (find_char_in_buffer(&client->inbuf, '=', 10))
{
if (client->status != HTTP_PIPE &&
client->status != HTTP_ENDING &&
client->status != HTTP_ERROR)
{
#ifdef DEBUG
printf("SEND\n");
#endif
copy_from_buffer(&client->inbuf, buf, '\0', 1023);
parse_http(client, buf);
}
}
}
else if (length > 200)
{
if (client->status == HTTP_CHAT)
chat_close(client, "line too long");
client->status = HTTP_ERROR;
close(client->fd);
client->fd = -1;
return -1;
}
return 1;
}
int flush_http_buffer(http_socket * client)
{
http_file_pipe *fpipe;
char buf[1024];
int length;
int count;
if (client == NULL || client->outbuf == NULL)
return -1;
while ((count = look_in_buffer(&client->outbuf, buf, '\0', 1023)) > 0)
{
if ((length = write(client->fd, buf, count)) <= 0)
{
if ((errno == EWOULDBLOCK || errno == EAGAIN) && length != 0)
{
return 0;
}
else
{
if (client->status == HTTP_PIPE)
{
for (fpipe = FilePipes; fpipe != NULL; fpipe = fpipe->next)
{
if (fpipe->hsock == client)
{
close(fpipe->fd);
destroy_file_pipe(fpipe);
break;
}
}
}
if (client->status == HTTP_CHAT)
chat_close(client, "write error");
close(client->fd);
client->fd = -1;
client->status = HTTP_ERROR;
return -1;
}
}
else
{
skip_char_in_buffer(&client->outbuf, length);
HTTPTTLSENTBYTES += length;
}
}
return 0;
}
/* sendto_client() by SeKs <intru@step.polymtl.ca>
* args (struct buffer_block **block, char *format, args...)
* adds 'args' according to 'format' to the client's output
* buffer.
*/
long sendto_http(http_socket * sck, char *format,...)
{
va_list args;
char string[1024];
va_start(args, format);
vsprintf(string, format, args);
va_end(args);
return copy_to_buffer(&sck->outbuf, string, strlen(string));
}
#endif /* DOHTTP */

198
Sources/special.c Normal file
View File

@@ -0,0 +1,198 @@
/* @(#)$Id: special.c,v 1.3 1996/11/13 00:40:49 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
#define SPECFILE "special.log"
void SpecLog(char *text)
{
int fd;
char date[80],buffer[1024];
strcpy(date,ctime(&now));
*strchr(date,'\n')='\0';
alarm(2);
if((fd=open(SPECFILE,O_WRONLY|O_CREAT|O_APPEND,0600))>=0){
alarm(0);
sprintf(buffer,"%s: %s\n",date,text);
alarm(2);
write(fd,buffer,strlen(buffer));
alarm(0);
close(fd);
}
alarm(0);
}
void logmap(aserver *server,FILE *fp)
{
static char prefix[80]="";
static int offset=0;
asuser *suser;
int nbusers=0,i;
if(server==NULL){
return;
}
/* count number of users */
for(i=0;i<100;i++){
suser=server->users[i];
while(suser!=NULL){
nbusers++;
suser=suser->next;
}
}
if(server->next==NULL){
fprintf(fp,"%s`-%s (%d user%s)\n",prefix,server->name,nbusers,(nbusers>1)?"s":"");
}else{
fprintf(fp,"%s|-%s (%d user%s)\n",prefix,server->name,nbusers,(nbusers>1)?"s":"");
}
if(server->next!=NULL)
strcpy(prefix+offset,"| ");
else
strcpy(prefix+offset," ");
offset+=2;
logmap(server->down,fp);
offset-=2;
prefix[offset]='\0';
logmap(server->next,fp);
}
void SpecMap(void)
{
FILE *fp;
if((fp=fopen(SPECFILE,"a"))!=NULL){
logmap(ServerList,fp);
fclose(fp);
}
}
#ifdef CHANNEL_LOG
void LogChan(void)
{
register achannel *chan;
register auser *user;
register aluser *luser;
register int i,isreg,count;
register FILE *fp;
char mode[80];
char flag;
if((fp=fopen(CHANNEL_LOG,"a"))==NULL)
return;
fprintf(fp,"%ld %s",now,ctime(&now));
for(i=0;i<1000;i++){
for(chan=ChannelList[i];chan!=NULL;chan=chan->next){
count=isreg=(chan->on)?1:0;
for(user=chan->users;user;user=user->next){
count++;
if(!isreg &&
!strcasecmp(user->N->username,DEFAULT_USERNAME)&&
!strcasecmp(user->N->site,DEFAULT_HOSTNAME)){
isreg=1;
}
}
GetWord(0,chan->mode,mode);
if(strchr(mode,'s'))
flag='S';
else if(strchr(mode,'p'))
flag='P';
else
flag='+';
fprintf(fp,"%s %c %d %s\n",
chan->name,flag,count,isreg?"REG'D":"");
}
}
count=0;
for(i=0;i<1000;i++){
luser=Lusers[i];
while(luser!=NULL){
count++;
luser=luser->next;
}
}
fprintf(fp,"* %d \n",count);
fclose(fp);
}
#endif
#ifdef HISTORY
void HistLog(char *text)
{
int fd;
char date[80],buffer[1024];
strcpy(date,ctime(&now));
*strchr(date,'\n')='\0';
alarm(2);
if((fd=open("hist.log",O_WRONLY|O_CREAT|O_APPEND,0600))>=0){
alarm(0);
sprintf(buffer,"%s: %s\n",date,text);
alarm(2);
write(fd,buffer,strlen(buffer));
alarm(0);
close(fd);
}
alarm(0);
}
void History(char *line)
{
static char Log[25][512];
static int offset=0;
if(line==NULL){
int i=offset,top=offset-1;
if(top==-1)
top=25;
while(i!=top){
if(i==25)
i=0;
HistLog(Log[i]);
i++;
}
}
else
{
strncpy(Log[offset],line,511);
Log[offset][511]='\0';
if(++offset==25)
offset=0;
}
}
#endif

303
Sources/struct.h Normal file
View File

@@ -0,0 +1,303 @@
/* @(#)$Id: struct.h,v 1.6 1997/07/01 21:51:09 cvs Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#ifdef NICKSERV
#include "nickserv.h"
#endif
typedef struct filehdr {
unsigned char magic;
unsigned int no;
} filehdr;
typedef struct RegUser {
char *realname;
char *match;
char *channel;
char *passwd;
char *modif;
int access;
unsigned long flags;
time_t suspend;
time_t lastseen;
off_t offset;
int modified;
int inuse;
time_t lastused;
struct RegUser *next;
} RegUser;
typedef struct dbuser {
unsigned char header[2];
char nick[80];
char match[80];
char passwd[20];
char channel[50];
char modif[80];
int access;
unsigned long flags;
time_t suspend;
time_t lastseen;
unsigned char footer[2];
} dbuser;
typedef struct achannel {
char *name;
int AmChanOp;
int on;
int MassDeopPro;
int NickFloodPro;
int MsgFloodPro;
int lang;
time_t TS;
time_t lastact;
time_t lasttopic;
unsigned long flags;
unsigned long uflags;
char mode[80];
char lastjoin[20];
struct modequeue *modebuff;
struct aban *bans;
struct auser *users;
struct achannel *next;
} achannel;
typedef struct adefchan {
char name[50];
char mode[80];
char url[80];
char topic[80];
int MassDeopPro;
int NickFloodPro;
int MsgFloodPro;
int lang;
time_t TS;
unsigned long flags;
unsigned long uflags;
struct adefchan *next;
} adefchan;
typedef struct achannelnode {
struct achannel *N;
struct anickchange *nickhist;
struct achannelnode *next;
} achannelnode;
typedef struct aserver {
char *name;
time_t TS;
struct asuser *users[100];
struct aserver *up;
struct aserver *down;
struct aserver *next;
} aserver;
typedef struct asuser {
struct aluser *N;
struct asuser *next;
} asuser;
typedef struct aluser {
char *nick;
char *username;
char *site;
time_t time;
char mode;
struct aserver *server;
struct achannelnode *channel;
struct avalchan *valchan;
struct aluser *next;
#ifdef NICKSERV
struct aregnick *regnick;
time_t reglimit;
#endif
} aluser;
typedef struct avalchan {
char *name;
RegUser *reg;
struct avalchan *next;
} avalchan;
typedef struct auser {
struct aluser *N;
char chanop;
time_t lastact;
struct amsg *msghist;
struct adeop *deophist;
struct auser *next;
} auser;
typedef struct aban {
char pattern[80];
struct aban *next;
} aban;
typedef struct adeop {
time_t time;
char nick[NICK_LENGTH];
struct adeop *next;
} adeop;
typedef struct anickchange {
time_t time;
char nick[NICK_LENGTH];
struct anickchange *next;
} anickchange;
typedef struct modequeue {
int AsServer;
char flag[3];
char arg[80];
struct modequeue *prev;
struct modequeue *next;
} modequeue;
typedef struct amsg {
time_t time;
int length;
struct amsg *next;
} amsg;
typedef struct ShitUser {
time_t time;
time_t expiration;
char *match;
char *from;
char *reason;
char *channel;
int level;
struct ShitUser *next;
} ShitUser;
typedef struct anevent {
time_t time;
int event;
char param[80];
struct anevent *next;
} anevent;
typedef struct alang {
int no;
char *abbr;
char *name;
} alang;
struct buffer_block {
char buf[BUFFER_BLOCK_SIZE];
short offset_read;
short offset_write;
struct buffer_block *next;
};
typedef struct irc_socket {
int fd;
time_t TS;
struct buffer_block *inbuf;
struct buffer_block *outbuf;
struct irc_socket *next;
} irc_socket;
typedef struct http_raw {
unsigned long key;
} http_raw;
typedef struct http_post {
char path[80];
char protocol[80];
int count;
int ready;
} http_post;
typedef struct http_socket {
int fd;
int status;
int dbio;
time_t TS;
time_t since;
void *hook;
struct buffer_block *inbuf;
struct buffer_block *outbuf;
struct sockaddr_in peer;
struct http_socket *next;
} http_socket;
typedef struct http_file_pipe {
int fd;
http_socket *hsock;
struct http_file_pipe *next;
} http_file_pipe;
typedef struct misc_socket {
int fd;
int type;
int status;
time_t TS;
char link[80];
struct buffer_block *inbuf;
struct buffer_block *outbuf;
struct misc_socket *next;
} misc_socket;
#define DBCALLBACK(X) void (*X)(int *,off_t,int,void *,void *,dbuser*,int)
typedef struct dbquery {
int fd;
off_t offset;
time_t time;
unsigned int type;
int action;
int count;
DBCALLBACK(callback);
struct buffer_block *buf;
void *hook1;
void *hook2;
struct dbquery *next;
char channel[80];
char info[80];
char passwd[80];
} dbquery;
typedef struct dbsync {
int fd;
off_t offset;
time_t time;
int type; /* update, delete, add */
int status; /* pending_write, seeking_empty_slot */
RegUser **reg;
struct buffer_block *buf;
struct dbsync *next;
} dbsync;
typedef struct syncchan {
char name[50];
struct syncchan *next;
} syncchan;

2139
Sources/userlist.c Normal file

File diff suppressed because it is too large Load Diff

521
Sources/users.c Normal file
View File

@@ -0,0 +1,521 @@
/* @(#)$Id: users.c,v 1.7 1998/11/21 14:58:43 seks Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
#include "h.h"
int lu_hash(char *nick)
{
register int i, j;
for (i = 0, j = 0; i < strlen(nick); i++)
j += toupper((unsigned char)nick[i]);
return (j % 1000);
}
int su_hash(char *nick)
{
register int i, j;
for (i = 0, j = 0; i < strlen(nick); i++)
j += toupper((unsigned char)nick[i]);
return (j % 100);
}
aluser *ToLuser(char *nick)
{
register aluser *curr;
curr = Lusers[lu_hash(nick)];
while (curr && strcasecmp(nick, curr->nick))
curr = curr->next;
return (curr);
}
void onnick(char *source, char *newnick, char *body)
{
register aluser *user, **u;
register asuser *suser, **s;
register aserver *serv;
char username[80];
char hostname[80];
char TS[80];
char server[80];
register achannelnode *chan;
register anickchange *curr, *prec;
char buffer[512];
int i = 0;
#ifdef DEBUG
printf("NICK: %s --> %s ...\n", source, newnick);
#endif
/* a new user */
if (!ToLuser(source))
{ /* Not a user, so a server or nothing */
if (strchr(source, '.') == NULL)
{
/* Source is not a user and not a server either */
return;
}
if (!strcasecmp(newnick, mynick))
{
log("ERROR: I'm nick collided");
#ifdef DEBUG
printf("ARGH!!! I'M NICK COLLIDED!\n");
#endif
GetWord(1, body, TS);
GetWord(2, body, username);
GetWord(3, body, hostname);
if (atol(TS) <= logTS &&
strcasecmp(username, myuser) &&
strcasecmp(hostname, mysite))
{
NickInUse();
log(source);
log(newnick);
log(body);
}
else
{
onquit(source);
return; /*ignore */
}
#ifdef BACKUP
}
else if (!strcasecmp(newnick, MAIN_NICK))
{
return; /* ignore */
#endif
}
else if (ToLuser(newnick))
{
#ifdef DEBUG
printf("ARGH!!! NICK COLLISION\n");
#endif
onquit(newnick);
}
GetWord(1, body, TS);
GetWord(2, body, username);
GetWord(3, body, hostname);
GetWord(4, body, server);
#ifdef FAKE_UWORLD
if (Uworld_status == 1 && !strcasecmp(newnick, UFAKE_NICK))
{
if (atol(TS) <= UworldTS && atol(TS) != 0 &&
strcasecmp(username, UFAKE_NICK) &&
strcasecmp(hostname, UFAKE_HOST))
{
sprintf(buffer, "%s nick collided", UFAKE_NICK);
log(buffer);
Uworld_status = 0;
KillUworld("nick collision");
return; /* ignore if younger */
}
}
#endif
user = (aluser *) MALLOC(sizeof(aluser));
user->nick = (char *)MALLOC(strlen(newnick) + 1);
strcpy(user->nick, newnick);
user->username = (char *)MALLOC(strlen(username) + 1);
strcpy(user->username, username);
user->site = (char *)MALLOC(strlen(hostname) + 1);
strcpy(user->site, hostname);
if (*newnick == '+')
serv = &VirtualServer;
else
serv = ToServer(server);
user->server = serv;
user->time = atol(TS);
user->mode = 0;
user->channel = NULL;
user->valchan = NULL;
user->next = Lusers[lu_hash(newnick)];
Lusers[lu_hash(newnick)] = user;
/* add user in server's userlist
*/
suser = (asuser *) MALLOC(sizeof(asuser));
suser->N = user;
suser->next = serv->users[su_hash(newnick)];
serv->users[su_hash(newnick)] = suser;
#ifdef NICKSERV
nserv_nick(newnick, user);
#endif
}
else
{ /* nick change */
#if 0
if (!strcasecmp(source, DEFAULT_NICKNAME) &&
strcasecmp(newnick, DEFAULT_NICKNAME))
{
ChNick(DEFAULT_NICKNAME);
}
#endif
if (!strcasecmp(newnick, mynick))
{
#ifdef DEBUG
printf("ARGH!!! I'M NICK COLLIDED!\n");
#endif
GetWord(0, body, TS);
if (atol(TS + 1) <= logTS)
{
NickInUse();
log(source);
log(newnick);
log(body);
}
else
{
onquit(source);
return; /*ignore */
}
}
u = &Lusers[lu_hash(source)];
while (*u && strcasecmp(source, (*u)->nick))
u = &(*u)->next;
user = *u;
#ifdef NICKSERV
nserv_nick(newnick, user);
#endif
if (user == NULL)
quit("ERROR! onnick() can't find user", 1);
s = &user->server->users[su_hash(source)];
while (*s && strcasecmp((*s)->N->nick, user->nick))
s = &(*s)->next;
suser = *s;
/* change the nick in memory */
TTLALLOCMEM -= strlen(user->nick) + 1;
free(user->nick);
user->nick = (char *)MALLOC(strlen(newnick) + 1);
strcpy(user->nick, newnick);
/* now relocate the structure */
*u = user->next;
user->next = Lusers[lu_hash(newnick)];
Lusers[lu_hash(newnick)] = user;
*s = suser->next;
suser->next = user->server->users[su_hash(newnick)];
user->server->users[su_hash(newnick)] = suser;
/* NICK FLOOD PROTECTION */
/* 1st wipe old nick changes off */
chan = user->channel;
while (chan)
{
curr = chan->nickhist;
prec = NULL;
/* if not on channel.. ignore nick flood pro */
if (!chan->N->on)
{
chan = chan->next;
continue; /* yurk.. as bad as a goto ;) */
}
while (curr)
{
if (curr->time < (now - 15))
{
if (prec)
{
prec->next = curr->next;
TTLALLOCMEM -= sizeof(anickchange);
free(curr);
curr = prec->next;
}
else
{
chan->nickhist = curr->next;
TTLALLOCMEM -= sizeof(anickchange);
free(curr);
curr = chan->nickhist;
}
}
else
{
prec = curr;
curr = curr->next;
}
}
/* now add the new nick change to the history */
curr = (anickchange *) MALLOC(sizeof(anickchange));
strcpy(curr->nick, source);
curr->time = now; /* a lil confusing :( */
curr->next = chan->nickhist;
chan->nickhist = curr;
/* now count the nick changes in history
if there are more than allowed.. grrrr */
for (i = 0, curr = chan->nickhist; curr;
curr = curr->next, i++);
if (i == chan->N->NickFloodPro && chan->N->NickFloodPro != 0
&& chan->N->on)
{
sprintf(buffer, "%s!%s@%s", user->nick, user->username, user->site);
notice(newnick,
"### NICK FLOOD PROTECTION ACTIVATED ###");
sprintf(buffer, "%s %d", newnick,
NICK_FLOOD_SUSPEND_TIME);
suspend("", chan->N->name, buffer);
ban("", chan->N->name, newnick);
}
chan = chan->next;
}
}
}
void onquit(char *nick)
{
register aluser *user, **u;
register asuser *suser, **s;
register avalchan *valchan;
#ifdef DEBUG
printf("Detected user quit..\n");
#endif
u = &Lusers[lu_hash(nick)];
while (*u && strcasecmp(nick, (*u)->nick))
u = &(*u)->next;
user = *u;
if (user == NULL)
{
log("ERROR: onquit() can't find user!");
#ifdef HISTORY
History(NULL);
#endif
return;
}
/* remove from memory */
while ((valchan = user->valchan) != NULL)
{
#ifdef DEBUG
printf("\twas validated on %s\n", valchan->name);
#endif
valchan->reg->inuse--;
user->valchan = valchan->next;
TTLALLOCMEM -= strlen(valchan->name) + 1;
free(valchan->name);
TTLALLOCMEM -= sizeof(avalchan);
free(valchan);
}
while (user->channel != NULL)
{
#ifdef DEBUG
printf("\twas on %s\n", user->channel->N->name);
#endif
/* onpart() free's the chan structure
* we can't do chan=chan->next after the
* onpart() call. We must start from the
* beginning of the list every time
*/
onpart(nick, user->channel->N->name);
}
/* remove user from server's userlist
*/
s = &user->server->users[su_hash(user->nick)];
while (*s != NULL && strcasecmp((*s)->N->nick, user->nick))
{
s = &(*s)->next;
}
if (*s != NULL)
{
suser = *s;
*s = (*s)->next;
TTLALLOCMEM -= sizeof(asuser);
free(suser);
}
else
{
log("ERROR: onquit() user not found in server's userlist!");
}
*u = user->next;
#if 0
if (!strcasecmp(user->nick, DEFAULT_NICKNAME))
{
ChNick(DEFAULT_NICKNAME);
}
#endif
#ifdef NICKSERV
nserv_quit(user);
#endif
TTLALLOCMEM -= strlen(user->nick) + 1;
free(user->nick);
TTLALLOCMEM -= strlen(user->username) + 1;
free(user->username);
TTLALLOCMEM -= strlen(user->site) + 1;
free(user->site);
TTLALLOCMEM -= sizeof(aluser);
free(user);
}
void onkill(char *source, char *target, char *comment)
{
char buffer[200];
if (!strcasecmp(target, mynick))
{
#if 0
/* ignore kill for nick collisions because we
* already check in onnick() if we're collided.
* This kill is prolly a lost kill resulting of
* another nick collision..
*/
if (strstr(comment, "older nick overruled") ||
strstr(comment, "collided yourself"))
{
log("ERROR: Nick collision on me?");
return;
}
#endif
sprintf(buffer, ":%s SQUIT %s 0 :killed by %s\n",
SERVERNAME, SERVERNAME, source);
sendtoserv(buffer);
dumpbuff();
close(Irc.fd);
Irc.fd = -1;
if (reconnect(server))
{
try_later(server);
}
#ifdef BACKUP
}
else if (!strcasecmp(target, MAIN_NICK))
{
quit(MAIN_NICK " is back", 0);
#endif
#ifdef FAKE_UWORLD
}
else if (!strcasecmp(target, UFAKE_NICK))
{
char buffer[200];
sprintf(buffer, "%s is KILLED by %s", UFAKE_NICK, source);
log(buffer);
Uworld_status = 0;
KillUworld("Killed");
#endif
}
else
onquit(target);
}
void onwhois(char *source, char *nick)
{
register aluser *user;
register auser *usr;
register achannelnode *chan;
char buffer[512];
user = ToLuser(nick);
if (user == NULL)
{
sprintf(buffer, ":%s 401 %s %s :No such nick\n", SERVERNAME, source, nick);
sendtoserv(buffer);
}
else
{
sprintf(buffer, ":%s 311 %s %s %s %s * :\n", SERVERNAME, source, user->nick,
user->username, user->site);
sendtoserv(buffer);
chan = user->channel;
if (chan != NULL && strcmp(user->nick, "X") && strcmp(user->nick, "W"))
{
sprintf(buffer, ":%s 319 %s %s :", SERVERNAME, source, nick);
while (chan != NULL)
{
/* show a channel only if it is
* not +s or +p
*/
if (!IsSet(chan->N->name, 's', "") &&
!IsSet(chan->N->name, 'p', ""))
{
usr = ToUser(chan->N->name, nick);
if (usr->chanop)
strcat(buffer, "@");
strcat(buffer, chan->N->name);
strcat(buffer, " ");
}
chan = chan->next;
if (strlen(buffer) > 300)
{
strcat(buffer, "\n");
sendtoserv(buffer);
sprintf(buffer, ":%s 319 %s %s :",
SERVERNAME, source, nick);
}
}
strcat(buffer, "\n");
sendtoserv(buffer);
}
sprintf(buffer, ":%s 312 %s %s %s :\n", SERVERNAME, source, source, user->server->name);
sendtoserv(buffer);
if (user->mode & LFL_ISOPER)
{
sprintf(buffer, ":%s 313 %s %s :is an IRC Operator\n",
SERVERNAME, source, user->nick);
sendtoserv(buffer);
}
}
sprintf(buffer, ":%s 318 %s :End of /WHOIS list.\n", SERVERNAME, source);
sendtoserv(buffer);
}

38
Sources/version.SH Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/sh
TAG="v20020715 build-`date -u '+%Y%m%d%H%M%S'`"
echo Updating version... $TAG
cat << NUFF > version.c
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
/* This file is generated by version.SH and any change will be
* overwritten when you recompile.
*/
char VERSION[]="Undernet Channel Service $TAG ";
NUFF

30
Sources/version.c Normal file
View File

@@ -0,0 +1,30 @@
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
/* This file is generated by version.SH and any change will be
* overwritten when you recompile.
*/
char VERSION[]="Undernet Channel Service v20020715151606 ";

4
Sources/version.h Normal file
View File

@@ -0,0 +1,4 @@
/* @(#)$Id: version.h,v 1.3 1996/11/13 00:40:51 seks Exp $ */
extern char VERSION[];

11
WARRANTY Normal file
View File

@@ -0,0 +1,11 @@
NO WARRANTY
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

20
XHELP/ACCESS Normal file
View File

@@ -0,0 +1,20 @@
SYNTAX: access [channel] [nick] [-min n] [-max n]
[-autoop] [-noautoop]
[-modif [mask]]
access shows the access of nick (or yours if no nick is
given) on channel (or current if no channel is given). The
following options can also be used to filter the list:
-min n Show only users with access higher than
or equal to n.
-max n Show only users with access lower than or
equal to n.
-autoop Show only users with the autoop flag on.
-noautoop Show only users with the autoop flag off.
-modif [mask] Show who made the last modification. If a search
mask is given, only the entries that have been
last modified by someone matching the mask will
be given.
Options can be combined at wish. (-autoop -noautoop == No match.)

16
XHELP/ADDUSER Normal file
View File

@@ -0,0 +1,16 @@
SYNTAX: adduser [channel] <nick> [mask] <access> <password>
modinfo [channel] <field> <nick|address> <new value>
remuser [channel] <nick|address>
adduser gives the given access to anyone matching mask.
nick is only used as a reference and should be the nickname the
person uses to most. If nick is online, mask is not necessary,
and the userhost will be looked up automatically. If default user
flags are defined (see help set), those flags are used.
modinfo is used to modify an entry in the userlist. field can
be either of the followings: MATCH, ACCESS, AUTOOP, PASSWORD.
new value must be ON or OFF for field AUTOOP, or other
valid values for the other fields.
remuser removes the access of the given user.

22
XHELP/BAN Normal file
View File

@@ -0,0 +1,22 @@
SYNTAX: ban [channel] <nick|n!u@h> [duration] [level] [reason]
unban [channel] <nick|n!u@h>
cleanbanlist
ban adds an entry to the 'banlist'. If channel is supplied,
it is used instead of the current channel. duration specifies how
long the entry should remain in the list (in hours). level is an
integer ranging from 0 to your access level on the channel. reason
is not mandatory and can be up to 80 characters long.
The effect of this command depends on the level supplied:
 level | effect 
>= 20 | user is not allowed to be chanop
>= 75 | user is not allowed to be on the
| channel at all.
Intermediate levels are used internally to manage warnings.
unban removes a ban from the banlist.
cleanbanlist purges expired entries from the banlist. This should
be handled automatically, so this command should only be used as a
debug tool.

3
XHELP/CHANINFO Normal file
View File

@@ -0,0 +1,3 @@
SYNTAX: chaninfo [channel]
Gives information about channel's manager.

5
XHELP/CLEARMODE Normal file
View File

@@ -0,0 +1,5 @@
SYNTAX: clearmode [channel]
clearmode clears all the channel modes. This
is useful when your channel is locked so you can't even
join the channel.

7
XHELP/DEFCHAN Normal file
View File

@@ -0,0 +1,7 @@
SYNTAX: addchan [channel]
remchan [channel]
addchan adds a channel to $NICK's auto-join list.
remchan removes a channel from $NICK's auto-join list. The
userlist for that channel remains unchanged.

18
XHELP/HELP Normal file
View File

@@ -0,0 +1,18 @@
SYNTAX: help <topic>
help displays the help file associated with topic.
Use showcommands to get a list of commands available
to you.
Commands must be sent by MSG and if the command has effect
on a specific channel, that channel's name must be the
first argument. ie:
/msg $NICK op #blah nick to op nick on channel #blah
or /msg $NICK op nick if you are on channel #blah
The administration of Undernet and the provider of this service
are NOT responsible for what is going on the channels this
service is on.
To get more information on this service, use help info

6
XHELP/HELPLIST Normal file
View File

@@ -0,0 +1,6 @@
X'S COMMAND LIST:
XACCESS XADDCHAN XADDUSER XBAN XBANLIST
XCHANINFO XCLEARMODE XDEOP XHELP XINVITE
XJOIN XKICK XLBANLIST XMAP XMOTD
XOP XPART XPASS XREMCHAN XREMUSER
XSET XSHOWCOMMANDS XSHOWIGNORE XSUSPEND XUNBAN

25
XHELP/INFO Normal file
View File

@@ -0,0 +1,25 @@
 Undernet's Channel Service Information 
This is the Undernet Channel Service written by Robin Thellend
aka SeKs <intru@step.polymtl.ca>.
A registered channel is under the responsibility of its channel
manager who has full control over it. To register a channel,
complete the registration that can be found at
http://cservice.undernet.org/regist/ and follow the instructions.
It is also recommended that you read the Channel Service Committee
Guidelines before sending in an application. This will explain the
process of registering a channel with the Undernet Channel Service.
The guidelines are available on the WWW at
http://cservice.undernet.org/ and by FTP at
ftp://ftp.undernet.org/pub/irc/docs/X/CSC-guidelines
They are also available from Undernet IRC by:
/msg HelpBot get CSC-guidelines
The number of channels one can register is currently limited to one
channel per person. Registration takes 2 to 3 weeks to complete.
For more general info, contact cservice@undernet.org
For technical info, contact cservice-coders@undernet.org.

6
XHELP/INVITE Normal file
View File

@@ -0,0 +1,6 @@
SYNTAX: invite [#channel] <nick>
invite makes $NICK invite nick to #channel for you.
This is useful on invite-only channels. For example, you can do
/msg $NICK invite #mychan mynick
to make $NICK invite you to your channel.

8
XHELP/JOIN Normal file
View File

@@ -0,0 +1,8 @@
SYNTAX: join <channel>
part [channel]
join is used to make $NICK join channel. Obviously, one
must have access on that channel in order to do that.
part makes $NICK leave the current channel (or channel if
it is specified).

6
XHELP/KICK Normal file
View File

@@ -0,0 +1,6 @@
SYNTAX: kick [channel] <nick> [reason]
kick [channel] <pattern> [reason] (Level 200)
This command kicks nick or any user matching the given
match pattern. If a reason is supplied, it will be
used as kick comment.

3
XHELP/MAP Normal file
View File

@@ -0,0 +1,3 @@
SYNTAX: map
map displays how the servers are connected together.

3
XHELP/MOTD Normal file
View File

@@ -0,0 +1,3 @@
SYNTAX: motd
Gives $NICK's Message Of The Day.

8
XHELP/OP Normal file
View File

@@ -0,0 +1,8 @@
SYNTAX: op [channel] <nick1> [nick2] [nick3] [...]
deop [channel] <nick1> [nick2] [nick3] [...]
op and deop respectively give and remove channel operator
priviledges to the specified users.
Note that this command is disabled when the channel is in NoOp
mode (SEE help set for more information).

15
XHELP/PASSWORD Normal file
View File

@@ -0,0 +1,15 @@
SYNTAX: login <channel> [your password]
newpass <channel> <new password>
deauth <channel>
login is used to validate yourself. You need to use this
command even if you don't have a password.
newpass changes your password to new password. You
have to validate yourself before using this command.
deauth is used to deauthenticate yourself on a channel;
this is provided for the security-minded.
Note: login and newpass must be sent to
$NICK@$SERVER for $NICK

32
XHELP/SET Normal file
View File

@@ -0,0 +1,32 @@
SYNTAX: set [channel] <variable> <value>
set is used to configure $NICK's reactions upon different
situations. variable is one of the following:
MassDeopPro NickFloodPro FloodPro UserFlags
NoOp AlwaysOp OpOnly StrictOp
Description URL AutoTopic
MassDeopPro is the maximum number of deops one can issue
before the MassDeop protection is activated.
NickFloodPro is maximum number of nick changes one can do
before the NickFlood protection is activated.
FloodPro is the limit of lines one can send to a channel.
NOTE: since $NICK is umode +d (Deaf) the floodpro doesn't work for
channels messages. It only works for TOPICs, KICKs, etc.
UserFlags is the default flags given to a newly added user.
NoOp is a special mode where only $NICK can be channel operator.
AlwaysOp makes $NICK always be op.
OpOnly disables all commands except op.
StrictOp will only allow authenticated users to be op.
Description will set the official channel description.
URL will set a link to the channel home page.
AutoTopic will reset the topic to the official URL and
description of the channel every 30 minutes *if* the channel
is active.
MassDeopPro, NickFloodPro and FloodPro have integer values and
are all based on a 15-second period.
UserFlags can be 1 (autoop) or 0 (no autoop).
NoOp, AlwaysOp, OpOnly, StrictOp and AutoTopic have either ON or OFF
values.
Description and URL are strings up to 80 characters long.

4
XHELP/SHOWCOMMANDS Normal file
View File

@@ -0,0 +1,4 @@
SYNTAX: showcommands [channel]
showcommands gives you the commands that are available to you
on channel (or current if no channel is given).

3
XHELP/SHOWIGNORE Normal file
View File

@@ -0,0 +1,3 @@
SYNTAX: showignore
Gives the list of users currently being ignored by $NICK.

3
XHELP/STATUS Normal file
View File

@@ -0,0 +1,3 @@
SYNTAX: status [channel]
status outputs informations about channel.

12
XHELP/SUSPEND Normal file
View File

@@ -0,0 +1,12 @@
SYNTAX: suspend [channel] <nick|address> <duration> [s|m|h|d]
unsuspend [channel] <nick|address>
The command suspend is used to remove one's access to this service
for a certain time specified with the duration argument. Time units
can be specified for duration (seconds,minutes,hours or days).
When a user is suspended he or she cannot use any command requiring
an access level greater than zero. One can only suspend a user who
has an inferior access than his.
unsuspend removes a suspension (same as suspend with a duration 0)

4
XHELP/TOPIC Normal file
View File

@@ -0,0 +1,4 @@
SYNTAX: topic [channel] <new topic>
topic changes the topic on channel (or on the current
channel if none is given) to new topic.

7
XHELP/VERIFY Normal file
View File

@@ -0,0 +1,7 @@
SYNTAX: verify <nick>
This command will tell you whether nick is an authenticated
CSERVICE representative.
A CSERVICE representative is capable of helping you solve problems
you may have with the channel service.

6
XHELP/X Normal file
View File

@@ -0,0 +1,6 @@
X'S COMMAND LIST:
XACCESS XADDCHAN XADDUSER XBAN XBANLIST
XCHANINFO XCLEARMODE XDEOP XHELP XINVITE
XJOIN XKICK XLBANLIST XMAP XMOTD
XOP XPART XPASS XREMCHAN XREMUSER
XSET XSHOWCOMMANDS XSHOWIGNORE XSUSPEND XUNBAN

179
XHELP/Xscript Normal file
View File

@@ -0,0 +1,179 @@
# This little script is intended to *ease* the use
# of the channel service interface "X". It works pretty
# much like the /help command, except that it's called
# /xhelp :)
#
# NB. Most aliases are X's commands prefixed by 'X'.
#
# Feel free to distribute this package to your friends, but
# just make sure my name stays on it. I want to make sure
# people know where to send their complaints ;)
#
# seks <intru@step.polymtl.ca>
# 95/07/13
# update 95/12/11
^SET DISPLAY OFF
SET EXEC_PROTECTION OFF
SET NOVICE OFF
ASSIGN XHELP_DIR ~/XHELP
#ASSIGN XHELP_DIR /usr/local/lib/irc/XHELP
ASSIGN CAT /bin/cat
ALIAS XX //QUOTE PRIVMSG X@CHANNELS.UNDERNET.ORG :$*
ALIAS WW //QUOTE PRIVMSG W@CHANNELS2.UNDERNET.ORG :$*
ALIAS XACCESS XX ACCESS
ALIAS XADDCHAN XX ADDCHAN
ALIAS XADDUSER XX ADDUSER
ALIAS XBAN XX BAN
ALIAS XBANLIST XX BANLIST
ALIAS XCHANINFO XX CHANINFO
ALIAS XCLEARMODE XX CLEARMODE
ALIAS XCOMMANDS XX SHOWCOMMANDS
ALIAS XDEOP XX DEOP
ALIAS XINFO XHELP INFO
ALIAS XINVITE XX INVITE
ALIAS XJOIN XX JOIN
ALIAS XKICK XX KICK
ALIAS XLBANLIST XX LBANLIST
ALIAS XMAP XX MAP
ALIAS XMODINFO XX MODINFO
ALIAS XMOTD XX MOTD
ALIAS XNEWPASS XX NEWPASS
ALIAS XOP XX OP
ALIAS XPART XX PART
ALIAS XPASS XX PASS
ALIAS XREMCHAN XX REMCHAN
ALIAS XREMUSER XX REMUSER
ALIAS XSET XX SET
ALIAS XSHOWCOMMANDS XX SHOWCOMMANDS
ALIAS XSTATUS XX STATUS
ALIAS XSUSPEND XX SUSPEND
ALIAS XTOPIC XX TOPIC
ALIAS XUNBAN XX UNBAN
ALIAS XUNSUSPEND XX UNSUSPEND
ALIAS WACCESS WW ACCESS
ALIAS WADDCHAN WW ADDCHAN
ALIAS WADDUSER WW ADDUSER
ALIAS WBAN WW BAN
ALIAS WBANLIST WW BANLIST
ALIAS WCHANINFO WW CHANINFO
ALIAS WCLEARMODE WW CLEARMODE
ALIAS WCOMMANDS WW SHOWCOMMANDS
ALIAS WDEOP WW DEOP
ALIAS WINFO WHELP INFO
ALIAS WINVITE WW INVITE
ALIAS WJOIN WW JOIN
ALIAS WKICK WW KICK
ALIAS WLBANLIST WW LBANLIST
ALIAS WMAP WW MAP
ALIAS WMODINFO WW MODINFO
ALIAS WMOTD WW MOTD
ALIAS WNEWPASS WW NEWPASS
ALIAS WOP WW OP
ALIAS WPART WW PART
ALIAS WPASS WW PASS
ALIAS WREMCHAN WW REMCHAN
ALIAS WREMUSER WW REMUSER
ALIAS WSET WW SET
ALIAS WSHOWCOMMANDS WW SHOWCOMMANDS
ALIAS WSTATUS WW STATUS
ALIAS WSUSPEND WW SUSPEND
ALIAS WTOPIC WW TOPIC
ALIAS WUNBAN WW UNBAN
ALIAS WUNSUSPEND WW UNSUSPEND
ALIAS XHELP
{
@_COUNT=0
@_HELPFILES=[HELPLIST ACCESS DEFCHAN ADDUSER BAN BAN CHANINFO OP HELP INVITE INFO JOIN KICK BAN MAP MOTD OP JOIN PASSWORD DEFCHAN ADDUSER SET SHOWCOMMANDS SHOWIGNORE SUSPEND SUSPEND TOPIC BAN CLEARMODE]
@_HELPCOMMS=[XACCESS XADDCHAN XADDUSER XBAN XBANLIST XCHANINFO XDEOP XHELP XINVITE XINFO XJOIN XKICK XLBANLIST XMAP XMOTD XOP XPART XPASS XREMCHAN XREMUSER XSET XSHOWCOMMANDS XSHOWIGNORE XSUSPEND XUNSUSPEND XTOPIC XUNBAN XCLEARMODE]
^SET HOLD_MODE ON
^ON ^EXEC XHELP {
@_COUNT=(_COUNT+1)
IF ( _COUNT == 22 )
{
INPUT "More? " @_COUNT=0
}
ECHO *** $1-
}
^ON ^EXEC_EXIT XHELP {
^ON ^EXIT_EXIT -XHELP
^ON ^EXEC -XHELP
^ASSIGN -_COUNT
^ASSIGN -_HELPFILES
^ASSIGN -_HELPCOMMS
^SET HOLD_MODE OFF
INPUT "XHelp? " IF ( [$0] ) { XHELP $* }
}
IF ( [$0] )
{
ECHO ***  HELP on $[55]0
IF ( [$[1]0] == [X] )
{
EXEC -NAME XHELP $CAT $XHELP_DIR/$WORD($RMATCH($0 $_HELPCOMMS) $_HELPFILES)
}
{
EXEC -NAME XHELP $CAT $XHELP_DIR/$WORD($RMATCH(X$0 $_HELPCOMMS) $_HELPFILES)
}
}
{
EXEC -NAME XHELP $CAT $XHELP_DIR/HELPLIST
}
}
ALIAS WHELP
{
@_COUNT=0
@_HELPFILES=[HELPLIST ACCESS DEFCHAN ADDUSER BAN BAN CHANINFO OP HELP INVITE INFO JOIN KICK BAN MAP MOTD OP JOIN PASSWORD DEFCHAN ADDUSER SET SHOWCOMMANDS SHOWIGNORE SUSPEND SUSPEND TOPIC BAN CLEARMODE]
@_HELPCOMMS=[WACCESS WADDCHAN WADDUSER WBAN WBANLIST WCHANINFO WDEOP WHELP WINVITE WINFO WJOIN WKICK WLBANLIST WMAP WMOTD WOP WPART WPASS WREMCHAN WREMUSER WSET WSHOWCOMMANDS WSHOWIGNORE WSUSPEND WUNSUSPEND WTOPIC WUNBAN WCLEARMODE]
^SET HOLD_MODE ON
^ON ^EXEC XHELP {
@_COUNT=(_COUNT+1)
IF ( _COUNT == 22 )
{
INPUT "More? " @_COUNT=0
}
ECHO *** $1-
}
^ON ^EXEC_EXIT WHELP {
^ON ^EXIT_EXIT -WHELP
^ON ^EXEC -WHELP
^ASSIGN -_COUNT
^ASSIGN -_HELPFILES
^ASSIGN -_HELPCOMMS
^SET HOLD_MODE OFF
INPUT "WHelp? " IF ( [$0] ) { WHELP $* }
}
IF ( [$0] )
{
ECHO ***  HELP on $[55]0
IF ( [$[1]0] == [W] )
{
EXEC -NAME WHELP $CAT $XHELP_DIR/$WORD($RMATCH($0 $_HELPCOMMS) $_HELPFILES)
}
{
EXEC -NAME WHELP $CAT $XHELP_DIR/$WORD($RMATCH(W$0 $_HELPCOMMS) $_HELPFILES)
}
}
{
EXEC -NAME XHELP $CAT $XHELP_DIR/HELPLIST
}
}
ON ^NOTICE X ECHO X** $1-
ON ^NOTICE W ECHO W** $1-
#ON ^SERVER_NOTICE "% % % % HACK% UWORLD%.UNDERNET.ORG MODE #% +o X*" ECHO *** X reop on $7
#ON ^SERVER_NOTICE "% % % % HACK% UWORLD%.UNDERNET.ORG MODE #% +o W*" ECHO *** W reop on $7
ON ^401 "% X@CHANNELS%.UNDERNET.ORG *" ECHO *** X is unreachable at the moment
ON ^401 "% W@CHANNELS%.UNDERNET.ORG *" ECHO *** W is unreachable at the moment
^SET DISPLAY ON
ECHO *** X script loaded! (try /xhelp)

30
XHELP/readme Normal file
View File

@@ -0,0 +1,30 @@
This is the undernet channel service help package.
To install it, execute this command in your home
directory:
tar zxf Xhelp.tgz
OR, gzip -cd < Xhelp.tgz | tar xf
Then, you only have to load the file ~/XHELP/Xscript
in your IRC session. The easiest way to do it is to
add it in your .ircrc with this command:
echo "//LOAD ~/XHELP/Xscript" >> ~/.ircrc
Make sure you type both '>'. Otherwise, your .ircrc
file will be lost.
To install it for your whole system, uncompress the
archive in your IRCLIB directory, edit the Xscript
file so XHELP_DIR points to the correct directory and
add the proper /LOAD in your script/local.
This package is likely to require updates.
The latest version of this package is always
available from:
ftp://ca.undernet.org/pub/undernet/X/Xhelp.tgz
-----
Robin Thellend (SeKs@IRC)
<intru@info.polymtl.ca>
<seks@alias.undernet.org>

304
config.h.dist Normal file
View File

@@ -0,0 +1,304 @@
/* @(#)CS/config.h.dist $Id: config.h.dist,v 1.16 2000/06/13 05:08:40 lgm Exp $ */
/* Undernet Channel Service (X)
* Copyright (C) 1995-2002 Robin Thellend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contact by email at <csfeedback@robin.pfft.net>
*
* Please note that this software is unsupported and mostly
* obsolete. It was replaced by GNUworld/CMaster. See
* http://gnuworld.sourceforge.net/ for more information.
*/
/* BINDADDR is the local address that all the sockets should be
* bound to.
*/
#define BINDADDR "12.34.56.78"
/* DEFAULT_PORTNUM is the port X will try to
* connect to. This can be overridden by
* DEFAULT_SERVER
*/
#ifdef MAIN
int DEFAULT_PORTNUM = 6667;
#else
extern int DEFAULT_PORTNUM;
#endif
/* DEFAULT_NICKNAME is the nick of the channel service interface
* DEFAULT_USERNAME, its username
* DEFAULT_HOSTNAME, its hostname
* DEFAULT_REALNAME, its realname.
*/
#define DEFAULT_NICKNAME "X"
#define DEFAULT_REALNAME "For help type: \002/msg X help\002"
/* If is very important that all the channel services running
* on the same net use the same user@host :)
*/
#define DEFAULT_USERNAME "cservice"
#define DEFAULT_HOSTNAME "undernet.org"
#ifdef MAIN
char UMODE[10] = "+kid";
#else
extern char UMODE[10];
#endif
/* DEFAULT_SERVER is the server X should connect to.
* It can be either "server" or "server:port"
*/
#define DEFAULT_SERVER "localhost"
/* SERVERNAME and SERVERINFO are for
* X's servername.
* PASSWORD is the password sent before the SERVER command.
*/
#ifdef MAIN
char SERVERNAME[80] = "channels.undernet.org";
char SERVERINFO[80] = "Channel Service";
char PASSWORD[80] = "pizza";
#else
extern char SERVERNAME[80];
extern char SERVERINFO[80];
extern char PASSWORD[80];
#endif
/* HOMEDIR is X's home directory.
* A chdir() is issued at the very beginning of
* the execution.
*/
#ifdef MAIN
char HOMEDIR[256] = "/home/seks/CS";
#else
extern char HOMEDIR[256];
#endif
/*#define HOMEDIR "/usr/home/adm/undernet/CS"*/
/*#define HOMEDIR "/usr/ircd/q/CS"*/
/*#define HOMEDIR "/home/intru/CS"*/
/* UMASK is the umask used when creating new files
*/
#ifdef MAIN
int UMASK = 0077;
#else
extern int UMASK;
#endif
/* USERFILE is where user lists are stored.
*/
#define USERFILE "userlist.dat"
/* DEFAULT_CHANNELS_FILE is the file containing the
* list of channel that should be joined by default.
* In other words, those that have been addchan'ed :)
*/
#define DEFAULT_CHANNELS_FILE "channellist.dat"
/* SHITLIST_FILE is the file where bans are stored
*/
#define SHITLIST_FILE "shitlist.dat"
/* EXEC_FILE is the name of the executable for the restart function
* (added by Kev)
*/
#ifdef MAIN
char EXEC_FILE[256] = "./cs";
#else
extern char EXEC_FILE[256];
#endif
/* Other useful files..
*/
#ifdef MAIN
char MOTD_FILE[256] = "cs.motd";
char LOGFILE[256] = "cs.log";
char LOGFILEBAK[256] = "cs.log.old";
#undef CHANNEL_LOG
#define CHANNEL_LOG_FREQ 3600
char PIDFILE[256] = "cs.pid";
char HELP_DIR[256] = "XHELP"; /* must be non-empty */
#else
extern char MOTD_FILE[256];
extern char LOGFILE[256];
extern char LOGFILEBAK[256];
extern char PIDFILE[256];
extern char HELP_DIR[256];
#endif
/* Information on the main administrator
*/
#ifdef MAIN
char MASTER_REALNAME[80] = "SeKs";
char MASTER_PASSWD[20] = "XXXXXXXXXX";
char MASTER_MATCH[80] = "*!*seks@*.*";
#else
extern char MASTER_REALNAME[80];
extern char MASTER_PASSWD[20];
extern char MASTER_MATCH[80];
#endif
#define MASTER_ACCESS 1000
#define MASTER_CHANNEL "*"
#define MASTER_FLAGS 0
/* Other stuff...
*/
#define PING_FREQ 120 /* seconds */
#define USERLIST_SAVE_FREQ 7200 /* seconds */
#define SHITLIST_SAVE_FREQ 7200 /* seconds */
#define DEFS_SAVE_FREQ 7200 /* seconds */
#define SYNC_FREQ 7200 /* seconds */
#define MODE_DELAY 2 /* seconds */
#ifdef MAIN
char BROADCAST_CHANNEL[80] = "#cservice_info";
char VERIFY_ID[256] = "CSERVICE";
#else
extern char BROADCAST_CHANNEL[80];
extern char VERIFY_ID[256];
#endif
#ifdef MAIN
char UWORLD[10] = "Uworld";
char UWORLD_HOST[80] = "*.nssl.uoknor.edu";
char UWORLD_SERVER[80] = "Uworld.undernet.org";
#else
extern char UWORLD[10];
extern char UWORLD_HOST[80];
extern char UWORLD_SERVER[80];
#endif
#define UWORLD2 UWORLD2_NICK
#ifdef UWORLD2
#ifdef MAIN
char UWORLD2_NICK[10] = "Uworld2";
char UWORLD2_HOST[80] = "undernet.org";
char UWORLD2_SERVER[80] = "Uworld2.undernet.org";
#else
extern char UWORLD2_NICK[10];
extern char UWORLD2_HOST[80];
extern char UWORLD2_SERVER[80];
#endif
#endif
#ifdef BACKUP
# define MAIN_NICK DEFAULT_NICKNAME
# define MAIN_REALNAME ":X's backup: ^B/msg Q motd^B"
# undef DEFAULT_NICKNAME
# undef DEFAULT_REALNAME
# define DEFAULT_NICKNAME "Q"
# define DEFAULT_REALNAME ":X's backup: ^B/msg Q help^B"
# define MAIN_SERVERNAME SERVERNAME
# undef SERVERNAME
# undef SERVERINFO
# define SERVERNAME "channels2.undernet.org"
# define SERVERINFO "Channel Service Backup"
#endif
#define UWORLD_COMMAND "reop %s"
#define FAKE_UWORLD
#ifdef FAKE_UWORLD
# define UFAKE_NICK UWORLD2
# define UFAKE_HOST DEFAULT_HOSTNAME
# define UFAKE_SERVER UWORLD2_SERVER
# define UFAKE_INFO "Uworld"
#endif
#define GETOPS_FREQ 600 /* seconds */
#define GETOPS_ONJOIN_DELAY 30 /* seconds */
#define MAX_IDLE_TIME (48*3600) /* seconds */
#define CHECK_IDLE_FREQ (3 *3600) /* seconds */
#define USERLIST_EXP_TIME (90*24*3600) /* seconds (90 days) */
#define RENAME_LOGFILE_FREQ (3*24*3600) /* seconds (3 days) */
#ifdef MAIN
char CALMDOWNTOPIC[512] =
"This channel is in NoOp mode because of repeated abuse. Please contact "
"the channel manager to have this fixed. For more info, mail "
"cservice@undernet.org";
#else
extern char CALMDOWNTOPIC[512];
#endif
/* Define this if you want the 'upgrade' command
*/
#undef UPGRADE
#ifdef UPGRADE
#define PATCH_SERVER "apache.wildstar.net:7358"
#define GETPATCHPASS "TEST"
#define RECPATCHPASS "BLAH"
#define MISC_TIMEOUT 60
#define PATCH "/usr/bin/patch"
#define MAKE "/usr/bin/make"
#endif
#define MAX_CONNECTIONS 50
#define MAX_SENDQ 300000
#define HIGHSENDQTHRESHOLD 10000
/* Max Ban Duration in days.
*/
#define MAX_BAN_DURATION 14
/* Define this if you want the built-in http server
*/
#undef DOHTTP
#ifdef DOHTTP
#define HTTP_PORT 7357
#define HTTP_TIMEOUT 60
#define HTTP_LOG "http.log"
#define HTTP_DENY "http.deny"
#define HTTP_REDIRECT "http://cservice.undernet.org/"
#define HTTP_FOOTER "\n"\
"<A HREF=\"http://cservice.undernet.org/\"><IMG SRC=\"/files/b_arrow.gif\">Back to main page</A><P>\n"\
"This page is automatically generated by the Undernet Channel Service.\n"\
"If you are experiencing any problem, please contact the \n"\
"<A HREF=\"mailto:cservice@undernet.org\">Undernet Channel Service \n"\
"Committee.</A><P>\n"\
"This service is maintained by: <br>\n"\
"<ADDRESS>Robin Thellend <EM>(SeKs@IRC)</EM> &lt;\n"\
"<A HREF=\"mailto:seks@alias.undernet.org\">seks@alias.undernet.org</A>\n"\
"&gt;</ADDRESS>\n"
#define HTTP_HEADER "<HEAD><TITLE>Undernet Channel Service: %s</TITLE></HEAD>\n"
#define HTTP_BODY "<BODY BGCOLOR=#000000 TEXT=#FFFFFF LINK=#FF0000 VLINK=#FF00FF>\n"
#define HTTP_BAN_DISCLAIMER "<EM>Disclaimer: The Undernet Channel Service\n" \
"Committee and the maintainer of this service in no way\n" \
"support/endorse actions of channel operators, or regulate\n" \
"channel content in any way. Channel bans shown in no way\n" \
"reflect the views of the Channel Service Committee, and belong\n" \
"solely to the indvidual making them. No editorial control is\n" \
"excised by the committee on either the channel or the webpage.\n" \
"</EM><P>\n"
#define check_referer(x) (strncasecmp((x),"http://cservice.undernet.org/",28) \
&& strncasecmp((x),"http://www.cservice.undernet.org/",28) \
&& strncasecmp((x),"http://cservice.wildstar.net/",28))
#ifdef check_referer
#define HTTP_BAD_REFERER "http://cservice.undernet.org/bad_referer.html"
#endif
#endif

3
count Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
./listall | cut -d" " -f1 | sort | uniq -c

62
cs.conf.dist Normal file
View File

@@ -0,0 +1,62 @@
# $Id: cs.conf.dist,v 1.5 1998/01/22 09:33:38 chaos Exp $
# Channel Service Runtime Configuration File
#
# Identity
#
NICKNAME X
USERNAME cservice
HOSTNAME undernet.org
REALNAME For help type: /msg X help
UMODE +kid
#
# Server to which X connects
#
UPLINK cheetah
PORT 6667
#
# How X introduces itself
#
SERVERNAME channels.undernet.org
SERVERINFO Undernet Channel Service
PASSWORD pizza
#
# Files and directories
#
HOMEDIR /home/seks/CS
#UMASK
EXEC ./cs
MOTD cs.motd
LOG cs.log
LOGBAK cs.log.old
PID cs.pid
HELPDIR XHELP
#
# ID of level 1000 user
#
MASTER_NICK seks
MASTER_MASK *!*seks@*.*
MASTER_PASSWD qwerty
#
# Channel where broadcast messages go
#
BROADCAST #cservice_info
#
# ID to put in verify replies
#
VERIFYID CSERVICE
#
# Uworld informations
#
UWORLD_NICK Uworld
UWORLD_HOST *.nssl.uoknor.edu
UWORLD_SERVER Uworld.undernet.org
#
UWORLD2_NICK Uworld2
UWORLD2_HOST undernet.org
UWORLD2_SERVER Uworld2.undernet.org
#
# Topic to set when CALMDOWN is used
#
CALMDOWNTOPIC CALMDOWN was used on this channel
#
# End of configuration file

5
http.count Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
# @(#)CS/http.count $Id: http.count,v 1.3 1996/10/20 16:23:25 seks Exp $
grep CONNECTION http.log | cut -d: -f4 | cut -d" " -f5 | sort | uniq -c | sort

8
http.deny Normal file
View File

@@ -0,0 +1,8 @@
# @(#)CS/http.deny $Id: http.deny,v 1.3 1996/10/20 16:23:25 seks Exp $
#
# This file contains the ip addresses that are not granted
# connection. The first '0' ends the mask and the rest isn't
# considered.
# i.e. 132.207.0.0 will block all connections from 132.207.*
#
#127.0.0.0

Some files were not shown because too many files have changed in this diff Show More