diff --git a/LDP/howto/docbook/Cable-Modem.sgml b/LDP/howto/docbook/Cable-Modem.sgml index 135a16e4..5f5b145b 100644 --- a/LDP/howto/docbook/Cable-Modem.sgml +++ b/LDP/howto/docbook/Cable-Modem.sgml @@ -16,11 +16,11 @@ - v4.17 - May 16, 2000 + v4.20 + June 29, 2000 vv - Additions to @home and new provider in Bombay, India + Addition to 21st Century Cable @@ -120,7 +120,7 @@ text of the license can be found at - + @@ -280,10 +280,10 @@ With a little luck, your ethernet card should be working in Windows 95, and ready to rock in Linux. - -If you live Hampton Roads, VA or Phoenix, AZ -you should read a little note from Mark Solomon - + +Notes from Hampton Roads, VA and Phoenix, +AZ by Mark Solomon: + With the @home service in Hampton Roads, VA, it is absolutly neccessary @@ -307,6 +307,7 @@ Ether Express cards can be found at http://www.monmouth.com/~jay/Linux/ + Notes for Baltimore, MD and Colleyville,TX @@ -467,6 +468,89 @@ words "router", "firewall", or "Linux". + +Notes from Mobile, Alabama R. Jason Valentine <email>miracle@procyon.com</email>: + + + +In Mobile, Comcast cable provides cable modem service through the @home +network. An RCA cable modem (model DCM205) is issued along with a SMC +EZ-Card (10/100) if you don't already have a cable modem. + + + +Static IPs are not given, but rather assigned through DHCP. You need to +make your ethernet card (eth*) use DHCP - linuxconf is the easiest way to +set that up. Next, you'll need to find the following line in /sbin/ifup + + + +----------------------------------------------------------------- +if [ -n "$PUMP" ]; then + echo -n "Determining IP information for $DEVICE..." + if /sbin/pump -i $DEVICE; then + echo " done." + else + echo " failed." + exit 1 + fi + else ... +----------------------------------------------------------------- + + + +and change it to + + + +----------------------------------------------------------------- +if [ -n "$PUMP" ]; then + echo -n "Determining IP information for $DEVICE..." + if /sbin/pump -i $DEVICE -h hostname; then + echo " done." + else + echo " failed." + exit 1 + fi + else ... +----------------------------------------------------------------- + + + +Where hostname is the computer name (cc123456-a - or whatever yours may +be.) + + + + + + +Notes from Auburn, Alabama by Andrew W. Jones +<email>andywjones@home.com</email> + + + +I would like to note that Auburn's @home service supports DHCP. If you +simply issue `dhcpcd -h hostname` all your network settings are taken +care of... + + + + + +Notes from Santa Barbara, California by Tim Newsome +<email>nuisance@cmu.edu</email> + + +My provider (Cox@Home, in Santa Barbara, CA) does the same thing as + . I'm using Debian, +with dhclient version 2.0. I added the following line to my +/etc/dhclient.conf: send host-name "cx803168-a"; Where cx803168-a is the +hostname I've been assigned. It is listed on the purchase order. + + + + Information about @Home Service can be found at http://www.home.com/. @@ -488,7 +572,7 @@ url="http://www.oswg.org/oswg-nightly/DHCP.html">http://www.oswg.org/oswg-nightl -If this doesn't work out for you you should check out +If this doesn't work out for you you should check out http://www.math.uakron.edu/RoadRunner/ for Akron, Ohio and @@ -507,18 +591,30 @@ One more thing that might be worth mentioning: you will need a Windows NT, 95, or 98 or Macintosh PC for the RoadRunner installers to configure the modem. It's not technically necessary, but they will insist, and will not install on a Linux system. It's also best not to mention the IPFW system -while they're around. +while they're around. - -Information about RoadRunner Service can be found at + +Additional notes by Phil Baird pjb@rocsoft.com from Rochester, NY: + + + +About getting hooked up initially. It is true the RR techs don't want +to talk about Linux. However, they now offer us a "self-install" that is +half the price ($50). Basically, they come out, run the cable, and make +sure the signal gets to the modem. You must supply your own nic card and +do the rest of the setup on your own. + + + +Information about RoadRunner Service can be found at http://www.rr.com/. - - + + Rogers@Home @@ -540,7 +636,7 @@ for Rogers@Home at http://members.home.net/randal.leavitt/CableModemConnectionNotes.html. -Notes from Greg Jacobs +Notes from Greg Jacobs gregjacobs@home.com They now only give out dynamic IP's. The techs says its pretty much fixed @@ -942,8 +1038,8 @@ Information about Videotron can be found at Telekabel (Teleweb), Austria -According to Andreas Kostyrka: - +There are two approaches to setting up your Telekabel +connection. First one is the approach used by Andreas Kostyrka: @@ -973,6 +1069,30 @@ url="ftp://ftp.redhat.com/pub/contrib/readmes/3c5x9utils-1.0-1.README">ftp://ftp + +Second approach is provided by Marcel Ebmer +marcel.ebmer@chello.at + + + + +Do NOT bother using dhcpcd or pump! + + + +In case you don't know, ask the provider for your IP-address, which +is static, for the DNSs, the Gateway and use linuxconf to configure the +network. For Vienna: 960 60 333 is the helpdesk's telephone number They +officially do not support linux, but you need not mention you +are running linux. + + + +Choose a unique name for your PC....not "localhost" + + + + Information about Telekabel can be found at http://www.telekabel.at/. @@ -1898,6 +2018,29 @@ my Linux box (which I never do really) I can go in and update the IP address that my web server www.xanderbelly.com and mail server + +Additional notes: + + + +The terms and conditions of 21st Century cable modem contains the +following statement: + + + +Distributing unsolicited information in any manner is prohibited on 21st +Century's network and will result in termination of 21st Century +service. (I.e. junk email, etc...) Any use of a server type application +or service on a computer system connected to 21st Century Cable Modem +Service is prohibited and may result in termination of 21st Century +Cable Modem Service (i.e. web, ftp, or game servers, etc...). 21st +Century Cable Modem Service is for client type applications ONLY. + + + +Also, technically, each additional dynamic IP address beyond the first +one carries a $4.95 monthly charge. + @@ -2060,7 +2203,7 @@ under a modern linux distribution. Last thing worth to be said is that Supercable doesn't provide support for Linux but you can always ask your questions in news.supercable.es in the Linux area. Their web page is located at http://www.supercable.es +url="http://www.supercable.es/">http://www.supercable.es/ (WARNING: get ready to download an almost 1MB of useless Macromedia's Flash garbage). @@ -2196,11 +2339,248 @@ worked. The Cable Modem that was used (provided by Hathway) was a SurfBoard 3100 + + +Siti Cable, Bangalore, India + + +This information is provided by Vinay Avasthi vinay@avasthi.com: + + + +Zee Telefilms has partnered with Siti Cable in Bangalore, India to +provide cable modem service. I subscribed to this service and it kind of +worked out of the box from linux. + + + +I am using Redhat 6.1 on a IBM Thinkpad 600 with Xircom Realport +Ethernet card. On autodetect links mentions that the card will be used +in 10MB/s only. + + + +Only problem that I faced was on shutdown, the system will hang while +shutting down pump. To temporarily fix the problem I just put that +particular like in rc-scripts to background. + + + +The steps that one needs to perform are as follows. + + + + + - Need to have an ethernet card that works with Linux. + + +- Enable DHCP by using pump. For some reason dhcpd does not seem to +work. + + + + +Only thing that I would suggest is to be careful regarding support since +the tech support do not seem to know much about software. + + + + + +Com Hem, Sweden + + +This information is provided by Zoltan Arpadffy arpadffy@polarfox.com: + + + +com hem http://www.comhem.se/ +is a Swedish cable TV/Internet provider, a sub-company +of Telia http://www.telia.com/ +the biggest Scandinavian carrier. +com hem does not support any other OS but Windows and Mac-OS (as com hem support +claims ), but it is not so complicate to set up on Linux as well. + + + +com hem sells NetGame's cable modem (NeMo). Initial speed is 512 kb/s and it can be +set up to 10Mb/s. You can order it with or without Ethernet card. +com hem internet service is available in the bigger cities all over Sweden. + + + +1. Setting up a single node + + + + +set up your network card to work properly +(Ethernet HOWTO) + + + + + +configure DHCP to that card (DHCP mini-HOWTO) + + + + + +you need some browser what supports Java-script (as Netscape) and go to the login +site http://login1.telia.com/ + + + + + +- fill in your user-name and password (provided by com hem) ... and you're there. + + + + + + +Network what you'd become a member is: + IP address: Assigned by com hem + Subnet mask: 255.255.255.0 + Default GW: Assigned by com hem + Hostname: Assigned by com hem + Domain name: telia.com + Primary DNS server (nameserver): 10.0.0.1 + Secondary DNS server (nameserver): 10.0.0.2 + + + + +2. Connecting your home LAN (if you have more than one machine) + + + +We have to turn one computer to gateway (I did it with an old Pentium 66MHz/16M) + + +install two network cards in your gateway +NET3-4 HOWTO + + + +first set up (and connect) to your LAN + + + +second network card have to use DHCP +(DHCP mini-HOWTO) + + + +enable ip forwarding + + +net.ipv4.ip_forward = 1 in /etc/sysctl.conf or by +echo "1" > /proc/sys/net/ipv4/ip_forwarding + + + + +set up IP masquerade +(IP Masquerade mini-HOWTO) + +ipchains -P forward DENY +ipchains -A forward -s your_network_here/24 -j MASQ + + +(for me it was ipchains -A forward -s 192.168.10.0/24 -j MASQ) +check your routing table with route command... it should be something like below: + + +Destination Gateway Genmask Flags Metric Ref Use Iface +gate.polarfox.h * 255.255.255.255 UH 0 0 0 eth0 +telia-net * 255.255.255.0 U 0 0 0 eth1 +polarfox-net * 255.255.255.0 U 0 0 0 eth0 +127.0.0.0 * 255.0.0.0 U 0 0 0 lo +default h2n5fdt22o429.t 0.0.0.0 UG 0 0 0 eth1 + + +Useful literature for security issues is +Linux IPCHAINS HOWTO + + + + +configure default gateway for all other hosts in your LAN. +On unix nodes it should look something like: + + +Destination Gateway Genmask Flags Metric Ref Use Iface +sea.polarfox.ho * 255.255.255.255 UH 0 0 0 eth0 +polarfox-net * 255.255.255.0 U 0 0 0 eth0 +127.0.0.0 * 255.0.0.0 U 0 0 0 lo +default gate.polarfox.h 0.0.0.0 UG 0 0 0 eth0 + + +Default gateway setup for other OSs you can find a very nice description in IP +Masquerade mini-HOWTO + + + +configure name server on your gateway DNS HOWTO or just set up your hosts to use +Telia's name server (10.0.0.1) + + + +log in from any host http://login1.telia.com/ +and you're on the road with all your LAN. + + + + + + + + + +Problems: + + + + + +If you don't use browser with Java-script support, you can not log in. +Solution: there is no elegant solution. Without it you can not log in and open the +connection. + + + + +After some network inactivity period (10-15 minutes) your connection will be +terminated and you have to log in again... meanwhile your gateway and all your inner +services will be unreachable from outside as well (if you're running some web server +at home etc). +Solution: start one ping process or even more elegant solution is to submit one cron +job for every 5-10 minutes on the gateway, to "do something" though the network. + + + + + +I did it with /etc/cron.d/keep-alive file when contains: + + + +# fake connection in order to keep line alive +# every 5 minutes send some packages +MAILTO="" +*/5 * * * * ping -f -c 5 www.polarfox.com + + + + - + Hybrid Cable modem ISPs If you think you have the card recognized you have to now look at the diff --git a/LDP/howto/linuxdoc/Bash-Prog-Intro-HOWTO.sgml b/LDP/howto/linuxdoc/Bash-Prog-Intro-HOWTO.sgml index 2a9d9062..af82e5f7 100644 --- a/LDP/howto/linuxdoc/Bash-Prog-Intro-HOWTO.sgml +++ b/LDP/howto/linuxdoc/Bash-Prog-Intro-HOWTO.sgml @@ -9,7 +9,7 @@
BASH Programming - Introduction HOW-TO by Mike G - v0.07, 22 June 2000 + 27 June 2000 This article intends to help you to start programming basic-intermediate shell scripts. It does not intend to be an @@ -27,11 +27,11 @@ Introduction - - Getting the latest version + +Getting the latest version -

- + @@ -90,6 +90,9 @@ Very simple Scripts to use to run the file.

The second line is the only action performed by this script, which prints 'Hello World' on the terminal. +

If you get something like ./hello.sh: Command not found. + Probably the first line '#!/bin/bash' is wrong, issue whereis bash or see + 'finding bash' to see how sould you write this line. A very simple backup script @@ -402,7 +405,7 @@ Conditionals #!/bin/bash T1="foo" T2="bar" - if [ $T1 = $T2 ]; then + if [ "$T1" = "$T2" ]; then echo expression evaluated as true else echo expression evaluated as false @@ -492,7 +495,7 @@ Loops for, while and until

This script 'emulates' the well known - (C, Pascal, perl, python, etc) 'for' structure + (C, Pascal, perl, etc) 'for' structure @@ -573,10 +576,10 @@ User interfaces #!/bin/bash OPTIONS="Hello Quit" select opt in $OPTIONS; do - if [ $opt = "Quit" ]; then + if [ "$opt" = "Quit" ]; then echo done exit - elif [ $opt = "Hello" ]; then + elif [ "$opt" = "Hello" ]; then echo Hello World else clear @@ -596,7 +599,7 @@ User interfaces

#!/bin/bash - if [ -z $1 ]; then + if [ -z "$1" ]; then echo usage: $0 directory exit fi @@ -620,7 +623,8 @@ Misc Reading user input with read -

In many ocations you may want to prompt the user for some input, and there are several ways +

In many ocations you may want to prompt the user for some input, and + there are several ways to achive this. This is one of those ways: #!/bin/bash @@ -628,7 +632,8 @@ Misc read NAME echo "Hi $NAME!" -

As a variant, you can get multiple values with read, this example may clarify this. +

As a variant, you can get multiple values with read, this example may + clarify this. #!/bin/bash echo Please, enter your firstname and lastname @@ -756,6 +761,11 @@ Tables echo "S1('$S1') is equal to S1('$S1')" fi +

I quote here a note from a mail, sent buy Andreas Beck, refering to use + This is not quite a good idea, as if either $S1 or $S2 is empty, you will + get a parse error. x$1=x$2 or "$1"="$2" is better. + @@ -765,7 +775,7 @@ Tables

-

*

/ -

% (reminder) +

% (remainder) @@ -785,25 +795,154 @@ Tables Useful commands -

-

sed (stream editor - very useful) -

gawk -

grep (show line matching this or not matching that) -

wc (count words, lines) -

sort -

bc (more than a calculator) -

cut (edit columns) -

tput (get information from the current terminal) - -

It it higly recommended to be familiarized with - this programs (at least). There are tons of little - programs that will let you do real magic in a - command line. - +

This section was re-written by Kees (see thank to...) +

Some of these command's almost contain complete programming languages. + From those commands only the basics will be explained. For a more detailed + description, have a closer look at the man pages of each command. + + Sed is a non-interactive editor. Instead of altering a file by moving the + cursor on the screen, you use a script of editing instructions to sed, plus the + name of the file to edit. You can also describe sed as a filter. Let's have + a look at some examples: + + + $sed 's/to_be_replaced/replaced/g' /tmp/dummy + + +

Sed replaces the string 'to_be_replaced' with the string 'replaced' and + reads from the /tmp/dummy file. The result will be sent to stdout (normally + the console) but you can also add '> capture' to the end of the line above so + that sed sends the output to the file 'capture'. + + + $sed 12, 18d /tmp/dummy + + +

Sed shows all lines except lines 12 to 18. The original file is not altered by this command. + + Many implementations of the AWK programming language exist (most known interpreters are GNU's + gawk and 'new awk' mawk.) The principle is simple: AWK scans for a pattern, and for every + matching pattern a action will be performed. +

Again, I've created a dummy file containing the following lines: +

+ $awk '/test/ {print}' /tmp/dummy + +

test123 + +

test + +

The pattern AWK looks for is 'test' and the action it performs when it found a line in the file + /tmp/dummy with the string 'test' is 'print'. + + + $awk '/test/ {i=i+1} END {print i}' /tmp/dummy + + +

3 + +

When you're searching for many patterns, you should replace the text between the quotes with '-f + file.awk' so you can put all patterns and actions in 'file.awk'. + + We've already seen quite a few grep commands in the previous chapters, that display the lines + matching a pattern. But grep can do more. + + $grep "look for this" /var/log/messages -c + +

12 +

The string "look for this" has been found 12 times in the file /var/log/messages. + +

[ok, this example was a fake, the /var/log/messages was tweaked :-)] + + In the following example, we see that the output is not what we expected. The dummy file, as used + in this example, contains the following text: + + $wc --words --lines --bytes /tmp/dummy + + +

2 5 34 /tmp/dummy + +

Wc doesn't care about the parameter order. Wc always prints them in a standard order, which is, + as you can see: . + + This time the dummy file contains the following text: +

+ $sort /tmp/dummy + + +

This is what the output looks like: + +

Commands shouldn't be that easy :-) + Bc is accepting calculations from command line (input from file. not from redirector or pipe), + but also from a user interface. The following demonstration shows some of the commands. Note that +

I start bc using the -q parameter to avoid a welcome message. + + + $bc -q + + +

A little demonstration of tput's capabilities: + + $tput cup 10 4 + +

The prompt appears at (y10,x4). + + $tput reset + +

Clears screen and prompt appears at (y1,x1). Note that (y0,x0) is the upper left corner. + + $tput cols + + Shows the number of characters possible in x direction. +

It it higly recommended to be familiarized with these programs (at least). There are tons of + little programs that will let you do real magic on the command line. +

[some samples are taken from man pages or FAQs] - - - @@ -980,16 +1119,20 @@ About the document Jon Abbott for sending comments about evaluating arithmetic expressions. Laurent Martelli for translating this document to French (soon here the URL) Felix Hudson for writing the Kees van den Broek (for sending many corrections) + Kees van den Broek + (for sending many corrections, re-writting usefull comands section) Mike (pink) made some suggestions about locating bash and testing files - fiesh make a nice suggestion for the loops section. + Fiesh make a nice suggestion for the loops section. + Lion suggested to mention a common error (./hello.sh: Command not found.) + Andreas Beck made several corrections and coments. History +

Added the section usefull commands re-writen by Kess. +

More corrections and suggestions incorporated.

Samples added on string comparison. -

v0.8 More little additions. +

v0.8 droped the versioning, I guess the date is enought.

v0.7 More corrections and some old TO-DO sections written.

v0.6 Minor corrections.

v0.5 Added the redirection section. diff --git a/LDP/howto/linuxdoc/C++Programming-HOWTO.sgml b/LDP/howto/linuxdoc/C++Programming-HOWTO.sgml index 98c2ccc6..ee6906f7 100644 --- a/LDP/howto/linuxdoc/C++Programming-HOWTO.sgml +++ b/LDP/howto/linuxdoc/C++Programming-HOWTO.sgml @@ -40,7 +40,7 @@ C++ Programming HOW-TO Al Dev (Alavoor Vasudevan) -v10.0, 02 June 2000 +v11.0, 03 July 2000 This document discusses methods to avoid memory problems in C++ and also will help you to program properly in C++ language. @@ -159,12 +159,12 @@ brace-surrounded block - in this case, everything in the header file and comp(), some_c_function() is compiled by a C compiler. Instead of using char * and char[] all the C++ programmers MUST use the -'mychar class' +'String class' which is given in this document and 'string class' included in the STDLIB. The -'mychar class' +'String class' utilises the constructor and destructor to automate the memory management and also provides many functions like ltrim, substring, etc.. @@ -175,13 +175,13 @@ in the C++ compiler. The string class is part of the standard GNU C++ library and provides lot of string manipulation functions. The 'string class' and -'mychar class' +'String class' can remove the need of char * datatype. Also, C++ programmers must be encouraged to use 'new', 'delete' features instead of using 'malloc' or 'free'. The -'mychar class' +'String class' does everything that char * or char [] does. It can completely replace char datatype. Plus added @@ -192,7 +192,7 @@ The GNU C++ compiler MUST drop off the support of char *, char[] datatypes and in order to compile older programs using char datatype, the compiler should provide a additional option called "-fchar-datatype" to g++ command. Over the next 2 years all the C++ programs will use -'mychar class' +'String class' and 'string class' and there will be no char * and char[]. The compiler @@ -247,12 +247,12 @@ Hence, Java runs on "client" and C++ runs on servers!! - Download mychar

All the programs, examples are given in Appendix of this document. -You can download as a single tar zip, the mychar class, libraries +You can download as a single tar zip, the String class, libraries and example programs from Go here and click on C++Programming howto.tar.gz file @@ -266,27 +266,34 @@ and example programs from - Usage of mychar class + Usage of String class --> - Usage of mychar class + Usage of String class

+To use String class, you should first refer to a +sample program "example_String.cpp" +given in + +and the String class which is given in +. + The -'mychar class' +'String class' is a complete replacement for char and char * datatype. You can use -'mychar class' +'String class' just like char and get much more functionalities. -You should include the library 'libmychar.a' which you can build from the +You should include the library 'libString.a' which you can build from the makefile given in and copy the library to /usr/lib directory where all the "C++" libraries are located. To use -the 'libmychar.a' compile your programs like - +the 'libString.a' compile your programs like - - g++ example.cpp -lmychar + g++ example.cpp -lString See illustration sample code as given below - - mychar aa; + String aa; aa = " Washington DC is the capital of USA "; @@ -308,12 +315,6 @@ See illustration sample code as given below - fprintf(stdout, "aa.val=%c ", *tmpcc); } -A complete -example program "example_mychar.cpp" implementing the -mychar class is given in - -and mychar class is given in -. Functions

-The -'mychar class' -provides these functions :- - +The functions provided by String class has the same name +as that Java language's +String class. The function names and the behaviour is exactly same +as that of Java's string class!! This will facilitate portability of code +between Java and C++ (you can cut and paste and do minimum changes to code). +The +'String class' +provides these Java like functions :- + Current string length length() + char charAt(int where); + void getChars(int sourceStart, int sourceEnd, char target, int targetStart); + char* toCharArray(); + bool equals(String str2); // See also == operator + bool equals(char *str2); // See also == operator + bool equalsIgnoreCase(String str2); + + bool regionMatches(int startIndex, String str2, int str2StartIndex, int numChars); + + bool regionMatches(bool ignoreCase, int startIndex, String str2, int str2StartIndex, int numChars); + + String toUpperCase(); + String toLowerCase(); + + bool startsWith(String str2); + bool startsWith(char *str2); + + bool endsWith(String str2); + bool endsWith(char *str2); + + int compareTo(String str2); + int compareTo(char *str2); + int compareToIgnoreCase(String str2); + int compareToIgnoreCase(char *str2); + + int indexOf(char ch, int startIndex = 0); + int indexOf(char *str2, int startIndex = 0); + int indexOf(String str2, int startIndex = 0); + + int lastIndexOf(char ch, int startIndex = 0); + int lastIndexOf(char *str2, int startIndex = 0); + int lastIndexOf(String str2, int startIndex = 0); + + String substring(int startIndex, int endIndex = 0); + String replace(char original, char replacement); + String replace(char *original, char *replacement); + + String trim(); // See also overloaded trim() + + String concat(String str2); // See also operator + + String concat(char *str2); // See also operator + + String append(String str2) {return concat(str2);} // See also operator + + String append(char *str2) {return concat(str2);} // See also operator + + String append(int bb) {return (*this + bb);} // See also operator + + String append(unsigned long bb) {return (*this + bb);} // See also operator + + String append(float bb) {return (*this + bb);} // See also operator + + + String insert(int index, String str2); + String insert(int index, char ch); + + String reverse(); // See also overloaded reverse() + String deleteCharAt(int loc); + String deleteStr(int startIndex, int endIndex); // Java's "delete()" + + +These are addional functions which are not available in Java. + Left trim the string. Remove leading white-spaces - newlines, tabs ltrim() Right trim the string. Remove trailing white-spaces - newlines, tabs rtrim() Remove trailing and leading white-spaces trim() @@ -378,11 +441,10 @@ from start pos(char *substr, unsigned long start) Explodes the string and returns the list in the list-head pointer explodeH explode(char *seperator) Implodes the strings in the list-head pointer explodeH and -returns the mychar variable implode(char *glue) +returns the String variable implode(char *glue) Joins the strings in the list-head pointer explodeH and -returns the mychar variable join(char *glue) +returns the String variable join(char *glue) Repeat the input string n times repeat(char *input, unsigned int multiplier) - Reverse the string characters reverse() Replace all occurences of string 'needle' with 'str' in the haystack 'val' replace(char *needle, char *str) Translate certain chars str_tr(char *from, char *to) @@ -418,7 +480,6 @@ of newstr overlay(char *newstr, int start = 0, int length = 0, char padchar Returns true if string is NULL value bool isnull() Resets the string to NULL clear() - Miscellaneous Functions

-Some miscellaneous mychar functions are given here, but DO NOT USE these, +Some miscellaneous String functions are given here, but DO NOT USE these, and instead use operators like '+', '+=', '==' etc.. These are 'private' members of -the 'mychar' class. +the 'String' class. Copy string str_cpy(char *bb) Long integer converted to string str_cpy(unsigned long bb) @@ -441,12 +502,12 @@ the 'mychar' class. String concatenate a int str_cat(int bb) String concatenate a int str_cat(unsigned long bb) String concatenate a float str_cat(float bb) - Is equal to mychar ? bool equalto(const mychar & rhs, bool type = false) + Is equal to String ? bool equalto(const String & rhs, bool type = false) Is equal to char* ? bool equalto(const char *rhs, bool type = false) For example to convert integer to string do - - mychar aa; + String aa; aa = 34; // The '=' operator will convert int to string cout << "The value of aa is : " << aa.val << endl; @@ -458,8 +519,8 @@ For example to convert integer to string do - cout << "The value of aa is : " << aa.val << endl; // The output aa will be '268.878' - // You must cast mychar to convert - aa = (mychar) 34 + " Honourable President Ronald Reagan " + 234.878; + // You must cast String to convert + aa = (String) 34 + " Honourable President Ronald Reagan " + 234.878; cout << "The value of aa is : " << aa.val << endl; // The output aa will be '34 Honourable President Ronald Reagan 234.878' @@ -528,7 +589,7 @@ Also , my_realloc() and my_free() should be used instead of malloc(), realloc() and free(), as they are much cleaner and have additional checks. -For an example, see the file "mychar.h" which is using +For an example, see the file "String.h" which is using the and my_free() functions. @@ -845,24 +906,19 @@ Visit following locators which are related to C, C++ - Other Formats of this Document

