SMS Applications
SMS Applications
SMS Applications
Stefan Frings, December 2005-January 2011
Page 1
SMS Applications
Table Of Content
1. Introduction.................................................................................................................................................................................................8
1.1. About This Book................................................................................................................................................................................8
1.2. About The Author..............................................................................................................................................................................9
1.3. What is SMS?...................................................................................................................................................................................9
1.4. What Is MMS?.................................................................................................................................................................................10
2. Hardware And Software............................................................................................................................................................................11
2.1. SUN Server.....................................................................................................................................................................................11
2.2. PC Server........................................................................................................................................................................................11
2.3. Serial Interfaces..............................................................................................................................................................................12
2.3.1. How Serial Interfaces Work...................................................................................................................................................12
2.3.2. Connector Layouts.................................................................................................................................................................13
2.3.3. Enhancing Serial Ports..........................................................................................................................................................15
2.3.4. Digi Etherlite...........................................................................................................................................................................15
2.4. GSM Modems And Mobile Phones.................................................................................................................................................16
2.4.1. Siemens GSM Modems.........................................................................................................................................................16
2.4.2. Falcom GSM Modems...........................................................................................................................................................16
2.4.3. Mobile Phones.......................................................................................................................................................................18
2.4.4. GSM Antenna........................................................................................................................................................................19
2.5. Operating Systems..........................................................................................................................................................................20
2.5.1. Microsoft Windows.................................................................................................................................................................20
2.5.2. SUN Solaris...........................................................................................................................................................................21
2.5.3. Linux.......................................................................................................................................................................................22
2.6. Software..........................................................................................................................................................................................23
2.6.1. PDU Spy................................................................................................................................................................................23
2.6.2. CygWin..................................................................................................................................................................................24
2.6.3. Apache Webserver................................................................................................................................................................24
2.6.4. War FTP Daemon..................................................................................................................................................................24
2.6.5. MySQL Database...................................................................................................................................................................25
2.6.6. PHP Programming Language................................................................................................................................................25
2.6.7. nnCron Lite............................................................................................................................................................................25
2.6.8. SMS Server Tools..................................................................................................................................................................26
2.6.9. EditPad Lite............................................................................................................................................................................26
2.6.10. Fetchmail, Ssmtp And Ncftp................................................................................................................................................27
3. System Design..........................................................................................................................................................................................28
3.1. Stability............................................................................................................................................................................................28
3.2. Mechanical Construction.................................................................................................................................................................29
3.3. Power Supply..................................................................................................................................................................................30
3.4. Data Safety......................................................................................................................................................................................31
3.5. Redundancy....................................................................................................................................................................................32
3.6. Firewall............................................................................................................................................................................................33
Page 2
SMS Applications
3.7. Concrete Example System.............................................................................................................................................................34
4. Basic KnowHow........................................................................................................................................................................................36
4.1. SMS Commands For GSM Modems..............................................................................................................................................36
4.1.1. Start A Terminal Program......................................................................................................................................................36
4.1.2. GSM Modem Commands......................................................................................................................................................37
4.1.3. SMS Modem Commands......................................................................................................................................................38
4.1.4. PDU Message Format (Receive)...........................................................................................................................................40
4.1.5. PDU Message Format (Status Report).................................................................................................................................41
4.1.6. PDU Message Format (Send)...............................................................................................................................................43
4.1.7. Character Set.........................................................................................................................................................................44
4.1.8. Practical Examples................................................................................................................................................................47
4.2. Software Installation........................................................................................................................................................................49
4.2.1. Software Installation On Solaris............................................................................................................................................49
4.2.1.1. Configure Solaris..........................................................................................................................................................49
4.2.1.2. Install Packages...........................................................................................................................................................50
4.2.1.3. Configure MySQL.........................................................................................................................................................50
4.2.1.4. Compile Apache and PHP...........................................................................................................................................52
4.2.1.5. Configure Apache and PHP.........................................................................................................................................53
4.2.1.6. Test Apache, PHP And MySQL...................................................................................................................................54
4.2.1.7. Install Sources..............................................................................................................................................................55
4.2.1.8. Reminder For Solaris...................................................................................................................................................56
4.2.2. Software Installation On Windows.........................................................................................................................................57
4.2.2.1. Install Windows Programs...........................................................................................................................................57
4.2.2.2. Install CygWin..............................................................................................................................................................57
4.2.2.3. Install Apache Webserver............................................................................................................................................59
4.2.2.4. Test Apache, PHP And MySQL...................................................................................................................................60
4.2.2.5. Install SMS Server Tools..............................................................................................................................................60
4.2.2.6. Reminder For Windows................................................................................................................................................61
4.2.3. Software Installation on Linux................................................................................................................................................62
4.2.3.1. Preparation...................................................................................................................................................................63
4.2.3.2. Install SMS Server Tools..............................................................................................................................................63
4.2.3.3. Configure MySQL.........................................................................................................................................................63
4.2.3.4. Test Apache, PHP and MySQL...................................................................................................................................64
4.2.3.5. Reminder For Linux......................................................................................................................................................65
4.3. CygWin Quick Start.........................................................................................................................................................................66
4.3.1. The Shell................................................................................................................................................................................66
4.3.2. Filenames..............................................................................................................................................................................66
4.3.3. Directory Names....................................................................................................................................................................69
4.3.4. File Permissions....................................................................................................................................................................70
4.3.5. Comparision of Windows/Unix commands............................................................................................................................71
4.3.6. Search Path...........................................................................................................................................................................72
4.4. Working With Cron Jobs.................................................................................................................................................................73
Page 3
SMS Applications
SMS Applications
4.8.8. Functions.............................................................................................................................................................................112
4.8.9. Form Variables And File Uploads........................................................................................................................................113
4.8.10. SQL queries.......................................................................................................................................................................115
4.8.11. Local And Global Variables...............................................................................................................................................117
4.8.12. Variable Variables..............................................................................................................................................................119
4.8.13. Using PHP Scripts Outside Apache..................................................................................................................................119
4.8.14. How To Proceed?..............................................................................................................................................................120
4.9. Shell Script Programming.............................................................................................................................................................121
4.9.1. The First Shell Script...........................................................................................................................................................121
4.9.2. The Printf Command...........................................................................................................................................................122
4.9.3. Strings..................................................................................................................................................................................123
4.9.4. Variables..............................................................................................................................................................................124
4.9.5. In/Out Redirection Into Files................................................................................................................................................125
4.9.6. In/Out Redirection Into Programs........................................................................................................................................125
4.9.7. In/Out Redirection Into Variables........................................................................................................................................126
4.9.8. Many Commands In One Line.............................................................................................................................................126
4.9.9. Control Structures................................................................................................................................................................126
4.9.9.1. if...then...else...fi.........................................................................................................................................................127
4.9.9.2. Comparisons..............................................................................................................................................................128
4.9.9.3. Combine Many Comparisons.....................................................................................................................................129
4.9.9.4. case..esac..................................................................................................................................................................130
4.9.9.5. while...do...done.........................................................................................................................................................131
4.9.9.6. for...in...do...done.......................................................................................................................................................131
4.9.9.7. break, continue And exit.............................................................................................................................................132
4.9.10. Functions...........................................................................................................................................................................133
4.9.11. Special Variables...............................................................................................................................................................134
4.9.12. More Than Nine Arguments..............................................................................................................................................135
4.9.13. Arithmetic Expressions With expr......................................................................................................................................136
4.9.14. Error Messages..................................................................................................................................................................137
4.9.15. Useful Tools.......................................................................................................................................................................137
4.9.15.1. cat.............................................................................................................................................................................137
4.9.15.2. cut.............................................................................................................................................................................138
4.9.15.3. sed............................................................................................................................................................................139
4.9.15.4. grep...........................................................................................................................................................................140
4.9.15.5. Regular Expressions................................................................................................................................................141
4.9.15.6. How To Cut Spaces.................................................................................................................................................142
4.10. Awk Programming.......................................................................................................................................................................143
4.10.1. How to start awk................................................................................................................................................................143
4.10.2. First awk examples............................................................................................................................................................143
4.10.3. Basic syntax of awk commands........................................................................................................................................144
4.10.4. Field separators.................................................................................................................................................................145
4.10.5. Internal Variables...............................................................................................................................................................146
Page 5
SMS Applications
SMS Applications
6. Useful Enhancements............................................................................................................................................................................197
6.1. Maintenance-free Operation.........................................................................................................................................................197
6.1.1. Clean-up logfiles..................................................................................................................................................................198
6.1.2. Delete Old SMS Files..........................................................................................................................................................201
6.1.3. Delete Old SQL Data...........................................................................................................................................................201
6.1.4. Self-Test...............................................................................................................................................................................202
6.2. Better Statusmonitor.....................................................................................................................................................................205
6.2.1. Statusmonitor As Website...................................................................................................................................................206
6.2.2. Alarms As Website..............................................................................................................................................................207
6.3. More than 32 Modems..................................................................................................................................................................208
6.4. One Message To Many Recipients...............................................................................................................................................209
7. Practical Example Applications..............................................................................................................................................................210
7.1. Central Alarm System...................................................................................................................................................................210
7.1.1. Sender Side.........................................................................................................................................................................210
7.1.2. Receiver Side.......................................................................................................................................................................211
7.2. Car Tracking..................................................................................................................................................................................212
7.2.1. Sender Side.........................................................................................................................................................................212
7.2.2. Receiver Side.......................................................................................................................................................................212
7.3. eMail To SMS Gateway.................................................................................................................................................................214
7.3.1. eMail To SMS Gateway With Local Mailserver...................................................................................................................214
7.3.2. eMail To SMS Gateway With External Mailserver..............................................................................................................214
7.4. Verifying Sender With SQL...........................................................................................................................................................216
7.5. Ovulation Reminder.......................................................................................................................................................................217
7.5.1. The Registration Form.........................................................................................................................................................217
7.5.2. The Registration Script........................................................................................................................................................218
7.5.3. The Table With Dates..........................................................................................................................................................220
7.5.4. The Cronjob.........................................................................................................................................................................220
7.6. Ringtones, Logos And Jokes........................................................................................................................................................222
7.6.1. Make Content Avaiable........................................................................................................................................................222
7.6.2. The Script.............................................................................................................................................................................223
7.7. Web form to send a message.......................................................................................................................................................223
7.7.1. The web form.......................................................................................................................................................................224
7.7.2. The send script....................................................................................................................................................................224
Page 7
SMS Applications
1. Introduction
In this chapter, I describe the intention of this book.
I write something about myself and how SMS and MMS services work in general.
You will find some registered company names, product names, logos and photos. They are all owned by the corresponding companies.
Page 8
SMS Applications
If you have question about the book or if you like to tell me what I could do better, then please contact me via eMail. My address is
[email protected].
Short
Message
Service
These are short text messages of up to 160 characters (7 Bit), that can be sent from one mobile phone to another.
Some devices support binary messages with 8 Bit for transferring small pictures, ringtones and configuration files for the mobile phone.
The short message is normally entered via the keypad of the mobile phone and stored onto the SIM card. Then is is sent through the
signalling channel to the SMSC. This channel is also used for call setup.
There are many SMSC, therefore you can configure in your phone which one you like to use when sending a message.
The SMSC stores the messages for some days (in Germany max. 2 days) and sends them through the signalling channel to the
receiver. If the sender requested it, the SMSC sends him a status report back to keep him updated about the status.
Page 9
SMS Applications
Multimedia
Message
Service
Multimedia messages can contain text, pictures, videos and audio. The latest generation of mobile phones,
like the Sharp GX-10 on the right side support this function.
MMS is not part of this book, but this service is just coming up and has some things together with SMS.
Therefore I like to write a little bit about it.
An MMS consists always of a text part with file attachments like an eMail. The MMSC transfers these
message without modification to the destination phone.
When somebody sends an MMS, the sending phone connects to the internet (WAP) and send the text and
attached files to the MMSC.
The MMSC stores it and checks, if the destination phone supports MMS. If not, the receiver gets a regular
text SMS with the URL, where he can download the message with a computer and a webbrowser.
If the destination phone supports MMS, it gets a notification SMS. This SMS tells the phone to go online now
and fetch the message through the internet (WAP).
At the moment you cannot create MMS applications without direct interwork with your local GSM network
providers. Therefore I do not develop an MMS software at the moment.
Page 10
SMS Applications
2.2. PC Server
PC Server run with Microsoft Windows or Linux.
If you buy a PC server then take care about the quality of the hardware. The newest computers are
often a bad solution because they often run unstable. For SMS applications the speed is less
important that the quality.
Ask yourself these questions:
Can you put standard hardware into the device or does it only work with "original" parts from the same Manufacturer?
Page 11
SMS Applications
With DCD the modem shows, that it has a connection to the destination. Not all SUN computers have this DCD line
but this is not important for SMS applications. They don't need this signal.
With DSR the computer shows, that the serial port is in use
With RTS the computer asks the modem to prepoare for sending data and the computer shows that it is ready to
receive data from the modem. So this line has two meanings.
The handshake lines are controlled by the operating system. In addition the operating system creates a buffer that holds all received
characters until the running program reads them. When the buffer of the computer or modem becomes full, they tell each other to stop
sending data using the RTS and CTS line.
The specification of the serial RS232 port says that the signals 1 and 0 should be represented by -12V and +12V but voltages between
3-15V are acceptable. In practice voltages between 9 and 12V are used by most computers.
Page 12
SMS Applications
Page 13
SMS Applications
2 TxD Port A
3 RxD Port A
4 RTS Port A
5 CTS Port A
8 DCD Port A
20 DTR Port A
7 GND
11 DTR Port B
12 DCD Port B
13 CTS Port B
14 TxD Port B
16 RxD Port B
19 RTS Port B
Page 14
SMS Applications
The first method is surely to expensive and the second is not useful because your server shall work automatically. Serial ports can
easily be expanded with USB converters but these devices are only delivered with Windows driver and therefore not usable with Linux
or Solaris.
You could buy PCI cards with two or much more serial ports. But the number of free PCI slots may be very limited and you may not
want to open the computer because you will loose warranty if you do that.
The last method, enhancing serial ports via ethernet, is my recommended method for all operating systems. There are different devices
available. They have up to 32 serial ports and one ethernet connector that goes to your server. These serial port work exactly like local
ports within the server. There are good devices available for every popular operating systems.
I would like to show you devices from the manufacturer Digi because they worked fine in my systems.
Page 15
SMS Applications
Page 16
SMS Applications
Falcom Samba
Initialize the Falcom Samba with the command AT^SSMSS=1, to be able to read out received
short messages. This small USB stick has no external antenna, therefore it is not useable in
some locations.
Page 17
SMS Applications
Page 18
SMS Applications
Page 19
SMS Applications
Windows NT 4
Windows XP
, where you should note that Microsoft does not support Windows NT anymore.
Please do not use a workstation version of Windows for professional SMS applications, like Windows 95, 98 or Me. All programs of this
book run fine on all Windows versions but is is not a good idea to let computers running 24h each day with a workstation version of
Windows.
Many people complain about a continuously decreasing performance and sometimes the computers stop running suddenly. I can
explain this:
The workstation versions have a much easier memory control mechanism. They are made to be as fast as possible giving as much
CPU power and memory to the running programs (primarily games) as possible. The disadvantage is that these Windows versions do
not defragment the memory which causes sooner or later a system slowdown and sometimes programs cannot allocate enough
coherent memory blocks.
On Windows 95 and 98 I noticed many times that the clock in the taskbar ran slightly slower than my watch but the clock chip on the
mainboard ran correct. After a restart of windows the taskbar showed again the correct time for a while. This affects all running
programs.
Windows is a good thing if you want to set up a simple fileserver. But in many other cases you are forced to buy very expensive
software (for example MS Exchange Server, Microsoft SQL, fax software, statistic programs and timed programs).
Software development for windows is typically not open-source, therefore you cannot modify programs if you want. The
interconnections between programs of different manufacturer is typically problematic or impossible. Software manufacturers tend to
separate from others so their products do not work very well together.
Of course you can get nearly everything that you need from Microsoft, but do you really want to depend on one single manufacturer?
Please keep also in mind that Windows and other Microsoft programs are very often the goal of virus attacks.
Page 20
SMS Applications
Basics of Solaris
In these trainings the EDV specialist learns all important commands and configuration files of Solaris. These trainings are also useful
for Linux administrators because there are only small differences between Solaris and Linux.
My opinion is: SUN is expensive but very good. Use it if stability and support is more important than money.
Page 21
SMS Applications
2.5.3. Linux
Linux is an operating system of Linus Torvalds and a lot of other developers. The name is a combination
of Unix and Linus, the developer of the Linux core part (kernel).
Linux is a Unix-style operating system for PC's. The developers started when DOS was actual, and they
continued their development quickly. Linux was started as a multitasking operating system with network
functions and in some points it is more powerful than Windows.
The name Linux refers only to the Linux core. A lot of professional and hobby-programmers added more
and more tools, drivers and applications. Some companies collect them together with the Linux kernel
and add a comfortable installation program.
Every Linux installation is based on such a "distribution" and therefore the meaning of the word "Linux"
has changed. The Linux distributions differ in support options and their size. I recommend Linux
distributions from RedHat and SuSE.
RedHat is the model of all Linux distributions. RedHat is not as large as SuSE Linux. Another difference
is that SuSE is very active in germany offering hardware, software and trainings. For international use RedHat is more popular. RedHat
keeps all the programs normally in their original state while SuSE often changes them a little bit to simplify installation and
configuration.
Decide for RedHat if you write programs that should also run on other Linux distributions or if you want English trainings. Decide for
SuSE if you want an easy installation and/or German configuration.
Linux is the ideal operating system for programmers because it includes nearly every possible programming language and
programming tools. Nearly all Linux programs are open-source, that means that their source code is free available for everybody. This
allows programmers, changing things and analysing source codes. They can learn from each other and develop own programs based
on existing ones.
As the opposite to Microsoft, who enforces own ideas as world-standard, the Linux programmers work together. This ensures that their
program fit together.
Linux is free, therefore you get normally no support from the developers. But companies like SuSE and RedHat offer commercial
support. You will need their help only seldom because the program authors are often reachable via eMail and they help as long as they
have time for your problem.
There is also a lot of information in the internet that should help in most cases. Many people wrote pretty good guildelines about
everything that a Linux administrator should know.
You can find Linux programs on http://www.freshmeat.net.
Normally Linux is much faster than Windows (after the boot process has finished). You can easily test this by compiling the Apache
Webserver from the CD, that came with this book, under Linux and Windows and then comparing the times.
If you plan to develop applications for Linux, you need somebody with appropriate Linux knowledge. In Windows you can typically try to
klick some buttons and see what happens and it is much easier to get help from somebody else. But for Linux you need to be familiar
with its command line and you should be prepared to read many manuals. There are not many computer dealers with Linux knowledge
and most of them sell their knowledge very expensive. There is free help available in the internet but without basic knowledge you will
not understand most of it.
My opinion is: Linux is cheap and good. There is only limited commercial support. Linux users should have fun experimenting with
software and reading manuals and they should have no problem searching help in the internet.
All applications in this book were tested under RedHat 7.3, SuSE 7.3 and SuSE 8.1. I'm pretty sure that they will also work fine on
newer Linux versions but I don't know if they work on older Linux versions.
Page 22
SMS Applications
2.6. Software
This chapter shows you the programs that I use for SMS applications.
You will see that most programs were primarily developed for Linux and modified to run also on Solaris and Windows. Therefore you
may miss colourful buttons and other graphical elements.
Anyway these programs work well under all three operating systems. Most documentation is available in the internet instead of printed
books.
I recommend to read the original documentation of every program before you work with it.
Page 23
SMS Applications
2.6.2. CygWin
CygWin is a set of powerful tools for programmers to develop software and migrate Unix software to Windows.
CygWin is not an emulator. All programs developed with CygWin are real Windows programs but their advantage is that they can use
the same commands and functions as Unix programs.
The core part of CygWin is the GNU C Compiler, the cygwin1.dll library and a set of programs that belong to Unix standard. The
package is maintained by RedHat. You can download it for free from http://www.cygwin.com.
I use CygWin as a base for all self-written Windows programs. This make it easy to use the usual Unix commands in the same way
under Windows - the programs can easily run on both operating systems.
After the installation of cygwin you will get a "CygWin Bash Shell" window that is similar to the "MS DOS Command line" but it accepts
Unix commands.
A typical installation needs about 150 MB disk space. Installing it is very easy. Download the "CygWin installer" and start it. This
program offers you a list of all available packages. After selecting them the installer downloads them from the internet and installs them
automatically.
Page 24
SMS Applications
Page 25
SMS Applications
Opens files from Unix and Macintosh (has no problems with line-breaks)
If you like EditPad Lite you may take a look at EditPad Pro. This larger program has some more features:
Hex-editor
File comapare
Bookmarks
Special-character table
Spell checking
Sorting
Regular expressions
Six clipboards
You can get EditPad on the website http://www.editpadlite.com/editpadlite.html. The program is free for non-commercial use.
Page 26
SMS Applications
Page 27
SMS Applications
3. System Design
This chapter will describe important things to know when it comes to developing a commercial SMS application.
After reading this chapter you know all parts that you will need. You will also learn which details are important in the system concept.
This chapter supports you to select hardware for good stability.
3.1. Stability
Commercial applications need a stable system. Stability may be more important than costs.
Looking to the software you have not many choices. But when you use the programs that I described in the last chapters you do not
need to fear hard problems. All these programs had a long development time and run very stable. If you find a bug, the authors help
you typically.
For the hardware you can decide between many devices. For SMS applications the performance is not very important. In general you
can use every PC or SUN computer. I's up to you to select the best computer for your needs.
SUN computer run very stable, but they run only with the operating system Solaris. You need a trained Solaris administrator and you
should check, if all programs that you need are available for Solaris. If both is not sure, you cannot use SUN computers for your
application.
For PC's it's easier because PC's run with Windows and Linux. Nearly all software is available for at least one of these operating
systems. Therefore you first have to decide what hardware you want to use. There are high quality PC's available but also cheap
devices. Cheap does not always meant that they are bad - I think you know that.
You should buy a PC only in a shop that offers enough support and spare parts. It would be quite bad if your SMS application does not
work for many days because a spare part is not available.
Experienced computer vendors can immediately tell you what hardware components are stable and what components make often
problems.
In case of doubt you may better buy a server from a good and large company, like Dell. With large vendors you can agree contracts
about support and financial penalties when the system is down for a longer time that allowed.
Last but not least I like to give you a small tip about hardware construction of servers: Try to create your application with a minimum of
hardware. As more parts the server has as more defects may occur. Less parts mean less outages and faster repair. If your server has
parts that are not really needed, like TV-card, sound-card, internal Modem and so on, remove them.
The mechanical construction influences the stability of a system. The next chapter is written about that.
Page 28
SMS Applications
Page 29
SMS Applications
Page 30
SMS Applications
Page 31
SMS Applications
3.5. Redundancy
A redundant system is secured against hardware faults by duplication parts of it.
The weakest parts of every server are the harddisks. They break most times and replacing them is not easy because the data are lost
and need to be restored.
You can protect your server against broken harddisks by installing more disks than only a single one.
A classical redundant harddisk system uses RAID-5. Such a system has 5 disks. The data are distributed over all 5 disks combined
with CRC checksums. The checksums allow to recreate the original data when a single disk fails. When more than one disk fails at the
same time, you will loose all data. RAID-5 systems offer the capacity of 4 disks but need a 5th disk for storing the checksums.
Today the capacity of a typical harddisk is so large that RAID-5 system do not make sense very often. For SMS applications this is
surely the case.
I recommend to use the easier harddisk-mirroring. That means that your server has two harddisks that store always the same data. If
one disk fails, the system continues working with the remaining disk.
For Windows you need a RAID controller to use such disk storages. On Solaris and Linux you can use a regular SCSI controller and
emulate the RAID controller by software. This is cheaper but a little bit slower. Linux has a raid function in it's kernel, Solaris can add
this function by separate software that is not part of the Solaris installation CD-Rom.
Please don't forget that a duplicated harddisk protects you only against broken disks. You could still loose all your data when the
operator enters a wrong command or when a program crashes.
Duplicated harddisks make sense. It is also a good idea to use duplicated power converters (power supplies) and fans because these
parts do also often break.
If you want to make the SMS application more stable you could run two servers with the same software. If one computer stops working,
the other continues and you will only notice a reduced performance. To set up such a system you need a single file server that holds
the message queues for both SMS servers. I think that you probably have already a good and stable file server.
Do not use the file server for other things than simply storing files. A file server that has no other jobs runs typically very stable and
without any problems. Outages are very seldom.
If you want to use two file server for redundancy then you should take a look at http://www.linux-ha.org. This website discusses, how to
setup a mirrored fileserver.
Page 32
SMS Applications
3.6. Firewall
As soon as your servers are connected to a large network - let's say the internet, you have to install a firewall.
Firewalls protect your computers against acces by unauthorized persons (hackers).
Firewalls block access through the network and allow only a few configured connections from authorized sources. For example you
could use a firewall to allow only the administrator to log into the SMS server from his own desktop PC and no other workstation. And
the internet customers can only acces websites from your webserver, nothing else.
A simple typical firewall has at least three network interfaces. One goes via a router to the internet, one goes into the company network
and one goes to your servers.
Please do not run Firewall software on Windows, because Windows seams to have a lot of security wholes that affect the security of
the firewall functionality.
Most Linux distributions come with firewall software, for Solaris you have to buy it. The german company SuSE offers a special LinuxFirewall distribution that contains only the Linux kernel and software that is necessary to set up a firewall. It has a very comfortable
setup program specially written to simplify the setup up of a firewall.
Page 33
SMS Applications
This system is partly redundant. I tried to find a good compromise between costs and stability.
Both SMS Servers are Dell Poweredge 350 with Linux and an additional ethernet card. The Firewall is also a Dell Poweredge 350 but
with an additional 4x ethernet card. For data-security all three computers have mirrored harddisks and internal DAT tape drives.
The file server is a SUN V880 with Solaris. It has also an additional ethernet card. Data are stored onto two mirrored harddisks and
backuped with a DAT tape drive.
The fileserver holds also the SQL database for dynamic websites and to store billing data.
The router goes to the internet. Your internet provider decides which router you should use.
The system administrator can log on to all Servers from his workstations. Therefore local monitors and keyboards are not necessary,
after the operating systems were installed once.
The firewall protects the servers against unauthorized access from the internet and from the company internal intranet.
For redundancy I use two SMS Server. They store statistics and message queues on the file server. Normally they share the load but
when one of them stops working, the remaining SMS Server will continue working and sending messages from the queues.
Both SMS servers have at least three modems, two for the major phone network provider (they have 80% of all mobile customers in
Germany) and one for the others. Using two modems for the two major network providers helps saving money because sending
messages within the own network is cheaper than sending into foreign networks (in germany, maybe also in your country).
The fileserver is a weak point in the system because it exists only once. Therefore I decided to use the very stable Sun V880. You
should be careful when administering it and do not use it for testing. As less functions this server has as more stable it will run.
The whole system was set up without any switches or hubs because a defect hub would result in a total loss of service. Instead of
them, I use more network interfaces and cables. In this construction every hardware is allowed to break except the fileserver. If the
fileserver breaks then you will be out of service. The fileserver has internally redundant hardware, so this should never happen.
Both SMS servers are also used as webserver running Apache and an FTP service. You can give your customers two IP-Addresses.
When one of them fails they can switch over to the other Webserver.
There are loadbalancer avaiable that can automatically switch over to a second webserver if the first one fails. When you use a
loadbalancer, your customers do not need to know two IP Adresses. My example above does not use loadbalancer.
Page 34
SMS Applications
If you plan to modify your websites or reconfigure a SMS server, you can do this on one SMS Server while the other continues working
for the "live" traffic. You could give the "test" server a temporary IP-address and a temporary queue directory to split it clearly from the
live traffic.
Page 35
SMS Applications
4. Basic KnowHow
This chapter shows you, how sending and receiving SMS works with GSM modems. You will learn the modem commands for SMS and
the data format of the messages. At the end you will learn how all the programs can be installed and how they can be configured.
Solaris:
Solaris does not have a terminal program with menus. The Solaris program "tip" reads its configuration from the file /etc/remote. Add
the following lines to this file:
porta:dv=/dev/cua/a:br#9600
portb:dv=/dev/cua/b:br#9600
If you have more than two serial ports in your SUN computer you can add all of them to this configuration file. The name in front of the
first colon is free selectable. After the colon the device name is set, and the bitrate.
After modifying the configuration file you can start the program by entering:
tip porta
for the first serial port. You can quit the program by entering the two characters "~.".
Page 36
SMS Applications
ERROR indicates a problem with the SIM card. The error message comes with an error code that should be explained
in your modems manual.
There are some other possible answers but I never saw them. If you see another answer to this command take a look
into the modem manual.
AT +CPIN=xxxx
Use this command to enter the PIN (instead of xxxx). After entering the PIN the modem tries to log into the network. This command is
necessary after every power-on.
AT +CPIN=yyyyyyyy,xxxx
This command changes the PIN. It works also when the PIN is locked. yyyyyyy is the PUK (also called super-PIN) and xxxx is the new
PIN that you want to use. You get the PUK always together with your SIM card, typically printed on paper.
AT +CSQ
shows you information about the received signal quality. The answer are two numbers. The first number is the signal strength and
should always be between 2 and 31. 0 means that the signal is too low and operation is not possible. 31 is the maximum allowed signal
strength. The second number has something to do with the bit error rate. This number is meaningless for SMS applications because it
is only measured during voice or data connections. For sending or receiving SM the modem does not establish such a connection.
AT +CREG?
show you if the modem is logged into the network. The answer 0,1 is positive. All other answer indicate a problem and the modem is
not logged in. As long as the modem does not answer with 0,1 you cannot send SM.
The next chapter shows you commands to send and receive short messages.
Page 37
SMS Applications
all messages
AT +CMGR=x
lists one received message. Replace x with the number of memory location that you like to read (for example a value between 1 and
20). When you try to read an empty location some modems answer with ERROR and some answer with an empty text. You cannot
read sent messages, there is no command for this.
A message is shown in this format:
+CMGR: status,name,length
data
OK
Status is a single digit value like in the AT+CMGL command. The name is the senders name if it is in the phone book. The length
indicator is not important. The data format is described in the next chapter.
As long as I noticed only Siemens modems show names.,All other modems leave it out.
AT+CMGD=x
deletes a stored received message. Replace x by the memory location.
The next commands are used to send messages:
AT +CSCA="+xxxxxxxxxxxx"
sets the number of the SMSC. Write it in international format starting with a plus, for example +491722270000. This setting is
meaningless for receiving because every SMSC can always send you messages. If you do not use this command most modems use a
default setting from the SIM card.
Page 38
SMS Applications
AT +CMGS=x
This command sends a message. x is the length of the PDU message calculated by this formula:
x=(number of characters/2)-1. If your message has 30 characters then x has to be 14.
After this command the modem shows an ">" prompt. Now enter the PDU message and terminate it with Ctrl-Z.
Page 39
SMS Applications
Length of SMSC number, in this case 7 bytes. The format indicator and number are counted.
91
94 71 22 72 00 00
04
Bit 6: User data header indicator. Is 1, if the data contain a header. Only used with 8 bit data.
0C
Length of senders number, in this case 12 digits. The format indicator is not counted.
91
94 71 12 32 54 F6
Sender (+)49172123456.
00
00
Bit 3+2: Data coding: 00=7bit text, 01=8bit data, 10=unicode text
Bit 1+0: 00=Flash-SMS, 01=normal SMS
03 10 92 51 61 95
Sent time in the order "Year Month Day Hour Minute Second" Every second digit is swapped. This
date/time means January 29. of 2003 15:16:59 (= 3:16:59 pm)
04
Timezone in quarter hours. Negative values are calculated by adding 80hex. 04 means GMT+1 hour.
0A
E8329BFD4697D9EC37
Phone numbers are filled with F if the number of digits is odd. Some SMSC count the F in the length indicator and some do not count it.
The digits of phone numbers are swapped as you can easily see in the example above.
Alphanumeric senders are coded like 7bit text messages. The length indicator counts the number of hex-digits of the senders name.
Text messages consist of character of 7 bit. These bits are concatenated to a long row of bits and then splitted into bytes (each of 8
bit). See this drawing:
I wrote the binary numbers in the wrong direction because that makes it easier to understand how the concatenating and splitting
works. So the least significant bit is always at the left side in my drawing. If there are not enough bits at the right end some 0 bits are
appended.
If you take a closer look at the drawing you can easily see why 8 bit data messages are limited to 140 bytes while 7 bit text messages
can be 160 characters long.
There are more number format, flags, protocol and data coding indicators as I wrote here. Others are not used in Germany and
therefore I did never see them myself. For more detailed information you could take a look into the ETSI specification TS 100 900.
Page 40
SMS Applications
Length of SMSC number, in this case 7 bytes. The format indicator and number are counted.
91
94
02
01
0C
Length of receiver number, in this case 12 digits. The format indicator is nor counted.
91
94 71 12 32 54 F6
03 10 92 51 61 95
Time when the message arrived the SMSC in the order "Year Month Day Hour Minute Second". Every Second
digit is swapped. This date/time value means January 29. of 2003 16:16:59 (=3:16:59 pm)
04
Timezone in quarter hours. Negative values are calculated by adding 80hex. 04 means GMT+1 hour.
03 10 92 51 71 05
Time when the message was delivered in the order "Year Month Day Hour Minute Second". Every second digit
is swapped. This date/time value means January 29. of 2003 15:17:50 (=3:17:50 pm). If the message is not
delivered this value is filled with zeroes.
04
Timezone in quarter hours. Negative values are calculated by adding 80hex. 04 means GMT+1 hour.
00
Status
...
There may be more data at this point. The meaning depends on the SMSC and is not standarised.
Phone numbers are filled with F if the number of digits is odd. Some SMSC count the F in the length indicator and some do not count it.
The digits of phone numbers are swapped as you can easily see in the example above.
Alphanumeric receivers are coded like 7bit text messages. The length indicator counts the number of hex-digits of the receivers name.
The status field can have one of the following values:
0
Ok,short message forwarded by the SC to the SME but the SC is unable to confirm
delivery
32
Still trying,congestion
33
34
35
36
37
64
65
Error,incompatible destination
66
67
Error,not obtainable
68
69
70
71
72
Page 41
SMS Applications
73
96
Error,congestion
97
Error,SME busy
98
99
Error,service rejected
100
101
Error,error in SME
Page 42
SMS Applications
Length of SMS number of 00 if the modem should use the already known number.
01
Bit 6: User data header indicator. 1 indicated that the user data contain a header. Only used for 8 bit
messages.
00
ID number of the message. In case of 00 the modem insert an automatic incremented number.
0C
Length of receivers number, in this case 12 digits. The format indicator is not counted.
91
94 71 12 32 54 F6
00
00
Bit 7-2: Data coding: 111100=7bit text, 111101=8bit data, 000110=unicode text
Bit 1+0: 00=Flash-SMS, 01=normal SMS
(...)
Validity period. Is skipped in this case because of the 00 bin bit 4+3 above.
0A
E8329BFD4697D9EC37
Phone number are filled with F if the number of digits is odd. The digits of phone numbers are swapped as you can see in the example
above.
Text messages consist of character of 7 bit. These bits are concatenated to a long row of bits and then splitted into bytes (each of 8
bit). See this drawing:
I wrote the binary numbers in the wrong direction because that makes it easier to understand how the concatenating and splitting
works. So the least significant bit is always at the left side in my drawing. If there are not enough bits at the right end some 0 bits are
appended.
If you take a closer look at the drawing you can easily see why 8 bit data messages are limited to 140 bytes while 7 bit text messages
can be 160 characters long.
The validity period can be in one of four different formats:
0
10
11
The relative format is normally used and it is only 1 byte long. Possible values are grouped:
0-143
144-167
168-196
197-255
In Germany all messages are limited to 2 days. Larger validity periods are ignored.
For the number format, flags, protocol and data coding there are more values than shown here. But these are not supported in
Germany. For more details see ETSI TS 100 900 specification.
Page 43
SMS Applications
Hex
Dez
Name
Zeichen
ISO-8859-1
0x00
COMMERCIAL AT
64
0x01
POUND SIGN
163
0x02
DOLLAR SIGN
36
0x03
YEN SIGN
165
0x04
232
0x05
233
0x06
249
0x07
236
0x08
242
0x09
199
0x0A
10
LINE FEED
0x0B
11
216
0x0C
12
248
0x0D
13
CARRIAGE RETURN
0x0E
14
197
0x0F
15
229
0x10
16
0x11
17
LOW LINE
0x12
18
0x13
19
0x14
20
0x15
21
0x16
22
0x17
23
0x18
24
0x19
25
0x1A
26
0x1B
27
0x1B0A
27 10
FORM FEED
0x1B14
27 20
CIRCUMFLEX ACCENT
94
0x1B28
27 40
123
0x1B29
27 41
125
0x1B2F
27 47
92
0x1B3C
27 60
91
0x1B3D
27 61
TILDE
126
0x1B3E
27 62
93
0x1B40
27 64
VERTICAL BAR
124
0x1B65
27 101
EURO SIGN
164
0x1C
28
198
0x1D
29
230
0x1E
30
ss
223
0x1F
31
201
Page 44
10
13
95
12
SMS Applications
Hex
Dez
Name
Zeichen
ISO-8859-1
0x20
32
SPACE
0x21
33
EXCLAMATION MARK
33
0x22
34
QUOTATION MARK
"
34
0x23
35
NUMBER SIGN
35
0x24
36
CURRENCY SIGN
164
0x25
37
PERCENT SIGN
37
0x26
38
AMPERSAND
&
38
0x27
39
APOSTROPHE
'
39
0x28
40
LEFT PARENTHESIS
40
0x29
41
RIGHT PARENTHESIS
41
0x2A
42
ASTERISK
42
0x2B
43
PLUS SIGN
43
0x2C
44
COMMA
44
0x2D
45
HYPHEN-MINUS
45
0x2E
46
FULL STOP
46
0x2F
47
SOLIDUS (SLASH)
47
0x30
48
DIGIT ZERO
48
0x31
49
DIGIT ONE
49
0x32
50
DIGIT TWO
50
0x33
51
DIGIT THREE
51
0x34
52
DIGIT FOUR
52
0x35
53
DIGIT FIVE
53
0x36
54
DIGIT SIX
54
0x37
55
DIGIT SEVEN
55
0x38
56
DIGIT EIGHT
56
0x39
57
DIGIT NINE
57
0x3A
58
COLON
58
0x3B
59
SEMICOLON
59
0x3C
60
LEss-THAN SIGN
<
60
0x3D
61
EQUALS SIGN
61
0x3E
62
GREATER-THAN SIGN
>
62
0x3F
63
QUESTION MARK
63
0x40
64
161
0x41
65
65
0x42
66
66
0x43
67
67
0x44
68
68
0x45
69
69
0x46
70
70
0x47
71
71
0x48
72
72
0x49
73
73
0x4A
74
74
0x4B
75
75
0x4C
76
76
0x4D
77
77
0x4E
78
78
0x4F
79
79
0x50
80
80
32
Page 45
SMS Applications
Hex
Dez
Name
Zeichen
ISO-8859-1
0x51
81
81
0x52
82
82
0x53
83
83
0x54
84
84
0x55
85
85
0x56
86
86
0x57
87
87
0x58
88
88
0x59
89
89
0x5A
90
90
0x5B
91
196
0x5C
92
214
0x5D
93
209
0x5E
94
220
0x5F
95
SECTION SIGN
167
0x60
96
191
0x61
97
97
0x62
98
98
0x63
99
99
0x64
100
100
0x65
101
101
0x66
102
102
0x67
103
103
0x68
104
104
0x69
105
105
0x6A
106
106
0x6B
107
107
0x6C
108
108
0x6D
109
109
0x6E
110
110
0x6F
111
111
0x70
112
112
0x71
113
113
0x72
114
114
0x73
115
115
0x74
116
116
0x75
117
117
0x76
118
118
0x77
119
119
0x78
120
120
0x79
121
121
0x7A
122
122
0x7B
123
228
0x7C
124
246
0x7D
125
241
0x7E
126
252
0x7F
127
224
Page 46
SMS Applications
Page 47
SMS Applications
Tip: Enter the PDU string in the program PDU-Spy and see how the string is decoded. Compare the output of PDU-Spy with the
previous pages.
Page 48
SMS Applications
Page 49
SMS Applications
gcc
, the GNU C and C++ compiler
make
, accessoires for gcc
autoconf
, accessoires for gcc
automake
, accessoires for gcc
tar
, packer/unpacker
gzip
, packer/unpacker
sed
, script intepreter for text files
fetchmail
, download eMails
procmail
, process eMails
mysql
, database server
Libraries for these programs:
db
expat
gdbm
libxml2
ssl
The website includes installation instructions on the link Downloading/Installing. In short terms:
Download the packages to an empty directory. Gzip is the only uncompressed package, all other need to become uncompressed
before installation:
pkgadd -d gzip-1.3.5.10
gunzip *.gz
pkgadd -d bzip-2.1.0.4
pkgadd -d sed-4.1.5
...
Page 50
SMS Applications
mysqladmin -u root password 'My_Password'
mysql -u root -p
mysql> use mysql;
mysql> delete from user where user="" or password="";
mysql> quit
mysqladmin -u root -p reload
The username root is not the same as the Solaris user root. MySQL has its own user and password management. In mysql the name
root is used for the database administrator by default.
Now you can use this database only from the local computer with a root password. A later chapter shows you how to add more users.
Page 51
SMS Applications
Page 52
SMS Applications
Page 53
SMS Applications
Page 54
SMS Applications
Page 55
SMS Applications
/etc/init.d/sms start
/etc/init.d/sms stop
/etc/smsd.conf
/var/log/smsd.log
/var/spool/sms
Apache webserver
start
stop
config file
error logfile
web pages
/etc/init.d/apache start
/etc/init.d/apache stop
/usr/local/apache2/conf/httpd.conf
/usr/local/apache2/logs/error.log
/usr/local/apache2/htdocs
MySQL database
start
stop
client
/etc/init.d/mysqld start
/etc/init.d/mysqld stop
mysql -u root -p
Crontab
modify
Page 56
SMS Applications
Page 57
SMS Applications
Here you see a lot of grouped programs. By clicking on them you toggle between these options:
Devel
gcc
make
Editors
vim
fetchmail
procmail
ssmtp
Net
inetutils
ncftp
System
Page 58
procps
SMS Applications
Page 59
SMS Applications
Page 60
SMS Applications
mkdir /var/spool
make
make install
smsd &
pkill smsd
/etc/smsd.conf
/var/log/smsd.log
/var/spool/sms
Apache webserver
start
stop
config file
web pages
net start apache (in DOS window, or use the monitor program)
net stop apache (in DOS window, or use the monitor program)
c:\Program Files\Apache Software Foundation\Apache2.2\conf\httpd.conf
c:\Program Files\Apache Software Foundation\Apache2.2\htdocs
MySQL database
start
stop
client
Crontab
change
logfiles
c:\program files\cron\cron.tab
c:\program files\cron\log
Page 61
SMS Applications
gcc
make
libmm
Depending on your application, you might also need the following packages:
procmail
fetchmail
apache
php
mysql
ncftp
Normally, the setup program of your Linux should configure all these programs properly. If this does not work as expected, then you
might find help in the following chapters.
Page 62
SMS Applications
4.2.3.1. Preparation
Log in as root to install software. Enter the command
grep :initdefault /ect/inittab
and write down the number between two semicolons (typically a 3).
This is the runlevel that your system boots into. You will create some links later that have to be placed into the correct runlevel directory
so they start automatically at boo time (mysql, apache, smstools).
In the next chapters I assume that the runlevel is 3. If your runlevel is a different one you have to change the command to your
runlevel.
SMS Applications
The username root is not the same as the Linux user root. MySQL has its own user and password management. In mysql the name
root is used for the database administrator by default.
Now you can use the database only as root from the local computer with password. A later chapter will explain how to add more users.
Now start your webbrowser and enter http://localhost/test.php or http://your_webserver_name/test.php. You should see this:
This is HTML text.
This is PHP text.
Now a MySQL query follows:
root localhost x4gdsag2354124
The first line was created by regular HTML code, the second line tests the PHP integration into the webserver. The third and fourth line
test the connection to your MySQL database.
Please review the example program above. You can see how a PHP code was placed into a HTML file. The beginning and end are
marked with <?php and ?>.
The PHP program connects to the SQL database and queries the list of SQL-users and their passwords. The passwords are encrypted
for security therefore you do not see them in clear text.
Page 64
SMS Applications
/etc/init.d/sms start
/etc/init.d/sms stop
/etc/smsd.conf
/var/log/smsd.log
/var/spool/sms
Apache webserver
start
stop
config file
error logfile
web pages
/etc/init.d/apache2 start
/etc/init.d/apache2 stop
/usr/apache2/conf/httpd.conf
/usr/apache2/logs/error.log
/usr/apache2/htdocs
/etc/init.d/mysqld start
/etc/init.d/mysqld stop
mysql -u root -p
Crontab
modify
Page 65
SMS Applications
The first command shows the content of the current directory in the easiest format. It is similar to the command "dir". The second
command tests the tabulator key. Enter the half filename as shown above and press the tabulator key. Then the filename is
automatically completed. In this case there are two files that begin with "cygwin", therefore the tab key does not complete the filename
extension (.bat or .ico) automatically.
If you close a shell window, then the programs that you started within that windows are also normally closed. But some programs
remain in memory and continue to run! In case of doubt you can check this using the taskmanager of Windows.
4.3.2. Filenames
All names in Unix are case-sensitive. You have to care capital and small letters.
If you use wildchars (jokers) in filenames you should keep in mind some small differences to the DOS command window. Description of
wildchars in Unix:
A star is a placeholder for zero or more characters.
A question mark is a placeholder for exactly one character.
The dot has no special meaning to Unix. It is treated like any other letter. Lets say there are many README files:
Page 66
SMS Applications
Then the command ls * shows all of them. In the DOS command windows you had to enter dir *.* because in Dos a star character
does not match a dot. In Unix the star also matches the dots, therefore all files appear.
Page 67
SMS Applications
In the DOS command window the wildchars are detected and handled by the command itself. You can enter dir *.txt because the dir
command knows what to do with stars. But not all commands know wilchars - try it with notepad:
Notepad outputs an error message because it does not understand the star and tries to open the file *.txt. This file does not exist.
You will notice that very much programs support stars and question marks but not all. MS-Word 2000 (and maybe older version) for
example works with them.
In every Unix shell the wildchars are detected by the shell itself and are replaced by the "real" filenames. Therefore you can start
editpad with wildchars (editpad *.txt) because the shell replaces *.txt by the filenames that match this pattern before it starts the
program editpad.
Page 68
SMS Applications
(This does not work with notepad because notepad cannot open more that one file at the same time).
Executable programs have no special filename extension in Unix, but Windows programs are typically called something with .exe at the
end.
CygWin Shell
c:\cygwin
c:\cygwin\tmp
/tmp
c:\
/cygdrive/c
d:\
/cygdrive/d
e:\
/cygdrive/e
c:\windows
/cygdrive/c/windows
If you enter ls /cygdrive you may not see all drive letters that you expected. I was not able to find an explanation for this. But you can
use all existing drives even if the ls command does not show their letters!
Page 69
SMS Applications
user
group
others
User is the person who created the file, also called the owner.
The group is always "unknown". All users of the Windows PC belong to the group "unknown" because Windows 95 does not know user
groups (in Unix style) and CygWin was initially developed for Windows 95.
Others are all other persons, people in the network that this PC does not know. They have normally no access to any file. Therefore the
file permissions to these users are meaningless in Windows.
There are three permissions for any of these three groups:
read (r )
write (w)
execute (x)
Directories have also permissions. They use the same letters but their meaning is slightly different:
The w permission allows to modify the table of content. This means adding and deleting files and renaming them because these
actions modify the directory content. Changes to existing files do not touch the table of content.
The x permission allows you step into the directory using the cd command.
The command ls -l /etc shows you the content of the directory /etc in detail:
-rw-r--r-- 1 SF unknown 12546 Oct 1 05:53 termcap
The first character is a d in case of directories and a dash to indicate a regular file (as above). Then three blocks of rwx permissions
follow. Left for the owner, in the middle for the group and right for others.
The file above can be read and written by the owner. The group and others can only read it.
The file was created by the user "SF" who is part of the group "unknown".
The file-size is 12546 bytes and it was created in the 1st october at 5:53.
The filename is termcap.
Nobody can execute the file because it has no "x" permission. This is not an executable program.
Page 70
SMS Applications
Windows Command
dir c:\windows
Unix Command
ls -l /cygdrive/c/windows
cd \temp
cd /tmp
Go to temp directory
md test
mkdir test
rm test
rmdir test
del hello
rm hello
deltree trash
rm -R trash
Deletes the whole directory trash with all files within it.
command /?
Windows Taskmanager
ps -ef
kill nummer
kill -9 nummer
Stops the program without taking care of any risks. This is similar to a multiple klick on "quit task" in the windows Taskmanager for
hanging programs.
attrib -w anyfile
Removes all users (a) the write (-w) permission. Instead of a you coud also use u,g or o. +w would add the write permission.
mv file destination
mv old new
Page 71
SMS Applications
Renames a file
type filename
cat filename
Shows content of a file page by page. Less can also scroll back.
exit
exit
Exits a shell
Page 72
SMS Applications
minute (0-59)
hour (0-23)
day (1-31)
month (1-12)
The first command runs every day and every hour at minute1 and minute 31.
The second command runs daily every 10 seconds (Solaris does not support this syntax, you could enter 0,10,20,30,40,50 instead of
*/10).
The third cronjob runs every monday at 01:05.
The fourth cronjob runs every day at 01:00, 02:00 and 03:00.
As you can see, the star means every minute, hour, day or month.
*/x means every x minutes, hours, days or month's.
You can enter many values by separating them with a comma. The comma means as much and the word "and".
Unix sends an eMail to the user who started a cron job whenever the commands generate any output.You can disable this by
redirecting the output into a file:
* * * * * command >/var/log/logfile
This redirects "normal" outputs into a file. Please note that the directory /var/log is only writeable by root user! For other users you need
to create an empty logfile with write permissions first.
If you redirect output to /dev/null they simply go to nowhere. /dev/null "eats" everything that you give him and does nothing with it.
You will still get eMails for error messages if you redirect only "normal" output. To disable also error messages use this command:
* * * * * command >/var/log/logfile 2>&1
Page 73
SMS Applications
You should not use this commadn with /dev/null because you would not be able to see any error message of the command. If you
redirect everything including error messages you should do it with a file that you can check later if something goes wrong.
Page 74
SMS Applications
Page 75
SMS Applications
Page 76
SMS Applications
Page 77
SMS Applications
If you encounter problems while sending eMails then use the option -v with sendmail (before the receipient address). The you will see a
lot of information about success or error messages.
Page 78
SMS Applications
Page 79
SMS Applications
Page 80
SMS Applications
Page 81
SMS Applications
After the connection has been established you are prompted for username and password. In this case both "mustermann".
I made this screenshot on a German PC therefore you see a mixture of English and German above.
Verbunden zu = Connected to
Benutzer = User
Kennwort = Password
I recommend to enter the next two commands always at first:
binary
Switches from 7bit to 8bit mode. This is necessary for all files except text files. The oppsite mode (text)
converts line breaks and removes the highest bit from every byte.
hash
Activates a progress bar while transferring files. This is useful for large files to see that something is
happening when the transfer takes a long time.
The next commands are used to transfer files. You need some or all of them:
cd directory
dir
rm filename
Removes a file
Page 82
SMS Applications
rmdir directory
Removes a directory
mdir directory
put filename
get filename
mput filename
mget filename
prompt
Disables "are you sure" questions for every file in mget and mput commands.
bye
Page 83
SMS Applications
Page 84
SMS Applications
Page 85
SMS Applications
BIGINT
FLOAT
DOUBLE
Floating number in the range -1.79E308 to +1.79E308 with 8 byte (more exactly)
DATE
TIME
DATETIME
TIMESTAMP
CHAR(n)
VARCHAR
TEXT
BLOB
LONGTEXT
LONGBLOB
When you store a date you may write the year with only 2 digits. MySQL converts it automatically to four digits. MySQL allows zeroes in
date and time, e.g. 0000-00-00 00:00:00 as a dummy value.
Strings of type CHAR have a fixed length, independently how many characters you store. The disk usage is always the same. They are
fast. The disadvantage is that they typically reserve unused disk space.
Strings of type TEXT, LONGTEXT, BLOB and LONGBLOB need exactly as much disk space as their length. The access to these types
is slower than to CHAR.
I you search or compare strings the types TEXT and LONGTEXT do not care the case while BLOB and LONGBLOB are case
sensitive.
If you store strings, trailing spaces at the right side are truncated but heading spaces at the left side are stored.
Page 86
SMS Applications
Page 87
SMS Applications
Now you can start to fill these two tables with data. The timestamp will be set automatically. The ID numbers for the addresses will be
set automatically while the ID's for the accounts have to be set manually.
The next chapter show you how to do this.
The result of the last UPDATE command should not surprise you:
mysql>select * from addresses;
+----+--------------+-----------+---------------+-----------+-------------+
| id |name
|firstname | street
| city_code | city
|
+----+--------------+-----------+---------------+-----------+-------------+
| 1 |Examplemann
|Markus
| Long Avenue 3 | 11111
| Somewhere
|
| 2 |Examplewoman |Lisa
| NULL
| 22222
| Watervalley |
+----+--------------+-----------+---------------+-----------+-------------+
2 rows in set(0.00sec)
Page 88
SMS Applications
+----+--------------+-----------+----------------+-----------+-------------+
| id | name
| firstname | street
| city_code | city
|
+----+--------------+-----------+----------------+-----------+-------------+
| 1 | Examplemann | Markus
| Long Avenue 3 | 11111
| Somewhere
|
| 2 | Examplewoman | Lisa
| NULL
| 22222
| Watervalley |
| 3 | Exampleman
| Sunnyboy | Long Avenue 3 | 11111
| Somewhere
|
+----+--------------+-----------+----------------+-----------+-------------+
3 rows in set(0.01sec)
You did already use the easiest form of the SELECT commandand are familiar with it.
It's also easy to count the number of rows:
select count(*) from addresses;
You learned already about the WHERE keyword that is used to specify the rows within the table that the command should affect.
WHERE can also be used with SELECT to filter out only some special lines that match a condition:
select * from addresses where id=2;
This shows you only the row with ID 2. You can also specify other filters:
select * from addresses where city_code="11111";
select * from addresses where name="Exampleman";
select * from addresses where name="Exampleman" and firstname<>"Markus";
The last command shows you all addresses from family Exampleman but not Markus. The remaining person is only one: Sunnyboy.
You can also search for strings that begin with some characters:
select * from adresses where name like "Example%";
You see now all addresses from persons whose name starts with "Example". It is also possible to search for the end of a String:
select * from adresses where name like "%man";
The percent character is a wildchar for one or more characters. Another wildchar is the underscore (_) that matches only exactly one
character.
Like you use the WHERE keyword together with SELECT to limit the output to special lines you can use the WHERE keyword also
together with the UPDATE command to affect only special lines.
If you do not use the WHERE keyword, the commands affect the whole table.
When having large tables you may not want to see all columns because the width of your screen is limited. In the last SELECT
commands you always used the star (*) to select all columns. Now I like to show you howe to select onyl some columns:
mysql>select id,name,city from addresses;
+----+--------------+-------------+
| id | name
| city
|
+----+--------------+-------------+
| 1 | Exampleman
| Somewhere
|
| 2 | Examplewoman | Watervalley |
| 3 | Exampleman
| Somewhere
|
+----+--------------+-------------+
3 rows in set(0.00sec)
When you enter SQL commands you should always surround strings and Date/Time values with double quotes ("). Numbers should
always written without quotes. The examples on the last pages did you show this.
Before you start wondering about the city_code: This is a string and not a number because you created the table columns as CHAR(5).
MySQL can convert numbers to strings and vice versa but not always. By using quotes in the correct way you prevent conversion faults
and error messages.
Page 89
SMS Applications
Now we enter these data into the second table. We have to set the ID numbers manually so that they match the addresses.
insert into accounts set id=2, value=6.5;
insert into accounts set id=1, value=18.3;
insert into accounts set id=3, value=23.1;
Now you have two tables. One for the addresses of our three persons and one for their accounts.
mysql>select * from addresses;
+----+--------------+-----------+----------------+-----------+-------------+
| id | name
|firstname |street
| city_code | city
|
+----+--------------+-----------+----------------+-----------+-------------+
| 1 | Examplemann |Markus
|Long Avenue 3
| 11111
| Somewhere
|
| 2 | Examplewoman |Lisa
|NULL
| 22222
| Watervalley |
| 3 | Exampleman
|Sunnyboy
|Long Avenue 3
| 11111
| Somewhere
|
+----+--------------+-----------+----------------+-----------+-------------+
3 rows in set(0.01sec)
Now we can come to the main topic of this chapter, the combination of two tables.
The most important part is already done - giving rows in two tables, that belong together, a column with the same value. In our case we
used the ID column. This is the relationship between both tables. The table with the accounts does not include addresses but using the
ID numbers MySQL can find the corresponding address in the other table.
The command that queries two tables together by combining them is quite easy:
mysql>select addresses.id,name,firstname,value
->from addresses,accounts
->where addresses.id=accounts.id;
+----+--------------+-----------+--------+
| id |name
|firstname | value |
+----+--------------+-----------+--------+
| 1 |Exampleman
|Markus
| 18.3
|
| 2 |Examplewoman |Lisa
| 6.5
|
| 3 |Exampleman
|Sunnyboy
| 23.1
|
+----+--------------+-----------+--------+
3 rows in set(0.00sec)
After the keyword FROM you enter both table names that you want to combine into one single SQL query.
After the keyword SELECT you enter all the columns that you want to see. As there are two ID columns we have to specify this more
detailed. Addresses.id means that we want to see the ID column of the addresses table.
After the keyword WHERE, we need to enter a condition that combines both tables. The condition says, which columns have the same
value and combine both tables.
If you don't want to see all accounts you can filter the output as you learned before:
Page 90
SMS Applications
select addresses.id,name,firstname,value
from addresses,accounts
where addresses.id=accounts.id and name="Exampleman";
+----+--------------+-----------+----------------+-----------+-------------+
| id | name
| firstname | street
| city_code | city
|
+----+--------------+-----------+----------------+-----------+-------------+
| 1 | Examplemann | Markus
| Long Avenue 3 | 11111
| Somewhere
|
| 2 | Examplewoman | Lisa
| NULL
| 22222
| Watervalley |
| 3 | Exampleman
| Sunnyboy | Long Avenue 3 |
| Somewhere
|
+----+--------------+-----------+----------------+-----------+-------------+
3 rows in set(0.01sec)
Please note that Lisa has no street and Sunnyboy has no city_code. The important difference is that the unset street of Lisa is
displayed as NULL while the empty city_code of Sunnyboy is displayed as an empty string.
In SQL "nothing" is not the same as "empty string". If a field is not set, the SQL client shows NULL. If the field contains an empty string,
it is shown as an empty field. An empty string is a string of zero characters - the shortest possible string, it has no characters but it is
still a string.
The difference is more important when you run the SELECT command in this way:
mysql>select * from addresses wherestreet="";
Empty set(0.00sec)
mysql>select * from addresses where street is NULL;
+----+--------------+-----------+----------------+-----------+-------------+
| id | name
| firstname | street
| city_code | city
|
+----+--------------+-----------+----------------+-----------+-------------+
| 2 | Examplewoman | Lisa
| NULL
| 22222
| Watervalley |
+----+--------------+-----------+----------------+-----------+-------------+
1 row in set(0.00sec)
There is no row where the street is an empty string ("") but there is one row where the street is not set (NULL).
Please note that the keyword NULL is slightly different used than in comparision expressions with "=" character.
select * from addresses where street is NULL;
select * from addresses where street is not NULL;
A small note: If you want tu unset a field that is already set, you need to assign the value NULL to it:
update addresses set city_code=NULL where id=3;
Page 91
SMS Applications
+----+--------------+-----------+----------------+-----------+-------------+
| id | name
| firstname | street
| city_code | city
|
+----+--------------+-----------+----------------+-----------+-------------+
| 3 | Exampleman
| Sunnyboy | Long Avenue 3 | NULL
| Somewhere
|
| 1 | Examplemann | Markus
| Long Avenue 3 | 11111
| Somewhere
|
| 2 | Examplewoman | Lisa
| NULL
| 22222
| Watervalley |
+----+--------------+-----------+----------------+-----------+-------------+
3 rows in set(0.01sec)
The output is now sorted by city_code. Please use the ORDER function only if you really need it, because it can take a long time and
use much memory on large tables.
Sorting backwards is also possible:
select * from addresses order by city desc;
Sometimes you may want to limit the sorted output by some lines. To see the row with the lowest city_code you can enter:
mysql>select * from addresses order by city_code limit 1;
+----+--------------+-----------+----------------+-----------+-------------+
| id | name
| firstname | street
| city_code | city
|
+----+--------------+-----------+----------------+-----------+-------------+
| 3 | Exampleman
| Sunnyboy | Long Avenue 3 | NULL
| Somewhere
|
+----+--------------+-----------+----------------+-----------+-------------+
1 row in set(0.01sec)
The keyword LIMIT specifies how many rows you want to see at maximum. In this example we queried only one row.
Page 92
SMS Applications
+----+--------------+-----------+---------------+----------+-------------+-----------+
| id | name
| firstname | street
| city_code| city
| birthdate |
+----+--------------+-----------+---------------+----------+-------------+-----------+
| 1 | Exampleman
| Markus
| Long Avenue 3 | 11111
| Somewhere
| NULL
|
| 2 | Examplewoman | Lisa
| NULL
| 22222
| Watervalley | NULL
|
| 3 | Exampleman
| Sunnyboy | Long Avenue 3 | NULL
| Somewhere
| NULL
|
+----+--------------+-----------+---------------+----------+-------------+-----------+
3 rows in set(0.00sec)
Page 93
SMS Applications
+----+--------------+-----------+---------------+-----------+-------------+-----------+
| id | name
| firstname | street
| city_code | city
| birthdate |
+----+--------------+-----------+---------------+-----------+-------------+-----------+
| 1 | Exampleman
| Markus
| Long Avenue 3 | 11111
| Somewhere
| NULL
|
| 2 | Examplewoman | Lisa
| NULL
|22222
| Watervalley | NULL
|
+----+--------------+-----------+---------------+-----------+-------------+-----------+
2 rows in set(0.00sec)
Please do not forget the keyword WHERE because otherwise the command would delete all rows!
At last I show you how to delete the whole tables and the database:
drop table addresses;
drop table accounts;
drop database mytest;
Now all the data and tables that you entered while reading this chapter are gone.
Page 94
SMS Applications
Now you have a small demo table with the following content:
mysql>select * from testtable;
+----+------+
| id | value|
+----+------+
| 1 | 10
|
| 2 | 13
|
| 3 | 19
|
| 4 | 21
|
| 5 | 57
|
+----+------+
5 rows in set(0.00sec)
You can enter the same SQL command in non-interactive mode at the command line or in a shell script. Please enter exit now to exit
the MySQL client program and return to the shell. Then enter this command:
mysql -u root -p'xxxxx' -D demo -e 'select * from testtable;'
Please note that there is no space between -p and the password (xxxxx). Replace xxxxx with your password that you set during
installation of MySQL. The option -D specifies the database to be used and -e specifies the SQL command to be executed.
The result is the same table as shown above and the MySQL client program exits itself.
By adding the option -B you switch the frames off and -N switches the table header off.
mysql -u root -p'xxxxx'-D demo -N -B -e'select * from testtable;'
1
2
3
4
5
10
13
19
21
57
You get this simple output that you can easily read in with other programs (e.g. Microsoft Excel and kSpread). What you cannot see in
this book is that the fields are separated by tab characters. This is exactly the best format for spreadsheet applications.
You can redirect the output into a file using the ">" character:
mysql -u root -p'xxxxx' -D demo -N -B -e 'select * from testtable;' > /tmp/test.txt
The option -H creates a table in HTML text instead of plain text, e.g.:
<TABLE BORDER=1>
<TR>
<TH>id</TH>
<TR>
<TD>1</TD>
<TR>
<TD>2</TD>
<TR>
<TD>3</TD>
<TR>
<TD>4</TD>
<TR>
<TD>5</TD>
</TABLE>
<TH>value</TH>
<TD>10</TD>
<TD>13</TD>
<TD>19</TD>
<TD>21</TD>
<TD>57</TD>
</TR>
</TR>
</TR>
</TR>
</TR>
</TR>
Page 95
SMS Applications
You can combine -H and -N if you want a bordered table without column headers.
To query only a single value and store it into a variable you can use this command:
thevalue=`mysql -u root -p'xxxxx' -D demo -N -B -e 'select value from testtable where id=1;'`
echo The value is $thevalue
Take care about correct quotes because there are three similar characters and each of them has another function. The example above
works only with SELECT commands that query a single value. If the command would answer with many rows, you would get all of them
in one single variable and that is not useful.
Page 96
SMS Applications
Copy the files *.frm, *.MYD and *.MYI onto another media, for example a tape.
2. Hot Backup
The hot backup allows you to backup tables while they can be accessed by other programs. Unfortunately these programs have only
read access while the table is backed up. Other programs that want to write into a table must wait until the backup of this special table
has finished.
Enter the command backup table demo.testtable to "/tmp" in the mysql client program. This creates new files in
/tmp with the content of the table.
Copy the files /tmp/*.frm and /tmp/*.MYD onto another media, for example a tape.
To restore the table you need to enter the command restore table demo.testtable from "/tmp". Restoring a table requires that it does
not already exist in the database. Maybe you need to delete it first.
Some hints about hot backups:
During a hot backup the table can only be read by other programs. Write attempts are queued until the backup into the temporary file
has completed. This can cause performance problems on large tables (of many megabytes).
Imagine you had a service that needs to run 24 hours and the database stores billing data. These data are collected monthly for a bill.
Customer-Nr.
Date
Service
Value
10001
01.03.03
SMS
0.49
10001
01.03.03
SMS
0.49
10001
02.03.03
SMS
0.49
10001
03.03.03
SMS
0.49
10001
05.03.03
SMS
0.49
10002
01.03.03
SMS
0.49
10002
02.03.03
SMS
0.49
10002
...
07.03.03
SMS
0.49
For every single service that you delivered you add one row to this table. That means the table must always be ready for write access.
Now you cannot make backups because that would disable write access for some seconds. And if the table becomes larger it may take
minutes or hours. It is not acceptable to wait until the backup has finished.
Therefore you need to keep tables as small as possible to make the backup as fast as possible. Small tables can be backed up faster
and a delay of some seconds is surely more acceptable than some minutes.
The solution is to split the table into two.
The first table stores the actual billing data until the bill is printed. The second table stores the old billing data that are already printed.
During some years the second table will grow more and more but the first table does not grow. Therefore you can backup the small
table that needs to be accesses as fast as possible in a short time. The backup of the second larger table may take longer but this
table is not time-critical.
To copy one table into another use this command:
insert into table2 select * from table1;
or
insert into table2 select * from table1 where date < "2003-04-01" ;
Page 97
SMS Applications
Another version of this command is useful when the destination table does not already exist:
create table table2 select * from table1;
or
create table table2 select * from table1 where date < "2003-04-01" ;
Page 98
SMS Applications
1058
1073
1074
1075
1076
1077
5896
1
1058
1058
1058
1058
1058
5865
0
0
0
0
0
0
0
20:13
20:13
20:13
20:13
20:13
20:13
20:28
?
?
?
?
?
?
pts/1
00:00:00
00:00:00
00:00:00
00:00:00
00:00:00
00:00:00
00:00:00
/usr/local/apache/bin/httpd
/usr/local/apache/bin/httpd
/usr/local/apache/bin/httpd
/usr/local/apache/bin/httpd
/usr/local/apache/bin/httpd
/usr/local/apache/bin/httpd
grep httpd
The last line with the grep command does not count. All the other lines show you that some processes of the Apache webserver are
running. If you don't see them then Apache is not running.
In case of problems, a look into the error logfile could also help. I wrote their location in the reminder list.
If you see an error message like this in the webbrowser:
Forbidden
You don't have permission to access /test.html on this server.
then the directory or file has not enough permissions. All users (including other) need to read the file, the directory and all directories
above this one.
Page 99
SMS Applications
Page 100
SMS Applications
decimal number
%i
%f
floating number
%s
string
%x
%X
If you want to print the % character you need to write it as double percent (%%) then it is not treated as a placeholder.
If you put a number in front of a placeholder and this number starts with 0 ,then the value is displayed with the specified width, filled
with zeroes at the left side. Values that are to large are displayed in their full length.
$day=1;
$month=4;
$year=2003;
printf("The date is %02d.%02d.04%d ",$day,$month,$year);
Page 101
SMS Applications
Page 102
SMS Applications
boolean vales
integer numbers
floating numbers
character strings
arrays
NULL
Variables can also store objects and references but I will not explain them in this book. Now I explain the data types above.
Boolean
Boolean values can only be TRUE or FALSE. You can write these keyword in capital or small letters whatever you prefer:
$value1=true;
$value2=false;
Integer
Integer values can be written as decimal, octal or hexadecimal. Octal numbers start always with a zero. Hexadecimal numbers start
with 0x. Decimal numbers start with any other digit. The following examples have all the same value:
$value1=123;
$value2=0173;
$value3=0x7B;
Floating
Floating numbers are written with a dot or in exponential way:
$value1 = 1234.56;
$value2 = 12.3456e2;
$value3 = -0.345;
$value4 = 345e-3;
Strings
Strings are written between double or single quotes:
$text1 = 'Hello, this is Stefan\'s text';
$text2 = "The first text was : $text1"
The difference between single and double quotes is that double quotes allow you to insert variables into the text while single quotes do
not allow this.
If you want to write a single quote into the text you need to precede it by a backslash, otherwise the PHP language interpreter would
misinterpret this character as the end of string.
Arrays
Arrays are lists of one or more values of the same type. They have an index that allows you access each single element of the array.
$name[1] = "Miriam";
$name[2] = "Rolf";
$name[3] = "Mucki";
Index values can also be zero and negative. Also strings are allowed as indexes:
Page 103
SMS Applications
$MotherOf["Miriam"] = "Petra";
$MotherOf["Rolf"] = "Heidi";
$MotherOf["Mucki"] = "Micki";
NULL
Null is a special value for variables that have no value or are cleared with the unset() command. You know NULL already from the
MySQL chapter.
As you can see in all the examples above, variable names start with a dollar character followed by at least one letter. After the first
letter you can also use digits and the underscore. PHP treats variable names case sensitive. Therefore $Test and $test are two
different variables.
Page 104
SMS Applications
4.8.5. Operators
Operators calculate or compare values. If you connect an operand and an operator you get an expression. Every expression gives a
string, value or boolean as its result.
Arithmetic operators
+
addition
1+2 returns 3
subtraction
5-2 returns 3
multiplication
3*4 returns 12
division
12/2 returns 6
Bit operators
&
and, only bits that are set in both operands are set in the result
11 & 7 returns 6
or, all bits that are set in one or both operands are set in the result
4|2 returns 6
exclusive or, only bits that are set in one but not both operands are in the result
6^4 returns 2
<<
shift to left, all bits from the first operand are shifted left by the number of positions given by the second
operand
4<<1 returns 8
>>
shift to right, all bits from the first operand are shifted right by the number of positions given by the
second operand
4>>1 returns 2
Compare operators
==
equal
3==3 returns true
!=
not equal
3!=4 returns true
<>
<
smaller than
3<4 returns true
>
greater than
4>3 returns true
<=
>=
Logical operators
and
and
true and true returns true
&&
and
see above
or
or
Page 105
SMS Applications
.
true or false returns true
||
or
see above
xor
exclusive or
true xor true returns false
rue xor false returns true
negation
!true returns false
returns 7
You can run external programs and store their text output into a variable
$result = `ls -l` ;
The ls command lists the current directory content. The directory is written into the variable $result. Take care to write the correct
quotes. These are backquotes, not normal quotes.
Page 106
SMS Applications
4.8.6.1. if...elseif...else
If, elseif and else are used to execute a program block only if an expression is true or not zero. You need to write the condition in
parentheses. "(" and ")".
if ($a > 3)
{
Commands;
Commands;
Commands;
}
You cann add an else block that is executed when the expression is not true.
if ($a >3)
{
Commands;
Commands;
Commands;
}
else
{
Other commands;
Other commands;
Other Commands;
}
Elseif is used to construct an if/else control structure with more than one expression. If the first expression is not true, then the seconds
is calculated. If this is also not true, then the else-block is executed.
if ($a < 0)
{
print("$a is negative.");
}
elseif ($a > 0)
{
print("$a is positive.");
}
else
{
print("$a is not negative and not positive. It is null.");
}
You do not need to use so many line breaks as I did in the examples above. The next example is also correct.
if ($a < 0) {
print("$a is negative.");
} elseif ($a > 0) {
print("$a is positive.");
} else {
print("$a is not negative and not positive. It is null.");
}
If you want, you can also write everything into one single line but that will not look clear. However it will surely work.
4.8.6.2. switch...case
Page 107
SMS Applications
If you like to combine a lot of if-expressions to check a variable for values, the program code will quickly become hardly readable. A
bad example is this:
if ($name=="Maria")
{
Commands_for_Maria;
}
elseif ($name=="Josef")
{
Commands_for_Josef;
}
elseif ($name=="Martin")
{
Commands_for Martin;
}
elseif ($name=="Kerstin")
{
Commands_for_Kerstin;
}
else
{
print("Unknown Name!");
}
PHP offers another way to construct such large commands. You may prefer the switch...case command:
switch ($name):
case "Maria":
Commands_for_Maria;
break;
case "Maria":
Commands_for_Josef;
break;
case "Maria":
Commands_for_Martin;
break;
case "Maria":
Commands_for_Kerstin;
break;
default:
printf("Unknown Name!")
endswitch
Do not forget the break commands, otherwise all following commands will be executed accidentally. The switch...case command is an
alternative to if...then...else. Decide yourself what command you prefer in what situation.
Page 108
SMS Applications
4.8.6.4. for
The for loop is used to execute a program part for a specified number of repetitions. It also counts the repetitions.
for ($i=1; i<=6; $i=$i+1)
{
print("i is now $i <br>");
}
This loop creates the output
i
i
i
i
i
i
is
is
is
is
is
is
now
now
now
now
now
now
1
2
3
4
5
6
The loop was executed six times. The counter variable was counted from1 up to 6.
After the for command you need to enter three commands or expressions, enclosed in parantheses and separated by semicolons.
for (initialisation; expression; modification)
The initialisation command is used to assign a start value to the counter variable.
The second expression is used to check if the end value is reached. This check is performed before every execution of the program
part. If the end value is reached, the for loop ends. The loop executes as long the expression returns true.
The modification command is used to modify the counter variable after any loop repetition. Typically you will add 1 to the variable but
you could also increase it in larger steps. It is also possible to decrease the variable until a low limit is reached.
The for loop is another version of the while loop, if you think a little bit about their differences.
for ($i=1; i<=6; $i=$i+1)
{
Commands;
}
is the same as
$i=1;
while ($i<=6)
{
Commands;
$i=$i+1;
}
4.8.6.5. foreach
The foreach loop is used to do something with all elements of an array.
$names[1]="Mary";
$names[2]="Hans";
$names[3]="Maxi";
$names[4]="Hannes";
foreach ($names as $n) {
print("The name is $n <br>");
}
This produces the output
The
The
The
The
name
name
name
name
is
is
is
is
Mary
Hans
Maxi
Hannes
There is also an extended version of the foreach loop available that can be used to query the array index.
$month["january"]="cold";
$month["april"]="unstable";
$month["july"]="warm";
Page 109
SMS Applications
This loop adds one pear until 1000 pears are collected. But if a pear is bad the the loop stops. To make the example as easy as
possible the 12th pear is always marked ad bad.
The continue command enforces the next loop repetition even if the actual execution is not finished to its end.
$pears=0;
$try=0;
while ($try < 1000)
{
$try=$try+1;
if ($bad == true)
{
print("The pear no. $try is bad <br>");
continue;
}
print("I take the pear no. $try, hmm smells good.<br>");
$pears=$pears+1;
}
print("Now I took 1000 pears or I skipped some bad fruits.<br>");
print("$pears fruits were good");
This loop tries 1000 pears. When it gets a bad fruit, it skips this one and does not count it. The remaining commands
print("I take the pear no. $try, hmm smells good.<br>");
$pears=$pears+1;
are not executed for bad fruits because the continue command enforces the next loop repetition ignoring that the loop is not executed
until its end at this point.
The variable $try is increased for every loop repetition but the variable $pears is only executed for good fruits.
Page 110
SMS Applications
The break commend escapes a loop. The next commands after the loop will be executed.
The continue command enforces the next repetition of a loop and breaks the current repetition.
Break and continue are also usable in do...while loops and for loops.
There is also another command to break loops and programs. The name is exit. This command stops the whole PHP program
execution.
4.8.7. include
The include command loads another file with PHP code into memory. For example:
The file part1.include has the content:
$a=2;
$b=3;
And the file test4.php has the content:
<html><body>
<?php
include 'part1.include';
print("The variable a is $a and the variable b is $b");
?>
</body></html>
This is very useful. You can collect variables and functions in one include-file and share them to many other php files.
Page 111
SMS Applications
4.8.8. Functions
Functions are small or large program parts that you can execute later like PHP commands. They are used to split the program into
many small parts (functions) to make the program code better readable. Example:
function calculate($value1, $value2)
{
$result = $value1 + $value2 * 24;
return $result;
}
$super = calculate(3,4);
print("The calculation of 3 and 4 returns $super <br>");
$cool = calculate(9,12);
print("The calculation of 9 and 12 returns $cool <br>");
print("Or another way " . calculate(3,2) . "<br>");
printf("Or like this %i <br>", calculate(1,2));
The example above uses the function calculate() four times to calculate different numbers. The function returns its result to the main
program using the return command.
The calculation of 3 and 4 returns 99
The calculation of 9 and 12 returns 297
Or another way 51
Or like this 49
Now another example, this time with a function that does something but does not return a result.
function error_message($text)
{
print("An error occurred: <br>");
print("$text <br>");
print("The program will now stop <br>");
exit;
}
commands;
commands;
commands;
error_message("The harddisk is full");
commands;
commands;
commands;
error_message("Text not found");
commands;
commands;
commands;
error_message("Wrong value, 0 is not allowed.");
This uses the function many times to output an error message and stop the program. The main program remains clearly readable and
its not necessary to write the code for the error message many times. The output of this PHP code would look like this:
An error occurred:
The harddisk is full
The program will now stop
Page 112
SMS Applications
$_POST
$_GET
$_FILES
$_COOKIE
The design of the form specifies in which array the values will be stored. Lets say you have this form (test5.html):
<html><body>
<form action="test5.php" method="post">
Name: <input type="text" name="username"><br>
<input type="submit">
</form>
</body></html>
The webbrowser will show a simple form with one text field named "username" and one submit button.
The value will be sent to the PHP program test5.php when the user clicks the submit button. The variable $_POST["username"] will
contain the field value.
You can read the variable, for example with this script (test5.php):
<html><body>
<?php
printf("You entered %s . Thanks", $_POST["username"]);
?>
</body></html>
You can also send the form with get method. The difference is that the URL row of the browser shows all get variables but no put
variable, for example:
http://localhost/test5.php?username=Stefan
The webbrowser checks the file size using the MAX_FILE_SIZE value and does not allow sending if the file is to large.
$_FILES["userfile"]["name"]
$_FILES["userfile"]["size"]
$_FILES["userfile"]["tmp_name"]
contains a temporary filename that the webserver gave to store the file onto the harddisk of the
webserver.
$_FILES["userfile"]["error"]
You cannot be sure that the webserver really checks the filesize. This is a recommended standard but broken webbrowsers could send
larger files. Your program must detect this and output an error message in this case.
An example, how you can receive uploaded files (test6.php):
<html><body>
<?php
Page 113
SMS Applications
if (is_uploaded_file($_FILES["userfile"]["tmp_name"]))
{
copy($_FILES["userfile"]["tmp_name"],
"/dokumente/uloaded_file.jpg");
print("Thanks, the file is saved.");
}
else
{
print("You did not really send the file!");
}
?>
</body></html>
The function is_uploaded_file checks, if the file was really sent. You can use this check to avoid hacker attacks. Without this check
hackers could send wrong filenames that may stop your server.
The function copy copies the temporary file into another new file. You could also do any other action with the temporary file at this
point.
If you need the file later you have to copy it to another file because the webserver deletes the temporary file immediately when the PHP
program ends.
You can read the original PHP manual to learn how to use cookies. I recommend not to use cookies because the number of Internet
users that disable cookies in their webbrowser increases permanently. Therefore you cannot be sure that all visitors of your websites
can (and want) use cookies.
Page 114
SMS Applications
SMS Applications
$rows = mysql_num_rows($result);
$columns = mysql_num_fields($result);
With both functions we ask for the number of rows and columns. Only select commands return a table. All other SQL commands are
simply successful or not.
for ($i=0; $i<$columns; $i++)
{
$name=mysql_field_name($result,$i);
printf("
<th> %s </th>\n",$name);
}
This loop outputs the names of all columns. It is important to know that the first collums has always the number 0. Therefore the for
loop starts counting with 0. The function mysql_field_name() returns the name of the column and we output this with a printf()
command.
for ($j=0; $j<$rows; $j++)
{
print(" <tr>\n");
$row=mysql_fetch_row($result);
for ($i=0; $i<$columns; $i++)
{
printf("
<td> %s </td>\n",$row[$i]);
}
print(" </tr>\n");
}
Here I combined two loops because we want to read out all rows and all columns within these rows. Also the row numbers start with 0,
therefore both loops start counting with 0. The print() and printf() commands output the values.
The HTML output created by this PHP program looks like this:
<html><body>
Dies ist das Ergebnis einer SQL Abfrage: <br>
<table border=1>
<tr>
<th> a </th>
<th> b </th>
<th> c </th>
</tr>
<tr>
<td> 1 </td>
<td> 2 </td>
<td> 3 </td>
</tr>
<tr>
<td> 4 </td>
<td> 5 </td>
<td> 6 </td>
</tr>
</table>
</body></html>
The table has three columns with the names a, b and c. The rows have the numbers 1 to 6 because this is the content of the table that
I read in this example. If you use another table you get other column names and other values.
Read this example carefully and try to understand it. Play a little bit around by changing the output format or show more informations
about the SQL table. For example you could show the number of rows and columns. Try to show the result in a different format, not a
HTML table. Create a HTML form that allows the user to enter any SQL command and see the result. You will need the variable
$_POST["fieldname"] instead of a fixed SQL command.
Another good idea is to create a set of HTML forms and PHP scripts that allows you to view and edit an postal address database.
For creation of dynamic websites it is important to understand, how SQL queries and forms are used with PHP.
Page 116
SMS Applications
local variables
global variables
All variables that you use within a function are local. Variables used outside any function (in the main program part) are global. One
example (test8.php):
<html><body>
<?php
function test1()
{
$a = "Two"
print("The local value in test1 is $a <br>");
}
function test2()
{
print("The local value in test2 is $a <br>");
}
$a = "One";
print("The global value is $a <br>");
test1();
test2();
print("The global value is still $a <br>");
?>
</body></html>
Run this program and test it. The output will look like this:
The
The
The
The
The last two lines are interesting. The third line shows you that the function test2 has its own variable compared two function test1.
Within test2 it has no value because nobody set it.
The fourth line shows you that the variable in the main program has still its old value and was not changed by the function test1. The
assignment $a="Two" changed the local variable in test1 but not the global variable.
As you can see, the local and global variables are completely separated. They have the same name, but they are really different
variables. And two local variables in different functions are also different variables, even if they have the same name.
The last chapter showed you how to pass a variable to a function so that it also knows the global content. You need to place the
variable name between the parentheses, like in test9.php:
<html><body>
<?php
function test($a)
{
print("The value in test is $a <br>");
$wert="two"
print("The new value in test is $a <br>");
}
$a = "One";
print("The global value is $a <br>");
test($a);
printf("The global value is still $a <br>");
?>
</body></html>
This program creates the output:
The
The
The
The
The value of variable $a is used as an argument of the function, not the variable itself. Because the function changed $a but the main
program saw still its old value. Again $a is a local variable within the function and a global variable in the main program. Both are
different variables.
Page 117
SMS Applications
Variables passed to functions can be used there, but changes are not visible in the main program because these are two different
variables with copied content.
Now please look at this example (test10.php):
<html><body>
<?php
function test($wert)
{
print("The value in test is $wert <br>");
$wert="Two"
print("The new value in test is $wert <br>");
}
$a = "One";
print("The global value is $a <br>");
test($a);
print("The global value is still $a <br>");
?>
</body></html>
This example shows exactly the same output on screen as the previous example. As you can see the variable given as an argument to
the function may have a different name within the function.
The cause: Only the content of the variable is given to the function and not the variable itself - do you remember? Keep in mind that
variable names used as arguments may have different names within the function and outside it.
Now we need a solution to access global variables within functions. Experienced programmers use this method only seldom, because it
makes copying source code from old programs into new ones difficult. The next example has the name test11.php and shows you how
to do it:
<html><body>
<?php
function test()
{
global $a, $b;
print("The values test are $a und $b <br>");
$a="Three"
}
$a = "One";
$b = "Two";
print("The global value are $a and $b <br>");
test();
print("Die globalen values are now $a and $b <br>");
?>
</body></html>
Page 118
SMS Applications
Now enter the command chmod a+x test2.php to make this script executable. Then enter the command ./test2.php to execute it. You
will see the same output as before in the webbrowser but this time the output is written to the terminal window.
Page 119
SMS Applications
Page 120
SMS Applications
Page 121
SMS Applications
decimal number
%s
text
%f
floating number
%e
%o
octal number
%x
%X
You can specify the output width for decimal numbers by entering the width between the percent character and the letter:
printf "%10d" 12
This command outputs the number 12 with 10 characters width. The left end is filled with zeroes if the length value starts with a zero.
Floating numbers can also have a fixed width after the dot:
printf "%.2f" 12.345678
This command outputs "12.35", the value is rounded mathematically. Unfortunately you cannot select the width before the comma. You
will always see all digits and the number is not filled with spaces or zeroes at the left end.
Please be sure to give printf exactly as many arguments as you insert placeholders into the text. Nobody knows what happens if you
enter to many or to less arguments.
Page 122
SMS Applications
4.9.3. Strings
Strings (or texts) are always written between double quotes. Sometimes commands work also without double quotes (for example
echo), but you should write them always. For example (test3.sh):
#!/bin/sh
echo "Hello
echo Hello
Stefan"
Stefan
Both commands do not produce the same output. The second command writes only one space character between "Hello" and "Stefan"
because the string was not included in double quotes. In real this are two strings and not one. The shell uses spaces and tabulators to
separate arguments. Many consecutive space and tabulator characters are treated as one single space character.
If you want to output a control character that normally has a special function, you need to preceed it by a backslash \ (test4.sh):
#!/bin/sh
echo "Hello \"Stefan\" "
This outputs
Hello "Stefan"
Another control character that needs a backslash is the dollar character. The backslash itself can be written as \\.
You can write strings also in single quotes. The difference is that " and $ have no special meaning when they are written between
single quotes. Example (test5.sh):
#!/bin/sh
echo "Your name is $USER"
echo 'Your name is $USER'
echo 'Hello "Stefan"'
echo "Hello 'Stefan'"
The first command shows the actual user name, an environment variable of the shell. The second command shows only the name of
the variable. The other commands demonstrate that single quotes within double quotes have no special meaning - and vice versa.
Page 123
SMS Applications
4.9.4. Variables
Variables can be set and then read later. Variables in shell scripts store always text. It is important not to write space characters before
or after the assignment operator "=". Example test6.sh:
#!/bin/sh
variable1="Stefan"
echo "Hello $variable"
variable2=0123
echo $variable2
The second echo command outputs 0123 because this is not a number but a text. Therefore the trailing 0 is still there.
I like to show you a special thing when reading variables (test7.sh):
#!/bin/sh
variable3="Hello
echo "$variable3"
echo $variable3
Stefan"
SMS Applications
this output:
The
--The
The
--The
As you can imagine, you can export $Name2 with export command or you can run the sub-script with the dot command to solve this
problem. The Alexander will also be visible in the main script.
At the end I like to tell you something more about variable names: Do not write variable names completely in capital letters. All
variables of the operating system are written in capital letters and your own variable names should never be the same as a reserved
operating system variable. If you do not use full capital names you avoid problems and do not change system variables accidentally.
For example, if you write accidentally PS1="Hello" because you did not know that this variable is used by the system... try it, it's
harmless but surely surprising.
Enter PS1="Hello" and look at the result. Your command prompt changes! If you had used small letters, the prompt would not have
changed.
If you like to see all shell variables, then enter env|more. You may find some variables useful.
Page 125
SMS Applications
Page 126
SMS Applications
4.9.9.1. if...then...else...fi
The control structure if...then...else...fi allows you to execute a part of the program only if a condition is true or a test command returns
0. The usage is:
if Command ; then
Program_part1
fi
or:
if Command ; then
Program_part1
else
Program_part2
fi
If the command was successful the Program_part1 is executed. If the command was not successful then the Program_part2 is
executed.
Only seldom the following enhanced version is used, that allows to test for more than one condition:
if Command1 ; then
Program_part1
elif Command2 ; then
Program_part2
else
Program_part3
fi
If Command1 was successful, then Program_part1 is executed. Otherwise Command2 is executed and if Command2 was successful,
then Program_Part2 is executed. Otherwise the Program_part3 is executed. The elif part can repeated as often as you want.
A concrete example is test12.sh:
#!/bin/sh
if rm /tmp/test.txt ; then
echo "Deleting was successful"
echo "Everything is Ok"
else
echo "Error:"
echo "The file could not be deleted"
fi
And now you see an example for the enhanced version (test13.sh):
#!/bin/sh
if rm /tmp/test.txt ; then
echo "Deleting of test.txt was successful"
elif rm /tmp/test2.txt ; then
echo "Deleting of test2.txt was successful"
elif rm /tmp/test3.txt ; then
echo "Deleting of test3.txt was successful"
else
echo "No of the three files could be deleted."
fi
Some people write the keyword then in a separate line, then the semicolon can be left out:
#!/bin/sh
if rm /tmp/test.txt
then
echo "Deletion was successful"
fi
Page 127
SMS Applications
4.9.9.2. Comparisons
If you want to execute a part of the program you want often compare two strings or numbers. This can be done using the test
command or brackets [ ].
There is no manual page for the brackets because its the same as the test command.
[ "Hello" = "Hello" ]
echo $?
This returns 0 because the comparison was successful. This command is the same as:
test "Hello" = "Hello"
echo $?
The echo $? command shows the exit code of the last command. $? is a special variable that I will explain later together with some
other special variables.
Most programmers like the brackets more than the test command because they are good visible when quickly browsing through a
script file. Take care about the spaces before and after any bracket and any operator! It's really important not to forget any space,
because otherwise the comparison will work not as expected.
Compare text
[ "Text1" = "Text2" ]
[ "Text1" != "Text2" ]
[ -z "Text" ]
0, if text is empty
[ "Text" ]
When comparing for alphabetic order A-Z comes before a-z. The computer simply uses the order from the ASCII table.
Compare numbers
[ Number1 -eq Number2 ]
You can only compare integer numbers, that are number without a dot.
The brackets or the test command are only useful when used together with control structures, like if...then...else or other. One example
(test13.sh):
#!/bin/sh
Number = 12
if [ $Number -gt 5 ] ; then
echo "The number $Number is larger than 5"
else
echo "The number $Number is not larger than 5"
fi
Check the result. If you change Number=12 to Number=3 then the result changes.
Another example is test14.sh:
#!/bin/sh
Name = "Manuela"
if [ $Name = "Manuela" ] ; then
echo "The name $Name is Manuela"
else
echo "The name $Name is not Manuela"
fi
Page 128
SMS Applications
Checking filenames
[ -r "Filename" ]
[ -w "Filename" ]
[ -x "Filename" ]
[ -f "Filename" ]
[ -d "Filename" ]
[ -L "Filename" ]
[ -e "Name" ]
-a means AND
-o means OR
[ ! "Text1" = "Text2" ]
neterr a number"
-lt 10 -o $Number -gt 100 ] ; then
number is less than 10 or greater than 100"
number is between 10 and 100"
Another more often used version is the following, although it runs slower:
[ "Text1" = "Text2" ] && [ "Text3" = "Text4" ]
|| means OR
neterr a number"
-lt 10 ] || [ $Number -gt 100 ] ; then
number is less than 10 or greater than 100"
number is between 10 and 100"
Page 129
SMS Applications
4.9.9.4. case..esac
If you build a large if and elif command with man comparisions the source code can become badly readable. A n example is test18.sh:
#!/bin/sh
echo "Please enter a
read Number
if [ $Number -eq 1 ]
echo "You entered
elif [ $Number -eq 2
echo "You entered
elif [ $Number -eq 3
echo "You entered
elif [ $Number -eq 4
echo "You entered
else
echo "You entered
fi
number"
; then
one"
] ; then
two"
] ; then
three"
] ; then
four"
another number"
You can write the same script using the case...esac control structure. This looks often more beautiful (test19.sh):
#!/bin/sh
echo "Please
read Number
case $Number
1)
echo
2)
echo
3)
echo
4)
echo
*)
echo
esac
enter a number"
in
"You
"You
"You
"You
"You
entered
entered
entered
entered
entered
one" ;;
two" ;;
three" ;;
four" ;;
another number" ;;
Do not forget the double semicolons! If you want to execute more than one single command for any condition, the write it as shown in
test20.sh:
#!/bin/sh
echo "Enter a number"
read Number
case $Number in
1)
echo "You entered one"
echo "I like ones"
;;
2)
echo "You entered two"
echo "Two is also ok for me"
;;
esac
This example demonstrates, that double semicolons can also be written in another line and that you may leave out the *) part.
You can also combine many comparisons with the OR function (test21.sh):
#!/bin/sh
echo "Enter a number"
read Number
case $Number in
1|2)
echo "You entered one or two" ;;
3|4|9) echo "You entered three, four or nine" ;;
esac
The case...esac control structure works also with text. Write strings and variables in double quotes to avoid problems with spaces
(test22.sh);
#!/bin/sh
echo "Please enter
read Word
case "$Word" in
"red"|"green")
"yellow")
*)
esac
Page 130
a word"
echo "You entered red or green" ;;
echo "You entered yellow" ;;
echo "You entered something else" ;;
SMS Applications
4.9.9.5. while...do...done
The while loop executes a block many times, as long a condition is true or a test command returns 0.
#!/bin/sh
while read Text ; do
echo "You entered $Text"
done
As long the read command is successful, the echo command is executed. For this program it's good to know that read returns with a
non-successful exit code when you press Ctrl-D.
4.9.9.6. for...in...do...done
The for loop executes a program part many times, one time for any element in a list. The following example test25.sh shows how to
use the for loop:
#!/bin/sh
for Colour in red yellow green blue ; do
echo "The colour is $Colour"
done
This script creates the output:
The
The
The
The
colour
colour
colour
colour
is
is
is
is
red
yellow
green
blue
Page 131
SMS Applications
#!/bin/sh
echo "Enter something or press enter to stop"
while true ; do
read Text
if [ -z "$Text" ] ; then
break;
fi
echo "Thanks"
done
This script does nearly the same as test24.sh but it uses different commands.
The while loop repeats endless because the true command returns always 0 (that means successful). True does nothing else. The
opposite is false - what a surprise!
The if command checks if the text is empty. If yes, then the loop breaks.
The continue command enforces the next repetition of the loop. The remaining commands are not executes in the current repetition
(test27.sh):
#!/bin/sh
echo "Please enter something or Ctrl-D to stop"
while read Text ; do
if [ -z "$Text" ] ; then
continue;
fi
echo "Thanks"
done
If you run this script you can enter as much as you like, also empty lines. But a "Thanks" appears only for lines that are not empty.
The exit command stops the whole shell script immediately. You can apply an exit code to the exit command if you like. If you leave out
the exit code, 0 is assumed. Example (test28.sh):
#!/bin/sh
echo "Please enter something"
read Input
if [ "$Input" = "stupid" ] ; then
echo "I'm not stupid!"
exit 1
fi
echo "Ok, thanks"
After running this script you can check the exit code by entering echo $?.
Page 132
SMS Applications
4.9.10. Functions
Functions are small sub-programs than can be used many times at different places. One example is test29.sh:
#!/bin/sh
function Error()
{
echo "An error occured:"
echo "$1"
}
echo "Please enter a three"
read Number
if [ $Number -ne 3 ]; then
Error "Wrong number!"
else
echo "Thanks"
fi
If you run this script and enter something else than a 3, you see this output:
Please enter a three
5
An error occured:
Wrong number!
This function does not only show simple fixed text but also a variable (Wrong number!) because it got this variable as an argument
from the main program.
Within the function the first argument is read with $1. If there would be more arguments, they would have the following number $2, $3
and so on. test30.sh:
#!/bin/sh
function Test()
{
echo "The arguments are:"
echo "$1 + $2 + $3 + $4"
}
Test "Hello" "Saskia" "my" "Sister"
This script creates the output:
The arguments are:
Hello + Saskia + my + Sister
Page 133
SMS Applications
$1, $2 ... $9
$#
"$@"
"$*"
$*
$?
$RANDOM
You learned already how to use $1 until $9 in the last chapter about functions. You can use these variables also to read scriptarguments (test31.sh):
#!/bin/sh
echo "You
echo "The
echo "The
echo "All
entered $# arguments"
script name is $0"
first argument is $1"
arguments together are $*"
Run the script by entering ./test31.sh One Two Three. The output will be:
You
The
The
All
entered 3 arguments
script name is ./test31.sh
first argument is One
arguments together are One Two Three
Now I like to show you the difference between "$@" and "$*" in test32.sh:
#!/bin/sh
for Word in "$@"; do
echo "-- $Word"
done
echo ""
for Word in "$*"; do
echo "-- $Word"
done
The first for loop outputs every single Word, "$@" created a list of three words. The second for loop outputs only one line, alls three
words are combined in one single line:
./test32.sh One Two Three
-- One
-- Two
-- Three
-- One Two Three
./test32.sh "One 1" "Two 2" "Three 3"
-- One 1
-- Two 2
-- Three 3
-- One 1 Two 2 Three 3
If you compare both outputs you will notice that the text "One 1" is still kept together as one string.
If you write $@ or $* without double quotes, then you will get always a list of single words. In this case "One 1" will also be split into two
words (test33.sh):
Page 134
SMS Applications
#!/bin/sh
for Word in $*; do
echo "-- $Word"
done
./test33.sh "One 1" "Two 2" "Three 3"
-------
One
1
Two
2
Three
3
Alltogether there are three different ways to read all arguments with one single variable.
$1"
The shift commands deletes the first argument and moves all other one position to left. The argument $2 moves to $1 and $3 moves to
$2 and so on. You can use the shift command as often as you like and it allows you to access more than 9 arguments.
Page 135
SMS Applications
Plus
Number1 - Number2
Minus
Number1 * Number2
Multiplication
Number1 / Number2
Division
Number1 % Number2
Returns count characters from the text beginning at the start position. "substr Hello 2 3" returns
"ell"
Returns the position of the first occurence of one character within a string "index Hello eb" returns
"2"
length Text
Do not forget the spaces and take care about the star because it has a special meaning to the shell. You need to write a backslash (\)
before the star and also before parantheses.
Expressions can use parentheses to specify the evaluation order:
Result=`expr \( 1 + 2 \) \* 3`
echo $Result
9
Text="Hello"
Length=`expr length "$Text"`
echo $Length
5
expr 6 \* 5
30
The last command shows you how to output the result to the screen instead redirecting it into a variable. This is used very seldom
because normally you want to use the result for whatever, e.g. in an if...then...else...fi control structure.
Page 136
SMS Applications
4.9.15.1. cat
This is not an animal but a shortcut for catalogue. The cat command shows the content of a text file:
cat test.txt
You can redirect the output into a variable:
Variable=`cat test.txt`
If you leave out the filename, cat reads from the keyboard until you press <Ctrl-D>:
Variable=`cat`
Page 137
SMS Applications
4.9.15.2. cut
The command cut reads from its standard input channel and cuts a part of it for output. You can select between
-c range
-f range
-d ','
Specified the separator character for columns
The range can be written in different ways:
3
3-5
-5
1,3,5
If you give a filename to the cut command, it reads from the file, otherwise it reads from the input channel (normally the keyboard) until
you press <Ctrl-D>. Of course you can redirect the output using arrows > < and the pipe character |. Some examples:
cut -c 3-5
Hallihallo
<Ctrl-D>
Creates the output:
lli
lets say you have a text file with this content,
Marius
Mariechen
Liesa
Robert
and then you enter
cut -c 1-3 test.txt
you will get this output
Mar
Mar
Lie
Rob
One,Four
You filtered out the fields 2 and 4. Please note that cut uses the same delimiter for input and output.
Page 138
SMS Applications
4.9.15.3. sed
Sed is a powerful program that modifies text. There are whole books written about sed, so many functions has it. I like to show you only
some few that I use often:
Like cat and cut also sed reads from a file or from the keyboard until you press <Ctrl-D>. Input and output are redirect-able.
Sed does not modify the source file. It shows the modifications only on screen.
Lets say you have the file test.txt with this content:
Hello
the
Weather
is
nice
and
i
have to
learn
The next command read this file and gets only some few lines from it ignoring the rest:
sed '2,4p' --silent test.txt
the
Weather
is
2,4p means: give me oly the lines from2 until 4. If you want to get only one single line, you do not need a comma:
sed '2p' --silent test.txt
The next command outputs the whole text except a given line number:
sed '1d' test.txt
Sed can also search and replace words:
sed 's/nice/wet/g' test.txt
The search word "nice" is a regular expression. A later chapter will show you what that means. Read it - its useful!
Page 139
SMS Applications
4.9.15.4. grep
The grep program reads its input line by line and outputs only lines that match a keyword (exact: regular expression). The input is again
a file or the keyboard. Grep can also read from more than one file if you give him mor filenames. Input and output can be redirected to
whatever you like. If you enter from keyboard, press <Ctrl-D> to stop.
Lets say you have a text file with this content (test.txt):
In winter the snows comes.
In summer its warm instead.
My mother is good to me.
Where are you going?
The man looks different.
If you now enter grep 'the' test.txt you get this output:
In winter the snow comes.
My mother is good to me.
The second line appears because "Mother" includes "the". The last line does not appear because grep is case sensitive.
The option -i lets grep to forget that it is case sensitive:
grep -i 'the' test.txt
In winter the snows comes.
My mother is good to me.
The man looks different.
The option -c is used to count the number of matching lines (test36.sh):
#!/bin/sh
Count=`grep -c 'der' test.txt`
if [ $Count -gt 2 ]; then
echo "More than 2 lines were counted, exactly $Count"
else
echo "Less or exactly 2 lines were counted."
fi
The option -l is used to list only the filenames that contain at least one matching line. This makes only sense if you give many
filenames to grep.
The option -v makes grep to show all lines that do not contain the searched word.
The next chapter explains regular expressions used by grep and sed.
Page 140
SMS Applications
\<
\>
is any character
[abc]
[a-z]
a*
a+
is an OR (only egrep)
()
Caution: The last three expressions are only known to egrep, an enhanced version of grep!
If you want to search for a character that has a special meaning to grep or egrep, you need to preceed it by a backslash \. For
example \. searches for a dot and not any single character.
Create a text file with this content:
In winter the snows comes.
In summer it's warm instead.
My mother is good to me.
Where are you going?
The man looks different.
My name is Dr. Irene Meier.
Your name is Ms. Dr.Dr. Liebig.
Brrrrrrr, it's cold here.
The next beep is 08:23:56.
Berries are sweet.
Bumm, that was a crash.
Brrrrumm, and another car.
We will use this text file to test some regular expressions.
grep 'i' test.txt
Shows all lines that contain an i. But
grep '^I' test.txt
shows only lines that start with a capital I. The difference is that "Ms. Dr. Irene Meier" is only found by the first command.
grep '\.$' test.txt
Shows all lines that end with a dot. The line that ends with a question mark is not one of them.
grep '..:..:..' test.txt
Shows all lines with a time value.
grep 're\>' test.txt
Shows all lines with a word that ends with "re".
grep '\<....\>' test.txt
Shows all lines that have a word with exactly four characters.
grep 'Br*umm' test.txt
Shows all lines where a word starts with B, continues with any number of r (alows no r) and then ends with umm. The output is:
Bumm, that was a crash.
Page 141
SMS Applications
Hello
The first echo command demonstrates that the variable content includes unwanted spaces. After that we use the echo command again
together with a redirection to variable b to cut off all spaces. The last echo command demonstrates that the spaces are now gone.
Why does that work?
To explain this We split the third line into two parts:
b=`...`
and
echo $a
The interesting part is the second one. This time I did not write $a between double quotes - like we normally do. This lets the shell split
the text into words removing all spaces that we do not need. And exactly this is what we want.
Page 142
SMS Applications
If the script is very small, you may also give it as a command line argument instead of storing it into a separate script-file:
awk 'commands' textfile
If you play around with different textfiles, you will notice that awk treates multiple spaces and tab-characters as single ones. In addition
awk removes leading and trailing spaces from each line. Lets assume, your textfile looks like this one:
Stefan
Frings
Michaela Meier
Gundula Geier
then the result would be:
Frings
Meier
Geier
The second example finds all lines with the keyword "Hello" and prints them (to the screen).
Page 143
SMS Applications
Page 144
SMS Applications
SMS Applications
OFS
Output Field Separator. Print inserts this characters instead of the comma. The default is one
space character.
FS
Field Separator. Lines are splitted using this regular expression. The default are one or multiple
spaces or tab-characters.
ORS
Output Record Separator. print ends each line with this character. It is normally a line-feed.
RS
Record Separator. Input lines are separated with this character, that is normally a line-feed.
OFMT
NF
NR
FNR
FILENAME
RSTART
RLENGTH
$0
$1
$2
$3
Page 146
SMS Applications
or
or
#!/bin/sh
echo "We have"
awk -v fruits=36 -v persons=12 'BEGIN {print fruits/persons}'
echo "apples for each child."
#!/bin/sh
apples=36
childs=12
echo "We have"
awk -v fruits=$apples -v persons=$childs 'BEGIN {print fruits/persons}'
echo "apples for each child."
#!/bin/sh
apples=36
childs=12
result=`awk -v fruits=$apples -v persons=$childs 'BEGIN {print fruits/persons}'`
echo "We have $result apples for each child"
All three examples produce (nearly) the same output. The last example prints everything in one single row because it has only one
echo command.
You saw, how to set variables from outside using the option -v. These variables can be used within awk scripts.
You have surely noticed, that the examples above do not read input files. After the BEGIN condition is only the mathematical
calculation. There is no condition that matches a text line and therefore, we do not need to use a textfile.
Page 147
SMS Applications
4.10.7. Operators
The previous chapters show you how do perform mathematical additions and divisions. Awk supports the following operators:
+
addition
subtraction
multiplication
division
modulus
++
increase by 1
--
decrease by 1
assign
+=
add to
-=
subtract from
*=
multiply by
/=
divide by
%=
modulus by
^=
Examples:
a=3
result is 3
a+=5
b=a+6
result is 14
b++
b/=3
equal
!=
not ewual
>
greater than
<
less than
>=
greater or equal
<=
less or equal
!~
Examples:
if ($1=="Stefan")
if ($1>5)
if ($1~/fan/)
Page 148
and
SMS Applications
||
or
not
Example:
if (a==3 && b==4)
or:
if (condition)
command;
else
command;
if (condition) {
commands;
commands;
commands;
} else {
commands;
commands;
commands;
}
Use brackets to execute more than one single command. Brackets are used to make blocks of commands. The else-part is optional.
Example:
if (a==3)
print "The variable a is now 3";
command;
while (condition)
The difference is only that the condition is checked either before the command or after the command. Example:
a=0
while (a<10) {
print "The variable a is now" a;
a++;
}
This loop counts from 0 up to 9.
Page 149
SMS Applications
Page 150
SMS Applications
\n
new line
\t
tab-character
\0xxx
Print can also write its output to a file instead to the screen.
print "Hello" > "filename";
print "Hello" >> "filename";
The second version appends to an already existing file. The first version creates a new file and eventually overwrites files that already
exist.
Print can also execute external command and send text to them:
print "Stefan\nMarkus\nJessica\nOlivia" | "sort";
The command above outputs four names and sends them to the external sort command. This command sorts the names
alphabetically.
an integer number
%f
%c
a single character
%s
a string (text)
Example:
printf("%f Euro",12.5);
You can specify the field length of the spaces that are reserved for the variables. The values appear right-aligned:
printf("%6f Euro",12.5);
Left-aligned is also possible:
printf("%-6f Euro",12.5);
One more complex example:
printf("%-20s %4.2f Euro\n","Inkjet paper",12.5);
This outputs the title "Inkjet paper" left-aligned and filled to 20 characters length. The the price follows right-aligned into a field with 4
digits before the dot and 2 digits after the dot. The a newline character follows.
Page 151
SMS Applications
Sprintf works like printf, but the output goes into a variable instead to the screen:
variable=sprintf("%f Euro",12.5);
Page 152
SMS Applications
4.10.15. Arrays
Arrays are variables that can store many values. Each value has a name or a number plus the value itself.
Examples:
fruits["apples"]=36;
fruits["pears"]=20;
fruits["cherries"]=340;
...
print "We have " fruits["apples"] " Apples";
print "We have " fruits["pears"] " Pears";
print "We have " fruits["cherries"] " Cherries";
...
The for loop makes this easier:
fruits["apples"]=36;
fruits["pears"]=20;
fruits["cherries"]=340;
...
for (name in fruits)
print "We have " fruits[name] " name;
Arrays are very useful to count the occurrences of error codes in a logfile. Lets say you have a logfile with this format:
05.04.2005
05.04.2005
05.04.2005
05.04.2005
05.04.2005
12:38
12:39
12:55
12:58
12:59
Error 12
Trying to read configuration file
Error 18
Starting Internet communication
Error 17
Then you could count the error codes with this script:
/Error/ {errors[$4]++}
END {for (code in errors)
print "Errro-Code " code " was counted " errors[code] " times.";
}
Page 153
SMS Applications
log(x)
natural logarithm of x
exp(x)
natural exponent x
sin(x)
sine of x in radians
cos(x)
cosine of x in radians
rand()
srand()
Initializes the random number generator. You should use this command one
time in the BEGIN condition of each program that uses rand().
toupper(s)
length(s)
returns length of s
substr(s,start,length)
Returns a part of s. The part begins with start and has a given length. If you omit the
length, then you will gte the whole rest of the string.
match(s,r)
Compares the string s with a regular expression r. It stores the result in two variables,
RSTART and RLENGTH. If r was not found in s, then RSTART is 0. Match returns the
found position or 0.
sub(r,s,dest)
Searches for the regular expression r in the destination string and replaces the first
occurrence by the string s. If you omit the destination, then $0 is used.
gsub(r,s,dest)
index(s,word)
Searches for a word in the string s and returns the position. The result is 0 if the word was
not found in s.
split(s,array,separator)
Splits a string s into fields. Each field becomes an element in an array. If you omit the
separator, FS is used.
Information: Regular expressions can be written between slashes instead of double-colons for better visual impression.
Functions for Input/Output:
close(filename)
closes a file
Reads one line from a text file. If you omit the filename, the the current input file is used.
If you omit the variable name, then $0 is used.
Executes a command and write the output of that command into a vriable. If you omit the
variable, then $0 is used.
system
Other functions:
delete array[element]
Examples:
text="Hello bruther";
gsub(/bruther/,"brother",text);
Results: "Hello Brother"
text="WRitteEN MIxeD";
print tolower(text);
Results: "written mixed";
text="Errocode [45]";
Page 154
SMS Applications
match(text,/\[[0-9]+\]/);
if (RSTART>0)
print substr(text,RSTART+1,RLENGTH-2);
Results: 45
Match searches for a number with at least one digit between square brackets. The position is stored in RSTART and RLENGTH.
The regular expression [0-9] searches for a digit. \[ searches for a square bracket. The + means that the previous digit must appear at
least 1 time.
Substr is used to extract only the number without the surrounding brackets. Printf prints the result.
Page 155
SMS Applications
function duplicate(a) {
return a*2;
}
{print duplicate($1)}
This script reads in a textfile, each line must begin with a number. These numbers are multiplied by 2 and then displayed.
Page 156
SMS Applications
You could use grep to check whether the received SMS contains the keyword "joke" and whether a valid item-number is included. But
grep cannot extract the number. Also the cut command is not useful because you do not now the exact position of the item-number.
Your customer could write the item-number as the very first word in his order or he could place it somewhere else. He could write
space characters between and he could include other meaningless words in his SMS. Example:
"Hello, I like to order the joke number 12345"
This is a valid order because it contains the keyword joke and also the item-number. I like to show you now, how to combine a shell
script with awk to process such orders.
Your items (the jokes) are stores as text files:
/var/spool/sms/jokes/12345.txt
/var/spool/sms/jokes/23456.txt
/var/spool/sms/jokes/98765.txt
When the SMS Server Tools receive SMS, they are also stored in text files in this format:
From: +491721234567
Hello, I like to order the joke number 12345
Whenever the SMS Server Tools receive a message, they store it into a text file and then run an eventhandler script. $1 is always the
keyword "RECEIVED" and $2 is the filename of the stored message.
Your eventhandler script could be this one:
#!/bin/sh
if [ "$1" != "RECEIVED" ]; then
exit
fi
from=`formail -zx From: < $2`
text=`formail -I "" <$2 | sed -e"1d"`
if echo "$text" | grep -i "joke"; then
smsfile=`mktemp /var/spool/sms/outgoing/send_XXXXXX`
echo "To: $from" >> $smsfile
echo "" >> $smsfile
number=`echo "$text" | awk '
{
}
if (match($0,/[0-9][0-9][0-9][0-9][0-9]/)
print substr($0,RSTART,RLENGTH)
'`
if [ -f "/var/spool/sms/jokes/$number.txt" ]; then
cat "/var/spool/sms/jokes/$number.txt" >> $smsfile
else
echo "Sorry, wrong article number" >> $smsfile
fi
fi
SMS Applications
write the destination phone number of your customer and the then an empty line into the SMS file.
After that awk extracts the item-number from the order. The next if command checks if such an article (textfile) really exists. Then the
ordered text gets written into the SMS file.
Finally the SMS server tools send this SMS file automatically.
I like to explain the awk line in detail:
number=`echo "$text" | awk '{if (match($0,/[0-9][0-9][0-9][0-9][0-9]/) print substr($0,RSTART,RLENGTH)}'`
number=`...`
Writes the result of the next command into the variable $number. We can use this variable to insert it into a filename later.
echo "$text" | awk ...
The echo command sends the text of the order to awk. We give awk only this next through a pipe and no input filename. I showed you
this principle in chapter 4.10.1.
if (match($0,/[0-9][0-9][0-9][0-9][0-9]/) ...
The match command searches for a regular expression. In this case we search for a number of 5 digits in range 0-9. Only if this
number was found, then the next print command gets executed.
print substr($0,RSTART,RLENGTH)
Here we output the found item-number. The match() command stored the position in RSTART and RLENGTH, so we can use substr()
to output only the important part from the order text.
Page 158
SMS Applications
5.1. Overview
This chapter is an introduction to the SMS Server Tools. You will learn how they work and what they can do.
A note about abbreviations:
SMS means Short Message Service and means the whole service. Therefore you cannot send SMS, but the abbreviation is still often
used in the wrong way by users of mobile phones - also the advertising uses it often wrong.
SM means Short Message. You do not send SMS but SM. many people avoid this abbreviation because SM means also SadoMasochism.
SMSC means Short Message Service Centre. This is the centre for SMS that queues messages and delivers them to the mobile
phones. ANY phone network operator has at least one SMSC. Like any phone call goes through the public switch any SM goes through
the SMSC.
The SIM card is the small removable chip-card that every GSM modem and mobile phone need to identify the device in the phone
network. Without a SIM card no GSM device can operate. Mobile phones and GSM modems do not only store the phone book onto this
card, they use it also to store their own phone number (MSISDN).
The next picture shows the most important parts of SMS Server Tools and how they are connected together.
The picture shows how the SMS Server Tools send SM. In this case we have five british phone network provider and we use four
modems to send messages.
The explanation follows on the next page.
Page 159
SMS Applications
This text file has to contain at least the phone number of the receiver and the message text.
You can also write the senders name or number into the file, it will appear in logfiles later.
After creating the SMS file you move it to the outgoing queue directory. This is a simple directory on the harddisk.
You can also create the file directly in the outgoing queue directory if this goes quickly. The main program smsd checks this directory
any few seconds and if there is a file that does not grow within one second. If smsd finds such a file, it thinks that the file creation is
finished and assumes that the file can now be sent.
Therefore, if you create a SMS file directly in the queue directory, do it quickly. This ensures that smsd does not attempt to send the file
before it is completely created.
The file format is simple. It is similar to eMails in Unix. First there is a header with sender, receiver and maybe some more information.
The header may contain as much lines as you like. Smsd ignores all unknown lines.
Then an empty line follows. After that the text or binary content follows. In case of binay SM, for example ringtones or logos, the same
rule is used. The binary content follows immediately after the empty line.
The picture above shows a valid SMS file.
The outgoing queue allows you to create many SMS files that are send one after the other. You do not need to wait for sending after
you create each file.
The next step is, to check if the SMS file is valid. Smsd does this for you.
It reads all files in the outgoing queue and compares the recipient numbers with the blacklist. This is a text file that contains all phone
numbers that never get a SM. The blacklist can also contain area codes to blacklist a whole area.
Instead of a blacklist you can also use a whitelist. It contains all numbers that are allowed to get SM. If there is a whitelist and a
blacklist, then all number in the white list can receive SM but not those who are also in the blacklist. The blacklist is more important.
If the SMS file specifies a provider name, then the files goes into the corresponding provider queue. If the provider name is not
specified, then Smsd compares the recipients phone number with the configuration file smsd.conf and assigns the provider by its area
code.
Page 160
SMS Applications
Note: After I developed this part the PPRTU project started. It allows mobile customers to change their provider and keep the old phone
number. The area code is not a good indicator for the provider name any more. This is not critical for smsd itself but a wrong
assignment to provider queues can increase your bill and affects your statistics.
If the SMS file does not include a provider name and the area code is also unknown, the message file is invalid and moved to the failed
queue. Such messages will not be sent.
If you do not want to keep failed files you can remove the failed queue directory form the configuration file.
Any provider queue as at least one attached modem. One program part of smsd (modem task) reads the SMS files from the provider
queue and sends it using the sub-program putsms.
You can assign many modems to each provider queue, an option that the pictures of this chapter do not show. This increases the
performance when sending many SM. In addition your system will not stop working if a single modems hangs because the other
modems continue their work.
To prevent that more than one modem send the same message at a time, smsd uses lockfiles. A lockfile is a file with the same name
as the message file but it has the ending ".LOCK". The existence of this file signals the other processes that the message file is already
in use.
Smsd writes an information into this file: The process number of the process that created this lockfile. The kernel of any operating
system gives any process a number, visible with the ps command. This number has no function for smsd, its only an information for
you.
Lockfiles allow you to connect many servers to the same queue directory. If you do so then a single failed computer will not stop your
service because the other computers continue to work.
If sending of a message fails also after a second try, the file will be moved into the failed queue directory.
If sending through the same modem fails three times, smsd thinks that the modem is out of order and blocks this modem for a
configurable time (for example 1 hour). This ensures that the remaining messages are sent through the other modems - if more
modems exist. Therefore it's good to have at least two modems for each provider.
As you can see in the big picture at the beginning of this chapter, it's also possible to use one modem for many provider queues. The
configuration file assigns modems to queues. The queue directories are handled with priority. One example with two modems:
Modem1 is for Telekom D1 and Vodafone D2. The modem has a SIM card from Telekom D1.
Modem2 is for Vodafone D2 and Telekom D1. The modem has a SIM card from Vodafone D2.
The Modem2 is normally used for sending messages to the D2 network. Only when there are no messages for D2 it send messages
for the secondary queue D1.
The same happens with the Modem1. It sends primarily messages for D1 network and secondarily messages for D2 network if the D1
queue is empty.
What is the advantage of this configuration?
There are many answers:
1. If the Modem1 goes out of order, then Modem2 is used to send the messages into D1 network. This ensures that your system
continues working even if a modem is broken. The same applies to Modem2.
2. If you send a lot of messages into D2 network and only a few to D1 network the Modem1 helps Modem2 to send messages. It
increases the speed. The same happens with Modem2.
3. If the network of one provider fails, the other modem continues to send the message.
Page 161
SMS Applications
4. You save some money because sending message to the "own" provider network is typically cheaper than sending messages to
"foreign" networks. Some contracts give a special low price when you send more than 100 messages within the "own" network.
Therefore at least one modem for each provider helps you to save money.
Because of answer 4. the program sorts messages by provider. Without this sorting you would not be able to use the low price in
optimum way.
The program part of smsd that controls the modem (modem task), checks the modem every few minutes or seconds for incoming
messages. It uses the sub-program getsms to do this. The received messages are kept in the incoming queue directory.
You can configure which modems are checked for received messages and if sending or receiving has higher priority.
Most modems need higher priority on receiving because if the input buffer is full, they cannot send outgoing messages. In case of
doubt you should test if you modem has this problem.
Other functions:
Page 162
SMS Applications
The following functions are secondarily to smsd but still important for many users.
Smsd can run a status monitor. The status monitor shows the state of each modem - if it is sending, receiving, idle or blocked.
Smsd collects statistics about the number of sent and received SM and how much percent the modems are loaded. This statistic helps
you to decide if adding more modems increases performance or not. A table calculation program like Microsoft Excel or KSpread can
read these statistic files and create beautiful graphs from them.
When you stop smsd or kill it, you do not loose statistic data. This is special to the SMS Server Tools. Most other programs loose all
statistic counters of the actual time slice (for example one hour) when you stop the program. But smsd saves these values into a
temporary file and loads them back into memory later.
There are logfiles that record any action of the SMS Server Tools. You can configure the detail level. Maybe you want to see only error
messages or any smallest detail like the modem commands.
Smsd can write the logfile to screen (standard output channel), into a file or it can use the good old syslog daemon of Unix to record
logfiles. If free configurable.
Eventhandler can be executed on special events, for example when a message was sent or received. Eventhandler allow you to
combine the SMS Server Tools with other external programs and enhance the function of smsd without much work. A typical usage of
this is a cost-counter with SQL database.
Since version 1.10 can also check the validity of SMS files using an external program before it send the message. As you can see in
later chapters this is a very useful advantage.
Alarm handler are also eventhandler. Alarm handler are executed whenever an error occurs. The can be used to send alarm messages
via eMail or to switch a flash-light on.
Page 163
SMS Applications
/usr/local/bin/putsms
/usr/local/bin/getsms
/usr/local/bin/sendsms
Example shell script, can be used to send a SM from the command line.
/usr/local/bin/sms2html,
sms2unicode, unicode2sms
Example eventhandler. This shell script logs sent and received messages and status reports in a
MySQL database.
/usr/local/bin/email2sms
Example shell script. Used to storeconvert eMail to a short message. Can be used together with
a mailserver to build an eMail to SMS gateway.
/etc/smsd.conf
/etc/init.d/sms
Startup-script, can be used to start and stop smsd, specially when booting.
/var/spool/sms/incoming
/var/spool/sms/outgoing
/var/spool/sms/checked
If you update the SMS Server Tools later by a newer version, your configuration files and scripts will be left untouched by the
installation command.
Smsd has only one configuration file, and it is normally /etc/smsd.conf. You can use another file using the option -c. Example:
smsd -c /etc/smsd.conf.test
The example configuration file shows you how to set up the SMS Server Tools with one modem. The file was made for a quick start
and it's small.
There is another example configuration file in smstools/examples that contains all possible options.
I like to show you all the options now. Let's start with a small and easy configuration file.
Page 164
SMS Applications
Page 165
SMS Applications
This configuration file does not include PIN numbers, therefore they need to be deactivated on all 5 SIM cards.
The five modems are connected to a Digi Etherlite, because no regular computer has so many serial interfaces. I found the names of
the serial ports in the manual of the Digi Etherlite.
The first two modems serve the provider queue for D1. The third and fourth modems serve the queue for D2. The last modem serves
all other provider queues.
This configuration doubles the throughput for D1 and D2 and protects the system against a single modem fault. I use only one modem
for the other provider to safe some money, because they do not have so many customers.
If you prefer you could also use two modems for the other providers. I like to show you in this example that the number of modems for
each provider can be different.
This example does not send messages into foreign countries. If you want that, you need to add an OTHER queue at the end and attach
at least one modem to it:
[queues]
...
OTHER = /var/spool/sms/OTHER
[provider]
...
Page 166
SMS Applications
OTHER = 0,1,2,3,4,5,6,7,8,9
If smsd find a message, that does not mahch any provider, then it will match to OTHER and is sent by the modem(s) that is attached to
this queue.
Page 167
SMS Applications
Page 168
SMS Applications
debug
info
Informations. The logfile contains many details but not the modem commands that you need for
debugging.
notice
Informations when a message was sent or received and informations when something not normal
happened.
warning
error
Error messages, when a program has a temporary problem, for example a modem answers with
ERROR or a file cannot be read.
critical
2
Critical errors, when a program has a permanent problem, for example sending failed many times or
permissions to the queue directories are insufficient.
This level is reserved for the operating system kernel and not used by the SMS Server Tools.
6
5
4
3
The numbers in this table are taken from Linux. I think that all operating system use the same numbers, but I'm not 100% sure.
If you use the syslog daemon or the Windows event log, then you can reduce the detail leve here or in the configuration of your
operating system.
alarmhandler = program name
Specifies a program that should run whenever an alarm occurs. This may also be a shell script. Enter the full filename with path.
Alarmhandler will be explained later. If you do not need an alarmhandler, leave this out.
alarmlevel = number
Page 169
SMS Applications
Specifies for what alarm levels an alarmhandler should start. You can enter values between 2 and 5.
notice
Informations when a message was sent or received and informations when something not normal
happened.
warning
error
Error messages, when a program has a temporary problem, for example a modem answers with
ERROR or a file cannot be read.
critical
Critical errors, when a program has a permanent problem, for example sending failed many times or
permissions to the queue directories are insufficient.
5
4
3
2
delaytime = number
This specifies the number of seconds that smsd waits if a queue is empty. After this time has elapsed, smsd checks again if there are
new SMS files in that queue.
Larger values save CPU and harddisk load. Smaller values like 1 second are good if you want best performance but then the computer
should not be used for other programs than SMS Server Tools.
The default is 10 seconds.
errorsleeptime = number
If a modem answers with ERROR, the program can insert an additional delay. Some modems need this before they can accept new
commands. The default is 10 seconds.
blocktime = number
When sending failed three times on the same modem, smsd thinks that the modem is broken. Then it block the modem for so many
seconds as you specify here. This ensures that the computer does not waste his time talking to a broken modem and that sending a lot
of messages fails. The default value is 3600 seconds, that is one hour. Only after one hour delay, smsd tried again to use this modem.
eventhandler = program name
Whenever a short messages was sent or received, or sending failed, then smsd can run an external program. Enter the program name
with full path. Eventhandlers are discussed later in this book.
stats = directory
If you write this line then smsd writes statistics into this directory. A later chapter describes how the statistc files look like.
stats_interval = number
This setting tells smsd for how many seconds it should collect statistic data before it writes them into a file. The default is 3600
seconds, that is one hour. Smsd ensures that the timepoints are always the same, it does not matter at what time you start the
program. For hourly statistics it write every full hour at 00 minutes into a file and not 60 minutes after program start.
blacklist = filename
This tells smsd the name of the blacklist file. If it is not set then it does not use a blacklist.
whitelist = filename
This tells smsd the name of the whitelist file. If it is not set then it does not use a blacklist.
checkhandler = program name
In addition to the black and white list you can also run external program to check if a SMS file is allowed to be sent or not. Before smsd
sorts the file into the provider queue directory, it runs the checkhandler. The checkhandler gets the filename as the first and only
argument. If the checkhandler exits with exit-code 0, then smsd send this message. If not, it does not send the message.
If you do not need a checkhandler, then leave this line out.
Autosplit = 0, 1, 2 oder 3
0
Long messages are sent in concatenated format, the receiving phone combines all parts to one message. Not all devices
support this format.
Binary and unicode messages (ringtnes, logos, and so on) are never splitted and must not exceed the size of 140 bytes.
receive_before_send = boolean
Page 170
SMS Applications
If you set this to yes then smsd ensures that ate least one memory space is free on the SIM card before it sends a message. Some
modems need this because they cannot send messages when the memory is full.
This option lets smsd check for received messages and send one after that. Without this option smsd prefers to send messages before
it receives something.
5.2.3.2. Queues
The SMS Server Tools sort outgoing messages into queues for each phone network provider. This allows you to save money using
different SIM cards from different provider.
This function is optional. If you do not want it, then do not write [queues] and [provider] sections into the config file.
After the main settings you define the names of the queue directories in the configuration file smsd.conf.
[queues]
Name = Directory Name
Name = Directory Name
...
Use only letters, digits and underscore and do not use special characters. One valid example:
[queues]
D1 = /var/spool/sms/D1
D2 = /var/spool/sms/D2
O2 = /var/spool/sms/O2
EPLUS = /var/spool/sms/EPLUS
QUAM = /var/spool/sms/QUAM
MOBILCOM = /var/spool/sms/MOBILCOM
If you do not want to sort messages, you need to create only one queue directory as shown below:
[queues]
ALL = /var/spool/sms/ALL
5.2.3.3. Provider
This section of configuration file lists the area codes of any phone network provider. The software uses this setting to sort outgoing
messages into queues.
There must be exactly the same number of rows in the sections [queues] and [provider] and the names must match.
Write area codes always in international format but without heading +.
[provider]
Name = List of area codes
Name = List of area codes
...
Example:
[provider]
D1 = 49160, 49170, 49171, 49175, 49151
D2 = 491520, 49162, 49172, 49173, 49174
O2 = 49176, 49179, 49159
EPLUS = 49163, 49177, 49178, 49157
QUAM = 49150
MOBILCOM = 49156
Page 171
SMS Applications
SMS Applications
old
Falcom A1 and other very old GSM modems from GSM phase 1
new
ascii
Onyl for testing. You can only send 140 characters in ascii mode. The program
uses clear text to submit a message to the modem instead of PDU coding.
Some modems do not support ascii mode
smsc = number
Any GSM modem and any mobile phone use automatically the default SMS centre that the network provider wants. This default setting
is stored in the SIM card. You can specify another SMSC by entering its number here. If you use tis setting the program runs slightly
slower because it has to send the number to the modem. The default is empty, so the modem uses its default from the SIM card.
Write the number in international format but without the heading +, for example 491722270000.
baudrate = number
Here you specify the speed of the serial communication between modem and computer. All modems that I know work fine with 19200
bits per second. If you modem does not answer to any command you could try 9600. Infrared ports ignore this setting, because the
operating system controls the speed. The default is 19200.
rtscts = boolean
If you write here "no", the the SMS Server Tools do not use hardware handshake lines. Some mobile phones and some cheap cables
do not support hardware handshake because they have a very cheap hardware.
Whenever possible you should use the default setting that is "yes". Hardware handshake ensures that the computer does not try to talk
to fast to the modem.
cs_convert = boolean
The default is "yes" and that means that the program converts the charaters of all short messages to ISO-8859-15 and vice versa.
Windows names this character set "Ansi".
You need this conversion the display the message text correctly on Unix and Windows and to send text files correctly as SMS.
If you set this to "no", the text files are transmitted in original form with one exception: The @ character of received messages is
translated to ascii code 183, because in the GSM alphabet it has the code 0 and 0 marks always the end of a string in nearly any
Windows and Unix program.
report = boolean
If you set this to "yes" the program asks for a status report for any sent message. Not all SMSC aupport this function.
If it does not work then the modem is mostly the weak point. Many modems of Siemens, Digicom and Wavecom cannot receive status
reports. And as far as I know all mobile phones can display status reports only on the phones display but you cannot read them through
the serial port using a computer.
Falcom modems work absolutely fine with status reports.
Page 173
SMS Applications
Windows NT, 2000 and XP can start the SMS Server Tools automatically as a service during boot process. You might install smsd as a
service by entering this command:
cygrunsrv --install smsd --path /usr/local/bin/smsd.exe --type auto --neverexits --shutdown --env "CYGWIN=server" --env
PATH=/usr/local/bin:/usr/bin:/bin" --desc "SMS Server Tools"
Start the service by entering the windows command net start smsd or using the control panel.
The program smsd can show a status monitor while it is running in a window. To activate this you need to start it with the option -s.
Chapter 5.8 explains, how to use this option.
Page 174
SMS Applications
If you want to take a look into the sendsms script you will see that it's very easy. It creates only a text file with destination number and
text in the outgoing queue directory:
FILE=`mktemp /var/spool/sms/outgoing/send_XXXXXX`
echo "To: $DEST" >> $FILE
echo "" >> $FILE
echo "$TEXT" >> $FILE
The first line creates a temporary file and stores its name in the variable FILE. Mktemp is a standard Unix command that replaces
XXXXXX by random characters ensuring that any file gets an unique name.
The next echo commands write the phone number, an empty line and the text into the temporary file.
You can also do the same yourself with any self written script or with a normal text editor. A correct file looks like this:
To: 491721234567
Hello
Do not forget the empty line and write the phone number always in international format. Apart from the configuration file you may write
phone numbers with + or without +. Smsd removes it when necessary.
Store such SMS files with any filename in the outgoing queue directory /var/spool/sms/outgoing. Smsd does not check the filename,
only the content is important, therefore you may use any filename that you like.
You should ensure that any message has its own filename. Otherwise you may accidentally overwrite old files that are not sent yet.
Page 175
SMS Applications
Page 176
SMS Applications
Page 177
SMS Applications
Page 178
SMS Applications
Page 179
SMS Applications
Page 180
SMS Applications
Page 181
SMS Applications
Page 182
SMS Applications
Ok,short message forwarded by the SC to the SME but the SC is unable to confirm
delivery
32
Still trying,congestion
33
34
35
36
37
64
65
Error,incompatible destination
66
67
Error,not obtainable
68
69
70
71
72
73
96
Error,congestion
97
Error,SME busy
98
99
Error,service rejected
100
101
Error,error in SME
Page 183
SMS Applications
All other codes are translated to "unknown". Some text translations may appear useless but they appear exactly as written here in the
ETSI TS 100 900 specification.
In most cases you will probably see the values 0 and 70.
Page 184
SMS Applications
5.6.7. Timestamps
On the last pages you saw some timestamps. They have always the format:
YY-MM-DD HH:MM:SS
YY
is the year
MM
is the month
DD
is the day
HH
is the hour
MM
SS
All numbers have always two digits. Timestamps may contain a lot of zeroes in case this information is missing in the short messages:
00-00-00 00:00:00
The SMS Server Tools use this way of displaying unknown timestamps because MySQL does it in the same way for date/time fields.
Page 185
SMS Applications
Page 186
SMS Applications
sending
receiving
idle
no modem
Many users prefer to start the program automatically during boot. They prefer to use the start/stop script. But now the program is not
allowed to write text onto the screen because it runs as a background program.
If you want you can still see the status by using a small trick. You simply need to modify your start/stop scrpt a little bit:
...
...
Now smsd writes status informations into a text file with the name /var/log/smsd.status. You can read the file later using the command:
tail -f -n1 /var/log/smsd.status
This command shows you always the last line of the logfile and waits endless that the file grows. The key <Ctrl>-C can be used to stop
the tail command.
Now you should not forget that the logfile grown permanently and some time your harddisk will be full. A cronjob can help out, that
deletes the logfile every night. Enter this into your cron table:
0 0 * * * cat /dev/log /var/log/smsd.status
Now the status protocol will be deleted every midnight. This should be enough.
How to work with cronjobs was explained in a previous chapter.
Page 187
SMS Applications
5.9. Eventhandler
Eventhandler are programs that are run whenever
$2
$3
Sent messages are either deleted or moved into the sent queue or moved into the failed queue directory, depending on the success
and the settins in the configuration file.
Eventhandler are always run before the files will be moved or deleted. The seconds argument is always a readable SMS file in a
provider queue directory or incoming queue.
A very simple eventhandler that forwards each received messages via eMails looks like this:
#!/bin/sh
if [ $1 = RECEIVED ]; then
cat $2 | /usr/sbin/sendmail root
fi
Page 188
SMS Applications
$2
$3
$4
$5
$6
Page 189
SMS Applications
Whitelists are text files that list all phone numbers that are allowed to get SM. Number that are not listed do not get SM.
whitelist = /etc/smsd.white
If you have no whitelist, anybody can receive messages, except those that are listed in the blacklist.
What happens if a phone number is in both lists? The the blacklist is more important, the number gets no SM.
The lists may contain comments. Comments start wih hash. Example:
#This is the blacklist
491721234567 # Is not allowed to receive SM
491721111111 # Does not want SM. 7.4.2003
If your black or white list becomes very large it may be better to use a checkhandler. This is a program that allows or disallows sending
messages by comparing the phone number with a SQL table. The examples at the end of this book show you how to write a
checkhandler program.
Page 190
SMS Applications
Global counters:
Runtime of the program in seconds since last statistic file.
Number of rejected SM, e.g. blacklisted number
year
MM
month
DD
day
hh
hour
mm
minute
ss
second
The SMS Server Tools ensure that statistics are written every day at the same times. For example if you write that smsd should write
every hour a file (3600 seconds), then this happens every full hour when the minutes and seconds are zero.
Smsd handles the statistics carefully. Different to most other programs does smsd not forget the values in memory when you stop or
restart the program. Also when you kill the program, the counters are not lost als long as you do not use the "hard" kill -9.
When the program exist it stores the counter values from memory into a temporary file. When the program starts next time, it reads the
values back into memory, so they will appear in the next statistic file. You will not loose counters.
Please note that newer program versions may add more counters. They will be added at the right end of the rows. If you write programs
that read these files you should keep this in mind.
Page 191
SMS Applications
Now you need to create a database with an empty table that will be filles with logging data. The table structure has to be this one:
+-------------+----------+------+-----+---------+----------------+
| Field
| Type
| Null | Key | Default | Extra
|
+-------------+----------+------+-----+---------+----------------+
| id
| int(11) |
| PRI | NULL
| auto_increment |
| type
| char(16) | YES |
| NULL
|
|
| sent
| datetime | YES |
| NULL
|
|
| received
| datetime | YES |
| NULL
|
|
| sender
| char(32) | YES |
| NULL
|
|
| receiver
| char(32) | YES |
| NULL
|
|
| status
| char(3) | YES |
| NULL
|
|
| msgid
| char(3) | YES |
| NULL
|
|
+-------------+----------+------+-----+---------+----------------+
Enter the following commands to create this table:
stefan@server> mysql -u root -p
mysql> create database smsd;
Query Ok...
mysql> use smsd;
Database changed.
mysql> create table sms_log (
-> id int auto_increment not null,
-> primary key(id),
-> type char(16),
-> sent datetime,
-> received datetime,
-> sender char(32),
-> receiver char(32),
-> status char(3),
-> msgid char(3)
-> );
Query Ok...
Now you prepared everything and can restart the SMS Server Tools to activate the changes. Now smsd creates database entries using
the script mysmsd for any sent and received SM.
Page 192
SMS Applications
After three actions the table could look like this example:
+---+--------+--------------------+-------------------+-------------+-------------+-------+------+
|id |type
|sent
|received
|sender
|receiver
|status |msgid |
+---+--------+--------------------+-------------------+-------------+-------------+-------+------+
| 1 |RECEIVED|2000-02-21 22:26:23 |2002-06-06 12:16:23|491721234567 |MODEM1
| NULL | NULL |
| 2 |SENT
|2002-06-06 12:16:34 |2002-06-06 12:16:59|somebody
|491721234567 |
0 | 117 |
| 3 |FAILED |2002-06-06 12:16:48 |NULL
|somebody
|491721234567 | NULL | NULL |
+---+--------+--------------------+-------------------+-------------+-------------+-------+------+
The first row tells you that the MODEM1 received a message at 22:26. It was sent at 12:16 by the sender 01721234567.
The second row tells you that you sent a message at 12:16 to 01721234567 and that this message was delivered successfully at
12:16:59 (status=0). The senders name "somebody" comes from the From: line in the SMS file.
The third row tells you that you tried to send a message at 12:16 to 01721234567 but sending failed.
Now I show you some example SQL commands that you can use to query this table:
To query the whole table, simply enter in the mysql client
select * from sms_log
To count all messages to a special destination number, enter
select count(*) from sms_log where type="SENT" AND receiver="491722056395";
The command
select * from sms_log where type="SENT" AND receiver="491721234567";
creates a list of all sent messages to a special destination number. The next command lists all received messages:
select * from sms_log where type="RECEIVED";
Page 193
SMS Applications
Page 194
SMS Applications
name.
SENT=`formail -zx Sent: < $2`
At last we extract the timestamp when the message was sent.
We have now the following informations:
DATE = Actual date and time
FROM = Sender
TO = Receiver
SUBJET = Name of the modem
SENT = Date and time, when the message was sent
At this point we have all options for the MySQL client and we can send SQL queries in this way:
mysql $SQL_ARGS "..."
Instead of the three dots we can insert any SQL command.
Now it is important what type of event occured. Different SQL commands are necessary for sending, receiving and status reports.
if [ "$1" = "FAILED" ] || [ "$1" = "SENT" ]; then
...;
elif [ "$1" = "RECEIVED" ]; then
...;
elif [ "$1" = "REPORT" ]; then
...;
fi
For sent and failed sendings we can use the same SQL command. Another second command is applied for received messages, and a
third command for status reports. The control structure uses $1 to detect the type of event.
Successful and failed sent messages are inserted into the database using this command:
insert into $SQL_TABLE (type,sent,sender,receiver,msgid)
values ("$1","$DATE","$FROM","$TO","$3");
The source code of the script contains a backslash before any double quote because quotes within the same quotes are not allowed.
This command creates a new table row with these values:
type
sent
sender
receiver
msgid
SENT or FAILED
actual date
senders name or number
receivers number
ID-number of the message
Received messages are entered into the database by a slightly different SQL command:
insert into $SQL_TABLE (type,sent,received,sender,receiver)
values ("RECEIVED","$SENT","$DATE","$FROM","$SUBJECT");
This creates a new table row with these data:
type
RECEIVED
sent
Page 195
SMS Applications
received
actual date
sender
receiver
Status reports contain some more informations that we did not extract from the message file at this point. This is done at this point
where it is clear that we have actually a status report:
DISCHARGE=`sed -e 1,7d < $2 | formail -zx Discharge_timestamp:`
MSGID=`sed -e 1,7d < $2 | formail -zx Message_id:`
STATUS=`sed -e 1,7d < $2 | formail -zx Status: | cut -f1 -d,`
The first command is the timestamp when the SMSC delivered the message. The second line extracts the message ID number that
refers to the original message for this status report. The third line extracts the status code.
A new command is sed. We use it because formail reads only the message header, not the message text field. But the status
information is in the text field.
The command
sed -e 1,7d < $2
reads the file and cuts the first seven lines (1,7d) from it using sed. The rest is the text part of the file and now we can use formail to
extract fields as done before with the header.
The output of sed is redirected to the input channel of formail using the pipe character "|".
The third command contains an additional redirection:
cut -f1 -d,
The status code is in one single row together with the status text, for example:
0,Ok,short message received by the SME
The cut command splits the line into three fields and returns only the first field (-f1). The delimiter between the fields is the comma (-d,).
STATUS
MSGID
Status reports are not simply added to the table. For the previously sent message is already a row in the table. Our job is now to find
out which row it is and add the status code to exactly this already existing row.
We do not need to search the whole table manually, we simply ask MySQL, what row matches our criteria. The criteria is the ID
number of the sent message. Therefore the SQL command is:
select id from $SQL_TABLE where receiver="$FROM"
and type="SENT"
and msgid="$MSGID"
order by id desc limit 1;
That means in words: Give me the ID from the table row in table sms_log, where the receiver matches the status report and the
message was previously sent and the Message-ID number matches the status report. If there are many matching rows, then give me
only the last one.
The ID-Number has nothing to do with the Message-ID number of the SM. It is only a number for the row.
ID
Now we know what row number in the table contains the sent message for the actual status report. We use this knowledge to add the
status code to this row:
update $SQL_TABLE set received="$DISCHARGE",
status="$STATUS"
where id="$ID";
Page 196
SMS Applications
6. Useful Enhancements
You learned what programs you can use to sent and received short messages.
You can install and use these programs.
This chapter shows how to enhance the functions of the SMS Server Tools. The content of this chapter is based on frequently asked
questions of users. They ask often for the same enhancements.
I offer the program for free but only the owners of this book get the following hints to enhance the program.
Page 197
SMS Applications
If you use windows, then try to delete the file now using the windows explorer or try to rename it. Windows will not allow it.
If you use Unix, then try to rename the file:
mv test.txt test2.txt
Check the file size with the ls command. You will see that it is still growing. Delete the file using the command
rm test2.txt
The file does not appear in the directory content any more but the endless loop continues writing into the file. Some time the harddisk
will be full. There is no command to check the file content. And also the command df -k does not show that the disk gets full because it
uses the information from the directories and no directory contains the deleted file anymore. But you could watch the harddisk LED and
you can see that is flashing permanently.
The device /dev/null delivers nothing when you read from it, therefore its name. By copying nothing into the logfile you delete its
content. The file still exists but now it is empty. This works in Unix and Windows.
Normally this is done automatically by a cron job like this:
10 0 * * * cp /var/log/smsd.log /var/log/smsd.log.old; cp /dev/null /var/log/smsd.log
In Windows you need to write the cronjob slightly different (all in one row):
Page 198
SMS Applications
10 0 * * * c:\cygwin\bin\bash -c "cp /var/log/smsd.log /var/log/smsd.log.old; cp
/dev/null /var/log/smsd.log"
In Windows you need to write bash -c "..." because these are CygWin commands. Without running the shell nnCron Lite can only
execute DOS and Windows commands.
This truncates the logfile every night shortly past midnight. The old logfile is kept in the backup file smsd.log.old.
You may wonder why I recommend to run this cronjob shortly past midnight and not exactly midnight. I avoid running scripts at exactly
full hours, specially midnight because the operating system itself maintains logfile at this time. As more actions are done at the same
time as slower they become.
In addition this would increase the fragmentation of the harddisk more than necessary. Fragmentation occurs always when many files
grow or become smaller at the same time. Fragmentation reduces the performance of the harddisk. You do not need think much about
fragmentation. This was a large problem 10 years ago because the disks were much slower than today. Also the filesystem of MS-DOS
(FAT) did not handle the fragmentation well and forced you to defragment it sooner or later.
Today's harddisks are much faster and also the operating system became better. Fragmentation is only seldom a problem.
The cronjob above ensures that the logfile of the SMS Server Tools does not grow endless. You can always access the last logfile from
the previous day. But what to do if you want more?
Copy the following script and run it once every night (logfiles.sh):
#!/bin/sh
rename()
{
# $1 is a filename
# $2 is the number of days to keep
rm $1.$2 >/dev/null 2>&1
num=$2
while [ $num -gt 1 ]; do
before=`expr $num - 1`
mv $1.$before $1.$num >/dev/null 2>&1
num=$before
done
cp $1 $1.1
cp /dev/null $1
}
rename /var/log/smsd.log 7
rename /usr/local/apache/logs/access_log 2
rename /usr/local/apache/logs/error_log 7
The cronjob entry for Unix is this:
10 0 * * * /usr/local/bin/logfiles.sh
The cronjob entry for windows is this:
10 0 * * * c:\cygwin\bin\bash /usr/local/bin/logfiles.sh
This script renames the three files at the end of the script. It keeps 7 or 2 old files. You can insert more filenames if you like.
The old logfiles are kept with numbers in the filename extension.
The file "smsd.log" of yesterday is "smsd.log.1". The file two days ago is "smsd.log.2" and so on.
Now I like to explain how the script works. You can read it if you are interested in a detailed explanation.
At the beginning the script declares the function rename(), that can be used many times in the main part of the script.
rename()
{
...
}
rename /var/log/smsd.log 7
rename /usr/local/apache/logs/access_log 2
rename /usr/local/apache/logs/error_log 7
The function rename() deletes the logfile and keeps so many old versions als you gives as second argument.
The filename within the function is $2 because it's the first argument. The number of days is $2.
First the function deletes the oldest logfile, because it has expired:
Page 199
SMS Applications
Page 200
SMS Applications
Page 201
SMS Applications
6.1.4. Self-Test
To ensure that the SMS Server Tools run correctly, you can write a script that performs a self-test. Send yourself messages and check
it they come in.
The following lines assume that you have three modems named GSM1, GSM2 and GSM3. You probably need to change this to your
configuration.
Create the following directories:
/var/spool/sms/self-test/GSM1.in
/var/spool/sms/self-test/GSM2.in
/var/spool/sms/self-test/GSM3.in
/var/spool/sms/self-test/GSM1.out
/var/spool/sms/self-test/GSM2.out
/var/spool/sms/self-test/GSM3.out
Enter the outgoing queues into the configuration file /etc/smsd.conf. Every modem shall serve this queue as the last one. The new lines
are:
[queues]
GSM1 = /var/spool/sms/GSM1.out
GSM2 = /var/spool/sms/GSM2.out
GSM3 = /var/spool/sms/GSM3.out
[GSM1]
queues = ..., GSM1
[GSM2]
queues = ..., GSM2
[GSM3]
queues = ..., GSM3
Instead of the dots (...) insert the already existing queues that the mode serves. It is important to add the selftest queues as the last
queue.
Now you can send messages via special selected modem by giving the mode name in the header:
To: 491721234567
Provider: GSM1
SELF-TEST-MESSAGE
The received test messages should not remain in the normal incoming queue. We want them in the modem specific incoming queue
directories that we just created. Add the following eventhandler to the configuration file /etc/smsd.conf:
eventhandler = /usr/local/bin/self-test-eventhandler.sh
The script content is this (self-test-eventhandler.sh):
#!/bin/sh
if [ "$1" = "RECEIVED" ]; then
if grep "SELF-TEST-MESSAGE" $2 >/dev/null; then
modem=`cat $2 | formail -zx Subject:`
mv $2 /var/spool/sms/self-test/$modem.in
fi
fi
If moves all received messages with the text "SELF-TEST-MESSAGE" into the test directory with ending .in. Tets messages from
Modem GSM1 go into the directory GSM1.in and so on.
You have no the possibility to send messages via selected modem and you receive these messages in modem specific incoming
queue directories.
Now you need a script that sends these test messages regulary and checks if they come back. The following script does this for one
single modem, so you need to run it three times in parallel if you have three modems. Name the script self-test.sh:
Page 202
SMS Applications
#!/bin/sh
out=/var/spool/sms/outgoing/$1.test
in=/var/spool/sms/self-test/$1.in
while true; do
echo "To: $2" > $out
echo "Provider: $1" >> $out
echo "" >> $out
echo "SELF-TEST-MESSAGE" >> $out
sleep 3600
found=`ls -A $in`
if [ "$found" ]; then
rm $in/*
echo "$1 test ok"
else
echo "$1 test failed"
fi
done
The whole process is repeated in an endless loop until you stop it with
pkill self-test.sh
Start the script for any modem by giving him the modem name and phone number. Then you have an automatic self-test for the SMS
Server Tools:
self-test.sh GSM1 491721234001 &
self-test.sh GSM2 491721234002 &
self-test.sh GSM3 491721234003 &
The & character at the line end tells the shell to run the command in background. This allows you to monitor each modem in one single
window.
Instead of the error message you could use any command that informs you about the problem. How about an eMail?:
echo "Subject: $1 test failed"
| sendmail myname@mydomain
If you want to run the self test when the computer boots, you need to create the start script /etc/init.d/self-test:
#!/bin/sh
case "$1" in
start)
/usr/local/bin/self-test.sh GSM1 401721234001 &
/usr/local/bin/self-test.sh GSM2 401721234002 &
/usr/local/bin/self-test.sh GSM3 401721234003 &
;;
stop)
pkill self-test.sh
;;
esac
Do not forget to make the script executable:
chmod a+x /etc/init.d/self-test
chmod a+x /usr/local/bin/self-test.sh
Create the link:
cd /etc/etc/rc3.d
ln -s /etc/init.d/self-test S83self-test
As I explained already in the chapter about installation you may need to change the 3 in rc3.d to the correct value that refers to your
runlevel directory that is used during boot.
Programs that start during boot must not write anything to the screen. Therefore replace any screen output by eMails or whatever
informs you about the problem. (self-test.sh):
Page 203
SMS Applications
#!/bin/sh
out=/var/spool/sms/outgoing/$1.test
in=/var/spool/sms/self-test/$1.in
while true; do
echo "To: $2" > $out
echo "Provider: $1" >> $out
echo "" >> $out
echo "SELF-TEST-MESSAGE" >> $out
sleep 3600
found=`ls -A $in`
if [ "$found" ]; then
rm $in/*
else
echo "Subject: $1 test failed" | sendmail myname@mydomain
fi
done
Insert your own eMail address instead of myname@mydomain.
You extended the SMS Server Tools by a program that detects failures after maximum one hour and alarms you via eMail.
The program detects also a system overload, if you have not enough modems to send the messages in an acceptable time.
If sending goes to slow, more and more entries are queued ind the provider queues. The queues for the test messages are the last
queues in the order, that means that they are only sent if the provider queues are empty.
A full loaded system will never send the test messages. Therefore the program self-test.sh will alarm this.
An alarm from the self test can be triggered by many causes:
Page 204
SMS Applications
Now write the following script and save it under the name /usr/local/bin/statusmonitor.sh:
#!/bin/sh
show()
{
case "$2"
r) echo
s) echo
i) echo
b) echo
esac
}
in
"Modem
"Modem
"Modem
"Modem
$1
$1
$1
$1
is
is
is
is
receiving" ;;
sending" ;;
idle" ;;
blocked" ;;
The show function changes the single character to readable text but only for the characters r, w, i and b. Other characters are not
displayed.
The output of the loop is written into the file /var/log/smsd.status. The actual modem state is always visible by looking into this file.
If you have three modem the file looks similar to this:
Modem 1 is sending
Modem 2 is idle
Modem 3 is receiving
Now it's not very comfortable to open the same file again and again to see always the actual status. You can enter the following
command to automate this:
while true; do cat /var/log/smsd.status; sleep 1; done
The while loop runs as long as you do not press Ctrl-C. It shows the actual state every second.
Page 205
SMS Applications
in
"<td
"<td
"<td
"<td
bgcolor=green>Modem $1<br>receiving</td>" ;;
bgcolor=red>Modem $1<br>sending</td>" ;;
bgcolor=white>Modem $1<br>idle</td>" ;;
bgcolor=lightgray>Modem $1<br>blocked</td>" ;;
Page 206
SMS Applications
Page 207
SMS Applications
Page 208
SMS Applications
Page 209
SMS Applications
The alarm inputs work only, when the modem gets power from an external power supply. The internal battery does not source this part
of the modem with energy.
Configure the modem to enter the PIN automatically after poweron, because you want to use it later without a computer standalone.
AT+CPIN=1234
&CNF PIN=1
Set the SMSC number:
AT+CSCA="+49172270000"
AT+CSAS
The next commands specify the destination numbers for the alarm messages and the text content:
&CNF KEY1,s01721234567,"Alarm Signal 1",H
&CNF KEY2,s01721234567,"Alarm Signal 2",H
&CNF KEY3,s01721234567,"Alarm Signal 3",H
H means that an alarm should be raised when the input signal changes to High. L would send an alarm when the input signal changes
to Low and E sends an alarm in both cases.
Now you can disconnect the modem from the computer and use it a a standalone alarm sender. On activation of one input the text
"Alarm Signal x" is sent via SMS.
If you need you can also tell the modem to send regular heathcheck messages that mean as much as "Im still living". These messages
can be used at the receivers end to see that the modem is still working and has power.
Enter
Page 210
SMS Applications
&CNF MSG,s01721234567,"Test",60
Then the modem send the given text messages every 60 minutes. To disable this enter 0 minutes.
Page 211
SMS Applications
Page 212
SMS Applications
stefan@server> mysql -u root -p
mysql> create database smsd;
Query Ok...
mysql> use smsd;
Database changed.
mysql> create table gps (
-> id int auto_increment not null,
-> primary key(id),
-> sent datetime,
-> text char(160)
-> );
Query Ok...
That's all. No you can receive the car's positions with your computer. To show the table entries you cound enter this command in an
SQL Client:
select * from gps where text like "%Auto%";
A list appears with all entries of the car with the name "Auto". To limit the output to a special time range enter:
select * from gps where text like "%Auto%"
and sent>="2003-02-22" and sent<="2003-02-24";
This shows all positions between 22.2.2003 0:00 and 24.2.2003 0:00.
The modem supports many different message formats. If you use the defaults, you receive messages in GGA format, that looks like:
$GPGGA,161229.487,3723.2475,N,12158.3416,W,1,07,1.0,9.0,M,,,,0000*18
The following numbers are the most interesting:
161229487
3723.2475 N
12158.3416 W
9.0 M
Page 213
SMS Applications
Page 214
SMS Applications
Before you start to search the installation files of Formail read this: Formail is a helper program of Procmail and it is part of the
Procmail package.
Chapter 4.5.4 showed you, how to receive eMail from a POP3 account.
Create the file /etc/fetchmailrc with this content:
poll mail.isis.de protocol POP3 user sms pass passwort mda "/usr/local/bin/email2sms"
Insert the name of your mailserver, the correct username and password. Set the file permissions in this way:
chmod 0710 /ect/fetchmailrc
Start the fetchmail daemon by entering
fetchmail -f /etc/fetchmailrc -d 300
Fetchmail checks every 300 seconds for new incoming eMails in the POP3 box and sends them via the script email2sms. This script
converts the eMails to SMS files and saves them in the outgoing queue directory. The SMS Server Tools send these messages.
As you see, the solution is as easy as the other solution in the previous chapter. The disadvantage is that fetchmail needs to check
every n seconds for new incoming mail. This makes the process slower than using a local mailserver.
The advantage is that you can use any existing mailserver and that there is no special configuration necessary in the mailserver.
The script email2sms is part of the SMS Server Tools. You can take a look into it to learn from it. The script is small and simple.
Page 215
SMS Applications
The script email2sms that you saw in the previous chapter creates an SMS file from the eMail that looks like this:
From: Michaela Meier
To: +491721234567
Subject: password
Hello World!
Write the following script and save it as /usr/local/checkhandler.sh:
#!/bin/sh
name=`formail -zx From: < $1`
to=`formail -zx To: < $1`
password=`formail -zx Subject: < $1`
SQL_ARGS="-h localhost -u root -ppasswort -D smsd -s -N -B -e"
result=`mysql $SQL_ARGS select name from smsuser where name=\"$name\" and password=\"$password\";`
if [ -z "$result" ]; then
exit 1
fi
The script checks the senders name and the password. If there is a matching entry in the database, the script exist without an error
code. If no matching table row exists, the script exits with exit code 1.
The name and password are extracted from the From: and Subject: lines with Formail.
The SMS Server Tools send the short message only when the checkhandler exits without an error code.
Install the script as a checkhandler in the configuration file /etc/smsd.conf:
checkhandler=/usr/local/bin/checkhandler.sh
Page 216
SMS Applications
<html><body>
<b>Welcome to the Ovulation Reminder service.</b>
<p>
After registration you get one year short messages on your
mobile phone that remind before ovulation and menstruation starts.
<p>
<form action="register.php" method="post">
My mobile phone number is
<input type="text" name="phonenumber"
size=15 maxlength=15 value="+491721234567"> .<p>
My settings shall be saved with the password
<input type="text" name="password"
size=10 maxlength=15 value="secret">
.<p>
The last menstruation started at
<input type="text" name="menstruation"
size=10 maxlength=10 value="23.3.2003">.<p>
A period is
<input type="text" name="period"
size=2 maxlength=2 value="28"> days long.<p>
<input type="submit" name="action" value="submit">
<input type="submit" name="action" value="remove">
</form>
<p>
To remove from the service you need to enter only your
phone number and the password. Then klick on "remove".
</body></html>
Page 217
SMS Applications
SMS Applications
print("$message <br>");
print("Please correct your input.");
exit;
function sqlerror()
{
print("An error occured in the database: <br>");
print(mysql_error());
exit;
}
$phonenumber=$_POST["phonenumber"];
$password=$_POST["password"];
$menstruation=$_POST["menstruation"];
$period=$_POST["period"];
$action=$_POST["action"];
if (($phonenumber=="") || ($password=="") || ($menstruation=="") || ($period==""))
inputerror("You need to fill all fields.");
if (($phonenumber=="+491721234567") || ($password=="secret"))
inputerror("You need to enter your phone number and the password.");
if (($period<20) || ($period>36))
inputerror("The length of the period must be wrong.");
$date=explode(".",$menstruation);
if (checkdate($date[1],$date[0],$date[2])==false)
inputerror("The date is invalid");
$now=time();
$timestamp=mktime(0,0,0,$date[1],$date[0],$date[2]);
if ($timestamp>$now)
inputerror("The date needs to be in the past.");
mysql_connect("localhost","root","password");
if ($result=mysql_db_query("smsd","select password from ovulation ".
"where phonenumber=\"$phonenumber\" limit 1;"))
{
$row=mysql_fetch_row($result);
$old_password=$row[0];
}
else
sqlerror();
if ($old_password!="")
{
if ($old_password!=$password)
inputerror("You entered a wrong password!");
else
{
if (mysql_db_query("smsd","delete from ovulation ".
"where phonenumber=\"$phonenumber\";"))
{
print("Your current order has been deleted.<br>");
}
else
sqlerror();
}
}
if ($action=="submit")
{
$anzahl=0;
while ($anzahl<24)
{
$timestamp=$timestamp+13*60*60*24;
if ($timestamp>$now)
{
$newdate=strftime("%Y-%m-%d",$timestamp);
if (mysql_db_query("smsd","insert into ovulation (phonenumber,password,date,type) ".
"values (\"$phonenumber\",\"$password\",\"$newdate\",\"E\");")==false)
sqlerror();
$anzahl++;
}
$timestamp=$timestamp+($period-13)*60*60*24;
if ($timestamp>$now)
{
$newdate=strftime("%Y-%m-%d",$timestamp);
if (mysql_db_query("smsd","insert into ovulation (phonenumber,password,date,type) ".
"values (\"$phonenumber\",\"$password\",\"$newdate\",\"B\");")==false)
sqlerror();
$anzahl++;
Page 219
SMS Applications
}
}
print("Your new order has been stored.");
?>
</body></html>
The script does some checks of the entered data. Then it deletes all existing entries in the SQL table and creates new orders in the
SQL table.
The arguments to the mysql_connect command need to be changed to match your database.
This table needs to be created before you can access it. Otherwise the script will not work:
stefan@server> mysql -u root -p
mysql> create database smsd;
Query Ok...
mysql> use smsd;
Database changed.
mysql> create table ovulation (
-> id int auto_increment not null,
-> primary key(id),
-> phonenumber char(15),
-> password char(15)
-> date date,
-> type char(1)
-> );
Query Ok...
Page 220
SMS Applications
#!/bin/sh
list=/tmp/ovulation.list
today=`date +%Y-%m-%d`
SQL_ARGS="-h localhost -u root -ppassword -D smsd -N -B -e"
mysql $SQL_ARGS "select type,phonenumber from ovulation where date=\"$today\";" > $list
while read line; do
type=`echo $line | cut -f1 -d' '`
number=`echo $line | cut -f2 -d' '`
case $type in
E) sendsms $number "You have an ovulation!" ;;
B) sendsms $number "Your menstruation will start today!" ;;
esac
echo $type $number
done < $list
mysql $SQL_ARGS "delete from ovulation where date<=\"$today\";"
The SQL arguments in the SQL_ARGS need to be changed to your SQL database settings.
Executed as a cronjob this script sends every morning SMS according to the ovulation table and after that it deletes old table entries.
The cronjob could look like this:
30 6 * * * /usr/local/bin/ovulation.sh
And in Windows it looks like this:
30 6 * * * c:\cygwin\bin\bash -c "/usr/local/bin/ovulation.sh"
Page 221
SMS Applications
/var/sms/content/0001
Ringtone 1
/var/sms/content/0002
Ringtone 2
/var/sms/content/0003
Ringtone 3
/var/sms/content/1001D1
Operator Logo 1 fr D1
/var/sms/content/1001D2
Operator Logo 1 fr D2
/var/sms/content/1001EPLUS
/var/sms/content/1002D1
Operator Logo 2 fr D1
/var/sms/content/1002D2
Operator Logo 2 fr D2
/var/sms/content/1002EPLUS
/var/sms/content/1003D1
Operator Logo 3 fr D1
/var/sms/content/1003D2
Operator Logo 3 fr D2
/var/sms/content/1003EPLUS
/var/sms/content/2001
Joke 1
/var/sms/content/2002
Joke 2
/var/sms/content/2003
Joke 3
All these files are SMS files with a header without a To: line.
If your customers order a file, they shall simply send them an SM with the filename. Your customers pay a higher price for sending
messages to you. The phone network provider gives you a large part of this money.
Page 222
SMS Applications
Page 223
SMS Applications
- END -
Page 224