This document is published in 11 different formats namely - DVI, Postscript, -Latex, Adobe Acrobat PDF, +Latex, Adobe Acrobat PDF, LyX, GNU-info, HTML, RTF(Rich Text Format), Plain-text, Unix man pages and SGML. You can get this HOWTO document as a single file tar ball in HTML, DVI, Postscript or SGML formats from - - - or - + -Plain text format is in: -or - +Plain text format is in: Translations to other languages like French, German, Spanish, Chinese, Japanese are in - -or + Any help from you to translate to other languages is welcome. The document is written using a tool called "SGML tool" which can be got from - @@ -874,9 +930,31 @@ Compiling the source you will get the following commands like sgml2latex C++Programming-HOWTO.sgml (to generate latex file) -This document is located at - +LaTeX documents may be converted into PDF files simply by +producing a Postscript output using sgml2latex ( and dvips) and running the +output through the Acrobat distill () command as follows: + +bash$ man sgml2latex +bash$ sgml2latex filename.sgml +bash$ man dvips +bash$ dvips -o filename.ps filename.dvi +bash$ distill filename.ps +bash$ man ghostscript +bash$ man ps2pdf +bash$ ps2pdf input.ps output.pdf +bash$ acroread output.pdf & + +Or you can use Ghostscript command ps2pdf. +ps2pdf is a work-alike for nearly all the functionality of +Adobe's Acrobat Distiller product: it +converts PostScript files to Portable Document Format (PDF) files. +ps2pdf is implemented as a very small command script (batch file) that invokes Ghostscript, selecting a special "output device" +called pdfwrite. In order to use ps2pdf, the pdfwrite device must be included in the makefile when Ghostscript was compiled; +see the documentation on building Ghostscript for details. + +This howto document is located at - - + Also you can find this document at the following mirrors sites - @@ -887,7 +965,7 @@ Also you can find this document at the following mirrors sites - Other mirror sites near you (network-address-wise) can be found at - + select a site and go to directory /LDP/HOWTO/C++Programming-HOWTO.html @@ -895,40 +973,40 @@ select a site and go to directory /LDP/HOWTO/C++Programming-HOWTO.html In order to view the document in dvi format, use the xdvi program. The xdvi program is located in tetex-xdvi*.rpm package in Redhat Linux which can be located through ControlPanel | Applications | Publishing | TeX menu buttons. - To read dvi document give the command - - xdvi -geometry 80x90 howto.dvi - And resize the window with mouse. See man page on xdvi. + + xdvi -geometry 80x90 howto.dvi + man xdvi + + And resize the window with mouse. To navigate use Arrow keys, Page Up, Page Down keys, also you can use 'f', 'd', 'u', 'c', 'l', 'r', 'p', 'n' letter keys to move up, down, center, next page, previous page etc. To turn off expert menu press 'x'. - + You can read postscript file using the program 'gv' (ghostview) or 'ghostscript'. The ghostscript program is in ghostscript*.rpm package and gv program is in gv*.rpm package in Redhat Linux which can be located through ControlPanel | Applications | Graphics menu buttons. The gv program is much more user friendly than ghostscript. -Ghostscript and gv are also available on other platforms like OS/2, -Windows 95 and NT. - +Also ghostscript and gv are available on other platforms like OS/2, +Windows 95 and NT, you view this document even on those platforms. + Get ghostscript for Windows 95, OS/2, and for all OSes from +To read postscript document give the command - - To read postscript document give the command - gv howto.ps - - To use ghostscript give - ghostscript howto.ps You can read HTML format document using Netscape Navigator, Microsoft Internet -explorer, Redhat Baron Web browser or any other web browsers. +explorer, Redhat Baron Web browser or any of the 10 other web browsers. -You can read the latex, LyX output using LyX a "X-Windows" front end to latex. +You can read the latex, LyX output using LyX a X-Windows front end to latex. - Appendix A example_mychar.cpp

-You can download all programs as a single tar.gz file from . +You can download all programs as a single tar.gz file from . To get this file, in the web-browser, save this file as 'Text' type. //***************************************************************** -// Copyright policy is GNU/GPL but additional restriction is -// that you include author's name and email on all copies +// Copyright policy is GNU/GPL and it is requested that +// you include author's name and email on all copies // Author : Al Dev Email: alavoor@yahoo.com //***************************************************************** +// To prevent memory leaks - a char class to manage character variables +// Always prefer to use string class +// instead of char[] or char * + // To compile and test this program do - -// Assuming that libmychar.a is in the current directory -// g++ example_mychar.cpp -L. -lmychar +// Assuming that libString.a is in the current directory +// g++ example_String.cpp -L. -lString #include // for putenv -#include "mychar.h" +#include "String.h" +//#include // This is at /usr/include/g++-2/string +//#include // This is at /usr/include/g++-2/cstring and includes /usr/inlcude/strings.h ///////////////////////////////////////////////// -// A example program to demo usage of mychar +// A example program to demo usage of String +// Note: In this example, I did not use memory +// manipulation functions like new, delete, malloc, +// strdup at all!! The String class takes care of +// it automatically !! ///////////////////////////////////////////////// int main(int argc, char **argv) @@ -987,7 +1075,8 @@ int main(int argc, char **argv) sprintf(p_name, "PROGRAM_NAME=%s", argv[0]); putenv(p_name); print_total_memsize(); // in the beginning - mychar aa, bb; + String aa, bb, egg; + char tmpaa[100]; //bb.str_cpy(" bbSTRing "); bb = " bbSTRing "; @@ -995,110 +1084,384 @@ int main(int argc, char **argv) // Testing the + operator // aa + " rhs "; // You will not get any output here !!! // You must directly use in fprintf as in below line - - fprintf(stdout, "\n0) aa.val is :%sEOF\n", (aa + " my rhs " ).val); + fprintf(stdout, "1) aa.val is :%sEOF\n", (aa + " my rhs " ).val); // Testing the = operator aa = " lhs " ; - fprintf(stdout, "0-1) With operator= aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "2) With operator= aa.val is :%sEOF\n", aa.val); // Testing the + operator // " lhs " + aa; // You will not get any output here !!! // You must directly use in fprintf as in below line - - fprintf(stdout, "\n0) With lsh operator+, aa.val is :%sEOF\n", (" my lhs " + aa ).val); + fprintf(stdout, "3) With lsh operator+, aa.val is :%sEOF\n", (" my lhs " + aa ).val); + + // ***************** Java like functions ******************** + aa = "Some Value 2345"; + fprintf(stdout, "4) aa.charAt() is :%c %sEOF\n", aa.charAt(3), aa.val); + + aa = "Some Value 2345"; + strcpy(tmpaa, "tmpaa value"); + aa.getChars(3, 8, tmpaa, 2); + fprintf(stdout, "5) aa.getChars() is : %s %sEOF\n", tmpaa, aa.val); + + aa = "Some Value 2345"; + fprintf(stdout, "6) aa.toCharArray() is : %sEOF\n", aa.toCharArray()); + + aa = "Some2345"; + if (aa.equals("Some2345")) + fprintf(stdout, "7) aa.equals() is true : %sEOF\n", aa.val); + else + fprintf(stdout, "7) aa.equals() is false : %sEOF\n", aa.val); + + aa = "testinglettercase"; + egg = "TestingLetterCase"; + if (aa.equalsIgnoreCase(egg)) + fprintf(stdout, "8) egg equals aa (case insensitive) aa.val is :%sEOF\n", aa.val); + else + fprintf(stdout, "8) egg not equals aa (case insensitive) aa.val is :%sEOF\n", aa.val); + + aa = "kkktestinglettercase"; + egg = "abtestingLetterCase"; + if (aa.regionMatches(true, 3, egg, 2, 7)) + fprintf(stdout, "9) regionMatches is true aa.val is :%sEOF\n", aa.val); + else + fprintf(stdout, "9) regionMatches is false aa.val is :%sEOF\n", aa.val); //aa.str_cpy(bb.val); - aa = bb; - aa.to_upper(); - fprintf(stdout, "1) aa.val is :%sEOF\n", aa.val); + aa = bb + "Some Value 2345"; + egg = aa.toUpperCase(); + fprintf(stdout, "10) egg.val is :%sEOF\n", egg.val); - aa = bb; - aa.to_lower(); - fprintf(stdout, "2) aa.val is :%sEOF\n", aa.val); + aa = bb + "Some Value 2345"; + egg = aa.toLowerCase(); + fprintf(stdout, "11) egg.val is :%sEOF\n", egg.val); - aa = bb; - aa.ltrim(); - fprintf(stdout, "3) aa.val is :%sEOF\n", aa.val); + aa = "Some Value 2345"; + egg = "Some"; + if (aa.startsWith("Some")) + //if (aa.startsWith(egg)) + fprintf(stdout, "12) aa.startsWith() is true :%sEOF\n", aa.val); + else + fprintf(stdout, "12) aa.startsWith() is false :%sEOF\n", aa.val); - aa = bb; - aa.rtrim(); - fprintf(stdout, "4) aa.val is :%sEOF\n", aa.val); + aa = "Some Value 2345"; + egg = " 2345"; + if (aa.endsWith(" 2345")) + //if (aa.endsWith(egg)) + fprintf(stdout, "13) aa.endsWith() is true :%sEOF\n", aa.val); + else + fprintf(stdout, "13) aa.endsWith() is false :%sEOF\n", aa.val); - aa = bb; - aa.trim(); - fprintf(stdout, "5) aa.val is :%sEOF\n", aa.val); + aa = "bbb Some Value 2345"; + egg = "caabc"; + if (aa.compareTo(egg) == 0) + fprintf(stdout, "14) aa.compareTo() is zero :%sEOF\n", aa.val); + else + if (aa.compareTo(egg) > 0) + fprintf(stdout, "14) aa.compareTo() is greater :%sEOF\n", aa.val); + else + if (aa.compareTo(egg) < 0) + fprintf(stdout, "14) aa.compareTo() is less than :%sEOF\n", aa.val); + + aa = "bbb Some Value 2345"; + strcpy(tmpaa, "aabbb Some Value 2345"); + if (aa.compareTo(tmpaa) == 0) + fprintf(stdout, "15) aa.compareTo() is zero :%sEOF\n", aa.val); + else + if (aa.compareTo(tmpaa) > 0) + fprintf(stdout, "15) aa.compareTo() is greater :%sEOF\n", aa.val); + else + if (aa.compareTo(tmpaa) < 0) + fprintf(stdout, "15) aa.compareTo() is less than :%sEOF\n", aa.val); + + aa = "bbb Some Value 2345"; + //egg = "bbb Some Value 2345"; + egg = "CCaabc"; // change values to caabc, aabc + if (aa.compareToIgnoreCase(egg) == 0) + fprintf(stdout, "16) aa.compareToIgnoreCase() is zero :%sEOF\n", aa.val); + else + if (aa.compareToIgnoreCase(egg) > 0) + fprintf(stdout, "16) aa.compareToIgnoreCase() is greater :%sEOF\n", aa.val); + else + if (aa.compareToIgnoreCase(egg) < 0) + fprintf(stdout, "16) aa.compareToIgnoreCase() is less than :%sEOF\n", aa.val); + + aa = "bbb Some Value 2345"; + //strcpy(tmpaa, "bbb Some Value 2345"); + strcpy(tmpaa, "CAABbb Some Value 2345"); // change value to caabb, aab + if (aa.compareToIgnoreCase(tmpaa) == 0) + fprintf(stdout, "17) aa.compareToIgnoreCase() is zero :%sEOF\n", aa.val); + else + if (aa.compareToIgnoreCase(tmpaa) > 0) + fprintf(stdout, "17) aa.compareToIgnoreCase() is greater :%sEOF\n", aa.val); + else + if (aa.compareToIgnoreCase(tmpaa) < 0) + fprintf(stdout, "17) aa.compareToIgnoreCase() is less than :%sEOF\n", aa.val); + + aa = "bbb Some Value 2345"; + strcpy(tmpaa, "Some"); + egg = "Value"; + fprintf(stdout, "18) aa.indexOf('S') %d :%sEOF\n", aa.indexOf('S'), aa.val); + fprintf(stdout, "18) aa.indexOf(tmpaa) %d :%sEOF\n", aa.indexOf(tmpaa), aa.val); + fprintf(stdout, "18) aa.indexOf(egg) %d :%sEOF\n", aa.indexOf(egg), aa.val); + + aa = "bbb Some Value Some 2345"; + strcpy(tmpaa, "Some"); + egg = "Some"; + fprintf(stdout, "19) aa.lastIndexOf('S') %d :%sEOF\n", aa.lastIndexOf('S'), aa.val); + fprintf(stdout, "19) aa.lastIndexOf(tmpaa) %d :%sEOF\n", aa.lastIndexOf(tmpaa), aa.val); + fprintf(stdout, "19) aa.lastIndexOf(egg) %d :%sEOF\n", aa.lastIndexOf(egg), aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "20) aa.substring(5) %s :%sEOF\n", + aa.substring(5).val, aa.val); + + aa = "bbb Some Value Some 2345"; + strcpy(tmpaa, "Some"); + egg = "Some"; + fprintf(stdout, "20) aa.replace('S', 'V') %s :%sEOF\n", + aa.replace('S', 'V').val, aa.val); + fprintf(stdout, "20) aa.replace(Som, Vzz) %s :%sEOF\n", + aa.replace("Som", "Vzz").val, aa.val); + + aa = " bbb Some Value Some 2345 "; + fprintf(stdout, "21) aa.trim() %s val :%sEOF\n", + aa.trim().val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "21) aa.concat() %s val :%sEOF\n", + aa.concat("add one").val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "21) aa.append() %s val :%sEOF\n", + aa.append("add append").val, aa.val); + + aa = "bbb Some Value Some 2345"; + egg = "jjjj"; + fprintf(stdout, "21) aa.insert(5, egg) %s val :%sEOF\n", + aa.insert(5, egg).val, aa.val); + fprintf(stdout, "21) aa.insert(5, ch) %s val :%sEOF\n", + aa.insert(5, 'M').val, aa.val); + + aa = "12345678"; + fprintf(stdout, "46) aa.reverse()=%s aa.val is :%sEOF\n", aa.reverse().val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "21) aa.deleteCharAt(4) %s val :%sEOF\n", + aa.deleteCharAt(4).val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "22) aa.deleteStr(3,5) %s val :%sEOF\n", + aa.deleteStr(3,5).val, aa.val); + + // ***************** end Java like functions ******************** + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "23) aa.str_tr(bomekk, BOME) %s val :%sEOF\n", + aa.tr("bomekk", "BOME").val, aa.val); + + aa = "bbb Some Value Some 2345"; + aa = "$1,934 100%.234"; + fprintf(stdout, "24) aa.compress() %s val :%sEOF\n", + aa.compress("$,%").val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "25) aa.xrange('a', 'j') %s val :%sEOF\n", + aa.xrange('a', 'j').val, aa.val); + fprintf(stdout, "25) aa.xrange('1', '8') %s val :%sEOF\n", + aa.xrange('1', '8').val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "26) aa.center(15) %s val :%sEOF\n", + aa.center(15).val, aa.val); + fprintf(stdout, "26) aa.center(15, '*') %s val :%sEOF\n", + aa.center(15, '*').val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "27) aa.space(3) %s val :%sEOF\n", + aa.space(3).val, aa.val); + + aa = " Some Value Some 2345"; + fprintf(stdout, "28) aa.left() %s val :%sEOF\n", + aa.left().val, aa.val); + fprintf(stdout, "28) aa.left(18) %s val :%sEOF\n", + aa.left(18).val, aa.val); + + aa = " 2345 "; + fprintf(stdout, "29) aa.right():%s val :%sEOF\n", + aa.right().val, aa.val); + fprintf(stdout, "29) aa.right(5):%s val :%sEOF\n", + aa.right(5).val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "30) aa.overlay(12345678, 4, 10, *):%s val :%sEOF\n", + aa.overlay("12345678", 4, 10, '*').val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "31) aa.at(Som) %s :%sEOF\n", + aa.at("Som").val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "32) aa.before(Som) %s :%sEOF\n", + aa.before("Skkkom").val, aa.val); + + aa = "bbb Some Value Some 2345"; + fprintf(stdout, "33) aa.after(Som) %s :%sEOF\n", + aa.after("Som").val, aa.val); + + aa = " bb some value "; + aa.ltrim(true); + fprintf(stdout, "34) aa.val is :%sEOF\n", aa.val); + + aa = " bb some value "; + aa.rtrim(true); + fprintf(stdout, "35) aa.val is :%sEOF\n", aa.val); + + aa = " bb some value "; + aa.trim(true); + fprintf(stdout, "36) aa.val is :%sEOF\n", aa.val); aa = bb; aa = aa + " testing newlines \n\n\n\n"; - aa.chop(); - fprintf(stdout, "5-1) aa.val is :%sEOF\n", aa.val); + aa.chopall(); + fprintf(stdout, "37) aa.val is :%sEOF\n", aa.val); aa = bb; aa = aa + " rhs "; - fprintf(stdout, "6) aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "38) aa.val is :%sEOF\n", aa.val); aa = bb; aa = " lhs " + aa; - fprintf(stdout, "7) aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "39) aa.val is :%sEOF\n", aa.val); // Sample addition of numbers - //aa = (mychar) 9989 + "kkk" + 33 ; + //aa = (String) 9989 + "kkk" + 33 ; aa = 9999; - fprintf(stdout, "7-1) aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "40) aa.val is :%sEOF\n", aa.val); aa = bb; aa = " lhs " + aa + " rhs " + " 9989 " + " 33 "; - fprintf(stdout, "8) aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "41) aa.val is :%sEOF\n", aa.val); aa = " AA value "; aa = bb + "alkja " + " 99djd " ; - fprintf(stdout, "9) aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "42) aa.val is :%sEOF\n", aa.val); aa = " AA value "; - aa = (mychar) "alkja " + " 99djd " ; - fprintf(stdout, "10) aa.val is :%sEOF\n", aa.val); + aa = (String) "alkja " + " 99djd " ; + fprintf(stdout, "43) aa.val is :%sEOF\n", aa.val); aa = " AA value "; - aa += (mychar) " al dev test kkk... " + " al2 slkj" + " al3333 "; - fprintf(stdout, "11) aa.val is :%sEOF\n", aa.val); + aa += (String) " al dev test kkk... " + " al2 slkj" + " al3333 "; + fprintf(stdout, "44) aa.val is :%sEOF\n", aa.val); aa = " AA value "; aa = aa + " add aa " + aa + aa + aa + " 1111 " + " 2222 " + aa + aa + aa + " 3333 "; - fprintf(stdout, "12) aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "45) aa.val is :%sEOF\n", aa.val); aa = "12345678"; - aa.reverse(); - fprintf(stdout, "13) aa.val is :%sEOF\n", aa.val); + aa.reverse(true); + fprintf(stdout, "46) aa.val is :%sEOF\n", aa.val); aa = " AA value "; aa = aa + " add aa " + aa + 1111 +" "+ 2222 + " " + 3.344 + aa; - fprintf(stdout, "14) aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "47) aa.val is :%sEOF\n", aa.val); aa.roundd(123456.0123456789012345, 13); - fprintf(stdout, "15) double aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "48) double aa.val is :%sEOF\n", aa.val); aa.roundf(123456.0123456789, 13); - fprintf(stdout, "16) float aa.val is :%sEOF\n", aa.val); + fprintf(stdout, "49) float aa.val is :%sEOF\n", aa.val); // Test equal to operators aa = " AA value "; - mychar cc(" AA value "); + String cc(" AA value "); if (aa == cc) - fprintf(stdout, "\naa=%s and cc=%s are equal!!\n", aa.val, cc.val); + fprintf(stdout, "50)aa=%s and cc=%s are equal!!\n", aa.val, cc.val); else - fprintf(stdout, "\naa=%s and cc=%s are NOT equal!!\n", aa.val, cc.val); + fprintf(stdout, "51)aa=%s and cc=%s are NOT equal!!\n", aa.val, cc.val); cc = "CC"; if (aa == cc) - fprintf(stdout, "\naa=%s and cc=%s are equal!!\n", aa.val, cc.val); + fprintf(stdout, "52)aa=%s and cc=%s are equal!!\n", aa.val, cc.val); else - fprintf(stdout, "\naa=%s and cc=%s are NOT equal!!\n", aa.val, cc.val); + fprintf(stdout, "53)aa=%s and cc=%s are NOT equal!!\n", aa.val, cc.val); if (aa == " AA value ") - fprintf(stdout, "\naa=%s and string are equal!!\n", aa.val); + fprintf(stdout, "54)aa=%s and string are equal!!\n", aa.val); else - fprintf(stdout, "\naa=%s and string are NOT equal!!\n", aa.val); + fprintf(stdout, "55)aa=%s and string are NOT equal!!\n", aa.val); if (aa == " AA valuexxx ") - fprintf(stdout, "\naa=%s and string are equal!!\n", aa.val); + fprintf(stdout, "56)aa=%s and string are equal!!\n", aa.val); else - fprintf(stdout, "\naa=%s and string are NOT equal!!\n", aa.val); + fprintf(stdout, "57)aa=%s and string are NOT equal!!\n", aa.val); + + aa = " AA bb value 12345678 "; + fprintf(stdout, "58) aa.length() is :%ldEOF\n", aa.length()); + + aa = " AA bb value 12345678 "; + fprintf(stdout, "59) aa.repeat(BA, 4).val=%s aa.val is :%sEOF\n", + aa.repeat("BA", 4).val, aa.val); + + aa = ""; + aa = "aa"; + if (aa.isnull()) + fprintf(stdout, "60) aa.isnull() result=true%sEOF\n", aa.val); + else + fprintf(stdout, "60) aa.isnull() result=false%sEOF\n", aa.val); + + aa = " some value aa"; + aa.clear(); + fprintf(stdout, "61) aa.clear() %sEOF\n", aa.val); + + aa = " abcd efg hijk lmno "; + fprintf(stdout, "62) aa.token():%s val :%sEOF\n", + aa.token().val, aa.val); + fprintf(stdout, "62) aa.token():%s val :%sEOF\n", + aa.token().val, aa.val); + fprintf(stdout, "62) aa.token():%s val :%sEOF\n", + aa.token().val, aa.val); + fprintf(stdout, "62) aa.token():%s val :%sEOF\n", + aa.token().val, aa.val); + fprintf(stdout, "62) aa.token():%s val :%sEOF\n", + aa.token().val, aa.val); + + aa = " 2345 "; + if (aa.is_integer()) // is true + fprintf(stdout, "63) aa is a integer val :%sEOF\n", aa.val); + else + fprintf(stdout, "63) aa is NOT a integer val :%sEOF\n", aa.val); + + aa = " 23.045 "; + if (aa.is_numeric()) // is true + fprintf(stdout, "64) aa is a numeric val :%sEOF\n", aa.val); + else + fprintf(stdout, "64) aa is NOT a numeric val :%sEOF\n", aa.val); + + aa = " 23045 "; + fprintf(stdout, "65) aa.int_value()=%d val :%sEOF\n", + aa.int_value(), aa.val); + + aa = " 230.45 "; + fprintf(stdout, "66) aa.double_value()=%f val :%sEOF\n", + aa.double_value(), aa.val); + + aa = " testing abcdefg"; + aa.chop(); + fprintf(stdout, "68) aa.chop() aa.val is :%sEOF\n", aa.val); + + aa = " str1 str2 string3 abcdefg joe john hardy "; + String *strlist; + int strcount = 0; + strlist = aa.explode(strcount); + for (int ii = 0; ii <= strcount; ii++) + { + fprintf(stdout, "69) strlist[%d] is :%sEOF\n", + ii, strlist[ii].val); + } + + aa = " some aa "; + cout << "\n\nPlease enter a line and hit return key : "; + aa.getline(); + fprintf(stdout, "70) aa.getline() is :%sEOF\n", aa.val); // You can use aa.val like a 'char *' variable in programs !! fprintf(stdout, "\n "); @@ -1110,7 +1473,7 @@ int main(int argc, char **argv) // Using pointers on 'char *' val ... fprintf(stdout, "\n "); - // Note: You must use a temporary local variable and assign the + // You must use a temporary local variable and assign the // pointer to aa.val. If you directly use aa.val and when // aa.val is incremented with aa.val++, then aa will go // call destructor and later when aa.val is accessed that @@ -1134,26 +1497,26 @@ int main(int argc, char **argv) - Appendix B mychar.h

-You can download all programs as a single tar.gz file from . +You can download all programs as a single tar.gz file from . To get this file, in the web-browser, save this file as 'Text' type. //***************************************************************** -// Copyright policy is GNU/GPL but additional restriction is -// that you include author's name and email on all copies +// Copyright policy is GNU/GPL and it is requested that +// you include author's name and email on all copies // Author : Al Dev Email: alavoor@yahoo.com //***************************************************************** // To prevent memory leaks - a char class to manage character variables -// Always prefer to use mychar or string class +// Always prefer to use String or string class // instead of char[] or char * // -#ifndef __MYCHAR_H_ -#define __MYCHAR_H_ +#ifndef __STRING_H_ +#define __STRING_H_ //#include // do not use iostream as program becomes bulky.. //#include // for free() amd malloc() @@ -1171,29 +1534,91 @@ const short NUMBER_LENGTH = 70; // a small class with a VERY MINIMUM of functions and variables... // This class to be kept small... -class mychar +class String { public: - mychar(); - mychar(char bb[]); // needed by operator+ - mychar(int bb); // needed by operator+ - mychar(unsigned long bb); // needed by operator+ - mychar(float bb); // needed by operator+ - mychar(double bb); // needed by operator+ - mychar(const mychar & rhs); // Copy Constructor needed by operator+ - ~mychar(); + String(); + String(char bb[]); // needed by operator+ + String(int bb); // needed by operator+ + String(unsigned long bb); // needed by operator+ + String(float bb); // needed by operator+ + String(double bb); // needed by operator+ + String(const String & rhs); // Copy Constructor needed by operator+ + ~String(); char *val; + // Functions below imitate Java language's String object unsigned long length() { return strlen(val); } + char charAt(int where); + void getChars(int sourceStart, int sourceEnd, + char target[], int targetStart); + char* toCharArray(); - void ltrim(); - void rtrim(); - void trim(); - void chop(); + bool equals(String str2); // See also == operator + bool equals(char *str2); // See also == operator + bool equalsIgnoreCase(String str2); - void to_upper(); - void to_lower(); + bool regionMatches(int startIndex, String str2, + int str2StartIndex, int numChars); + bool regionMatches(bool ignoreCase, int startIndex, + String str2, int str2StartIndex, int numChars); + + String toUpperCase(); + String toLowerCase(); + + bool startsWith(String str2); + bool startsWith(char *str2); + + bool endsWith(String str2); + bool endsWith(char *str2); + + int compareTo(String str2); + int compareTo(char *str2); + int compareToIgnoreCase(String str2); + int compareToIgnoreCase(char *str2); + + int indexOf(char ch, int startIndex = 0); + int indexOf(char *str2, int startIndex = 0); + int indexOf(String str2, int startIndex = 0); + + int lastIndexOf(char ch, int startIndex = 0); + int lastIndexOf(char *str2, int startIndex = 0); + int lastIndexOf(String str2, int startIndex = 0); + + String substring(int startIndex, int endIndex = 0); + String replace(char original, char replacement); + String replace(char *original, char *replacement); + + String trim(); // See also overloaded trim() + + String concat(String str2); // See also operator + + String concat(char *str2); // See also operator + + String append(String str2) {return concat(str2);} // See also operator + + String append(char *str2) {return concat(str2);} // See also operator + + String append(int bb) {return (*this + bb);} // See also operator + + String append(unsigned long bb) {return (*this + bb);} // See also operator + + String append(float bb) {return (*this + bb);} // See also operator + + + String insert(int index, String str2); + String insert(int index, char ch); + + String reverse(); // See also overloaded reverse() + String deleteCharAt(int loc); + String deleteStr(int startIndex, int endIndex); // Java's "delete()" + // ---- End of Java like String object functions ----- + + // These are additional functions which are not + // available in Java's String object... + void reverse(bool dummy); // dummy to get different signature + void trim(bool dummy); // dummy to get different signature + String ltrim(); + void ltrim(bool dummy); // dummy to get different signature + String rtrim(); + void rtrim(bool dummy); // dummy to get different signature + + void chopall(char ch='\n'); // removes trailing character 'ch' + void chop(); // removes one trailing character void roundf(float input_val, short precision); void decompose_float(long *integral, long *fraction); @@ -1201,49 +1626,70 @@ class mychar void roundd(double input_val, short precision); void decompose_double(long *integral, long *fraction); - long pos(char substr[], unsigned long start); - - void explode(char *seperator); + void explode(char *seperator); // see also token() and overloaded explode() + String *explode(int & strcount, char seperator = ' '); // see also token() void implode(char *glue); void join(char *glue); - void repeat(char *input, unsigned int multiplier); - void reverse(); - void replace(char *needle, char *str); - void str_tr(char *from, char *to); - void center(int length, char padchar = ' '); - void space(int number = 0, char padchar = ' '); - void xrange(char start, char end); - void compress(char *list); - void delstr(int start, int length); - void insert(char *newstr, int start = 0, int length = 0, char padchar = ' '); - void left(int length = 0, char padchar = ' '); - void right(int length = 0, char padchar = ' '); - void overlay(char *newstr, int start = 0, int length = 0, char padchar = ' '); - mychar substr(int start, int length = 0); + String repeat(char *input, unsigned int multiplier); + String tr(char *from, char *to); // translate characters + String center(int padlength, char padchar = ' '); + String space(int number = 0, char padchar = ' '); + String xrange(char start, char end); + String compress(char *list = " "); + String insert(char *newstr, int start = 0, int length = 0, char padchar = ' '); + String left(int slength = 0, char padchar = ' '); + String right(int slength = 0, char padchar = ' '); + String overlay(char *newstr, int start = 0, int slength = 0, char padchar = ' '); - mychar at(char *regx); // matches first match of regx - mychar before(char *regx); // returns string before regx - mychar after(char *regx); // returns string after regx + String at(char *regx); // matches first match of regx + String before(char *regx); // returns string before regx + String after(char *regx); // returns string after regx + String mid(int startIndex = 0, int length = 0); - bool isnull(); - void clear(); + bool isnull(); + void clear(); + bool is_integer(); + bool is_numeric(); + int int_value(); + double double_value(); + String token(char seperator = ' '); // see also explode() + String crypt(char *original, char *salt); + String getline(FILE *infp = stdin); + + /////////////////////////////////////////////// + // List of duplicate function names + /////////////////////////////////////////////// + // bool find(); // Use regionMatches() + // bool search(); // Use regionMatches() + // bool matches(); // Use regionMatches() + // int rindex(String str2, int startIndex = 0); Use lastIndexOf() + // String blanks(int slength); // Use repeat() + // String prepend(String str2); // Use + operator. See also append() + // String split(char seperator = ' '); // Use token() + bool contains(char *str2, int startIndex = 0); // use indexOf() + // void empty(); Use clear() + // void vacuum(); Use clear() + // bool is_float(); Use is_numeric(); + // bool is_decimal(); Use is_numeric(); + // double float_value(); Use double_value(); + // double numeric_value(); Use double_value(); // All Operators ... - mychar operator+ (const mychar & rhs); - friend mychar operator+ (const mychar & lhs, const mychar & rhs); + String operator+ (const String & rhs); + friend String operator+ (const String & lhs, const String & rhs); - mychar& operator+= (const mychar & rhs); // using reference will be faster - mychar& operator= (const mychar & rhs); // using reference will be faster - bool operator== (const mychar & rhs); // using reference will be faster + String& operator+= (const String & rhs); // using reference will be faster + String& operator= (const String & rhs); // using reference will be faster + bool operator== (const String & rhs); // using reference will be faster bool operator== (const char *rhs); - bool operator!= (const mychar & rhs); + bool operator!= (const String & rhs); bool operator!= (const char *rhs); - static list explodeH; // list head + static list explodeH; // list head private: - //static mychar *global_mychar; // for use in add operator - //inline void free_glob(mychar **aa); + //static String *global_String; // for use in add operator + //inline void free_glob(String **aa); void str_cpy(char bb[]); void str_cpy(int bb); // itoa void str_cpy(unsigned long bb); @@ -1254,12 +1700,14 @@ class mychar void str_cat(unsigned long bb); void str_cat(float bb); - bool equalto(const mychar & rhs, bool type = false); + bool equalto(const String & rhs, bool type = false); bool equalto(const char *rhs, bool type = false); + String *pString; // temporary pointer for internal use.. + inline void allocpString(); }; -// Global variables are defined in mychar.cpp +// Global variables are defined in String.cpp -#endif // __MYCHAR_H_ +#endif // __STRING_H_ - Appendix C mychar.cpp

-You can download all programs as a single tar.gz file from . +You can download all programs as a single tar.gz file from . To get this file, in the web-browser, save this file as 'Text' type. //***************************************************************** -// Copyright policy is GNU/GPL but additional restriction is -// that you include author's name and email on all copies +// Copyright policy is GNU/GPL and it is requested that +// you include author's name and email on all copies // Author : Al Dev Email: alavoor@yahoo.com //***************************************************************** // Use string class or this class -// + // To prevent memory leaks - a char class to manage character variables // Always prefer to use string class // instead of char[] or char * // // To compile and test this program do - -// g++ mychar.cpp +// g++ String.cpp -#include "mychar.h" +#include "String.h" // Global variables .... -//mychar *mychar::global_mychar = NULL; // global var -list mychar::explodeH; +//String *String::global_String = NULL; // global var +list String::explodeH; -mychar::mychar() +String::String() { debug_("In cstr()", "ok"); val = (char *) my_malloc(sizeof(char)* INITIAL_SIZE); + + pString = NULL; } -mychar::mychar(char *bb) +String::String(char *bb) { unsigned long tmpii = strlen(bb); val = (char *) my_malloc(sizeof(char)* tmpii); @@ -1317,34 +1767,44 @@ mychar::mychar(char *bb) //fprintf(stderr, "\nAddress of val=%x\n", & val); //fprintf(stderr, "\nAddress of this-pointer=%x\n", this); #endif // DEBUG + + pString = NULL; } -mychar::mychar(int bb) +String::String(int bb) { val = (char *) my_malloc(NUMBER_LENGTH); // integers 70 digits max sprintf(val, "%d", bb); + + pString = NULL; } -mychar::mychar(unsigned long bb) +String::String(unsigned long bb) { val = (char *) my_malloc(NUMBER_LENGTH); // long 70 digits max sprintf(val, "%lu", bb); + + pString = NULL; } -mychar::mychar(float bb) +String::String(float bb) { val = (char *) my_malloc(NUMBER_LENGTH); // float 70 digits max sprintf(val, "%f", bb); + + pString = NULL; } -mychar::mychar(double bb) +String::String(double bb) { val = (char *) my_malloc(NUMBER_LENGTH); // double 70 digits max sprintf(val, "%f", bb); + + pString = NULL; } // Copy Constructor needed by operator + -mychar::mychar(const mychar & rhs) +String::String(const String & rhs) { // Do a deep-copy instead of compiler's default shallow copy copy-cstr debug_("In copy-cstr()", "ok"); @@ -1352,9 +1812,11 @@ mychar::mychar(const mychar & rhs) val = (char *) my_malloc(sizeof(char)* tmpii); strncpy(val, rhs.val, tmpii); val[tmpii] = '\0'; + + pString = NULL; } -mychar::~mychar() +String::~String() { //debug_("In dstr val", val); #ifdef DEBUG @@ -1364,12 +1826,23 @@ mychar::~mychar() my_free(val); //delete [] val; val = NULL; + + delete pString; pString = NULL; +} + +inline void String::allocpString() +{ + // pString will be deleted in destructor + if (!pString) // if (pString == NULL) + pString = new String(this->val); + else + *pString = this->val; } // MUST use pointer-to-pointer **aa, otherwise the argument // is NOT freed !! /* -inline void mychar::free_glob(mychar **aa) +inline void String::free_glob(String **aa) { debug_("called free_glob()", "ok" ); if (*aa != NULL) // (*aa != NULL) @@ -1386,27 +1859,731 @@ inline void mychar::free_glob(mychar **aa) } */ +// Imitating Java's charAt string function... +char String::charAt(int where) +{ + if (where <= (int) length() ) + return (val[where]); + else + return 0; +} + +// Imitate Java's getChars function... +// The sourceStart specifies the index of the beginning of the substring +// and sourceEnd specifies an index that is one past the end of desired +// substring. Thus the substring contains characters from sourceStart +// through (sourceEnd - 1). The array that will receive the characters +// is specified by target. The index within target at which the substring +// will be copied is passed in targetStart. Care must be taken to assure +// that the target array is large enough to hold the number of characters +// in the specified substring. +// For e.g. getChars(3, 6, aa, 0) on "ABCDEFGHIJK" gives aa ="DEF" +void String::getChars(int sourceStart, int sourceEnd, char target[], int targetStart) +{ + if (sourceEnd >= sourceStart) + { + if (sourceEnd > (int) (length() - 1) ) + sourceEnd = (int) length() - 1; + strncpy(& target[targetStart], & val[sourceStart], sourceEnd - sourceStart); + target[targetStart + (sourceEnd - sourceStart)] = 0; + } + else + { + cerr << "\nSourceEnd is greater than SourceStart!!\n" << endl; + } +} + +// Imitate Java's getChars string function... +// Returns array of characters for the entire string +char* String::toCharArray() +{ + return (val); +} + +// Imitate Java's equals string function... +bool String::equals(String str2) // See also == operator +{ + return ( equalto(str2.val)); +} + +// Imitate Java's equals string function... +bool String::equals(char *str2) // See also == operator +{ + return ( equalto(str2)); +} + +// Imitate Java's equalsIgnoreCase string function... +bool String::equalsIgnoreCase(String str2) +{ + String aa, bb; + aa = this->toLowerCase(); + bb = str2.toLowerCase(); + return ( aa.equalto(bb.val) ); +} + +// Imitate Java's regionMatches string function... +// The startIndex specifies the index at which the region begins within +// the invoking String object. The string being compared is str2. The +// index at which comparison will start within str2 is specified by +// str2Index. The length of the substring being compared is numChars. +bool String::regionMatches(int startIndex, String str2, int str2StartIndex, int numChars) +{ + if (startIndex > (int) length()) + { + cerr << "\nstartIndex greater than length of string\n" << endl; + return false; + } + if (str2StartIndex > (int) str2.length()) + { + cerr << "\nstr2StartIndex of string2 greater than length of string\n" << endl; + return false; + } + if (strncmp(& this->val[startIndex], & str2.val[str2StartIndex], numChars) == 0) + return true; + else + return false; +} + +// Imitate Java's regionMatches string function... +// This is overloaded function of regionMatches +// If ignoreCase is true, the case of the characters is ignored, otherwise +// case is significant (i.e. if ignoreCase is true then ignore the +// case and compare) +// The startIndex specifies the index at which the region begins within +// the invoking String object. The string being compared is str2. The +// index at which comparison will start within str2 is specified by +// str2Index. The length of the substring being compared is numChars. +bool String::regionMatches(bool ignoreCase, int startIndex, String str2, int str2StartIndex, int numChars) +{ + if (ignoreCase) // if (ignoreCase == true) + { + if (startIndex > (int) length()) + { + cerr << "\nstartIndex greater than length of string\n" << endl; + return false; + } + if (str2StartIndex > (int) str2.length()) + { + cerr << "\nstr2StartIndex of string2 greater than length of string\n" << endl; + return false; + } + String string1, string2; + string1 = this->toLowerCase(); + string2 = str2.toLowerCase(); + if (strncmp(& string1.val[startIndex], & string2.val[str2StartIndex], numChars) == 0) + return true; + else + return false; + } + else + { + return regionMatches(startIndex, str2, str2StartIndex, numChars); + } +} + +// Imitate Java's toLowerCase string function... +// String ss("sometest"); +// String egg = ss.toLowerCase(); +String String::toLowerCase() +{ + allocpString(); + + for (long tmpii = strlen(pString->val); tmpii >= 0; tmpii--) + { + pString->val[tmpii] = tolower(pString->val[tmpii]); + } + return *pString; // return the object now +} + +// Imitate Java's toUpperCase string function... +// String ss("sometest"); +// String egg = ss.toUpperCase(); +String String::toUpperCase() +{ + allocpString(); + + for (long tmpii = strlen(pString->val); tmpii >= 0; tmpii--) + { + pString->val[tmpii] = toupper(pString->val[tmpii]); + } + return *pString; // return the object now +} + +// Imitate Java's startsWith string function... +bool String::startsWith(String str2) +{ + if (!strncmp(this->val, str2.val, str2.length() )) // if (strncmp() == 0) + return true; + else + return false; +} + +// Imitate Java's startsWith string function... +// overloaded function +bool String::startsWith(char *str2) +{ + int lenstr2 = strlen(str2); + if (!strncmp(this->val, str2, lenstr2)) // if (strncmp() == 0) + return true; + else + return false; +} + +// Imitate Java's endsWith string function... +bool String::endsWith(String str2) +{ + // string length of str2 should be less than current string + if (str2.length() > length()) + return false; + + if (!strncmp(& this->val[length() - str2.length()], str2.val, str2.length() )) // if (strncmp() == 0) + return true; + else + return false; +} + +// Imitate Java's endsWith string function... +bool String::endsWith(char *str2) +{ + // string length of str2 should be less than current string + if (strlen(str2) > length()) + return false; + + if (!strncmp(& this->val[length() - strlen(str2)], str2, strlen(str2) ) ) // if (strncmp() == 0) + return true; + else + return false; +} + +// Imitate Java's compareTo string function... +// For sorting applications, you need to know which is less than, equal to +// or greater than the next. +// A string is less than another if it comes before the other in dictionary +// order. A string is greater than another if it comes after the other in +// dictionary order. +// Less than zero --> The invoking string is less than str2 +// Greater than zero --> The invoking string is greater than str2 +// Zero --> The two strings are equal. +int String::compareTo(String str2) +{ + int flag = 0; + // Compare letters in string to each letter in str2 + for (int tmpii = 0, tmpjj = length(), tmpkk = str2.length(); tmpii < tmpjj; tmpii++) + { + if (tmpii > tmpkk) + break; + if (val[tmpii] == str2.val[tmpii]) + flag = 0; + else + if (val[tmpii] > str2.val[tmpii]) + { + flag = 1; + break; + } + else // if (val[tmpii] < str2.val[tmpii]) + { + flag = -1; + break; + } + } + return flag; +} + +// Imitate Java's compareTo string function... +// Overloaded function of compareTo +int String::compareTo(char *str2) +{ + int flag = 0; + // Compare letters in string to each letter in str2 + for (int tmpii = 0, tmpjj = length(), tmpkk = strlen(str2); tmpii < tmpjj; tmpii++) + { + if (tmpii > tmpkk) + break; + if (val[tmpii] == str2[tmpii]) + flag = 0; + else + if (val[tmpii] > str2[tmpii]) + { + flag = 1; + break; + } + else // if (val[tmpii] < str2[tmpii]) + { + flag = -1; + break; + } + } + return flag; +} + +// Imitate Java's compareToIgnoreCase string function... +int String::compareToIgnoreCase(String str2) +{ + String tmpaa = this->toLowerCase(), + tmpbb = str2.toLowerCase(); + + return tmpaa.compareTo(tmpbb); +} + +// Imitate Java's compareToIgnoreCase string function... +// Overloaded function +int String::compareToIgnoreCase(char *str2) +{ + String tmpaa = this->toLowerCase(), + tmpcc(str2), tmpbb = tmpcc.toLowerCase(); + + return tmpaa.compareTo(tmpbb); +} + +// Imitate Java's indexOf string function... +// Searches for the first occurence of a character or string +// Return the index at which the character or substring was +// found, or -1 on failure. +int String::indexOf(char ch, int startIndex = 0) +{ + int ii = startIndex; + for (; ii < (int) length(); ii++) + { + if (val[ii] == ch) + break; + } + if (ii == (int) length()) + return -1; + return ii; +} + +// Imitate Java's indexOf string function... +// Overloaded function +int String::indexOf(char *str2, int startIndex = 0) +{ + char * tok; + long res = -1; + + if ( !isnull() && (startIndex < (int) strlen(val) ) ) + { + tok = strstr(val + startIndex, str2); + if (tok == NULL) + res = -1; + else + res = (int) (tok - val); + } + return res; +} + +// Imitate Java's indexOf string function... +// Overloaded function +int String::indexOf(String str2, int startIndex = 0) +{ + char * tok; + long res = -1; + + if ( !isnull() && (startIndex < (int) strlen(val) ) ) + { + tok = strstr(val + startIndex, str2.val); + if (tok == NULL) + res = -1; + else + res = (int) (tok - val); + } + return res; +} + +// Imitate Java's lastIndexOf string function... +// Searches for the last occurence of a character or string +// Return the index at which the character or substring was +// found, or -1 on failure. +int String::lastIndexOf(char ch, int startIndex = 0) +{ + int ii; + + // Begin search from the last character of string + if (!startIndex) // if (startIndex == 0) + ii = length(); + else + ii = startIndex; + for (; ii > -1; ii--) + { + if (val[ii] == ch) + break; + } + if (!ii && val[ii] != ch) // if (ii == 0) + return -1; + return ii; +} + +// Imitate Java's lastIndexOf string function... +// Overloaded function +int String::lastIndexOf(char *str2, int startIndex = 0) +{ + char *tok = NULL; + int res = -1; + + register char *tmpaa = strdup(val); // malloc here + if (!tmpaa) // tmpaa == NULL + { + cerr << "\nMemory alloc failed in strdup in lastIndexOf()\n" << endl; + exit(-1); + } + + if (!startIndex) // if (startIndex == 0) + startIndex = strlen(val); + else + tmpaa[startIndex+1] = 0; + + for (int ii = 0; ii <= startIndex; ii++) + { + tok = strstr(& tmpaa[ii], str2); + if (tok == NULL) + break; + else + { + res = (int) (tok - tmpaa); + debug_("res", res); + ii = res; // jump to where it matched (+1 in for loop) + } + } + free(tmpaa); + debug_("res", res); + debug_("indexOf", & val[res]); + + return res; +} + +// Imitate Java's lastIndexOf string function... +// Overloaded function +int String::lastIndexOf(String str2, int startIndex = 0) +{ + char *tok = NULL; + int res = -1; + + register char *tmpaa = strdup(val); // malloc here + if (!tmpaa) // tmpaa == NULL + { + cerr << "\nMemory alloc failed in strdup in lastIndexOf()\n" << endl; + exit(-1); + } + + if (!startIndex) // if (startIndex == 0) + startIndex = strlen(val); + else + tmpaa[startIndex+1] = 0; + + for (int ii = 0; ii <= startIndex; ii++) + { + tok = strstr(& tmpaa[ii], str2.val); + if (tok == NULL) + break; + else + { + res = (int) (tok - tmpaa); + debug_("res", res); + ii = res; // jump to where it matched (+1 in for loop) + } + } + free(tmpaa); + debug_("res", res); + debug_("indexOf", & val[res]); + + return res; +} + +// Imitate Java's substring string function... +// The startIndex specifies the beginning index, and endIndex specifies +// the stopping point. The string returned contains all the characters +// from the beginning index, up to, but not including, the ending index. +String String::substring(int startIndex, int endIndex = 0) +{ + if (!endIndex) // endIndex == 0 + return(String(& val[startIndex] ) ); + else + { + String tmp = String(& val[startIndex] ); + tmp.val[endIndex -1] = 0; + return(tmp); + } +} + +// Imitate Java's concat string function... +String String::concat(String str2) +{ + return (*this + str2); +} + +// Imitate Java's concat string function... +// overloaded function +String String::concat(char *str2) +{ + return (*this + str2); +} + +// Imitate Java's replace string function... +// Replace all occurences of string 'original' with +// 'replacement' in 'val' +String String::replace(char original, char replacement) +{ + // For example - + // replace('A', 'B') on val = "some AAA and AAACC" + // reurns val = "some BBB and BBBCC" + //String *tmpstr = new String(val); Use default copy cstr + String tmpstr(val); + for (int ii = 0, len = length(); ii < len; ii++) + { + if (tmpstr.val[ii] == original) + tmpstr.val[ii] = replacement; + } + return tmpstr; // this will use copy constructor to make a default copy +} + +// Imitate Java's replace string function... +// overloaded function +// Replace all occurences of string 'original' with +// 'replacement' in 'val' +String String::replace(char *original, char *replacement) +{ + char *tok = NULL, *bb; + register char *aa = strdup(val); + int lenrepl = strlen(replacement); + + // Allocate space for bb + { // local scope + int tmpii = 0; + for (int ii = 0; ;ii++) + { + tok = strstr(& aa[ii], original); + if (tok == NULL) + break; + else + { + ii = ii + (int) (tok -aa); + tmpii++; + } + } + if (!tmpii) // tmpii == 0, no match of 'original' found + return (String(val)); // return original string + tmpii = length() + (tmpii * lenrepl) + 20; + debug_("strstr tmpii", tmpii ); + bb = (char *) malloc(tmpii); + memset(bb, 0, tmpii); + } + + for (int res = -1; ;) + { + debug_("aa", aa); + tok = strstr(aa, original); + if (tok == NULL) + { + strcat(bb, aa); + break; + } + else + { + res = (int) (tok - aa); + strncat(bb, aa, res); + strcat(bb, replacement); + //bb[strlen(bb)] = 0; + debug_("res", res ); + debug_("bb", bb ); + strcpy(aa, & aa[res+lenrepl]); + } + } + debug_("bb", bb ); + free(aa); + String tmpstr(bb); + free(bb); + return tmpstr; +} +/* +another method of doing replace function but slow.. +String String::replace(char *original, char *replacement) +{ + // For example - + // replace("AAA", "BB") on val = "some AAA and AAACC" + // reurns val = "some BB and BBCC" + String bb(this->before(original).val); + if (bb.length() == 0) + return String(val); // return original string + bb += replacement; + + String tmpaa(this->val), cc, dd; + for (;;) + { + cc = tmpaa.after(original).val; + debug_("cc", cc.val ); + if (!cc.length()) // if (cc.length() == 0) + break; + + dd = cc.before(original).val; + if (dd.length() == 0) + { + bb += cc; + break; + } + else + { + bb += dd; + bb += replacement; + } + tmpaa = cc; + } + debug_("bb.val", bb.val ); + return bb; +} +*/ + +// Imitate Java's trim string function... +String String::trim() +{ + //String *tmpstr = new String(val); + String tmpstr(val); + tmpstr.rtrim(true); + tmpstr.ltrim(true); + debug_("tmpstr.val", tmpstr.val); + return tmpstr; // this will use copy constructor to make a default copy +} + +// Imitate Java's insert string function... +String String::insert(int index, String str2) +{ + String tmpstr(this->insert(str2.val, index).val); + debug_("tmpstr.val", tmpstr.val); + return tmpstr; +} + +// Imitate Java's insert string function... +String String::insert(int index, char ch) +{ + char aa[2]; + aa[0] = ch; + aa[1] = 0; + String tmpstr(this->insert(aa, index).val); + debug_("tmpstr.val", tmpstr.val); + return tmpstr; +} + +// Imitate Java's deleteCharAt string function... +String String::deleteCharAt(int loc) +{ + char *tmpaa = strdup(val); // malloc here + strcpy(& tmpaa[loc], & tmpaa[loc+1]); + String tmpstr(tmpaa); + free(tmpaa); + return tmpstr; +} + +// Imitate Java's delete string function... +// Note: -->Java name is "delete()", cannot use reserved name delete() in C++ +// The startIndex specifies the index of the first character to remove, +// and endIndex specifies an index one past the last character to remove. +// Thus, the substring deleted runs from startIndex to (endIndex - 1) +String String::deleteStr(int startIndex, int endIndex) +{ + // For example - + // deleteStr(3,3) on val = 'pokemon' returns 'poon' + char *tmpaa = strdup(val); // malloc here + strcpy(& tmpaa[startIndex], & tmpaa[endIndex]); + String tmpstr(tmpaa); + free(tmpaa); + return tmpstr; +} + +// Imitate Java's reverse string function... +String String::reverse() +{ + // For example - + // reverse() on "12345" returns "54321" + String tmpstr(val); + char aa; + unsigned long tot_len = length(); + unsigned long midpoint = tot_len / 2; + for (unsigned long tmpjj = 0; tmpjj < midpoint; tmpjj++) + { + aa = tmpstr.val[tmpjj]; // temporary storage var + tmpstr.val[tmpjj] = tmpstr.val[tot_len - tmpjj - 1]; // swap the values + tmpstr.val[tot_len - tmpjj - 1] = aa; // swap the values + } + return tmpstr; +} + +// ---- End of Java like String object functions ----- + +// Returns string before regx. Matches first occurence of regx +String String::at(char *regx) +{ + char *tok = NULL; + tok = strstr(val, regx); + if (tok == NULL) + return(String("")); + else + { + int res = (int) (tok - val); + char *lefttok = strdup(val); + memset(lefttok, 0, length()); + strcpy(lefttok, & val[res]); + String tmpstr(lefttok); + free(lefttok); + return(tmpstr); + } +} + +// Returns string before regx. Matches first occurence of regx +String String::before(char *regx) +{ + char *tok = NULL; + tok = strstr(val, regx); + if (tok == NULL) + return(String("")); + else + { + int res = (int) (tok - val); + char *lefttok = strdup(val); + lefttok[res] = 0; + String tmpstr(lefttok); + free(lefttok); + return(tmpstr); + } +} + +// Returns string after regx. Matches first occurence of regx +String String::after(char *regx) +{ + char *tok = NULL; + tok = strstr(val, regx); + if (tok == NULL) + return(String("")); + else + { + int res = (int) (tok - val); + char *lefttok = strdup(val); + memset(lefttok, 0, length()); + strcpy(lefttok, & val[res + strlen(regx)]); + String tmpstr(lefttok); + free(lefttok); + return(tmpstr); + } +} + // Explodes the string and returns the list in // the list-head pointer explodeH -void mychar::explode(char *seperator) +// See also token() +void String::explode(char *seperator) { char *aa = NULL, *bb = NULL; aa = (char *) my_malloc(length()); for (bb = strtok(aa, seperator); bb != NULL; bb = strtok(NULL, seperator) ) { - mychar *tmp = new mychar(bb); - mychar::explodeH.insert(mychar::explodeH.end(), *tmp); + String *tmp = new String(bb); + String::explodeH.insert(String::explodeH.end(), *tmp); } my_free(aa); - list::iterator iter1; // see file include/g++/stl_list.h + list::iterator iter1; // see file include/g++/stl_list.h debug_("Before checking explode..", "ok"); - if (mychar::explodeH.empty() == true ) + if (String::explodeH.empty() == true ) { debug_("List is empty!!", "ok"); } - for (iter1 = mychar::explodeH.begin(); iter1 != mychar::explodeH.end(); iter1++) + for (iter1 = String::explodeH.begin(); iter1 != String::explodeH.end(); iter1++) { if (iter1 == NULL) { @@ -1417,39 +2594,69 @@ void mychar::explode(char *seperator) } } +// Overloaded function of explode(). This will return an +// array of strings and total number in strcount reference +// variable. +// See also token() +String *String::explode(int & strcount, char seperator = ' ') +{ + String aa(val); + aa.trim(true); + strcount = 0; + for (int ii = 0, jj = aa.length(); ii < jj; ii++) + { + if (aa.val[ii] == seperator) + strcount++; + } + + String *tmpstr = new String[strcount+1]; + if (!strcount) // strcount == 0 + tmpstr[0] = aa.val; + else + { + for (int ii = 0; ii <= strcount; ii++) + tmpstr[ii] = aa.token(); + } + return tmpstr; +} + // Implodes the strings in the list-head -// pointer explodeH and returns the mychar class -void mychar::implode(char *glue) +// pointer explodeH and returns the String class +void String::implode(char *glue) { } // Joins the strings in the list-head -// pointer explodeH and returns the mychar class -void mychar::join(char *glue) +// pointer explodeH and returns the String class +void String::join(char *glue) { implode(glue); } // Repeat the input string n times -void mychar::repeat(char *input, unsigned int multiplier) +String String::repeat(char *input, unsigned int multiplier) { // For example - - // repeat("1", 4) returns "1111" + // repeat("k", 4) returns "kkkk" if (!input) // input == NULL { - val[0] = 0; - return; + return (String("")); } - val = (char *) my_malloc(strlen(input) * multiplier); + char *aa = (char *) my_malloc(strlen(input) * multiplier); for (unsigned int tmpii = 0; tmpii < multiplier; tmpii++) { - strcat(val, input); + strcat(aa, input); } + String tmpstr(aa); + my_free(aa); + return tmpstr; } // Reverse the string -void mychar::reverse() +// Overloaded version of reverse(). This will directly +// change the object. +void String::reverse(bool dummy) { // For example - // reverse() on "12345" returns "54321" @@ -1464,28 +2671,56 @@ void mychar::reverse() } } -// Replace all occurences of string 'needle' with 'str' in the haystack 'val' -void mychar::replace(char *needle, char *str) -{ - // For example - - // replace("AAA", "BB") on val = "some AAA and AAACC" - // reurns val = "some BB and BBCC" -} - // Translate certain chars -void mychar::str_tr(char *from, char *to) +// For e.g ("abcd", "ABC") translates all occurences of each +// character in 'from' to corresponding character in 'to' +String String::tr(char *from, char *to) { - // For e.g ("abcd", "ABC") translates all occurences of each - // character in 'from' to corresponding character in 'to' + int lenfrom = strlen(from), lento = strlen(to); + if (lento > lenfrom) + lento = lenfrom; // set it to least + else + if (lento < lenfrom) + lenfrom = lento; // set it to least + debug_("lento", lento); + + register char *aa = strdup(val); + for (int ii = 0, jj = length(); ii < jj; ii++) // for every char in val + { + for (int kk = 0; kk < lento; kk++) // for every char in "from" string + { + if (aa[ii] == from[kk]) + aa[ii] = to[kk]; + } + } + String tmpstr(aa); + free(aa); + return tmpstr; } // Center the text -void center(int length, char padchar = ' ') +String String::center(int padlength, char padchar = ' ') { // For example - // center(10, '*') on val="aa" returns "****aa****" // center(10) on val="aa" returns " aa " - // The result is a string of 'length' characters with val centered in it. + // The result is a string of 'padlength' characters with val centered in it. + int tmpii = sizeof(char) * (padlength + length() + 10); + char *aa = (char *) malloc(tmpii); + memset(aa, 0, tmpii); + + for (int jj = 0, kk = (int) padlength/2; jj < kk; jj++) + { + aa[jj] = padchar; + } + strcat(aa, val); + for (int jj = strlen(aa), kk = jj + (int) padlength/2; jj < kk; jj++) + { + aa[jj] = padchar; + } + String tmpstr(aa); + free(aa); + return tmpstr; } // Formats the original string by placing of characters @@ -1493,7 +2728,7 @@ void center(int length, char padchar = ' ') // are always removed. If is omitted or is 0, then all spaces are // in the string are removed. The default number is 0 and // default padchar ' ' -void space(int number, char padchar = ' ') +String String::space(int number, char padchar = ' ') { // For example - // space(3) on val = "I do not know" @@ -1502,89 +2737,257 @@ void space(int number, char padchar = ' ') // will return "A_deep_black_space" // space() on val = "I know this" // will return "Iknowthis" + + debug_("this->val", this->val ); + String tmpstr = this->trim().val; + debug_("tmpstr.val", tmpstr.val ); + + // count spaces + int spacecount = 0; + for (int ii = 0, jj = tmpstr.length(); ii < jj; ii++) + { + if (tmpstr.val[ii] == ' ') + spacecount++; + } + debug_("spacecount", spacecount); + + char ee[2]; + ee[0] = padchar; + ee[1] = 0; + String bb = tmpstr.repeat(ee, spacecount); + + int tmpii = sizeof(char) * (tmpstr.length() + (number * spacecount) + 20); + char *aa = (char *) malloc(tmpii); + memset(aa, 0, tmpii); + for (int ii = 0, jj = tmpstr.length(); ii < jj; ii++) + { + if (tmpstr.val[ii] == ' ') + strcat(aa, bb.val); + else + { + ee[0] = val[ii]; + strcat(aa, ee); + } + } + tmpstr = aa; + free(aa); + return tmpstr; } // The result is string comprised of all characters between // and including and -void xrange(char start, char end) +String String::xrange(char start, char end) { // For example - // xrange('a', 'j') returns val = "abcdefghij" // xrange(1, 8) returns val = "12345678" + + if (end < start) + { + cerr << "\nThe 'end' character is less than 'start' !!" << endl; + return String(""); + } + + // Note: The 'end' is greater than 'start'!! And add +1 + int tmpii = sizeof(char) * (end - start + 11); + char *aa = (char *) malloc(tmpii); + memset(aa, 0, tmpii); + debug_("xrange tmpii", tmpii); + for (int ii = start, jj = 0; ii <= end; ii++, jj++) + { + aa[jj] = ii; + debug_("xrange aa[jj]", aa[jj] ); + } + String tmpstr(aa); + free(aa); + return tmpstr; } // Removes any characters contained in . The default character // for is a blank ' ' -void compress(char *list) +String String::compress(char *list = " ") { // For example - // compress("$,%") on val = "$1,934" returns "1934" // compress() on val = "call me alavoor vasudevan" returns "callmealavoorvasudevan" + int lenlist = strlen(list); + register char *aa = strdup(val); + for (int ii = 0, jj = length(); ii < jj; ii++) // for every char in val + { + for (int kk = 0; kk < lenlist; kk++) // for every char in "from" string + { + if (aa[ii] == list[kk]) + { + strcpy(& aa[ii], & aa[ii+1]); + } + } + } + String tmpstr(aa); + free(aa); + return tmpstr; } -// Deletes a portion of string of characters from position. -// If start is greater than the string length then string is unchanged. -void delstr(int start, int length) -{ - // For example - - // delstr(3,3) on val = 'pokemon' returns 'poon' -} - -// The in inserted into val beginning at . The will +// The is inserted into val beginning at . The will // be padded or truncated to characters. The default is // string length of newstr -void insert(char *newstr, int start = 0, int length = 0, char padchar = ' ') +String String::insert(char *newstr, int start = 0, int lengthstr = 0, char padchar = ' ') { // For example - // insert("something new", 4, 20, '*') on val = "old thing" // returns "old something new*******thing" + int tmplen = sizeof(char) * length() + strlen(newstr) + lengthstr + 10; + char *tmpaa = (char *) malloc (tmplen); + memset(tmpaa, 0, tmplen); + if (!start) // start == 0 + { + strcpy(tmpaa, newstr); + strcat(tmpaa, this->val); + } + else + { + strncpy(tmpaa, this->val, start); + strcat(tmpaa, newstr); + strcat(tmpaa, & this->val[start]); + } + + String tmpstr(tmpaa); + free(tmpaa); + return tmpstr; } // The result is string of chars madeup of leftmost chars in val. // Quick way to left justify a string. -void left(int length = 0, char padchar = ' ') +String String::left(int slength = 0, char padchar = ' ') { // For example - - // left(10) on val = "Wig" returns "Wig " - // left(4) on val = "Wighat" returns "Wigh" + // left(15) on val = "Wig" returns "Wig " + // left(4) on val = "Wighat" returns "Wigh" + // left() on val = " Wighat" returns "Wighat " + if (!slength) // slength == 0 + slength = length(); + debug_("left() slength", slength); + + int tmpii = slength + 20; + char *aa = (char *) malloc(tmpii); + memset(aa, 0, tmpii); + debug_("this->ltrim().val ", this->ltrim().val); + strcpy(aa, this->ltrim().val); + debug_("left() aa", aa ); + + int currlen = strlen(aa); + if (currlen < slength) + { + // pad the string now + char ee[2]; + ee[0] = padchar; + ee[1] = 0; + strcat(aa, this->repeat(ee, (unsigned int) (slength-currlen) ).val); + } + else + { + aa[slength] = 0; + } + + debug_("left() aa", aa ); + String tmpstr(aa); + free(aa); + return tmpstr; } // The result is string of chars madeup of rightmost chars in val. // Quick way to right justify a string. -void right(int length = 0, char padchar = ' ') +String String::right(int slength = 0, char padchar = ' ') { // For example - - // right(10) on val = "never stop to saying" returns " to saying" - // right(4) on val = "Wighat" returns "ghat" - // right(6) on val = "4.50" returns " 4.50" + // right(10) on val = "never to saying " returns " to saying" + // right(4) on val = "Wighat" returns "ghat" + // right(8) on val = "4.50" returns " 4.50" + // right() on val = " 4.50 " returns " 4.50" + + if (!slength) // slength == 0 + slength = length(); + debug_("right() slength", slength); + + int tmpii = slength + 20; + char *aa = (char *) malloc(tmpii); + memset(aa, 0, tmpii); + + int currlen = this->rtrim().length(); + debug_("right() currlen", currlen ); + if (currlen < slength) + { + // pad the string now + char ee[2]; + ee[0] = padchar; + ee[1] = 0; + strcpy(aa, this->repeat(ee, (unsigned int) (slength-currlen) ).val); + strcat(aa, this->rtrim().val); + debug_("right() aa", aa ); + } + else + { + strcpy(aa, this->rtrim().val); + strcpy(aa, & aa[currlen-slength]); + aa[slength] = 0; + } + + debug_("right() aa", aa ); + String tmpstr(aa); + free(aa); + return tmpstr; } -// The in overlayed into val beginning at . The will +// The is overlayed into val beginning at . The will // be padded or truncated to characters. The default is // string length of newstr -void overlay(char *newstr, int start = 0, int length = 0, char padchar = ' ') +String String::overlay(char *newstr, int start = 0, int slength = 0, char padchar = ' ') { // For example - // overlay("12345678", 4, 10, '*') on val = "oldthing is very bad" // returns "old12345678**ery bad" -} - -// sub string -mychar mychar::substr(int start, int length = 0) -{ - if (!length) // length == 0 - return(mychar(& val[start-1]) ); + // overlay("12345678", 4, 5, '*') on val = "oldthing is very bad" + // returns "old12345ery bad" + int len_newstr = strlen(newstr); + if (!slength) // slength == 0 + slength = len_newstr; + char *aa = (char *) malloc(slength + len_newstr + 10); + aa[0] = 0; + char ee[2]; + ee[0] = padchar; + ee[1] = 0; + if (len_newstr < slength) + { + // pad it now + strcpy(aa, newstr); + strcat(aa, this->repeat(ee, (slength-len_newstr)).val ); + } else { - mychar tmp = mychar(& val[start-1]); - tmp.val[length-1] = 0; - return(tmp); + strcpy(aa, newstr); + aa[slength] = 0; } + + // Now overlay the string. + String tmpstr(val); + + debug_("tmpstr.val", tmpstr.val); + for (int ii=start, jj=tmpstr.length(), kk=start+slength, mm=0; + ii < jj; ii++, mm++) + { + if (ii == kk) + break; + if (mm == slength) + break; + tmpstr.val[ii] = aa[mm]; + } + free(aa); + debug_("tmpstr.val", tmpstr.val); + return tmpstr; } // If string is literrally equal to .. or not equal to -// If type is false then it is == -bool mychar::equalto(const mychar & rhs, bool type = false) +// If type is false than it is == +bool String::equalto(const String & rhs, bool type = false) { if (type == false) // test for == { @@ -1613,8 +3016,8 @@ bool mychar::equalto(const mychar & rhs, bool type = false) } // If string is literrally equal to .. or not equal to -// If type is false then it is == -bool mychar::equalto(const char *rhs, bool type = false) +// If type is false than it is == +bool String::equalto(const char *rhs, bool type = false) { if (type == false) // test for == { @@ -1642,24 +3045,8 @@ bool mychar::equalto(const char *rhs, bool type = false) } } -// find position, matching substr beginning from start.. -long mychar::pos(char *substr, unsigned long start) -{ - char * tok; - long res = -1; - - if ( !isnull() && (start < strlen(val) ) ) - { - tok = strstr(val + start, substr); - if (tok == NULL) - res = -1; - else - res = (long) (tok - val); - } - return res; -} - -bool mychar::isnull() +// Synonym function is empty() +bool String::isnull() { if (val[0] == '\0') return true; @@ -1672,26 +3059,48 @@ bool mychar::isnull() } } -void mychar::clear() +// Synonym function is vacuum() +void String::clear() { val = (char *) my_realloc(val, 10); val[0] = '\0'; } -// Remove trailing new-lines -void mychar::chop() +// Remove trailing ALL given character 'ch' - see also chop() +// For example : +// val = "abcdef\n\n\n" then chopall() = "abcdef" +// val = "abcdefffff" then chopall('f') = "abcde" +void String::chopall(char ch='\n') { unsigned long tmpii = strlen(val) - 1 ; for (; tmpii >= 0; tmpii--) { - if (val[tmpii] == '\n') + if (val[tmpii] == ch) val[tmpii] = 0; else break; } } -void mychar::ltrim() +// Remove trailing character - see also chopall() +// chop() is often used to remove trailing newline character +void String::chop() +{ + val[strlen(val)-1] = 0; +} + +// Overloaded version of trim(). This will directly +// change the object. +void String::trim(bool dummy) +{ + this->rtrim(true); + this->ltrim(true); + debug_("this->val", this->val); +} + +// Overloaded version of ltrim(). This will directly +// change the object. +void String::ltrim(bool dummy) { // May cause problems in my_realloc since // location of bb will be destroyed !! @@ -1707,14 +3116,41 @@ void mychar::ltrim() if (bb != NULL && bb != val) { debug_("doing string copy", "done"); - //str_cpy(bb); // causes problems in my_realloc and bb is getting destroyed!! - strcpy(val, bb); // strcpy is ok since val space is > bb space + str_cpy(bb); // causes problems in my_realloc and bb is getting destroyed!! } else debug_("Not doing string copy", "done"); } -void mychar::rtrim() +String String::ltrim() +{ + // May cause problems in my_realloc since + // location of bb will be destroyed !! + char *aa, *bb = strdup(val); + + if (bb == NULL) // strdup failed .. + return String(""); + + for (aa = bb; isspace(*aa);) + aa++; + debug_("aa", aa); + + if (aa == NULL) + { + free(bb); + // bb = NULL; not required as you are returning immdly + return String(val); // No-change, return as it is + } + + String tmpstr(aa); + free(bb); + // bb = NULL; not required as you are returning immdly + return tmpstr; +} + +// Overloaded version of rtrim(). This will directly +// change the object. +void String::rtrim(bool dummy) { for (long tmpii = strlen(val) - 1 ; tmpii >= 0; tmpii--) { @@ -1725,25 +3161,24 @@ void mychar::rtrim() } } -void mychar::trim() +String String::rtrim() { - rtrim(); - ltrim(); -} - -void mychar::to_lower() -{ - for (long tmpii = strlen(val); tmpii >= 0; tmpii--) + String tmpstr(val); + for (long tmpii = strlen(tmpstr.val) - 1 ; tmpii >= 0; tmpii--) { - val[tmpii] = tolower(val[tmpii]); + if ( isspace(tmpstr.val[tmpii]) ) + tmpstr.val[tmpii] = '\0'; + else + break; } + return tmpstr; } // Use for rounding off fractions digits of floats // Rounds-off floats with given precision and then -// stores the result into mychar's val field +// stores the result into String's val field // Also returns the result as a char * -void mychar::roundf(float input_val, short precision) +void String::roundf(float input_val, short precision) { float integ_flt, deci_flt; const short MAX_PREC = 4; @@ -1779,7 +3214,7 @@ void mychar::roundf(float input_val, short precision) sprintf(val, "%lu.00000%lu", (unsigned long) integ_flt, deci_int); } -void mychar::roundd(double input_val, short precision) +void String::roundd(double input_val, short precision) { double integ_flt, deci_flt; const short MAX_PREC = 6; @@ -1820,15 +3255,155 @@ void mychar::roundd(double input_val, short precision) sprintf(val, "%lu.00000%lu", (unsigned long) integ_flt, deci_int); } -void mychar::to_upper() +// Provided for documentation purpose only +// You must use the function indexOf() +bool String::contains(char *str2, int startIndex = 0) { - for (long tmpii = strlen(val); tmpii >= 0; tmpii--) + // For example - + // if (indexOf("ohboy") > -1 ) + // cout << "\nString contains 'ohboy'" << endl; + // if (indexOf("ohboy") < 0 ) + // cout << "\nString does NOT contain 'ohboy'" << endl; + // if (indexOf("ohboy", 4) > -1 ) + // cout << "\nString contains 'ohboy'" << endl; + // if (indexOf("ohboy", 4) < 0 ) + // cout << "\nString does NOT contain 'ohboy'" << endl; + cerr << "\nYou must use indexOf() function instead of contains()\n" << endl; + exit(-1); +} + +// Leading, trailing white-spaces of string are ignored +bool String::is_integer() +{ + String tmpstr(val); + tmpstr.trim(true); + debug_("tmpstr.val", tmpstr.val ); + if ( strspn ( tmpstr.val, "0123456789" ) != tmpstr.length() ) + return ( false ) ; + else + return ( true ) ; +} + +// Leading, trailing white-spaces of string are ignored +bool String::is_numeric() +{ + String tmpstr(val); + tmpstr.trim(true); + debug_("tmpstr.val", tmpstr.val ); + if ( strspn ( tmpstr.val, "0123456789.+-e" ) != tmpstr.length() ) + return ( false ) ; + else + return ( true ) ; +} + +// See also explode() +// Warning : The String instance is modified by removing +// the returned token from the string. It is advised +// that you save the original string before calling +// this function like for example : +// String savestr = origstr; +// String aa, bb, cc; +// aa = origstr.token(); +// bb = origstr.token(); +// cc = origstr.token(); +// +// This routine returns the first non-'seperator' (default +// white-space) token string from the String instance +String String::token(char seperator = ' ') +{ + char ee[2]; + ee[0] = seperator; + ee[1] = 0; + char *res = strtok(val, ee); + if (!res) // if res == NULL { - val[tmpii] = toupper(val[tmpii]); + debug_("token", res); + debug_("val", val); + return(String(val)); + } + else + { + String tmpstr(res); + + // Should take string length of val and not res + // because strtok() had put a NULL ('\0') at the location + // and also strtok() ignores the leading blanks of val + strcpy(val, & val[strlen(val)+1]); + debug_("token", res); + debug_("val", val); + return tmpstr; } } -void mychar::str_cpy(char bb[]) +String String::crypt(char *original, char *salt) +{ + return String(""); +} + +int String::int_value() +{ + if ( length() == 0 ) { + cerr << "Cannot convert a zero length string " + << " to a numeric" << endl ; + abort() ; + } + + if ( ! is_integer() ) { + cerr << "Cannot convert string [" << val + << "] to an integer numeric string" << endl ; + abort() ; + } + + return ( atoi ( val ) ) ; +} + +double String::double_value() +{ + if ( length() == 0 ) { + cerr << "Cannot convert a zero length string " + << " to a numeric" << endl ; + abort() ; + } + + if ( ! is_numeric() ) { + cerr << "Cannot convert string [" << val + << "] to a double numeric string" << endl ; + abort() ; + } + + double d = atof ( val ) ; + + return ( d ) ; +} + +String String::getline(FILE *infp = stdin) +{ + register char ch, *aa = NULL; + + register const short SZ = 100; + // Initial value of ii > SZ so that aa is alloc'ed memory + register int jj = 0; + for (int ii = SZ+1; (ch = getc(infp)) != EOF; ii++, jj++) + { + if (ii > SZ) // allocate memory in steps of SZ for performance + { + aa = (char *) realloc(aa, jj + ii + 15); // +15 is safe mem + ii = 0; + } + if (ch == '\n') // read untill newline is encountered + break; + aa[jj] = ch; + } + aa[jj] = 0; + str_cpy(aa); // puts the value in string + free(aa); + return *this; +} + +////////////////////////////////////////////////////////// +// Private functions start from here ......... +////////////////////////////////////////////////////////// +void String::str_cpy(char bb[]) { debug_("In str_cpy bb", bb); if (bb == NULL) @@ -1857,28 +3432,28 @@ void mychar::str_cpy(char bb[]) debug_("In str_cpy val", val); } -void mychar::str_cpy(int bb) +void String::str_cpy(int bb) { char tmpaa[100]; sprintf(tmpaa, "%d", bb); str_cpy(tmpaa); } -void mychar::str_cpy(unsigned long bb) +void String::str_cpy(unsigned long bb) { char tmpaa[100]; sprintf(tmpaa, "%ld", bb); str_cpy(tmpaa); } -void mychar::str_cpy(float bb) +void String::str_cpy(float bb) { char tmpaa[100]; sprintf(tmpaa, "%f", bb); str_cpy(tmpaa); } -void mychar::str_cat(char bb[]) +void String::str_cat(char bb[]) { unsigned long tmpjj = strlen(bb), tmpii = strlen(val); val = (char *) my_realloc(val, tmpii + tmpjj); @@ -1886,7 +3461,7 @@ void mychar::str_cat(char bb[]) strncat(val, bb, tmpjj); } -void mychar::str_cat(int bb) +void String::str_cat(int bb) { char tmpaa[100]; sprintf(tmpaa, "%d", bb); @@ -1896,7 +3471,7 @@ void mychar::str_cat(int bb) strncat(val, tmpaa, tmpjj); } -void mychar::str_cat(unsigned long bb) +void String::str_cat(unsigned long bb) { char tmpaa[100]; sprintf(tmpaa, "%ld", bb); @@ -1906,7 +3481,7 @@ void mychar::str_cat(unsigned long bb) strncat(val, tmpaa, tmpjj); } -void mychar::str_cat(float bb) +void String::str_cat(float bb) { char tmpaa[100]; sprintf(tmpaa, "%f", bb); @@ -1916,58 +3491,61 @@ void mychar::str_cat(float bb) strncat(val, tmpaa, tmpjj); } -mychar operator+ (const mychar & lhs, const mychar & rhs) +////////////////////////////////////////////////////////// +// All operator functions start from here ......... +////////////////////////////////////////////////////////// +String operator+ (const String & lhs, const String & rhs) { /*******************************************************/ - // Note : For adding two char strings, first cast mychar + // Note : For adding two char strings, first cast String // as in - - //aa = (mychar) "alkja " + " 99djd " ; + //aa = (String) "alkja " + " 99djd " ; /*******************************************************/ - mychar tmp(lhs); + String tmp(lhs); tmp.str_cat(rhs.val); return(tmp); /* - if (mychar::global_mychar == NULL) + if (String::global_String == NULL) { - mychar::global_mychar = new mychar; - mychar::global_mychar->str_cpy(lhs.val); - mychar::global_mychar->str_cat(rhs.val); - //return *mychar::global_mychar; - return mychar(mychar::global_mychar->val); + String::global_String = new String; + String::global_String->str_cpy(lhs.val); + String::global_String->str_cat(rhs.val); + //return *String::global_String; + return String(String::global_String->val); } */ /* else - if (mychar::global_mychar1 == NULL) + if (String::global_String1 == NULL) { debug_("1)global", "ok" ); - mychar::global_mychar1 = new mychar; - mychar::global_mychar1->str_cpy(lhs.val); - mychar::global_mychar1->str_cat(rhs.val); - return *mychar::global_mychar1; + String::global_String1 = new String; + String::global_String1->str_cpy(lhs.val); + String::global_String1->str_cat(rhs.val); + return *String::global_String1; } */ /* else { - fprintf(stderr, "\nError: cannot alloc global_mychar\n"); + fprintf(stderr, "\nError: cannot alloc global_String\n"); exit(-1); } */ /* - mychar *aa = new mychar; + String *aa = new String; aa->str_cpy(lhs.val); aa->str_cat(rhs.val); return *aa; */ } -mychar mychar::operator+ (const mychar & rhs) +String String::operator+ (const String & rhs) { - mychar tmp(*this); + String tmp(*this); tmp.str_cat(rhs.val); debug_("rhs.val in operator+", rhs.val ); debug_("tmp.val in operator+", tmp.val ); @@ -1975,7 +3553,7 @@ mychar mychar::operator+ (const mychar & rhs) } // Using reference will be faster in = operator -mychar& mychar:: operator= ( const mychar& rhs ) +String& String:: operator= ( const String& rhs ) { if (& rhs == this) { @@ -1987,21 +3565,21 @@ mychar& mychar:: operator= ( const mychar& rhs ) debug_("rhs value", rhs.val ); // Free global vars memory - //free_glob(& mychar::global_mychar); - //if (mychar::global_mychar == NULL) - //fprintf(stderr, "\nglobal_mychar is freed!\n"); + //free_glob(& String::global_String); + //if (String::global_String == NULL) + //fprintf(stderr, "\nglobal_String is freed!\n"); - //return (mychar(*this)); + //return (String(*this)); return *this; } // Using reference will be faster in = operator -mychar& mychar::operator+= (const mychar & rhs) +String& String::operator+= (const String & rhs) { /*******************************************************/ - // Note : For adding two char strings, first cast mychar + // Note : For adding two char strings, first cast String // as in - - //aa += (mychar) "cccc" + "dddd"; + //aa += (String) "cccc" + "dddd"; /*******************************************************/ if (& rhs == this) @@ -2011,28 +3589,30 @@ mychar& mychar::operator+= (const mychar & rhs) } this->str_cat(rhs.val); return *this; - //return (mychar(*this)); + //return (String(*this)); } -bool mychar::operator== (const mychar & rhs) +bool String::operator== (const String & rhs) { return(equalto(rhs.val)); } -bool mychar::operator== (const char *rhs) +bool String::operator== (const char *rhs) { return(equalto(rhs)); } -bool mychar::operator!= (const mychar & rhs) +bool String::operator!= (const String & rhs) { return(equalto(rhs.val, true)); } -bool mychar::operator!= (const char *rhs) +bool String::operator!= (const char *rhs) { return(equalto(rhs, true)); } + + Appendix D my_malloc.cpp

-You can download all programs as a single tar.gz file from . +You can download all programs as a single tar.gz file from . To get this file, in the web-browser, save this file as 'Text' type. //***************************************************************** -// Copyright policy is GNU/GPL but additional restriction is -// that you include author's name and email on all copies +// Copyright policy is GNU/GPL and it is requested that +// you include author's name and email on all copies // Author : Al Dev Email: alavoor@yahoo.com //***************************************************************** @@ -2596,12 +4176,12 @@ static void raise_error_exit(short mtype, short datatype, char fname[], int line --> Appendix E my_malloc.h

-You can download all programs as a single tar.gz file from . +You can download all programs as a single tar.gz file from . To get this file, in the web-browser, save this file as 'Text' type. //***************************************************************** -// Copyright policy is GNU/GPL but additional restriction is -// that you include author's name and email on all copies +// Copyright policy is GNU/GPL and it is requested that +// you include author's name and email on all copies // Author : Al Dev Email: alavoor@yahoo.com //***************************************************************** @@ -2653,15 +4233,19 @@ void local_print_total_memsize(char fname[], int lineno); --> Appendix F debug.h

-You can download all programs as a single tar.gz file from . +You can download all programs as a single tar.gz file from . To get this file, in the web-browser, save this file as 'Text' type. //***************************************************************** -// Copyright policy is GNU/GPL but additional restriction is -// that you include author's name and email on all copies +// Copyright policy is GNU/GPL and it is requested that +// you include author's name and email on all copies // Author : Al Dev Email: alavoor@yahoo.com //***************************************************************** +/**************************************************************** + Program for debugging C++/C programs +*****************************************************************/ + #define print_log(AA, BB, CC, DD, EE) ((void) 0) #ifdef DEBUG @@ -2706,16 +4290,20 @@ void local_dbg(char name[], double value, char fname[], int lineno, bool logfile --> Appendix G debug.cpp

-You can download all programs as a single tar.gz file from . +You can download all programs as a single tar.gz file from . To get this file, in the web-browser, save this file as 'Text' type. //***************************************************************** -// Copyright policy is GNU/GPL but additional restriction is -// that you include author's name and email on all copies +// Copyright policy is GNU/GPL and it is requested that +// you include author's name and email on all copies // Author : Al Dev Email: alavoor@yahoo.com //***************************************************************** -#ifdef DEBUG // ONLY if DEBUG is defined then these functions below are needed +/**************************************************************** +Program for debugging C++/C programs +*****************************************************************/ + +#ifdef DEBUG // ONLY if DEBUG is defined than these functions below are needed #include "debug.h" //#include "log.h" @@ -2787,6 +4375,8 @@ void local_dbg(char name[], double value, char fname[], int lineno, bool logfile // You add many more here - value can be a class, ENUM, datetime, etc... +#endif // DEBUG + #endif // DEBUG Appendix H Makefile

-You can download all programs as a single tar.gz file from . +You can download all programs as a single tar.gz file from . To get this file, in the web-browser, save this file as 'Text' type. #//***************************************************************** -#// Copyright policy is GNU/GPL but additional restriction is -#// that you include author's name and email on all copies +#// Copyright policy is GNU/GPL and it is requested that +#// you include author's name and email on all copies #// Author : Al Dev Email: alavoor@yahoo.com #//***************************************************************** @@ -2816,24 +4406,24 @@ CC=gcc CXX=g++ MAKEMAKE=mm -LIBRARY=libmychar.a +LIBRARY=libString.a DEST=/home/myname/lib # To build the library, and main test program uncomment line below :- #MYCFLAGS=-O -Wall # To test without debug trace uncomment line below:- -#MYCFLAGS=-g3 -Wall +MYCFLAGS=-g3 -Wall # To enable 'full debug ' tracing uncomment line below:- -MYCFLAGS=-g3 -DDEBUG -Wall +#MYCFLAGS=-g3 -DDEBUG -Wall #PURIFY=purify -best-effort -SRCS=my_malloc.cpp mychar.cpp debug.cpp example_mychar.cpp -HDR=my_malloc.h mychar.h debug.h -OBJS=my_malloc.o mychar.o debug.o example_mychar.o -EXE=mychar +SRCS=my_malloc.cpp String.cpp debug.cpp example_String.cpp +HDR=my_malloc.h String.h debug.h +OBJS=my_malloc.o String.o debug.o example_String.o +EXE=String # For generating makefile dependencies.. SHELL=/bin/sh @@ -2842,14 +4432,14 @@ CPPFLAGS=$(MYCFLAGS) $(OS_DEFINES) CFLAGS=$(MYCFLAGS) $(OS_DEFINES) # -# If the libmychar.a is in the current +# If the libString.a is in the current # directory then use -L. (dash L dot) MYLIBDIR=-L$(MY_DIR)/libmy -L. ALLLDFLAGS= $(LDFLAGS) $(MYLIBDIR) COMMONLIBS=-lstdc++ -lm -MYLIBS=-lmychar +MYLIBS=-lString LIBS=$(COMMONLIBS) $(MYLIBS) all: $(LIBRARY) $(EXE) diff --git a/LDP/howto/linuxdoc/C-C++Beautifier-HOWTO.sgml b/LDP/howto/linuxdoc/C-C++Beautifier-HOWTO.sgml index d17b3a5d..7043991a 100644 --- a/LDP/howto/linuxdoc/C-C++Beautifier-HOWTO.sgml +++ b/LDP/howto/linuxdoc/C-C++Beautifier-HOWTO.sgml @@ -40,7 +40,7 @@ C-C++ Beautifier HOW-TO Al Dev (Alavoor Vasudevan) -v3.0, 21 April 2000 +v4.0, 03 July 2000 This document will help you to format (beautify) the C/C++ programs so that it is more readable and confirms to your site C/C++ coding standards. @@ -79,12 +79,24 @@ On Linux/Unixes there is a command called "indent" and "cb" cb work for only "C" programs. For "C++" programs use "bcpp". Download the beautifier program from one of the following -C++ : BCPP site is at -C++ : +C++ : BCPP site is at + +or at + +C++ : BCPP ftp site is at + +C++ : C : I used BCPP to format the C++ programs and it worked fine for me. You may want to check other tools and use the one which you may like the most. + +BCPP was written by Steven De Toni at + Linux IPCHAINS-HOWTO -<author>Paul Russell, <tt>ipchains@rustcorp.com</tt> -<date>v1.0.7, 12 March 1999 +<author>Rusty Russell +<date>v1.0.8, Tue Jul 4 14:20:53 EST 2000 <abstract> This document aims to describe how to obtain, install and configure the enhanced IP firewalling chains software for Linux, and @@ -76,15 +76,19 @@ some functionality that ipchains offers. <sect1>Where?<label id="intro-where"> <p> -The official page is -<url url="http://www.rustcorp.com/linux/ipchains" - name="The Linux IP Firewall Chains Page"> +The official page is in three places: +<url url="http://netfilter.filewatcher.org/ipchains" + name="Thanks to Penguin Computing"> +<url url="http://www.samba.org/netfilter/ipchains" + name="Thanks to the SAMBA Team"> +<url url="http://netfilter.kernelnotes.org/ipchains" + name="Thanks to Jim Pick"> <p> There is a mailing list for bug reports, discussion, development and usage. Join the mailing list by sending a message containing the word -``subscribe'' to ipchains-request at rustcorp.com. To mail to the -list use `ipchains' instead of `ipchains-request'. +``subscribe ipchains-list'' to subscribe at east.balius.com. To mail +to everyone on the list use ipchains-list at east.balius.com. <sect>Packet Filtering Basics @@ -216,8 +220,8 @@ for how to make sure they are restored the next time Linux is booted. old IP Firewall code. There is a set of useful scripts available from the ipchains ftp site: -<url url="ftp://ftp.rustcorp.com/ipchains/ipchains-scripts-1.1.2.tar.gz" -name="ftp://ftp.rustcorp.com/ipchains/ipchains-scripts-1.1.2.tar.gz"> +<url url="http://netfilter.filewatcher.org/ipchains/ipchains-scripts-1.1.2.tar.gz" +name="http://netfilter.filewatcher.org/ipchains/ipchains-scripts-1.1.2.tar.gz"> This contains a shell script called <tt>ipfwadm-wrapper</tt> which @@ -262,8 +266,8 @@ case "$1" in stop) echo -n "Turning off packet filtering:" echo 0 > /proc/sys/net/ipv4/ip_forward - /sbin/ipchains -X /sbin/ipchains -F + /sbin/ipchains -X /sbin/ipchains -P input ACCEPT /sbin/ipchains -P output ACCEPT /sbin/ipchains -P forward ACCEPT @@ -322,10 +326,10 @@ Use ifconfig to find out, and adjust to taste. <p> You can buy off-the-shelf firewalls. An excellent one is WatchGuard's FireBox. It's excellent because I like it, it's secure, it's -Linux-based, and because they are funding the maintenance of ipchains -as well as the new firewalling code (aimed for 2.3). In short, -WatchGuard are paying for me to eat while I work for you. So please -consider their stuff. +Linux-based, and because they funded the maintenance of ipchains as +well as the new firewalling code (for 2.4). In short, WatchGuard were +paying for me to eat while I work for you. So please consider their +stuff. <url url="http://www.watchguard.com" name="http://www.watchguard.com"> @@ -346,8 +350,8 @@ common. Read carefully, because they are each subtly different. <p> In this scenario, packets from the private network never traverse the Internet, and vice versa. The IP addresses of the private network -should be assigned from the RFC1597 Private Network Allocations -(ie. 10.*.*.*, 172.16.*.* or 192.168.*.*). +should be assigned from the RFC1918 Address Allocation for Private +Internets (ie. 10.*.*.*, 172.16.*.*-172.31.*.* or 192.168.*.*). <p> The only way things ever connect to the Internet is by connecting to @@ -411,8 +415,8 @@ is made from 192.168.1.100 (myhost) port 1050, to 192.168.1.1 <p> In this scenario, packets from the private network never traverse the Internet, and vice versa. The IP addresses of the private network -should be assigned from the RFC1597 Private Network Allocations -(ie. 10.*.*.*, 172.16.*.* or 192.168.*.*). +should be assigned from the RFC1918 Address Allocation for Private +Internets (ie. 10.*.*.*, 172.16.*.*-172.31.*.* or 192.168.*.*). <p> The only way things ever connect to the Internet is by connecting to @@ -485,8 +489,9 @@ proxy. <p> In this scenario, packets from the private network never traverse the Internet without special treatment, and vice versa. The IP addresses -of the private network should be assigned from the RFC1597 Private -Network Allocations (ie. 10.*.*.*, 172.16.*.* or 192.168.*.*). +of the private network should be assigned from the RFC1918 Address +Allocation for Private Internets (ie. 10.*.*.*, 172.16.*.*-172.31.*.* +or 192.168.*.*). <p> Instead of using a proxy, we use a special kernel facility called @@ -534,7 +539,7 @@ local port 1050, and asks the web server (port 80) for the web page. <item> As the packets from myhost (port 1050) to slashdot.org (port 80) pass through the firewall, they are rewritten to come from the PPP interface of the firewall, port 65000. The firewall has a valid -Internet address (1.2.3.4) so reply packets from www.linuxhq.com get +Internet address (1.2.3.4) so reply packets from slashdot.org get routed back OK. <item> As packets from slashdot.org (port 80) to @@ -628,16 +633,13 @@ Internet host to the server. <sect1>More Information on Masquerading +<p> David Ranch has written an excellent new HOWTO on Masquerading, which has a large amount of overlap with this HOWTO. You can currently find that HOWTO at -<htmlurl url="http://www.ecst.csuchico.edu/~dranch/LINUX/index-LINUX.html#ipmasq" name="http://www.ecst.csuchico.edu/~dranch/LINUX/index-LINUX.html#ipmasq"> - -<p> -Soon I would expect it to be found under the auspices of the Linux -Documentation Project, at -<url url="http://www.metalab.unc.edu/LDP" name="http://www.metalab.unc.edu/LDP"> +<htmlurl url="http://www.linuxdoc.org/HOWTO/IP-Masquerade-HOWTO.html" +name="http://www.linuxdoc.org/HOWTO/IP-Masquerade-HOWTO.html"> <p> The official Masquerading home page is at @@ -802,6 +804,15 @@ The final (and perhaps the most useful) function allows you to check what would happen to a given packet if it were to traverse a given chain. +<sect2> What You'll See When Your Computer Starts Up + +<p> +Before any ipchains commands have been run (be careful: some +distributions run ipchains in their initialization scripts), there +will be no rules in any of the built-in chains (`input', `forward' and +`output'), and each of the chains will have a policy of ACCEPT. This +is as wide-open as you can get. + <sect2> Operations on a Single Rule <p> @@ -895,7 +906,7 @@ address such as `127.0.0.1'. <p> The third and fourth ways allow specification of a group of IP addresses, such as `199.95.207.0/24' or `199.95.207.0/255.255.255.0'. -These both specify any IP address from 192.95.207.0 to 192.95.207.255 +These both specify any IP address from 199.95.207.0 to 199.95.207.255 inclusive; the digits after the `/' tell which parts of the IP address are significant. `/32' or `/255.255.255.255' is the default (match all of the IP address). To specify any IP address at all `/0' can be @@ -916,6 +927,9 @@ preceded by `!' (pronounced `not') to match addresses NOT equal to the ones given. For example. `-s ! localhost' matches any packet not coming from localhost. +<p> +Don't forget the spaces around the `!': they really are needed. + <sect3>Specifying Protocol <p> @@ -1800,7 +1814,7 @@ Minimum delay for web traffic & telnet. <tscreen><verb> # ipchains -A ppp-out -p TCP -d proxy.virtual.net.au 8080 -t 0x01 0x10 -# ipchains -A ppp-out -p TCP -d 0.0.0.0 telnet -t 0x01 0x10 +# ipchains -A ppp-out -p TCP -d 0.0.0.0/0 telnet -t 0x01 0x10 # </verb></tscreen> @@ -1847,6 +1861,14 @@ be going to a port above 1023, and not the X11 ports around 6000). # </verb></tscreen> +<p> +I allow TCP reply packets back in + +<tscreen><verb> +# ipchains -A ppp-in -p TCP ! -y -j ACCEPT +# +</verb></tscreen> + <p> Finally, local-to-local packets are OK: @@ -2106,7 +2128,7 @@ following: This drops all packets for the duration of the changes. <p> -If you changes are restricted to a single chain, you might want to +If your changes are restricted to a single chain, you might want to create a new chain with the new rules, and then replace (`-R') the rule that pointed to the old chain with one that points to the new chain: then you can delete the old chain. This replacement will occur @@ -2243,16 +2265,17 @@ patterns. <p> Michael Hasenstein of SuSE has written a kernel patch which adds ftp connection tracking to ipchains. It can currently be found at -<url url="http://www.csn.tu-chemnitz.de/~mha/patch.ftp-data-2.gz" -name="http://www.csn.tu-chemnitz.de/~mha/patch.ftp-data-2.gz"> +<url url="http://www.suse.de/~mha/patch.ftp-data-2.gz" +name="http://www.suse.de/~mha/patch.ftp-data-2.gz"> <sect1> Future Enhancements <p> -Firewalling and NAT are being redesigned for 2.3. Plans and -discussions are available on the netdev archive, and ipchains-dev -list. These enhancements should clear up many outstanding usability -issues (really, firewalling and masquerading shouldn't be <em>this +Firewalling and NAT have being redesigned for 2.4. Plans and +discussions are available on the netfilter list (see <url +url="http://lists.samba.org" name="http://lists.samba.org">). These +enhancements should clear up many outstanding usability issues +(really, firewalling and masquerading shouldn't be <em>this hard</em>), and allow growth for far more flexible firewalling. <sect> Common Problems @@ -2265,6 +2288,21 @@ You're probably blocking DNS lookups; it will eventually time out. Try using the `-n' (numeric) flag to ipchains, which suppresses the lookup of names. +<p> +<sect1> Inverse doesn't work! + +<p> +You must put the `!' option by itself, with spaces either side. A +classic mistake (warned about in 1.3.10) is: + +<tscreen><verb> +# ipchains -A input -i !eth0 -j DENY +# +</verb></tscreen> + +There will never be an interface called `!eth0', but ipchains doesn't +know that. + <p> <sect1> Masquerading/Forwarding Doesn't Work! @@ -2614,9 +2652,12 @@ don't. Since noone in the internal network should be trying to do evil things, we log any packets that get denied. <p> +Note that old versions of Debian called `pop3' `pop-3' in +/etc/services, which disagrees with RFC1700. + <tscreen><verb> ipchains -A good-dmz -p tcp -d 192.84.219.128 smtp -j ACCEPT -ipchains -A good-dmz -p tcp -d 192.84.219.128 pop-3 -j ACCEPT +ipchains -A good-dmz -p tcp -d 192.84.219.128 pop3 -j ACCEPT ipchains -A good-dmz -p udp -d 192.84.219.129 domain -j ACCEPT ipchains -A good-dmz -p tcp -d 192.84.219.129 domain -j ACCEPT ipchains -A good-dmz -p tcp -d 192.84.218.130 www -j ACCEPT @@ -2684,12 +2725,13 @@ ipchains -A bad-dmz -j DENY <itemize> <item> Log violations. <item> Passive FTP handled by masq. module. + <item> UDP destination ports 33434 and up are used by traceroute. </itemize> <tscreen><verb> ipchains -A good-bad -p tcp --dport www -j MASQ ipchains -A good-bad -p tcp --dport ssh -j MASQ ipchains -A good-bad -p udp --dport 33434:33500 -j MASQ -ipchains -A good-bad -p tcp --dport ftp --j MASQ +ipchains -A good-bad -p tcp --dport ftp -j MASQ ipchains -A good-bad -p icmp --icmp-type ping -j MASQ ipchains -A good-bad -j REJECT -l </verb></tscreen> @@ -2721,7 +2763,7 @@ ipchains -A dmz-good -p tcp ! -y -s 192.84.219.129 domain -j ACCEPT ipchains -A dmz-good -p tcp ! -y -s 192.84.218.130 www -j ACCEPT ipchains -A dmz-good -p tcp ! -y -s 192.84.218.130 rsync -j ACCEPT ipchains -A dmz-good -p icmp -j icmp-acc -ipchains -A dmz-bad -j DENY -l +ipchains -A dmz-good -j DENY -l </verb></tscreen> </itemize> @@ -2806,13 +2848,14 @@ ipchains -A input -d 192.168.1.250 -j good-if <item> Access DNS </itemize> -<item> External interface also receives replies to masqueraded packets, - and ICMP errors for them and PING replies. +<item> External interface also receives replies to masqueraded packets +(masquerading uses source ports 61000 to 65095) and ICMP errors for +them and PING replies. <tscreen><verb> ipchains -A bad-if -i ! ppp0 -j DENY -l -ipchains -A bad-if -p TCP --dport 61000:65096 -j ACCEPT -ipchains -A bad-if -p UDP --dport 61000:65096 -j ACCEPT +ipchains -A bad-if -p TCP --dport 61000:65095 -j ACCEPT +ipchains -A bad-if -p UDP --dport 61000:65095 -j ACCEPT ipchains -A bad-if -p ICMP --icmp-type pong -j ACCEPT ipchains -A bad-if -j icmp-acc ipchains -A bad-if -j DENY @@ -3072,7 +3115,7 @@ or directing the standard output of the script to /dev/null. <p> If you should find any mistakes in this script, or any changes between the real ipfwadm and this script, <em>please</em> report a bug to me: send -an EMail to ipchains@rustcorp.com with "BUG-REPORT" in the subject. +an EMail to rusty@linuxcare.com with "BUG-REPORT" in the subject. Please list your old version of <tt>ipfwadm</tt> (<tt>ipfwadm -h</tt>), your version of <tt>ipchains</tt> (<tt>ipchains --version</tt>), the version of the ipfwadm wrapper script (<tt>ipfwadm-wrapper --version</tt>). Also send the @@ -3108,7 +3151,29 @@ Franck Sicard, Kevin Littlejohn, Matt Kemner, John D. Hardin, Alexey Kuznetsov, Leos Bitto, Jim Kunzman, Gerard Gerritsen, Serge Sivkov, Andrew Burgess, Steve Schmidtke, Richard Offer, Bernhard Weisshuhn, Larry Auton, Ambrose Li, Pavel Krauz, Steve Chadsey, Francesco -Potorti` and Alain Knaff. +Potorti`, Alain Knaff, Casper Boden-Cummins and Henry Hollenberg. +<sect1>Translations + +<p> +People who do translations should put themselves at the <em>top</em> +of the Thanks page, like so: `Special thanks to XXX, for translating +everything exactly from my English.'. Then tell me about your +translation so I can include it here. + +<p> +Arnaud Launay, asl@launay.org: +<url url="http://www.freenix.fr/unix/linux/HOWTO/IPCHAINS-HOWTO.html" + name="http://www.freenix.fr/unix/linux/HOWTO/IPCHAINS-HOWTO.html"> + +<p> +Giovanni Bortolozzo, borto@pluto.linux.it: +<url url="http://www.pluto.linux.it/ildp/HOWTO/IPCHAINS-HOWTO.html" + name="http://www.pluto.linux.it/ildp/HOWTO/IPCHAINS-HOWTO.html"> + +<p> +Herman Rodríguez, herman@maristas.dhis.org: +<url url="http://netfilter.kernelnotes.org/ipchains/spanish/HOWTO.html" + name="http://netfilter.kernelnotes.org/ipchains/spanish/HOWTO.html"> </article> diff --git a/LDP/howto/linuxdoc/MIPS-HOWTO.sgml b/LDP/howto/linuxdoc/MIPS-HOWTO.sgml index 5c557ee4..3606aabf 100644 --- a/LDP/howto/linuxdoc/MIPS-HOWTO.sgml +++ b/LDP/howto/linuxdoc/MIPS-HOWTO.sgml @@ -5,7 +5,7 @@ <title>Linux/MIPS HOWTO <author>Ralf Bächle, <tt/ralf@gnu.org/ -<date>v0.1, 31 March 1999 +<date>June 24, 2000 <abstract> This FAQ describes the MIPS port of the Linux operating system, common problems and their solutions, availability and more. It also tries to @@ -34,6 +34,25 @@ find information that actually should be covered elsewhere. However as usual your mileage may vary and you should examine Linux's suitability for your purpose which purpose this document tries to serve.<p> +<sect>Getting this FAQ<p> + You can download this document in various formats: + + <itemize> + <item>The HTML version + <url url="http://oss.sgi.com/mips/mips-howto.html"> + <item>The text version + <url url="http://oss.sgi.com/mips/mips-howto.txt"> + <item>The Postscript version + <url url="http://oss.sgi.com/mips/mips-howto.ps"> + <item>The Linux-Doc SGML version. + <url url="http://oss.sgi.com/mips/mips-howto.sgml"> + </itemize> + + This FAQ is also available as SGML source code via anonymous CVS from + oss.sgi.com. The archive also has a Makefile which will translate it into + various formats. An ASCII version is regularly being posted via + <em>comp.os.linux.answers</em> and the other Linux HOWTO channels. + <sect>What hardware does Linux/MIPS support? <sect1>Hardware platforms<p> <label id="hardware-platforms"> @@ -84,10 +103,31 @@ find information that actually should be covered elsewhere. The Cobalt Qube support has never been integrated into the official Linux/MIPS 2.1.x kernels. + <sect2>NEC machines<p> + The NEC uniprocessor machines are OEM <em>Acer PICA</em> systems, see + that section for details. The SMP systems are different from that. The + Linux/MIPS developers have no technical documentation as necessary to write + an OS. As long as this does not change this will pretty much stay a show + stopper preventing a port to NEC's SMP systems. + + <sect2>NEC VR41xx-based platforms<p> + The Linux VR project is porting Linux to devices based on the NEC VR41xx + microprocessors. Many of these devices were originally designed to run + Windows CE. The project has produced working kernels with basic drivers + for the Vadem Clio, Casio E-105, Everex Freestyle, and more. For more + information please see <url url="http://linux-vr.org/">. + + <sect2>Toshiba TMPR39xx/Philips PR31700 platforms<p> + Similar to the VR41xx, devices with these processors were originally intended + for running Windows CE. However, there are working kernels with basic drivers + for <em>Sharp Mobilon</em> and the <em>Compaq C-Series</em>. Support for more devices + is under construction. The code is part of the Linux VR project and as such + more information can be found at <url url="http://linux-vr.org/">. + <sect2>Netpower 100<p> - The <em>Netpower 100</em> is apparently an <em>Acer PICA</em> in disguise. It - should therefore be supported but this is untested. If there is a problem - then it is probably the machine detection. + The <em>Netpower 100</em> is apparently an <em>Acer PICA</em> in disguise. + It should therefore be supported but this is untested. If there is a + problem then it is probably the machine detection. <sect2>Nintendo 64<p> The <em>Nintendo 64</em> is R4300 based game console with 4mb RAM. Its @@ -96,15 +136,37 @@ find information that actually should be covered elsewhere. Nintendo decides to publish the necessary technical information. The question remains as to whether this is a good idea. - <sect2>Silicon Graphics Indy<p> + <sect2>Silicon Graphics Challenge S<p> + This machine is very similar to the Indy; the difference is that it doesn't + have a keyboard and a GFX card but has an additional SCSI WD33C95 based + adapter. This WD33C95 hostadapter is currently not supported. + <sect2>Silicon Graphics Indigo<p> + This machine is only being mentioned here because occasionally people have + confused it with Indys or the Indigo 2. The Indigo is a different, + R3000 based architecture however and not yet unsupported. + + <sect2>Silicon Graphics Indigo2<p> + This machine is the successor to the Indigo and is very similar to the Indy. + It is now supported, however it is lacking in several areas. You will have + to use serial console. If you have a Indigo2 and still want to run Linux on + it, contact either <htmlurl url="mailto:flo@rfc822.org" + name="Florian Lohoff (flo@rfc822.org)"> or <htmlurl + url="mailto:spock@mgnet.de" name="Klaus Naumann (spock@mgnet.de)"> . + + <sect2>Silicon Graphics Indy<p> The Indy is currently the only (mostly) supported Silicon Graphics machine. The only supported graphics card is the Newport card aka - “XL” graphics. The Indy is available with a large number of - CPU options at various clock rates all of which are supported. There is - currently no X server available for the Indy; <htmlurl - url="mailto:alan@lxorguk.ukuu.org.uk" name="Alan Cox - (alan@lxorguk.ukuu.org.uk)"> is working on one. + ``XL'' graphics. The Indy is available with a large number of + CPU options at various clock rates all of which are supported. + There's also a X server available now written by + <htmlurl url="mailto:guido.guenther@gmx.net" + name="Guido Guenther (guido.guenther@gmx.net)">. + If you're able to use the Newport console on your Indy it should be + possible to also use this X server. It's based on XFree86 4.0 and + currently running at snail speed but seems to work quite ok. + If you want to try it take a look at + <url url="http://honk.physik.uni-konstanz.de/~agx/mipslinux/x/"> . <sect3>Strange numbers of available memory<p> On bootup the kernel on the Indy will report available memory with a @@ -116,14 +178,14 @@ find information that actually should be covered elsewhere. 128mb area in the Indy's memory address space which mirrors up to the first 128mb of memory. The difference between the two numbers will always be about 128mb and does not indicate a problem of any kind. + Kernels since 2.3.23 don't count this 128mb gap any longer. - <sect3>Indy PROM related problems<p> - - Several people have reported these problems with their machines after upgrading them - typically from surplus parts. There are several PROM versions for the - Indy available. Machines with old PROM versions which have been upgraded - to newer CPU variants like a R4600SC or R5000SC module can crash during - the self test with an error message like + <sect3>Indy PROM related problems<p> + Several people have reported these problems with their machines after + upgrading them typically from surplus parts. There are several PROM + versions for the Indy available. Machines with old PROM versions which + have been upgraded to newer CPU variants like a R4600SC or R5000SC module + can crash during the self test with an error message like <verb> Exception: <vector=Normal> Status register: 0x30004803<CU1,CU0,IM7,IM4,IPL=???,MODE=KERNEL,EXL,IE> @@ -148,7 +210,7 @@ find information that actually should be covered elsewhere. for this is of course a PROM upgrade. Alternatively you can use Sash of IRIX 5 or newer to boot the kernel. Sash knows how to load ELF binaries and doesn't care if it's an IRIX or Linux kernel. Simply type - “Sash” to the prom monitor. You should get another shell + ``Sash'' to the prom monitor. You should get another shell prompt, this time from Sash. Now launch Linux as usual.<p> Sash can read EFS or XFS filesystems or read the kernel from bootp / tftp. That means if you intend to use Sash for booting the kernel from local disk you'll @@ -162,18 +224,25 @@ find information that actually should be covered elsewhere. its memory is mirrored. Linux knows about it and just ignores that memory, thus this message.<p> - <sect2>Silicon Graphics Challenge S<p> - This machine is very similar to the Indy; the difference is that it doesn't - have a keyboard and a GFX card but has an additional SCSI WD33C95 based adapter. - This WD33C95 hostadapter is currently not supported. + <sect2>Silicon Graphics Origin 200 and 2000<p> + <htmlurl url="mailto:ralf@gnu.org" name="Ralf Bächle (ralf@gnu.org)"> + and a team of SGI employees are currently working on a port to the + Origin 200. While still in it's early stages it's running in + uniprocessor and multiprocessor mode and has drivers for the builtin + IOC3 Ethernet and SCSI hostadapters. The code is available in the + Linux/MIPS CVS tree.<p> - <sect2>Silicon Graphics Indigo<p> - This machine is only being mentioned here because occasionally people - have confused it with Indys. The Indigo series is a different architecture - however and therefore yet unsupported. - <htmlurl url="mailto:andrewb@uab.edu" - name="Andrew R. Baker (andrewb@uab.edu)"> announced - a university project to port Linux to the Indigo on January 2, 1999. + <sect2>Silicon Graphics Onyx 2<p> + The Onyx 2 is basically an Origin 2000 with additional graphics + hardware. As of now about Linux support for the graphics hardware has + not yet been decieded. Aside of that Linux should run just as well as + on a normal headless Origin 2000 configuration.<p> + + <sect2>Silicon Graphics Power Series<p> + This is a very old series of R3000 SMP systems. There is no hardware + documentation for these machines, few of them exist anymore, the hardware + is weird. In short, chances that Linux will ever run on them are + approximating zero. Not that we want to disencourage takers ... <sect2>Serial console on SGI machines<p> Make sure the kernel you're using includes the appropriate driver for a @@ -189,45 +258,18 @@ find information that actually should be covered elsewhere. documentation; it's in /usr/src/linux/Documentation/serial-console.txt if you have the kernel source installed. - <sect2>Motorola 68k based machines like the Iris 3000<p> - These are <sl>very</sl> old machines, probably more than ten years old by - now. As these machines are not based on MIPS processors this document is - the wrong place to search for information. However, in order to make things - easy, these machines are currently not supported. - - <sect2>SGI VisPC<p> - This is actually an x86 based system, therefore not covered by this FAQ. - But to make your search for answers simple, here it is. - <htmlurl url="mailto:kck@mailbox.esd.sgi.com" - name="Ken Klingman (kck@mailbox.esd.sgi.com)"> - posted on January 17, 1999 to SGI's Linux mailing list: - <verb> - We are working on it. We're actually close to getting - the base level system support into the 2.2 release. - Software-only X and OpenGL should follow relatively - shortly, but hardware-accelerated OpenGL is still - some time off. See www.precisioninsight.com for - news about hardware-accelerated OpenGL. - </verb> - For more information see the Documentation/ of Linux kernel versions from - 2.2.0 and newer. There is additional information available on the web on - <url url="http://www.linux.sgi.com/intel/">. Note that the SGI/MIPS and - SGI/Intel people are working independently of each other, therefore the - sources in the anonymous CVS on linus.linux.sgi.com may or may not work - for Intel machines; we don't test this. - <sect2>Other Silicon Graphics machines<p> At this time no other Silicon Graphics machine is supported. This also applies to the <sl>very</sl> old Motorola 68k based systems. <sect2>Sony Playstation<p> - The Sony Playstation is based on an R3000 derivative and uses a set of graphics - chips developed by Sony themselves. While the machine in theory would be - capable of running Linux, a port is difficult, since Sony so far hasn't provided - the necessary technical information. This still leaves the question of - whether the port would be worthwhile. So in short, - nothing has happend yet even though many people have shown their interest - in trying Linux on a Playstation so far. + The Sony Playstation is based on an R3000 derivative and uses a set of + graphics chips developed by Sony themselves. While the machine in theory + would be capable of running Linux, a port is difficult, since Sony so far + hasn't provided the necessary technical information. This still leaves the + question of whether the port would be worthwhile. So in short, nothing has + happend yet even though many people have shown their interest in trying Linux + on a Playstation so far. <sect2>SNI RM200C<p> In contrast to the RM200 (see below) this machine has EISA and PCI slots. @@ -235,65 +277,68 @@ find information that actually should be covered elsewhere. NCR53c810A SCSI controller. <sect2>SNI RM200<p> - If your machine has both EISA and PCI slots, then it is an RM200C; please - see above. Due to the slight architectural differences of the RM200 and - the RM200C this machine isn't currently supported in the official sources. - <htmlurl url="mailto:engel@numerik.math.uni-siegen.de" - name="Michael Engel (engel@numerik.math.uni-siegen.de)"> has managed to get his RM200 - working partially but the patches haven't yet been included in the official - Linux/MIPS - sources. + If your machine has both EISA and PCI slots, then it is an RM200C; please + see above. Due to the slight architectural differences of the RM200 and + the RM200C this machine isn't currently supported in the official sources. + <htmlurl url="mailto:engel@numerik.math.uni-siegen.de" + name="Michael Engel (engel@numerik.math.uni-siegen.de)"> has managed to get + his RM200 working partially but the patches haven't yet been included in the + official Linux/MIPS sources. <sect2>SNI RM300C<p> - The RM300 is technically very similar to the RM200C. It should be supported - by the current Linux kernel, but we haven't yet received any reports. + The RM300 is technically very similar to the RM200C. It should be supported + by the current Linux kernel, but we haven't yet received any reports. <sect2>SNI RM400<p> - The RM400 isn't supported. + The RM400 isn't supported. + + <sect2>SNI RW320<p> + This machine is a OEM variant of the SGI Indigo and therefore also still + unsupported. <sect2>Algorithmics P4032<p> The Algorithmics P4032 port is at the time of this writing still running Linux 2.1.36. - <sect2>Algorithmics P5064<p> - The P5064 is basically an R5000-based 64bit variant of the P4032. It's not - yet supported but a Linux port will be quite easy. + <sect2>Algorithmics P5064<p> + The P5064 is basically an R5000-based 64bit variant of the P4032. A port is + ongoing. <sect2>DECstation series<p> - During the late 80's and the early 90's Digital (now Compaq) built MIPS based - Workstations named DECstation resp. DECsystem. Other x86 and Alpha based - machines were sold under the name DECstation, but these are obviously not - subject of this FAQ. Support for DECstations is still under development, - started by Paul M. Antoine. These days most of the work is done by - <htmlurl url="mailto:Harald.Koerfgen@home.ivm.de" - name="Harald Koerfgen (Harald.Koerfgen@home.ivm.de)"> and others. On the - Internet, DECstation-related information can be found at - <url url="http://decstation.unix-ag.org/">. + During the late 80's and the early 90's Digital (now Compaq) built MIPS based + Workstations named DECstation resp. DECsystem. Other x86 and Alpha based + machines were sold under the name DECstation, but these are obviously not + subject of this FAQ. Support for DECstations is still under development, + started by Paul M. Antoine. These days most of the work is done by + <htmlurl url="mailto:Harald.Koerfgen@home.ivm.de" + name="Harald Koerfgen (Harald.Koerfgen@home.ivm.de)"> and others. On the + Internet, DECstation-related information can be found at + <url url="http://decstation.unix-ag.org/">. - The DECstation family ranges from the DECstation 2100 with an R2000/R2010 - chipset at 12 Mhz to the DECstation 5000/260 with a 60 MHz R4400SC. + The DECstation family ranges from the DECstation 2100 with an R2000/R2010 + chipset at 12 Mhz to the DECstation 5000/260 with a 60 MHz R4400SC. - The following DECstation models are actively supported: - <itemize> - <item>2100, codename PMAX - <item>5000/xx (Personal DECstation), codename MAXine - <item>5000/1xx, codename 3MIN - <item>5000/2x0, codename 3MAX+ - <item>5900/2x0 (identical to the 3MAX+). - </itemize> + The following DECstation models are actively supported: + <itemize> + <item>2100, codename PMAX + <item>5000/xx (Personal DECstation), codename MAXine + <item>5000/1xx, codename 3MIN + <item>5000/200, codename 3MAX + <item>5000/2x0, codename 3MAX+ + <item>5900/2x0 (identical to the 3MAX+). + </itemize> - These DECstation models are orphaned because nobody is working on them, - but support for these should be relatively easy to achieve. - <itemize> - <item>3100, identical to the 2100 except the R2000A/R2010A @ 16 MHz - <item>5100, codename MIPSMATE, almost identical to the 2100 but with an - R3000/R3010 chipset. - <item>5000/200, codename 3MAX - </itemize> + These DECstation models are orphaned because nobody is working on them, + but support for these should be relatively easy to achieve. + <itemize> + <item>3100, identical to the 2100 except the R2000A/R2010A @ 16 MHz + <item>5100, codename MIPSMATE, almost identical to the 2100 but with an + R3000/R3010 chipset. + </itemize> The other members of the DECstation family, besides the x86 based ones, should be considered as VAXen with the CPU replaced by a MIPS CPU. - There is absolutely no information available about these machines and support + There is absolutely no information available about these machines and support for them is unlikely to happen ever unless the VAXLinux port comes to a new life. These are: <itemize> @@ -302,10 +347,6 @@ find information that actually should be covered elsewhere. <item>5800, codename ISIS </itemize> - The R2000/R3000 support in the Linux/MIPS kernel is a merge of the - DECstation and Baget/MIPS code and isn't yet integrated into the official - Linux/MIPS source tree. - <sect2>Mips Magnum 4000 / Olivetti M700-10<p> These two machines are almost completely identical. Back during the ACE initiative Olivetti licensed the Jazz design and marketed the machine @@ -339,14 +380,6 @@ find information that actually should be covered elsewhere. The Mips Magnum 4000SC is the same as a Magnum 4000 (see above) with the exception that it uses an R4000SC CPU. - <sect2>VaxStation<p> - As the name already implies this machine is a member of Digital Equipment's - VAX family. It's mentioned here because people often confuse it with - Digital's MIPS based DECstation family due to the similar type numbers. - These two families of architectures share little technical similarities. - Unfortunately the VaxStation, like the entire VAX family, is currently - unsupported. - <sect1>Processor types <label id="supported-cpus"> <sect2>R2000, R3000 family<p> @@ -355,20 +388,23 @@ find information that actually should be covered elsewhere. market. Later versions were clocked faster: for instance, the R3000 is a 100% compatible redesign of the R2000, just clocked faster. Because of their high compatibility, where this document mentions - the R3000, in most cases the same facts also apply to the R2000.<p> + the R3000, in most cases the same facts also apply to the R2000. The R3000A is basically an R2000 plus an R3010 FPU - and 64k cache running at up to 40Mhz and integrated into the same chip. - Support for the R3000 processor is currently in the works by various - people. <htmlurl url="mailto:Harald.Koerfgen@home.ivm.de" + and 64k cache running at up to 40Mhz and integrated into the same chip.<p> + + <htmlurl url="mailto:Harald.Koerfgen@home.ivm.de" name="Harald Koerfgen (Harald.Koerfgen@home.ivm.de)"> and <htmlurl url="mailto:raiko@niisi.msk.ru" name="Gleb O. Raiko (raiko@niisi.msk.ru)"> - have both independently worked on patches which haven't yet been integrated - into the official Linux/MIPS sources. + have both independently worked on patches for R3000 processors. + The work has been merged and is integrated into the official Linux/MIPS + sources since July 1999. Actually Linux supports R3000 processors including + some derivatives like the R3081 and the TMPR3912/PR31700<p> <sect2>R6000<p> Sometimes people confuse the R6000, a MIPS processor, with RS6000, a series - of workstations made by IBM. So if you're reading this in hope of finding out - more about Linux on IBM machines you're reading the wrong document.<p> + of workstations made by IBM. So if you're reading this in hope of finding + out more about Linux on IBM machines you're reading the wrong document.<p> + The R6000 is currently not supported. It is a 32-bit MIPS ISA 2 processor and a pretty interesting and weird piece of silicon. It was developed and produced by a company named <sl>BIT Technology</sl>. Later NEC took @@ -379,6 +415,7 @@ find information that actually should be covered elsewhere. primary cache, a technology called <sl>TLB slice</sl>. That means its MMU is substantially different from those of the R3000 or R4000 series, which is also one of the reasons why the processor isn't supported. + <sect2>R4000 and R5000 family<p> Linux supports many of the members of the R4000 family. Currently these are R4000PC, R4400PC, R4300, R4600, R4700, R5000, R5230, R5260. Many @@ -390,26 +427,76 @@ find information that actually should be covered elsewhere. unlike other systems, especially PCs, on MIPS the cache is architecturally visible and needs to be controlled by software.<p> Special credit goes to <htmlurl url="mailto:grim@zigzegv.ml.org" - name="Ulf Carlsson (grim@zigzegv.ml.org)"> who provided the CPU module for debugging the - R4000SC / R4400SC support. + name="Ulf Carlsson (ulfc@engr.sgi.com)"> who provided the CPU module for + debugging the R4000SC / R4400SC support. + <sect2>R8000<p> - The R8000 is currently unsupported partly because this - processor is relatively rare and has only been used in a few SGI machines, - partly because the Linux/MIPS developers don't have such a machine.<p> + The R8000 is currently unsupported partly because this processor is + relatively rare and has only been used in a few SGI machines, partly because + the Linux/MIPS developers don't have such a machine.<p> The R8000 is a pretty interesting piece of silicon. Unlike the other - members of the MIPS family it is a set of seven chips. Its cache and - TLB architecture is pretty different from the other members of the MIPS - family. It was born as a hack to get the floating point crown - back to Silicon Graphics before the R10000 is finished. + members of the MIPS family it is a set of seven chips. It's cache and TLB + architecture are pretty different from the other members of the MIPS family. + It was born as a quick hack to get the floating point crown back to + Silicon Graphics before the R10000 is finished. + <sect2>R10000<p> - The R10000 is currently unsupported because the Linux/MIPS developers - don't have an R10000 machine. + The R10000 is supported as part of the mips64 kernel which currently is + supported on the IP22 (SGI Indy, Challenge S and Indigo 2) and + Origin.<p> + Due to the very hard to handle way this processor works in non-cachecoherent + systems it's probably still taking some time until we support this processor + in such systems. As of today these systems are the SGI O2 and + Indigo <p> + + <sect1>Hardware we're never going to support<p> + <sect2>IBM RS6000<p> + As the name say these are IBM machines which are based on the RS6000 + processor series and as such they're not subject of the Linux/MIPS project. + People frequently confuse the IBM RS6000 with the MIPS R6000 architecture. + However the Linux/PPC project might do so. Checkout + <url url="http://www.linuxppc.org/"> for further information. + + <sect2>VaxStation<p> + As the name already implies this machine is a member of Digital Equipment's + VAX family. It's mentioned here because people often confuse it with + Digital's MIPS based DECstation family due to the similar type numbers. These + two families of architectures share little technical similarities. + Unfortunately the VaxStation, like the entire VAX family, is currently + unsupported. + + <sect2>SGI VisPC<p> + This is actually an x86 based system, therefore not covered by this FAQ. + But to make your search for answers simple, here it is. + <htmlurl url="mailto:kck@mailbox.esd.sgi.com" + name="Ken Klingman (kck@mailbox.esd.sgi.com)"> + posted on January 17, 1999 to SGI's Linux mailing list: + <verb> + We are working on it. We're actually close to getting + the base level system support into the 2.2 release. + Software-only X and OpenGL should follow relatively + shortly, but hardware-accelerated OpenGL is still + some time off. See www.precisioninsight.com for + news about hardware-accelerated OpenGL. + </verb> + For more information see the Documentation/ of Linux kernel versions from + 2.2.0 and newer. There is additional information available on the web on + <url url="http://oss.sgi.com/">. Note that the SGI/MIPS and SGI/Intel + people are working independently of each other, therefore the sources in the + anonymous CVS on oss.sgi.com may or may not work for Intel machines; we don't + test this. + + <sect2>Motorola 68k based machines like the Iris 3000<p> + These are <sl>very</sl> old machines, probably more than ten years old by + now. As these machines are not based on MIPS processors this document is + the wrong place to search for information. However, in order to make things + easy, these machines are currently not supported. <sect>Linux distributions.<p> <sect1>RedHat<p> For MIPSeb, there's Rough Cuts Linux, previously known as Hard Hat Linux, which is most of Red Hat Linux 5.1 ported for MIPSeb. You can get this at - <url url="ftp://ftp.linux.sgi.com/pub/hardhat">. + <url url="ftp://oss.sgi.com/pub/hardhat">. It is also bundled along with M68k, UltraSparc and PowerPC in a package called "Rough Cuts" pressed by Red Hat, and available wherever Red Hat @@ -421,6 +508,8 @@ find information that actually should be covered elsewhere. Cobalt Qubes; those binaries will work perfectly on other MIPSel architectures available at <url url="ftp://intel.cleveland.lug.net/pub/Mipsel">. + <url url="ftp://bolug.uni-bonn.de/mips"> has various rpm packages from + Redhat 6.0 and 6.1. <sect1>Debian<p> A Debian port is underway. Current efforts are being bootstrapped using @@ -433,50 +522,61 @@ find information that actually should be covered elsewhere. <sect1>Anonymous FTP servers.<p> The two primary anonymous FTP servers for Linux/MIPS are <descrip> - <tag><htmlurl url="ftp://ftp.linux.sgi.com" name="ftp.linux.sgi.com"><p> + <tag><htmlurl url="ftp://oss.sgi.com" name="oss.sgi.com"><p> This server should satisfy almost all your Linux/MIPS related ftp desires. - Really. + Really.<p> <tag><htmlurl url="ftp://ftp.fnet.fr" name="ftp.fnet.fr"><p> This server is currently pretty outdated; it's included here mostly for completeness and for people with interest in prehistoric software. </descrip> On all these ftp servers there is a list of mirror sites you may - want to use for faster access. + want to use for faster access.<p> + + Another source for little endian MIPS binaries is + <htmlurl url="ftp://intel.cleveland.lug.net/pub/Mipsel" + name="ftp://intel.cleveland.lug.net/pub/Mipsel"> which carries mostly newer + versions of binaries for the Redhat flavour shipping with the Cobalt's.<p> <sect1>Anonymous CVS servers.<p> For those who always want to stay on the bleeding edge and want to avoid having to download patch files or full tarballs we also have an anonymous CVS server. Using CVS you can checkout the Linux/MIPS source tree with the following commands:<p> + <verb> - cvs -d :pserver:cvs@linus.linux.sgi.com:/cvs login + cvs -d :pserver:cvs@oss.sgi.com:/cvs login (Only needed the first time you use anonymous CVS, the password is "cvs") - cvs -d :pserver:cvs@linus.linux.sgi.com:/cvs co <repository> + cvs -d :pserver:cvs@oss.sgi.com:/cvs co <repository> </verb> - where you insert linux, libc, or gdb for <repository>. + where you insert linux, libc, gdb or faq for <repository>. The other important CVS archive of the Linux community is vger.rutgers.edu where a lot of code is being collected before being sent to Linus for distribution. Although vger itself no longer offers anonymous access, there are mirror sites which do provide anonymous access. For details how to access - them see <url url="http://cvs.on.openprojects.net/">. The modules - which are of interest are “linux”, “modutils”, - “pciutils”, “netutils”. + them see <url url="http://cvs.on.openprojects.net/">. The modules which are + of interest are ``linux'', ``modutils'', ``pciutils'', ``netutils''. <sect1>Web servers.<p> - The two primary anonymous web servers for Linux/MIPS are + The two primary web servers for Linux/MIPS are <descrip> - <tag><htmlurl url="ftp://www.linux.sgi.com" name="www.linux.sgi.com"><p> + <tag><url url="http://oss.sgi.com/mips"><p> This server covers most of Linux/MIPS; it's somewhat SGI centric but since Linux/MIPS tries to be the same on every platform most of its information is of interest to all users. - <tag><htmlurl url="ftp://lena.fnet.fr" name="lena.fnet.fr"><p> + <tag><url url="http://lena.fnet.fr"><p> This server is currently pretty outdated; it's included here mostly for completeness. </descrip> All these servers have mirrors scattered all over the world; you may want to use one for best performance. + <sect1>Web CVS server.<p> + Via <url url="http://oss.sgi.com/mips/cvsweb"> you have + directs access the new Linux/MIPS kernel sources and a few other projects + hosted in the same CVS archive. The intuitive interface allows you to + follow the development at the click of your mouse. + <sect1>Mailing lists.<p> There are three Linux/MIPS oriented mailing lists: <descrip> @@ -484,20 +584,21 @@ find information that actually should be covered elsewhere. This mailing list is used for most non-SGI related communication of all kinds. Subscription is handled by a human; send your subscription requests to <htmlurl url="mailto:linux-mips-request@fnet.fr" - name="linux-mips-mips@fnet.fr">. You can unsubscribe from this mailing + name="linux-mips-request@fnet.fr">. You can unsubscribe from this mailing list by sending <em>unsubscribe <your-email-address></em> to the same address. - <tag><htmlurl url="mailto:linux@engr.sgi.com" - name="linux@engr.sgi.com"><p> - This mailing list currently has the most traffic. It's somewhat SGI-centric - but is nevertheless of interest especially to developers as a good number - of SGI engineers are subscribed to this list. Subscription to this list - is handled via <htmlurl url="mailto:majordomo@engr.sgi.com" - name="Majordomo (majordomo@engr.sgi.com)">; just send an email with the - words <em>subscribe linux-mips</em>. In order to unsubscribe send - <em>unsubscribe linux-mips</em>. Note that you have to be subscribed if you - want to post; the growth of spam forced us into that policy. + <tag><htmlurl url="mailto:linux-mips@oss.sgi.com" + name="linux-mips@oss.sgi.com"><p> This mailing list currently has the most + traffic. It's somewhat SGI-centric but is nevertheless of interest + especially to developers as a good number of SGI engineers are subscribed + to this list. Subscription to this list is handled via + <htmlurl url="mailto:majordomo@oss.sgi.com" + name="Majordomo (majordomo@oss.sgi.com)">; just send an email with the + words <em>subscribe linux</em>. In order to unsubscribe send + <em>unsubscribe linux</em>. Note that you have to be subscribed if you + want to post; the growth of spam forced us into that policy. For more + information see also <url url="http://oss.sgi.com/mips/email.html">. <tag><htmlurl url="mailto:linux-mips@vger.rutgers.edu" name="linux-mips@vger.rutgers.edu"><p> @@ -509,6 +610,10 @@ find information that actually should be covered elsewhere. <em>unsubscribe linux-mips</em>. </descrip> + <sect1>IRC channel.<p> + There is a IRC channel named #mipslinux for Linux/MIPS which may be found on + irc.openprojects.net. + <sect>Installation of Linux/MIPS and common problems.<p> <sect1>NFS booting fails.<p> @@ -592,6 +697,21 @@ find information that actually should be covered elsewhere. This is a known bug in older binutils versions. You will have to upgrade to binutils 2.8.1 plus very current patches. + <sect1>My machine doesn't download the kernel when I try to netboot<p> + + Your machine is replying to the BOOTP packets (you may verify this + using a packet sniffer like tcpdump or ethereal) but doesn't download the + kernel from your BOOTP server. This is happens if your boot server is + running a kernel of the 2.3 series or higher. The problem may be circumvented + by doing a "echo 1 > /proc/sys/net/ipv4/ip_no_pmtu_disc" as root on your + boot server. + + <sect1>Bug in DHCP version 2<p> + When using DHCP version 2 you might see the following problem: + Your machines receives it's BOOTP reply 3 times but refuses to start TFTP. + You can fix this by doing a "unsetenv netaddr" in the PROM command monitor before you boot your + system. DHCP version 3 fixes that problem. + <sect>Milo<p> Milo is the boot loader used to boot the little endian MIPS systems with ARC firmware, currently the Jazz family and the SNI RM 200. @@ -621,10 +741,40 @@ find information that actually should be covered elsewhere. version 2.1.121 installed. Older versions won't work. <sect>How do I setup a crosscompiler?<p> - First of all go and download the following source packages: + <sect1>Available binaries<p> + The easist thing to setup a crosscompiler is to just download the binaries. + For Linux/i386 hosts and big endian targets this are the packages: + <verb> + binutils-mips-linux-2.8.1-1.i386.rpm + egcs-c++-mips-linux-1.0.3a-1.i386.rpm + egcs-g77-mips-linux-1.0.3a-1.i386.rpm + egcs-libstdc++-mips-linux-2.8.0-1.i386.rpm + egcs-mips-linux-1.0.3a-1.i386.rpm + egcs-objc-mips-linux-1.0.3a-1.i386.rpm + </verb> + + And this is the list of packages for little endian targets: + <verb> + binutils-mipsel-linux-2.8.1-1.i386.rpm + egcs-c++-mipsel-linux-1.0.3a-1.i386.rpm + egcs-g77-mipsel-linux-1.0.3a-1.i386.rpm + egcs-libstdc++-mipsel-linux-2.8.0-1.i386.rpm + egcs-mipsel-linux-1.0.3a-1.i386.rpm + egcs-objc-mipsel-linux-1.0.3a-1.i386.rpm + </verb> + + It's not necessary that you install all these packages; most people can + just omit the C++, Objective C and Fortran 77 compilers. The + Intel binaries have been linked against GNU libc 2.1, so you may have + to install that as well when upgrading. + + <sect1>Building your own crosscompiler<p> + First of all go and download the following source packages and patches: <itemize> <item>binutils-2.8.1.tar.gz - <item>egcs-1.0.2.tar.gz + <item>binutils-2.8.1-2.diff.gz + <item>egcs-1.0.3a.tar.gz + <item>egcs-1.0.3a-1.diff.gz <item>glibc-2.0.6.tar.gz <item>glibc-crypt-2.0.6.tar.gz <item>glibc-localedata-2.0.6.tar.gz @@ -636,15 +786,15 @@ find information that actually should be covered elsewhere. order binutils, egcs, then glibc. Unless you have older versions already installed, changing the order <sl>will</sl> fail. The installation description below mentions a number of patches which you can get from the - respective SRPM packages on <htmlurl url="ftp://ftp.linux.sgi.com" - name="ftp.linux.sgi.com">. However since these SRPM packages are intended + respective SRPM packages on <htmlurl url="ftp://oss.sgi.com" + name="oss.sgi.com">. However since these SRPM packages are intended to be compiled natively it's not possible to just rebuild them. <sect1>Diskspace requirements<p> For the installation you'll have to choose a directory for installation. I'll refer to that directory below with <prefix>. To avoid a certain - problem it's best to use the same value for <prefix> as your native gcc. For - example if your gcc is installed in /usr/bin/gcc then choose /usr for + problem it's best to use the same value for <prefix> as your native gcc. + For example if your gcc is installed in /usr/bin/gcc then choose /usr for <prefix>. You must use the same <prefix> value for all the packages that you're going to install.<p> During compilation you'll need about 31mb diskspace for binutils; for @@ -670,8 +820,9 @@ find information that actually should be covered elsewhere. <sect1>Configuration names<p> Many of the packages based on autoconf support many different architectures and operating systems. In order to differentiate between - these many configurations, names are constructed with <cpu>-<company>-<os> - or even <cpu>-<company>-<kernel>-<os>. Expressed this way + these many configurations, names are constructed with + <cpu>-<company>-<os> or even + <cpu>-<company>-<kernel>-<os>. Expressed this way the configuration names of Linux/MIPS are mips-unknown-linux-gnu for big endian targets or mipsel-unknown-linux-gnu for little endian targets. These names are a bit long and are allowed to be abbreviated to mips-linux or @@ -705,7 +856,22 @@ find information that actually should be covered elsewhere. scripts to fail silently; it was never necessary and was only installed because of a bug in older GCC versions. Check to see if the file <prefix>/<target>/include/assert.h exists in your installation. If - so, just delete the it: it should never have been installed. + so, just delete the it: it should never have been installed for any version + of the crosscompiler and will cause trouble. + + <sect1>Installing the kernel sources<p> + Installing the kernel sources is simple. Just place them into some directory + of your choice and configure them. Configuring them is necessary such that + files which are generated by the procedure will be installed. Make shure + you enable CONFIG_CROSSCOMPILE near the end of the configuration process. + The only problem you may run into is that you may need to install some + required GNU programs like bash or have to override the manufacturer-provided + versions of programs by placing the GNU versions earlier in the PATH variable. + Now go to the directory <prefix>/<target>/include and create two + symbolic links named asm and linux pointing to include/asm rsp. include/linux + within your just installed and configured kernel sources. These are + necessary such that necessary header files will be found during the next + step. <sect1>First installation of egcs<p> Now the not-so-funny part begins: there is a so-called bootstrap problem. @@ -715,16 +881,12 @@ find information that actually should be covered elsewhere. once when you install a crosscompiler for the first time. Later when you already have glibc installed things will be much smoother. So now do: <verb> - gzip -cd egcs-<version>.tar.gz | tar xf - + gzip -cd egcs-1.0.3a.tar.gz | tar xf - cd egcs-<version> - for i in egcs-1.0.2-libio.patch egcs-1.0.2-hjl.patch \ - egcs-1.0.2-rth1.patch egcs-1.0.2-rth2.patch egcs-1.0.2-rth3.patch \ - egcs-1.0.2-rth4.patch egcs-1.0.2-hjl2.patch egcs-1.0.2-jim.patch \ - egcs-1.0.2-haifa.patch egcs-1.0.1-objcbackend.patch \ - egcs-1.0.2-mips.patch; do patch -p1 -d < ../$i; done + patch -p1 < ../egcs-1.0.3a-mips.patch ./configure --prefix=<prefix> --with-newlib --target=<target> - cd gcc - make LANGUAGES="c" + make SUBDIRS="libiberty texinfo gcc" ALL_TARGET_MODULES= \ + CONFIGURE_TARGET_MODULES= INSTALL_TARGET_MODULES= LANGUAGES="c" </verb> Note that we deliberately don't build gcov, protoize, unprotoize and the libraries. Gcov doesn't make sense in a crosscompiler environment and @@ -733,47 +895,18 @@ find information that actually should be covered elsewhere. because we don't have glibc installed yet. If everything went successfully, install with: <verb> - make LANGUAGES="c" install + make SUBDIRS="libiberty texinfo gcc" INSTALL_TARGET_MODULES= \ + LANGUAGES="c" install </verb> - <sect1>float.h<p> - Another bootstrap problem is that building GCC requires running programs - on the machine for which GCC will generate code, but since a crosscompiler - is running on a different type of machine this cannot work. When building - GCC this happens for the header file float.h. Luckily there is a simple - solution: download the header file from one of the Linux/MIPS ftp servers - or rip it from one of the native Linux/MIPS binary packages. Later when - recompiling or upgrading egcs usually the already-installed float.h file - will do because float.h changes rarely. Install it with: - <verb> - cp float.h <prefix>/<target/<version>/include/float.h - </verb> - where <version> is the internal version number of the egcs version you're - using. For egcs 1.0.2 for example you would use egcs-2.90.27 for - <version>. If not sure - ls is your friend.<p> + If you only want the crosscompiler for building the kernel, you're done. + Crosscompiling libc is only required to be able to compile user applications. - <sect1>Installing the kernel sources<p> - Installing the kernel sources is simple. Just place them into some - directory of your choice and configure them - such that some files which are generated by the procedure will be - installed. This works the same as you're used to when configuring the - kernel sources for native compilation. The only problem you may run - into is that you may need to install some required GNU programs like - bash or have to override the manufacturer-provided versions of - programs by placing the GNU versions earlier in the PATH variable. When - configuring you should answer the question ``Are you using a - crosscompiler'', that is the option CONFIG_CROSSCOMPILE, with ``yes''. - When you're done with configuring type make clean; make depend; make. - The last make command will generate the header file <linux/version.h> - which compiling some programs depends on. This file is - generated right at the beginning of the make command, so if - you're not interested in actually building a kernel you may interrupt - the compilation after this file has been built. It may be a good idea, - however, to compile the kernel as a test for your newly-built crosscompiler. - - If you only want the crosscompiler for building the kernel, you're done. - Crosscompiling libc is only required to be able to compile user - applications. + <sect1>Test what you've done so far<p> + Just to make shure that what you've done so far is actually working you + may now try to compile the kernel. Cd to the MIPS kernel's sources and + type ``make clean; make dep; make''. If everything went ok do ``make clean'' + once more to clean the sources. <sect1>Installing GNU libc<p> Do: @@ -827,11 +960,7 @@ find information that actually should be covered elsewhere. <verb> gzip -cd egcs-<version>.tar.gz | tar xf - cd egcs-<version> - for i in egcs-1.0.2-libio.patch egcs-1.0.2-hjl.patch \ - egcs-1.0.2-rth1.patch egcs-1.0.2-rth2.patch egcs-1.0.2-rth3.patch \ - egcs-1.0.2-rth4.patch egcs-1.0.2-hjl2.patch egcs-1.0.2-jim.patch \ - egcs-1.0.2-haifa.patch egcs-1.0.1-objcbackend.patch \ - egcs-1.0.2-mips.patch; do patch -p1 < ../$i; done + patch -p1 < ../egcs-1.0.3a-mips.patch ./configure --prefix=<prefix> --target=<target> make LANGUAGES="c c++ objective-c f77" </verb> @@ -842,12 +971,9 @@ find information that actually should be covered elsewhere. <verb> make LANGUAGES="c c++ objective-c f77" install </verb> - You're almost finished. All you have left to do now is to reinstall - float.h, which has been overwritten by the last make install command. - You'll have to do this every time you reinstall egcs as a crosscompiler. - If you think you don't need the Objective C or F77 compilers you can - omit them from above commands; each will save you about 3mb. Do not - build gcov, protoize or unprotoize. + You're almost finished. If you think you don't need the Objective C or + F77 compilers you can omit them from above commands; each will save you about + 3mb. Do not build gcov, protoize or unprotoize. <sect1>Should I build the C++, Objective C or F77 compilers?<p> The answer to this question largely depends on your use of your crosscompiler @@ -856,6 +982,21 @@ find information that actually should be covered elsewhere. F77 compilers. You must, however, build the C++ compiler, because building the libraries included with the egcs distribution requires C++. + <sect1>Known problem when crosscompiling<p> + <sect2>IRIX crashes<p> + Origin 200 running IRIX 6.5.1 may crash when running ``make depend'' + on the Linux kernel sources. IRIX 6.5 on Indy and IRIX 6.5.4 on + Origin 200 are known to work. Further reports on that help isulating + the problematic configuration are welcome. + + <sect2>Resource limits on System V based hosts<p> + Typical System V based Unices like IRIX or Solaris have limits for + the maximum number of arguments to be passed to a child process which + may be exceeded when crosscompiling some software like the Linux kernel + or GNU libc. For IRIX systems the maximum length of the argument list + defaults to 20kb while Linux defaults to at least 128kb. This size + can be modified by the command ``systune ncargs 131072'' as root. + <sect1>GDB<p> Building GDB as crossdebugger is only of interest to kernel developers; for them GDB may be a life saver. Such a remote debugging setup always @@ -886,9 +1027,8 @@ find information that actually should be covered elsewhere. to the Linux/MIPS mailing list! John Hennessey, father of the MIPS architecture, was kind enough to write - in the foreword: “ ... this book is the best combination of - completeness and readability of any book on the MIPS architecture - ...” + in the foreword: ``... this book is the best combination of completeness + and readability of any book on the MIPS architecture ...''; It includes some context about RISC CPUs, a description of the architecture and instruction set including the "co-processor 0" @@ -918,11 +1058,11 @@ find information that actually should be covered elsewhere. level, by the author of PMON. Strengths: lots of examples; weakness: leaves out some big pieces of the architecture (such as memory management, floating point and advanced caches) because they didn't feature in the LSI - “embedded” products this book was meant to partner. + ``embedded''; products this book was meant to partner. <sect1>Computer Architecture - A Quantitative Approach<p> authors Hennessy & Patterson, published Morgan Kaufmann, - ISBN 1-58860-329-8. + ISBN 1-55860-329-8. The bible of modern computer architecture and a must-read if you want to understand what makes programs run slow or fast. Is it about MIPS? @@ -930,211 +1070,11 @@ find information that actually should be covered elsewhere. defect is its size and weight - but unlike most big books it's worth every page. -<sect>Linux/MIPS news<p> - Some of this chapter is pretty historic ... - - <descrip> - <tag>04-Dec-98<p> - Ariel Faigon announces that SGI has joined Linux International. - - <tag>13-Oct-98<p> - Ralf Bächle fixes the support for R4000SC / R4400SC CPUs. - - <tag>12-Oct-98<p> - Vladimir Roganov reports that his R3000 system is now stable enough to - compile GDB. - - <tag>03-Oct-98<p> - Harald Körfgen reports that his DECstation 5000/133 is now running - single user. Congratulations! - - <tag>29-Sep-98<p> - Ralf starts rewriting this FAQ to fit with reality. - - <tag>10-Jun-98<p> - ftp.linux.sgi.com now offers anonymous CVS access. - - <tag>01-Feb-98<p> - First commercial Linux/MIPS based product accounced. - - <tag>26-Jan-98<p> - One more timewarp in this list because the maintainer is lazy^H^H^H^H - busy coding. The driver for the NCR53c8xx has been modified and has been - successfully tested with several machines, most notably the SNI RM200. Even - better, the initial version seems to be reliable.<p> - Already some time ago Thomas Bogendörfer implemented the necessary - changes to the NCR53C9x driver aka ESP driver, so there is now SCSI support - for the builtin hostadapters in the Mips Magnum 4000, Olivetti M700-10 and - Acer PICA. - - <tag>28-Nov-97<p> - First public release of X11 client binaries. - - <tag>30-Aug-97<p> - Duh, time warp in this page once again. A lot has happend in the meantime - and the maintainer of this pages is a lazy person that rather prefers to - code and hack than write docs...<p> - SGI now has its own Linux/MIPS server reachable as http://www.linux.sgi.com, - with lots of SGI specific information and many links. The server is also reachable - under ftp.linux.sgi.com. In addition to binaries, sources and docs specific - to Silicon Graphic machines this server also has all the other Linux/MIPS - stuff in stock. Only available on this server is the developers' cvs archive - for download. Sorry, no anonymous CVS yet.<p> Silicon Graphics has supported - some of the Linux key developers' work on Linux/MIPS with hardware. As a - result the work is now advancing more quickly and Ralf is no longer the lone - workhorse ...<p> Already available for some time the Indy port is now in - the standard kernel source tree.<p> Long missing, but finally there: Thomas - Bogendoerfer contributed patches to the NCR53C9x driver for Mips Magnum 4000, - Olivetti M700 and Acer PICA.<p> Many more packages of a RedHat port to MIPS - are now available for ftp download. Installing is still more a thing for - experts ... but we're working on it!<p> Eeecmacs lovers will be pleased to - hear that this FAQ has been edited by Emacs running on a Linux/MIPS machine. - - <tag>6-May-97<p> - David Monro releases version 1.01 of bfsd. bfsd is a daemon that can be - used to boot the machines built by Mips Computersystems, Inc. over a - network. - - <tag>10-Jun-96<p> - Release of Linux/MIPS kernel 2.0.4. This release features a partially - rewritten signal handler that should match POSIX.1. - - <tag>3-Jun-96<p> - First release of shared libraries for Linux/MIPS based on GNU libc snapshot - 960619.<p> - Release of Linux/MIPS kernel 2.0.1.<p> - - <tag>25-May-96<p> - David S. Miller starts working on SGI support at Silicon Graphics.<p> - - <tag>20-May-96<p> - Release 1.3.98 of the kernel adds support for the SNI RM200 PCI.<p> - - <tag>27-Mar-96<p> - Linux/MIPS works as NFS server. <p> - The IDE CD driver now also supports Linux/MIPS. - - <tag>24-Mar-96<p> - Added reference to literature available online form SGI to the FAQ.<p> - - <tag>23-Mar-96<p> - New chapter in the FAQ about the ARC standard. - - <tag>27-Jan-96<p> - Release of Milo 0.26 and a kernel patch to use it. This release passes - parameters to the kernel in a completly different way that makes porting - Linux/MIPS to another architecture a lot easier. - - <tag>24-Jan-96<p> - Release of crosscompiler binaries based on the FSF's Binutils version 2.6. - This release brings lots of new features and many bugfixes. - - <tag>21-Jan-96<p> - Warner Losh started working on a port of Linux/MIPS to Deskstation rPC44. - - <tag>20-Jan-96<p> - Linux/MIPS kernel updated to version 1.3.58.<p> - Patch gcc-2.7.2-1.diffs.gz has been released.<p> - Patch binutils-2.6-1.diffs.gz has been released. This patch contains lots of - bugfixes. The Linux kernel Makefiles will automatically detect whether - Binutils 2.6 or an older version is installed and use the new features - resulting in a much smaller kernel executable which is especially useful for - bootdisks.<p> - - <tag>15-Jan-96<p> - Release of a complete root and /usr filesystem that can be NFS mounted to use - a Linux/MIPS system as a diskless client. A native development kit based on - GCC 2.7.2, Binutils 2.6 and GNU libc snapshot 951218 is included as well as - many of the standard utilities. - <P> - - <tag>25-Dec-95<p> - Linux/MIPS boots off an NFS filesystem as a diskless client. This also means - that the rest of Linux/MIPS networking is operational now. - - <tag>7-Jan-95<p> - Soft-N-Hard GMBH and SNI sign a contract. SNI will loan an RM200 - to Soft-N-Hard for porting Linux/MIPS to it. - - <tag>22-Sep-95<p> - The Linux/MIPS FTP archive and mailing list have been moved to fnet.fr. - (There is much more news I currently have no time to document) - - <tag>18-Jul-95<p> - New crossdevelopment tools released. GCC-2.6.3-2 and Binutils-2.5.2-2 for - Linux/i386 need kernels with ELF support and libc-5.0.9 installed. The new - crossdev tools are required for Linux/MIPS kernels above 1.2.9. A.out - versions of the crossdev tools will follow soon. - - <tag>14-Jul-95<p> - We have a working shell! - - <tag>12-Jul-95<p> - Patches 2.6.3-2 for Linux/MIPS GCC released. This compiler better complies - with the MIPS standard of symbol names. - - <tag>10-Jul-95<p> - Linux/MIPS kernel 1.2.9 released. - - <tag>9-Jun-95<p> - Milo 0.24 released. This version features improved machine type detection and - many cleanups and bugfixes. - - <tag>24-May-95<p> - Linux/MIPS kernel 1.2.8 released. This version features many bugfixes and has - the Magnum 4000 specific changes from Linux-1.2.7 integrated.<p> - Milo 0.23 released. This version features built-in support for Olivetti M700 - machines. Milo is now split into two binaries: A simple bootloader and a - standalone debugger/monitor with boot capability.<p> - - <tag>23-5-95<p> - Linux/MIPS kernel 1.2.7 on Olivetti M700 mounts root file system.<p> - - <tag>22-May-95<p> - Linux/MIPS kernel 1.2.7 on Mips Magnum 4000 mounts root file system.<p> - Added NEC RiscStation and RiscServer to target list.<p> - Milo 0.22 successfully tested on NEC RiscStation and RiscServer. - - <tag>18-May-95<p> - Linux/MIPS kernel 1.2.7 released. This release features initial - Magnum 4000 support and tons of bugfixes.<p> - - <tag>12-May-95<p> - Milo 0.22 released. This version contains some cleanups and several - bugfixes. - - <tag>5-May-95<p> - The Linux/MIPS archive is now also available from - ftp://ftp.mcc.ac.uk/pub/linux/MIPS. - - <tag>3-May-95<p> - Milo 0.21 released. This version features more built-in debugger/monitor - commands and contains some important bug fixes. - - <tag>30-Apr-95<p> - Milo 0.20 released. This version features a built-in debugger/monitor - and a lot of new library functions.<p> - Port to Olivetti M700 started.<p> - - <tag>26-Apr-95<p> - Linux/MIPS kernel 1.2.6 released. - - <tag>13-Apr-95<p> - Milo 0.19 released. This version includes some minor fixes plus initial - support for kernels in ELF format. - - <tag>13-Apr-95<p> - Milo 0.18b released. - This version includes support for Mips Magnum 4000. Port to - Mips Magnum 4000 started. - - <tag>27-Mar-95<p> - Linux/MIPS kernel 1.2.2 released. Kernel now mounts its root file system. - - <tag>22-Mar-95<p> - Milo 0.18 released. This version includes support for Deskstation rPC44 - systems.<p> - Port to DeskStation rPC44 started.<p> - </descrip> + <sect1>UNIX System V ABI MIPS Processor Supplement<p> + by Prentice Hall, published 05/1991, ISBN 0-13880-170-3. + This book defines many of the MIPS specific technical standards like calling + conventions, ELF properties and much more that are being used by Linux/MIPS. + Unfortunately it's out of print. Similarly the site + <em>"http://www.mipsabi.org/"</em> is offline. </article> diff --git a/LDP/howto/linuxdoc/Modem-HOWTO.sgml b/LDP/howto/linuxdoc/Modem-HOWTO.sgml index 960cbd7a..f2485373 100644 --- a/LDP/howto/linuxdoc/Modem-HOWTO.sgml +++ b/LDP/howto/linuxdoc/Modem-HOWTO.sgml @@ -1,13 +1,19 @@ <!doctype linuxdoc system> <article> -<title>The Linux Modem-HOWTO +Modem-HOWTO David S.Lawyer - v0.10, May 2000 + v0.11, June 2000 + + "Hayes" is a trademark of Microcomputer Products Inc. I use "winmodem" to mean any modem which requires MS-Windows and not in the trademark sense. @@ -139,11 +147,10 @@ available to browse and/or download at LDP mirror sites. For a list of such sites see: If you only want to quickly check the date of the latest version go to and -compare it to the version you are currently reading: v0.10, May 2000 +compare it to the version you are currently reading: v0.11, June 2000 New in this Version -

Modem-Sharing mini-howto, digital modems, Newcom -modem, more re "no response to AT" and "can't find modem". +

What is a Modem ?

A modem is a device that lets one send digital signals over @@ -378,7 +385,10 @@ Linux drivers for these modems, specs were not made available so this couldn't be done. Prior to about 2000, no software modem could be used with Linux due to no drivers for them under Linux. -Then finally in late 1999 two software modems appeared that could work +See the new (April 2000) Winmodems-and-Linux-HOWTO for details of how +to get some winmodems to work under Linux. + +Finally in late 1999 two software modems appeared that could work under Linux. Lucent Technologies unofficially released a Linux binary-only code to support its PCI software modems but bugs were reported in early versions. PC-TEL introduced a new software @@ -611,10 +621,9 @@ an ISP?">. Cyclades promotes their own products here so please do comparison shopping before buying anything. -

Before reading this - - Modem & Serial Port -Basics

The kernel 2.2 serial driver contains no special support for the @@ -1412,23 +1423,32 @@ that they only show what the device driver thinks. Some people view certain "files" in the /proc directory and erroneously think that what they see is set in the hardware but "it ain't necessarily so". -/proc/ioports will show the IO addresses that the drivers are using. -/proc/interrupts shows the IRQs that are used by drivers of -currently running processes (that have devices open). Note that -in both cases above you are only seeing what the driver thinks and not -necessarily what is actually set in the hardware. /proc/interrupts also -shows how many interrupts have been issued (often thousands) for each -device. You can get a clue from this because if you see a large -number of interrupts that have been issued it means that there is a -piece of hardware somewhere that is using that interrupt. Sometimes a -showing of just a few interrupts doesn't mean that that interrupt is -actually being physically generated by any serial port. Thus if you -see almost no interrupts for a port that you're trying to use, that -interrupt might not be set in the hardware and it implies that the -driver is using the wrong interrupt. To view /proc/interrupts to -check on a program that you're currently running (such as "minicom") -you need to keep the program running while you view it. To do this, -try to jump to a shell without exiting the program. +/proc/ioports will show the IO addresses that the drivers are using. +/proc/interrupts shows the IRQs that are used by drivers of +currently running processes (that have devices open). It shows how +many interrupts have actually be issued. +/proc/tty/driver/serial shows most of the above, plus the +number of bytes that have been received and sent (even if the device +is not now open). + +Note that for the IO addresses and IRQ assignments, you are only seeing +what the driver thinks and not necessarily what is actually set in the +hardware. The data on the actual number of interrupts issued and +bytes processed is real however. If you see a large number of +interrupts and/or bytes then it probably means that the device is (or +was in the case of bytes) working. If there are no bytes received +(rx:0) but bytes were transmitted (tx:3749 for example), then only one +direction of flow is working (or being utilized). + +Sometimes a showing of just a few interrupts doesn't mean that the +interrupt is actually being physically generated by any serial port. +Thus if you see almost no interrupts for a port that you're trying to +use, that interrupt might not be set in the hardware and it implies +that the driver is using the wrong interrupt. To view +/proc/interrupts to check on a program that you're currently running +(such as "minicom") you need to keep the program running while you +view it. To do this, try to jump to a shell without exiting the +program. What is set in my serial port hardware ?

The IO address of the IBM 8514 video board (and others like it) is -allegedly 0x?2e8 where ? is 2, 4, 8, or 9. This may conflict (but -shouldn't if the serial port is well designed) with the IO address of - ttyS0 address 0x3f8 @@ -1592,6 +1614,13 @@ ttyS2 address 0x3e8 ttyS3 address 0x2e8 +Suppose there is an address conflict (as reported by setserial -g +/dev/ttyS*) between a real serial port and another port which +does not physically exist (and shows UART: unknown). Such a conflict +shouldn't cause problems but it sometimes does in older kernels. To +avoid this problem don't permit such address conflicts or delete +/dev/ttyS? if it doesn't physically exist. + Set IO Address & IRQ in the hardware (mostly for PnP)

The examples given in this subsection are from the Hayes AT modem command set. All command strings must be prefaced by the two letters -AT (for example: AT&C1&D3 ). When a modem is powered on, it -automatically configures itself with one of the configurations it has -stored in its non-volatile memory. If this configuration is -satisfactory there is nothing further to do. +AT. For example: AT&C1&D3^M (^M is the return character). +When a modem is powered on, it automatically configures itself with +one of the several configurations it has stored in its non-volatile +memory. If this configuration is satisfactory there is nothing +further to do. If it's not satisfactory, then one may either alter the stored configuration or configure the modem each time you use it by sending it a string of commands known as an "init string" (= initialization -string). Normally a a communication program does this. What it sends -will depend on how you configured the communications program or what -script you wrote for it if you use Kermit. You can usually edit the -init string your communication program uses and change it to whatever -you want. Sometimes the communications program will let you select -the model of your modem and then it will use an init string that it -thinks is best for that modem. +string). Normally, a a communication program does this. What it +sends will depend on how you configured the communications program. +You can usually edit the init string your communication program uses +and change it to whatever you want. Sometimes the communications +program will let you select the model of your modem and then it will +use an init string that it thinks is best for that modem. -The configuration of the modem uses when it's first powered on could -be expressed by an init string. You might think of this as the -default "string" (called a profile). If your communications program -sends the modem another string (the init string), then this string -will modify the default configuration. For example, if the init -string only contains two commands, then only those two items will be -changed. However, some commands will recall a stored profile from -inside the modem so a single such command in the init string can -thereby change everything in the configuration. +The configuration of the modem when it's first powered on may be +expressed by an init string. You might think of this as the default +"string" (called a profile). If your communications program sends the +modem another string (the init string), then this string will modify +the default configuration. For example, if the init string only +contains two commands, then only those two items will be changed. +However, some commands will recall a stored profile from inside the +modem so a single such command in the init string can thereby change +everything in the configuration. Modern modems have a few different stored profiles to choose from that are stored in the modem's non-volatile memory (it's still there when you turn it off). In my modem there are two factory profiles (0 and 1, neither of which you can change) and two user defined profiles (0 and 1) that the user may set and store. Your modem may have more. -Which one of these user-defined profiles is used at power-up depends -on another item stored in the profile. If the command &Y0 is -given then in the future profile 0 will be used at power-on. If it's -a 1 instead of a 0 then profile 1 will be used at power-on. +To view some of these profiles send the command &V. +At power-up one of the user-defined profiles is loaded. For example, +if you type the command &Y0 then in the future profile 0 will be +used at power-on. -There are also commands to recall (use it now) any of the 4 stored -profiles. One may put such a command in an init string. Of course if -it recalls the same profile as was automatically loaded at power-up, -nothing is changed unless the active profile has been modified since -power-up. Since it could have been modified It's a good idea to use -some kind of an init string even if it does nothing more than -recalling a stored profile. +There are also commands to load (activate) any of the stored profiles. +Such a load command may be put in an init string. Of course if it +loads the same profile that was automatically loaded at power-up, +nothing is changed (unless the active profile has been modified since +power-up). Since it could have been modified it's a good idea to use +some kind of an init string even if it does nothing more than load a +stored profile. -Recalling a saved profile (use 1 instead of 0 for profile 1): -Z0 recalls user-defined profile 0 and resets (hangs up, etc.) -&F0 recalls factory profile 0 +Examples of loading saved profiles: +Z0 loads user-defined profile 0 and resets (hangs up, etc.) +&F1 loads factory profile 1 Once you have sent commands to the modem to configure it the way you -want (including recalling a factory profile and modifying it a little) +want (such as loading a factory profile and modifying it a little) you may save this as a user-defined profile: &W0 saves the current configuration to user-profile 0 Many people don't bother saving a good configuration in their modem, but instead, send the modem a longer init string each time the modem -is used. Another method is to restore the factory default at the -start of the init string and then modify it a little by adding a few -other commands to the end of the init string. By doing it this way no -one can cause problems by modifying the user-defined profile which is -loaded at power-on. +is used. Another method is to restore the factory default by &F1 +at the start of the init string and then modify it a little by adding +a few other commands to the end of the init string. By doing it this +way no one can cause problems by modifying the user-defined profile +which is loaded at power-on. -You may pick an init string supplied by someone else that they think +You may choose an init string supplied by someone else that they think is right for your modem. Some communication programs have a library of init strings to select from. The most difficult method (and one which will teach you the most about modems) is to study the modem manual and write one yourself. You could save this configuration inside the modem so that you don't need an init string. A third -alternative is to start with an init string someone else wrote, but -modify it to suit your purposes. +alternative is to start with an init string that someone else wrote, +but modify it to suit your purposes. -Now if you look at init strings used by communication programs you may -see symbols which are not valid modem commands. These symbols are -commands to the communication program itself (such as ~ meaning to -pause briefly) and will not be sent to the modem. +If you look at init strings used by communication programs you may see +symbols which are not valid modem commands. These symbols are +commands to the communication program itself and will not be sent to +the modem. For example, ~ means to pause briefly. Other Modem Commands

Future editions of Modem-HOWTO may contain more AT commands but @@ -1848,22 +1878,18 @@ default or by a saved configuration). E1 command echo ON Q0 result codes are reported -V1 verbose ON +V1 result codes are verbose S0=0 never answer (uugetty does this with the WAITFOR option) Here's some more codes concerning modem control lines DCD and DSR: -&ero;C1 DCD is on after connect only +&ero;C1 DCD is on only after connect &ero;S0 DSR is always on These affect what your modem does when calls start and end. -What DTR does may also be set up but it's more complicated. - -

If your modem does not support a stored profile, you can set these -through the Greg Hankins has a collection of modem setups for different types of modems. If you would like to send him your working configuration, @@ -1955,15 +1981,18 @@ even when the modem fails to assert DCD (since no one has called into it and there's no carrier). That's why cua was once used for dial-out and ttyS used for dial-in. -Starting with Linux kernel 2.2, a warning message will be put in the -kernel log when one uses cua. This is an omen that cua is on the way -out. +Starting with Linux kernel 2.2, a warning message is put in the +kernel log when one uses cua. This is an omen that cua is defunct and +should be avoided if possible. Interesting Programs You Should Know About What is setserial ?

This part is in 3 HOWTOs: Modem, Serial, and Text-Terminal. There are some minor differences, depending on which HOWTO it appears in. @@ -1975,8 +2004,8 @@ set in the port's hardware, what type of UART you have, etc. It can also show how the driver is currently set. In addition, it can be made to probe the hardware and try to determine the UART type and IRQ, but this has severe limitations. See . Note that it can't set the IRQ, etc in the hardware -of PnP serial ports. +name="Probing">. Note that it can't set the IRQ or the port address +in the hardware of PnP serial ports. If you only have one or two built-in serial ports, they will usually get set up correctly without using setserial. Otherwise (or if there @@ -1993,10 +2022,10 @@ equivalent was compiled into your kernel). If you should (for some reason) unload the serial module later on, the changes previously made by you'll see some info about how that device driver is configured for -your ports. Add a -a to the option -g to see more info although few +your ports. Note that where it says "UART: unknown" it +probably means that no uart exists. In other words you probably have +no such serial port and the other info shown about the port is +meaningless and should be ignored. If you really do have such a +serial port, setserial doesn't recognize it and that needs to be +fixed. + +If you add -a to the option -g you will see more info although few people need to deal with (or understand) this additional info since the default settings you see usually work fine. In normal cases the hardware is set up the same way as "setserial" reports, but if you are @@ -2030,7 +2066,11 @@ In fact, you can run "setserial" and assign a purely fictitious I/O port address, any IRQ, and whatever uart type you would like to have. Then the next time you type "setserial ..." it will display these bogus values without complaint. Of course the serial port driver will -not work correctly (if at all) with such bogus values. +not work correctly (if at all) if you attempt to use such a port. +Thus when giving parameters to "setserial" anything goes. It gives +you no warning if what you tell it is incorrect and will allow you to +create conflicts in IRQs and I/O port addresses that will have +disastrous results later on. While assignments made by setserial are lost when the PC is powered off, a configuration file may restore them (or a previous @@ -2243,10 +2283,11 @@ Debian labeled obsolete files with "...pre-2.15". IRQs -

By default, both ttyS0 and ttyS2 share IRQ 4, while ttyS0 and -ttyS3 share IRQ 3. But sharing serial interrupts is not permitted -unless you: 1. have kernel 2.2 or better, and 2. you've complied in -support for this, and 3. your serial hardware supports it. See +

By default, both ttyS0 and ttyS2 will share IRQ 4, while ttyS1 and +ttyS3 share IRQ 3. But actually sharing serial interrupts (using them +in running programs) is not permitted unless you: 1. have kernel 2.2 +or better, and 2. you've complied in support for this, and 3. your +serial hardware supports it. See @@ -2320,12 +2361,12 @@ you may use stty again. Are You Ready to Dial Out ?

Once you've plugged in your modem and know which serial port it's on you're ready to try using it. Before you try to get the Internet -on it or have people call in to you, first try something simpler like -dialing out to some number to see if your modem is working OK. Find a -phone number that is connected to a modem. It you don't know what -number to call, ask at computer stores for such phone numbers of bulletin -boards, etc. or see if a local library has a phone number for their -on-line catalog. +on it or have people call in to you, you could first try something +simpler like dialing out to some number to see if your modem is +working OK. Find a phone number that is connected to a modem. If you +don't know what number to call, ask at computer stores for such phone +numbers of bulletin boards, etc. or see if a local library has a phone +number for their on-line catalog. Then make sure you are ready to phone. Do you know what serial port (such as ttyS2) your modem is on? You should have found this out when @@ -2962,7 +3003,7 @@ speed. The reason the crystal frequency needs to be higher is so that this high crystal speed can be used to take a number of samples of each bit to determine if it's a 1 or a 0. - + Speed Table

It's best to have at least a 16650 UART for a 56k modem but few @@ -3269,7 +3310,7 @@ Minicom). If you have installed an internal modem (serial port is builtin) or are using an external one and don't know what serial port it's connected to then the problem is to find the serial port. See This section is about finding out which serial port +Can't be Found">. This section is about finding out which serial port has the modem on it. There's a program that looks for modems on commonly used serial ports @@ -3287,7 +3328,7 @@ will not detect modems on them. Thus "wvdialconf" is best to try first. Another way try to find out if there's a modem on a port is to start -"minicom" on the port (after first setting up minicon for the correct +"minicom" on the port (after first setting up minicom for the correct serial port --you will need to save the setup and then exit minicom and start it again). Then type "AT" and you should see OK (or 0 if it's set for "digit result codes"). The results may be: @@ -3297,7 +3338,7 @@ it's set for "digit result codes"). The results may be: (including only the cursor moving down one line). See - Some stange characters appear but they are not in response to + Some strange characters appear but they are not in response to AT. This likely means that your modem is still connected to something at the other end of the phone line which is sending some cryptic packets or the like. @@ -3306,24 +3347,28 @@ packets or the like. No response to AT

The modem should send you "OK" in response to your "AT" which you type to the modem (using minicom or the like). If you don't see "OK" -(and in most cases don't even see the "AT" you typed either) the modem -is not responding (assuming there is really a modem on the port you -are typing to). +(and in most cases don't even see the "AT" you typed either) then the +modem is not responding (often because what you type doesn't even get +to the modem). -One reason that a real modem doesn't respond is that it is in -"online data" mode where it can't accept any AT commands. It may be -in use by another process. If such a process is running on the port you -may see it by typing "ps -t ttyS2" or the like. However the process -that's using the serial port (where the modem is) may be running on a -terminal such at /dev/tty1 and will not be found using the above command. +A common cause is that there is no modem on the serial port you are +typing to. For the case of an internal modem, that serial port likely +doesn't exist either. That's because the PnP modem card (which has a +built-in serial port) has either not been configured (by isapnp or the +like) or has been configured incorrectly. See . -You may have been using the modem and then abruptly disconnected (such -as killing the process with signal 9). In that case your modem did -not get reset to "command mode" where it can interact to AT commands. -Thus the message from minicom "You are already online. Hangup first." -Well, you are sort of online but you are may not be connected to -anything over the phone line. wvdial will report "modem not -responding" for the same situation. +If what you type is really getting thru to a modem, then the lack of +response could be due to the modem being in "online data" mode where +it can't accept any AT commands. You may have been using the modem +and then abruptly disconnected (such as killing the process with +signal 9). In that case your modem did not get reset to "command +mode" where it can interact to AT commands. Thus the message from +minicom "You are already online. Hangup first." Well, you are sort +of online but you are may not be connected to anything over the phone +line. Wvdial will report "modem not responding" for the same +situation. To fix this as a last resort you could reboot the computer. Another way to try to fix this is to send +++ to the modem to tell it to @@ -3332,13 +3377,24 @@ of the +++ sequence there must be about 1 second of delay (nothing sent during "guard time"). This may not work if another process is using the modem since the +++ sequence could wind up with other characters inserted in between them or after the +++ (during the guard -time). Ironically, even if the modem line is idle, putting an -unexpected +++ is likely to set off an exchange of packets (or the -like) that will violate the required guard time so that the +++ -doesn't do what you wanted. +++ is usually in the string that is -named "hangup string" so if you command minicom (or the like) to -hangup it might work. Another way to do this is to just exit minicom -and then run minicom again. +time). Ironically, even if the modem line is idle, typing an +unexpected +++ is likely to set off an exchange of control packets +(that you never see) that will violate the required guard time so +that the +++ doesn't do what you wanted. +++ is usually in the string +that is named "hangup string" so if you command minicom (or the like) +to hangup it might work. Another way to do this is to just exit +minicom and then run minicom again. + + "Modem busy" +

The modem could actually be in use (busy). Another cause reported +for the SuSE distribution is that there may be two serial drivers +present instead of one. Both try to work at the same time with +confusing results. One driver may run ahead of the other and the +second driver finds the modem "busy" since the first driver is trying +(in vain) to use it. If serial driver support is built-in, don't also +compile it in. Also, don't let the serial module load if serial +support is already built-in (or compiled-in). There are likely other +causes for a false "modem busy". I can't get near 56k on my 56k modem

There must be very low noise on the line for it to work at even @@ -3438,8 +3494,10 @@ it. - The following subsections are in both the Serial and Modem HOWTOs: +Apr. 00: 2 ports on same address +May 00: address conflict +--> +(The following subsections are in both the Serial and Modem HOWTOs) My Serial Port is Physically There but Can't be Found

The new package PCI Utilities (= pciutils, incorrectly called +

The package PCI Utilities (= pciutils, incorrectly called "pcitools"), should let you manually PnP-configure the PCI bus. -"lspci" lists bus-resources while "setpci" sets resource allocations -in the hardware devices. It appears that setpci is mainly intended -for use in scipts and presently one needs to know the details of the -PCI configuation registers in order to use it. That's a topic not -explained here nor in the manual page for setpci. +"lspci" or "scanpci" (Xwindows) lists bus-resources while "setpci" +sets resource allocations in the hardware devices. It appears that +setpci is mainly intended for use in scripts and presently one needs to +know the details of the PCI configuration registers in order to use it. +That's a topic not explained here nor in the manual page for setpci. Patch the Kernel to Make Linux PnP

David Howells has created a patch to do this called "Linux Kernel @@ -914,9 +923,42 @@ url="http://www.astarte.free-online.co.uk"> Windows Configures

If you have Windows9x (or 2k) on the same PC, then just start Windows and let it configure PnP. Then start Linux from Windows (or -DOS). It has been reported that Windows erased the IRQs from PCI -devices registers. Then Linux complained that it found a zero IRQ. -Thus you may not be able to use this method. +DOS). But there may be a problem with IRQs for PCI devices. As +Windows shuts down to make way for Linux, it may erase (zero) the IRQ +which is stored in one of the PCI device's configuration registers. +Linux will complain that it has found an IRQ of zero. + +The above is reported to happen if you start Linux using a shortcut +(PIF file). But a workaround is reported where you still use the +shortcut PIF. A shortcut is something like a symbolic link in Linux +but it's more than that since it may be "configured". To start Linux +(from DOS you create a batch file (script) which starts Linux. (The +program that starts Linux is in the package called "loadlin"). Then +create a PIF shortcut to that batch file and get to the "Properties" +dialog box for the shortcut. Select "Advanced" and then check "MS-DOS +mode" to get it to start in genuine MS-DOS. + +Now here's the trick to prevent zeroing the PCI IRQs. Check "Specify +a new MS-DOS configuration". Then either accept the default +configuration presented to you or click on "Configuration" to change +it. Now when you start Linux by clicking on the shortcut, new +configuration files (Config.sys and Autoexec.bat) will be created per +your new configuration. The old files are stored as "Config.wos and +Autoexec.wos". Windows would normally restore these files to their +original names if Windows were to be entered again and shut down. But +after Linux boots you don't get back to Windows again so you should +enter commands in the batch file to rename these files to their *.bat +and *.sys names. Put the renaming commands into the batch file before +the line that loads Linux. This will permit Windows (and not Linux) +to start the next time the PC is powered on. + +Also it's reported that you should click on the "General" tab (of the +"Properties" dialog) and check "Read-only". Otherwise Windows may +reset the "Advanced Settings" to "Use current MS-DOS configuration" +and PCI IRQs get zeroed. Thus Windows erases the IRQs when you use the +current MS-DOS configuration but doesn't erase when you use a new +configuration (which may actually configure things identical to +the old configuration). Windows does not seem to be very consistent. Device Driver Configures

A few device drivers will use PnP methods to set the bus-resources in @@ -1098,11 +1140,11 @@ the kernel) may still issue some interrupts for various reasons. How Are My Hardware Devices Configured?

It's easy to find out what bus-resources have been assigned to -devices on the PCI bus with the "lspci" command. For for kernels < -2.2: see /proc/pci or /proc/bus/pci. Note that IRQs -for /proc/pci are in hexadecimal. Don't bother trying to -decipher /proc/bus/pci/devices since "lspci" will do that for -you. +devices on the PCI bus with the "lspci" or "scanpci" commands. For +for kernels < 2.2: see /proc/pci or /proc/bus/pci +for later kernels. Note that IRQs for /proc/pci are in +hexadecimal. Don't bother trying to decipher +/proc/bus/pci/devices since "lspci" will do that for you. For the ISA bus you may try running pnpdump --dumpregs but it's not a sure thing. The results may be seem cryptic but they @@ -1240,9 +1282,10 @@ starting with Kernel 2.2) it's possible for two (or more) devices to share the same IRQ number. When such an interrupt is issued, the CPU runs all interrupt service routines for all devices using that interrupt. The first thing the first service routine does is to check -to see if an interrupt actually happened for its device. If there was -no interrupt (false alarm) it likely will exit and the next service -routine starts, etc. +the device registers to see if an interrupt actually happened for its +device. If it finds that its device didn't issue an interrupt (a false +alarm) it likely will immediately exit and the next service routine +starts, etc. PCI Interrupts

PCI interrupts are different but since they are normally mapped to diff --git a/LDP/howto/linuxdoc/Serial-HOWTO.sgml b/LDP/howto/linuxdoc/Serial-HOWTO.sgml index 41dc5d6e..f5675d4e 100644 --- a/LDP/howto/linuxdoc/Serial-HOWTO.sgml +++ b/LDP/howto/linuxdoc/Serial-HOWTO.sgml @@ -1,14 +1,15 @@

-The Linux Serial HOWTO +<title> Serial HOWTO <author>David S.Lawyer <tt><htmlurl url="mailto:dave@lafn.org" name="dave@lafn.org"></tt> original by Greg Hankins -<date> v2.07 May 2000 +<date> v2.08 June 2000 <!-- Change log: -v2.07 Apr. locking methods, clarity re uart protocol, sticky parity +v2.08 /proc/tty, fixed link to Gary's Encyclopedia. +v2.07 May 2000. locking methods, clarity re uart protocol, sticky parity v2.06 2 March 2000 more on multiport, not 3-3 for null modem, butter -> buffer, v2.05 Vern's & my url, ref to multiport modem cards @@ -108,21 +109,6 @@ to Ted Ts'o for answering questions about the serial drivers. Approximately half of v2.00 was from Greg Hankins HOWTO and the other half is by David Lawyer. Ted Ts'o has continued to be helpful. -<sect1> Release Notes -<p> 2.00 was a major revision which has removed info on Terminals and -Modems from the old Serial-HOWTO and put such info into: -<itemize> -<item> Text-Terminal-HOWTO -<item> Modem-HOWTO -</itemize> - -2.01: Added info on Plug-and-Play from Modem-HOWTO and more. Info on -setserial and stty has been updated. I still haven't checked out all -the info on multiport cards to see if it's up-to-date. The fact that -this HOWTO was pieced together from various sources has resulted in a -certain lack of integration. This may be improved on in future -versions. - <sect1> New Versions of this Serial-HOWTO <p> New versions of the Serial-HOWTO will be available to browse and/or download at LDP mirror sites. For a list of mirror @@ -130,8 +116,7 @@ sites see: <url url="http://metalab.unc.edu/LDP/mirrors.html">. Various formats are available. If you only want to quickly check the date of the latest version look at <url url="http://metalab.unc.edu/LDP/HOWTO/Serial-HOWTO.html"> and compare -it to this version: v2.07 May 2000 . New in this version is: locking methods, clarity re uart protocol, - sticky parity. +it to this version: v2.08 June 2000 . New in this version is: /proc/tty, fixed link to Gary's Encyclopedia. <sect1> Related HOWTO's re the Serial Port <label id="related_howtos"> <p> Modems, Text-Terminals, some printers, and other peripherals often @@ -143,9 +128,12 @@ explained above. <item><tt>Printing-HOWTO</tt> has info on using a serial printer <item><tt>Serial-Programming-HOWTO</tt> helps you write C programs (or parts of them) that read and write to the serial port - and/or check/set its state. A new version is expected soon. + and/or check/set its state. A new version has been written by Vern + Hoxie but not submitted. A copy is at <ref id="vern_" name="Internet">. <item><tt>Text-Terminal-HOWTO</tt> is about how they work, how to install - configure, and repair them. + configure, and repair them. It includes a section on "Make a + Terminal the Console" which is useful for using a remote terminal to + control a server (via the serial port). </itemize> <sect1>Feedback @@ -327,7 +315,8 @@ transmit buffer in main memory and puts them into the small 16-byte transmit buffer in the hardware. <sect> Serial Port Basics <label id="basics_"> -<!-- basics.H begin <sect> Serial Port & Modem Basics --> +<!-- basics.H begin <sect> Serial Port and Modem Basics + or <sect> Serial Port Basics In SS and MM --> <!-- Change log: Nov. '99: 2 serial drivers concurrently NG --> @@ -908,7 +897,7 @@ linux# ./MAKEDEV ttyS17 Besides the listing of various brands of multiports found in this HOWTO there is <url -url="http://members.aa.net/~swear/serialcards.html" name="Gary's +url="http://members.aa.net/~swear/pedia/serialcards.html" name="Gary's Encyclopedia - Serial Cards">. It's not as complete, but may have some different links. @@ -1185,8 +1174,10 @@ name="http://www.ssc.com/lj/issue14"></tt>. </itemize> <sect>Configuring the Serial Port -<!-- configure.H begin -<sect>Configuring the Serial Port --> +<!-- configure.H begin (in MM, SS) +<sect>Configuring the Serial Port +Change-log: +--> <sect1> PCI Bus Support Underway <label id="PCI_"> <p> The kernel 2.2 serial driver contains no special support for the @@ -1414,23 +1405,32 @@ that they only show what the device driver thinks. Some people view certain "files" in the /proc directory and erroneously think that what they see is set in the hardware but "it ain't necessarily so". -/proc/ioports will show the IO addresses that the drivers are using. -/proc/interrupts shows the IRQs that are used by drivers of -currently running processes (that have devices open). Note that -in both cases above you are only seeing what the driver thinks and not -necessarily what is actually set in the hardware. /proc/interrupts also -shows how many interrupts have been issued (often thousands) for each -device. You can get a clue from this because if you see a large -number of interrupts that have been issued it means that there is a -piece of hardware somewhere that is using that interrupt. Sometimes a -showing of just a few interrupts doesn't mean that that interrupt is -actually being physically generated by any serial port. Thus if you -see almost no interrupts for a port that you're trying to use, that -interrupt might not be set in the hardware and it implies that the -driver is using the wrong interrupt. To view /proc/interrupts to -check on a program that you're currently running (such as "minicom") -you need to keep the program running while you view it. To do this, -try to jump to a shell without exiting the program. +<tt>/proc/ioports</tt> will show the IO addresses that the drivers are using. +<tt>/proc/interrupts</tt> shows the IRQs that are used by drivers of +currently running processes (that have devices open). It shows how +many interrupts have actually be issued. +<tt>/proc/tty/driver/serial</tt> shows most of the above, plus the +number of bytes that have been received and sent (even if the device +is not now open). + +Note that for the IO addresses and IRQ assignments, you are only seeing +what the driver thinks and not necessarily what is actually set in the +hardware. The data on the actual number of interrupts issued and +bytes processed is real however. If you see a large number of +interrupts and/or bytes then it probably means that the device is (or +was in the case of bytes) working. If there are no bytes received +(rx:0) but bytes were transmitted (tx:3749 for example), then only one +direction of flow is working (or being utilized). + +Sometimes a showing of just a few interrupts doesn't mean that the +interrupt is actually being physically generated by any serial port. +Thus if you see almost no interrupts for a port that you're trying to +use, that interrupt might not be set in the hardware and it implies +that the driver is using the wrong interrupt. To view +/proc/interrupts to check on a program that you're currently running +(such as "minicom") you need to keep the program running while you +view it. To do this, try to jump to a shell without exiting the +program. <sect2> What is set in my serial port hardware ? <label id="io-irq_in_hdw" @@ -1574,18 +1574,20 @@ conflicts. <sect1> Choosing Addresses --Video card conflict with ttyS3 <p> The IO address of the IBM 8514 video board (and others like it) is -allegedly 0x?2e8 where ? is 2, 4, 8, or 9. This may conflict (but -shouldn't if the serial port is well designed) with the IO address of -<tt/ttyS3/ at 0x02e8 if the serial port ignores the leading 0 hex -digit (many do). That is bad news if you try to use <tt/ttyS3/ at -this IO address. +allegedly 0x?2e8 where ? is 2, 4, 8, or 9. This may conflict with the +IO address of <tt/ttyS3/ at 0x02e8. Your may think that this shouldn't +happen since the addresses are different in the high order digit (the +leading 0 in 02e8). You're right, but a poorly designed serial port +may ignore the high order digit and respond to any address that ends +in 2e8. That is bad news if you try to use <tt/ttyS3/ at this IO +address. In most cases you should use the default addresses if feasible. Addresses shown represent the first address of an 8-byte range. For example 3f8 is really the range 3f8-3ff. Each serial device (as well as other types of devices that use IO addresses) needs its own unique address range. There should be no overlaps (conflicts). Here are the -default addresses for the serial ports: +default addresses for commonly used serial ports: <tscreen><verb> ttyS0 address 0x3f8 @@ -1594,6 +1596,13 @@ ttyS2 address 0x3e8 ttyS3 address 0x2e8 </verb></tscreen> +Suppose there is an address conflict (as reported by <tt>setserial -g +/dev/ttyS*</tt>) between a real serial port and another port which +does not physically exist (and shows UART: unknown). Such a conflict +shouldn't cause problems but it sometimes does in older kernels. To +avoid this problem don't permit such address conflicts or delete +/dev/ttyS? if it doesn't physically exist. + <sect1> Set IO Address & IRQ in the hardware (mostly for PnP) <label id="io-irq_methods"> @@ -1817,12 +1826,14 @@ the use of getty with directly connected terminals now found in Text-Terminal-HOWTO. <sect1> Serial Monitoring/Diagnostics Programs <label id="serial_mon"> -<p> A few Linux programs will monitor various modem control lines and -indicate if they are positive (1 or green) or negative (0 or red). +<p> A few Linux programs (and one "file") will monitor various modem +control lines and indicate if they are positive (1 or green) or +negative (0 or red). <itemize> +<item> The "file": /proc/tty/driver/serial lists those that are positive <item> modemstat (Only works correctly on Linux PC consoles. Status monitored in a tiny window. Color-coded and compact. Must kill - process to quit.) + it (a process) to quit. <item> statserial (Info displayed on entire screen) <item> serialmon (Doesn't monitor RTS, CTS, DSR but logs other functions) @@ -1842,7 +1853,10 @@ for the serial port. <sect1>What is Setserial ? <label id="set_serial"> <!-- setserial.H begin (in MM TT SS) -<sect1>What is Setserial ? <label id="set_serial"> --> +<sect1>What is Setserial ? <label id="set_serial"> +Change Log: +May 2000: <sect2> IRQs near end ttyS0 -> ttyS1 + clarity +--> <p> This part is in 3 HOWTOs: Modem, Serial, and Text-Terminal. There are some minor differences, depending on which HOWTO it appears in. @@ -1854,8 +1868,8 @@ set in the port's hardware, what type of UART you have, etc. It can also show how the driver is currently set. In addition, it can be made to probe the hardware and try to determine the UART type and IRQ, but this has severe limitations. See <ref id="probing_ss" -name="Probing">. Note that it can't set the IRQ, etc in the hardware -of PnP serial ports. +name="Probing">. Note that it can't set the IRQ or the port address +in the hardware of PnP serial ports. If you only have one or two built-in serial ports, they will usually get set up correctly without using setserial. Otherwise (or if there @@ -1872,10 +1886,10 @@ equivalent was compiled into your kernel). If you should (for some reason) unload the serial module later on, the changes previously made by <tt/setserial/ will be forgotten by the kernel. So <tt/setserial/ must be run again to reestablish them. In addition to running via a -start-up script, something akin to <tt/setserial/ also runs when the -serial module is loaded (or the like). Thus when you watch the -start-up messages on the screen it may look like it ran twice, and in -fact it has. +start-up script, something akin to <tt/setserial/ also runs earlier +when the serial module is loaded (or the like). Thus when you watch +the start-up messages on the screen it may look like it ran twice, and +in fact it has. Setserial can set the time that the port will keep operating after it's closed (in order to output any characters still in its buffer in @@ -1900,7 +1914,14 @@ Note that setserial calls an IO address a "port". If you type: setserial -g /dev/ttyS* </verb></tscreen> you'll see some info about how that device driver is configured for -your ports. Add a -a to the option -g to see more info although few +your ports. Note that where it says <tt>"UART: unknown"</tt> it +probably means that no uart exists. In other words you probably have +no such serial port and the other info shown about the port is +meaningless and should be ignored. If you really do have such a +serial port, setserial doesn't recognize it and that needs to be +fixed. + +If you add -a to the option -g you will see more info although few people need to deal with (or understand) this additional info since the default settings you see usually work fine. In normal cases the hardware is set up the same way as "setserial" reports, but if you are @@ -1909,7 +1930,11 @@ In fact, you can run "setserial" and assign a purely fictitious I/O port address, any IRQ, and whatever uart type you would like to have. Then the next time you type "setserial ..." it will display these bogus values without complaint. Of course the serial port driver will -not work correctly (if at all) with such bogus values. +not work correctly (if at all) if you attempt to use such a port. +Thus when giving parameters to "setserial" anything goes. It gives +you no warning if what you tell it is incorrect and will allow you to +create conflicts in IRQs and I/O port addresses that will have +disastrous results later on. While assignments made by setserial are lost when the PC is powered off, a configuration file may restore them (or a previous @@ -2122,10 +2147,11 @@ Debian labeled obsolete files with "...pre-2.15". <sect2> IRQs -<p> By default, both ttyS0 and ttyS2 share IRQ 4, while ttyS0 and -ttyS3 share IRQ 3. But sharing serial interrupts is not permitted -unless you: 1. have kernel 2.2 or better, and 2. you've complied in -support for this, and 3. your serial hardware supports it. See +<p> By default, both ttyS0 and ttyS2 will share IRQ 4, while ttyS1 and +ttyS3 share IRQ 3. But actually sharing serial interrupts (using them +in running programs) is not permitted unless you: 1. have kernel 2.2 +or better, and 2. you've complied in support for this, and 3. your +serial hardware supports it. See <ref id="int_share-2.2" name="Interrupt sharing and Kernels 2.2+"> @@ -2523,7 +2549,6 @@ available via FTP, if they didn't come with your distribution. portable, scriptable, serial and TCP/IP communications including file transfer, character-set translation, and zmodem support <item><tt/minicom/ - <tt/telix/-like communications program -<item><tt/procomm/ - <tt/procomm/-like communications program with zmodem <item><tt/seyon/ - X based communication program <item><tt/xc/ - xcomm communication package @@ -2666,8 +2691,10 @@ id="serial_mon" name="Serial Monitoring/Diagnostics"> <!-- currently in <sect>Troubleshooting --> <!-- troubleshooting.H begin Change Log: -Apr. 00: 2 ports on same address --> -<sect1> The following subsections are in both the Serial and Modem HOWTOs: +Apr. 00: 2 ports on same address +May 00: address conflict +--> +<sect1>(The following subsections are in both the Serial and Modem HOWTOs) <sect1> My Serial Port is Physically There but Can't be Found <label id="cant_find_port"> @@ -2675,25 +2702,28 @@ Apr. 00: 2 ports on same address --> serial port that it's on has been found. If it doesn't work at all, then you need to make sure your serial port can be found. -Check the BIOS menus and BIOS messages. For the PCI bus use lspci. -If it's an ISA bus PnP serial port, try "pnpdump --dumpregs" and/or -see Plug-and-Play-HOWTO. Using "scanport" will scan all ISA bus ports -and may discover an unknown port that could be a serial port (but it -doesn't probe the port). It could hang your PC. You may try probing -with setserial. See <ref id="probing_ss" name="Probing">. If +Check the BIOS menus and BIOS messages. For the PCI bus use lspci or +scanpci. If it's an ISA bus PnP serial port, try "pnpdump --dumpregs" +and/or see Plug-and-Play-HOWTO. Using "scanport" will scan all ISA +bus ports and may discover an unknown port that could be a serial port +(but it doesn't probe the port). It could hang your PC. You may try +probing with setserial. See <ref id="probing_ss" name="Probing">. If nothing seems to get thru the port it may be accessible but have a bad interrupt. See <ref id="slow_" name="Extremely Slow: Text appears on -the screen slowly after long delays">. +the screen slowly after long delays">. Use <tt>setserial -g</tt> to +see what the serial driver thinks and check for IRQ and I0 address +conflicts. Even if you see no conflicts the driver may have incorrect +information and conflicts may still exist. If two ports have the same IO address then probing it will erroneously indicate only one port. Plug-and-play detection will find both ports so this should only be a problem if at least one port is not plug-and-play. All sorts of errors may be reported/observed for -devices on "sharing" a port but the fact that there are two devices on -the same a port doesn't seem to get detected (except hopefully by -you). If the IRQs are different then probing for IRQs with setserial -might "detect" this situation by failing to detect an IRQ. See <ref -id="probing_ss" name="Probing">. +devices illegally "sharing" a port but the fact that there are two +devices on the same a port doesn't seem to get detected (except +hopefully by you). In the above case, if the IRQs are different then +probing for IRQs with setserial might "detect" this situation by +failing to detect any IRQ. See <ref id="probing_ss" name="Probing">. <sect1> Extremely Slow: Text appears on the screen slowly after long delays <label id="slow_"> @@ -2841,11 +2871,15 @@ start the second device (without quitting the first device) you get a keeps track of what IRQs are actually in use and conflicts don't happen unless the devices are in use (open). -There are two cases. There may be a real interrupt conflict that is -being avoided. But if setserial has it wrong, there may be no reason -why <tt/ttyS2/ can't be used, except that setserial erroneously predicts a -conflict. What you need to do is to find the interrupt setserial -thinks <tt/ttyS2/ is using. This is easier said than done since you can't +There are two possible cases when you see this message: +<enum> +<item> There may be a real interrupt conflict that is being avoided. +<item> Setserial has it wrong and the only reason <tt/ttyS2/ can't be + used is that setserial erroneously predicts a conflict. +</enum> + +What you need to do is to find the interrupt setserial thinks +<tt/ttyS2/ is using. This is easier said than done since you can't use the "setserial" command for <tt/ttyS2/ since the IRQ for ttyS2 is supposedly "busy" and you will get the same "... busy" error message. To fix this either reboot or: exit or gracefully kill all likely @@ -2855,14 +2889,14 @@ messages for the serial ports. 2. Hope that the file that runs again. If you think you know what IRQ <tt/ttyS2/ is using then you may look -at /proc/interrupts to find what else is currently using this IRQ. -You might also want to double check that any suspicious IRQs shown -here (and by "setserial") are correct (the same as set in the -hardware). A way to test whether or not it is a potential interrupt -conflict is to set the IRQ to 0 (polling) using "setserial". Then if -the busy message goes away, it was likely a potential interrupt -conflcit. It's not a good idea to leave it permanently set at 0 since -more CPU resources will be used. +at /proc/interrupts to find what else (besides another serial port) is +currently using this IRQ. You might also want to double check that +any suspicious IRQs shown here (and by "setserial") are correct (the +same as set in the hardware). A way to test whether or not it is a +potential interrupt conflict is to set the IRQ to 0 (polling) using +"setserial". Then if the busy message goes away, it was likely a +potential interrupt conflcit. It's not a good idea to leave it +permanently set at 0 since more CPU resources will be used. @@ -3726,7 +3760,7 @@ Monitoring/Diagnostics"> of mailing lists. <sect1> Internet -<p> +<p> <label id="vern_"> <itemize> <item> <url url="ftp://scicom.alphacdc.com/pub/linux" name="Serial Suite"> by Vern Hoxie is a collection of blurbs about the care and diff --git a/LDP/howto/linuxdoc/Text-Terminal-HOWTO.sgml b/LDP/howto/linuxdoc/Text-Terminal-HOWTO.sgml index 6331c7da..1572142d 100644 --- a/LDP/howto/linuxdoc/Text-Terminal-HOWTO.sgml +++ b/LDP/howto/linuxdoc/Text-Terminal-HOWTO.sgml @@ -3,10 +3,11 @@ <title> Text-Terminal-HOWTO David S. Lawyer - v1.12, May 2000 + v1.13, June 2000 +What is Setserial ?