gammu-smsd-run

title: gammu-smsd-run(7)

text:
# gammu-smsd-run(7)

## NAME
gammu-smsd-run - documentation for RunOnReceive directive

## DESCRIPTION
Gammu SMSD can be configured by RunOnReceive directive (see gammu-smsdrc for details) to run defined program after receiving every message. It can receive single message or more messages, which are parts of one multipart message.

This parameter is executed through shell, so you might need to escape some special characters and you can include any number of parameters. Additionally parameters with identifiers of received messages are appended to the command line. The identifiers depend on used service backend, typically it is ID of inserted row for database backends or file name for file based backends.

Gammu SMSD waits for the script to terminate. If you make some time consuming there, it will make SMSD not receive new messages. However to limit breakage from this situation, the waiting time is limited to two minutes. After this time SMSD will continue in normal operation and might execute your script again.

NOTE:

All input and output file descriptors are closed when this program is invoked, so you have to ensure to open files on your own.

## ENVIRONMENT
New in version 1.28.0.

Program is executed with environment which contains lot of information about the message. You can use it together with NULL service (see gammu-smsd-null) to implement completely own processing of messages.

### Global variables
SMS_MESSAGES

Number of physical messages received.

DECODED_PARTS

Number of decoded message parts.

PHONE_ID

New in version 1.38.2.

Value of PhoneID. Useful when running multiple instances (see smsd-multi).

### Per message variables
The variables further described as SMS_1_... are generated for each physical message, where 1 is replaced by current number of message.

SMS_1_CLASS

Class of message.

SMS_1_NUMBER

Sender number.

SMS_1_TEXT

Message text. Text is not available for 8-bit binary messages.

SMS_1_REFERENCE

New in version 1.38.5.

Message Reference. If delivery status received, this variable contains TPMR of original message

### Per part variables
The variables further described as DECODED_1_... are generated for each message part, where 1 is replaced by current number of part. Set are only those variables whose content is present in the message.

DECODED_1_TEXT

Decoded long message text.

DECODED_1_MMS_SENDER

Sender of MMS indication message.

DECODED_1_MMS_TITLE

title of MMS indication message.

DECODED_1_MMS_ADDRESS

Address (URL) of MMS from MMS indication message. SEE ALSO:

faq-mms-download

DECODED_1_MMS_SIZE

Size of MMS as specified in MMS indication message.

## EXAMPLES

### Activating RunOnReceive
To activate this feature you need to set RunOnReceive in the gammu-smsdrc.

```
[smsd]
RunOnReceive = /path/to/script.sh
```

### Processing messages from the files backend
Following script (if used as RunOnReceive handler) passes message data to other program. This works only with the gammu-smsd-files.

```
#!/bin/sh
INBOX=/path/to/smsd/inbox
PROGRAM=/bin/cat
for ID in "$@" ; do

    $PROGRAM < $INBOX/$ID
done
```

### Invoking commands based on message text
Following script (if used as RunOnReceive handler) executes given programs based on message text.

```
#!/bin/sh
# Check for sender number
if [ "$SMS_1_NUMBER" != "+420123456789" ] ; then

    exit
fi
# Handle commands
case "$SMS_1_TEXT" in

    "DMS A")

        /usr/bin/dms-a

        ;;

    "DMS B")

        /usr/bin/dms-b

        ;;
esac
```

### Passing message text to program
Following script (if used as RunOnReceive handler) passes message text and sender to external program.

```
#!/bin/sh
PROGRAM=/bin/echo
for i in `seq $SMS_MESSAGES` ; do

    eval "$PROGRAM \"\${SMS_${i}_NUMBER}\" \"\${SMS_${i}_TEXT}\""
done
```

### Passing MMS indication parameters to external program
Following script (if used as RunOnReceive handler) will write information about each received MMS indication to the log file. Just replace echo command with your own program to do custom processing.

```
#!/bin/sh
if [ $DECODED_PARTS -eq 0 ] ; then

    # No decoded parts, nothing to process

    exit
fi
if [ "$DECODED_1_MMS_ADDRESS" ] ; then

    echo "$DECODED_1_MMS_ADDRESS" "$DECODED_1_MMS_SENDER" "$DECODED_1_MMS_TITLE" >> /tmp/smsd-mms.log
fi
```

### Processing message text in Python
Following script (if used as RunOnReceive handler) written in Python will concatenate all text from received message:

```
#!/usr/bin/env python
from __future__ import print_function
import os
import sys
numparts = int(os.environ['DECODED_PARTS'])
text = ''
# Are there any decoded parts?
if numparts == 0:

    text = os.environ['SMS_1_TEXT']
# Get all text parts
else:

    for i in range(1, numparts + 1):

        varname = 'DECODED_%d_TEXT' % i

        if varname in os.environ:

            text = text + os.environ[varname]
# Do something with the text
print('Number %s have sent text: %s' % (os.environ['SMS_1_NUMBER'], text))
```

## AUTHOR
Michal Čihař <michal@cihar.com>

## COPYRIGHT
2009-2015, Michal Čihař <michal@cihar.com>


gammu-smsd-sql

package: gammu

title: gammu-smsd-sql(7)

text:
# gammu-smsd-sql(7)

## NAME
gammu-smsd-sql - gammu-smsd(1) backend using SQL abstraction layer to use any supported database as a message storage

## DESCRIPTION
SQL service stores all its data in database. It can use one of these SQL backends (configuration option Driver in smsd section):

- native_mysql for gammu-smsd-mysql

- native_pgsql for gammu-smsd-pgsql

- odbc for gammu-smsd-odbc

-

drivers supported by DBI for gammu-smsd-dbi, which include:

- sqlite3 - for SQLite 3

- mysql - for MySQL

- pgsql - for PostgeSQL

- freetds - for MS SQL Server or Sybase

## SQL CONNECTION PARAMETERS
Common for all backends:

- User - user connecting to database

- Password - password for connecting to database

- Host - database host or data source name

- Database - database name

- Driver - native_mysql, native_pgsql, odbc or DBI one

- SQL - SQL dialect to use

Specific for DBI:

- DriversPath - path to DBI drivers

- DBDir - sqlite/sqlite3 directory with database

SEE ALSO:

The variables are fully described in gammurc documentation.

## TABLES
New in version 1.37.1.

You can customize name of all tables in the [tables]. The SQL queries will reflect this, so it's enough to change table name in this section.

gammu

Name of the gammu-table table.

inbox

Name of the inbox table.

sentitems

Name of the sentitems table.

outbox

Name of the outbox table.

outbox_multipart

Name of the outbox_multipart table.

phones

Name of the phones table.

You can change any table name using these:

```
[tables]
inbox = special_inbox
```

## SQL QUERIES
Almost all queries are configurable. You can edit them in [sql] section. There are several variables used in SQL queries. We can separate them into three groups:

- phone specific, which can be used in every query, see Phone Specific Parameters

- SMS specific, which can be used in queries which works with SMS messages, see SMS Specific Parameters

- query specific, which are numeric and are specific only for given query (or set of queries), see Configurable queries

### Phone Specific Parameters
%I

IMEI of phone

%S

SIM IMSI

%P

PHONE ID (hostname)

%N

client name (eg. Gammu 1.12.3)

%O

network code

%M

network name

### SMS Specific Parameters
%R

remote number [1]

%C

delivery datetime

%e

delivery status on receiving or status error on sending

%t

message reference

%d

receiving datetime for received sms

%E

encoded text of SMS

%c

SMS coding (ie 8bit or UnicodeNoCompression)

%F

sms centre number

%u

UDH header

%x

class

%T

decoded SMS text

%A

CreatorID of SMS (sending sms)

%V

relative validity

[1]

Sender number for received messages (insert to inbox or delivery notifications), destination otherwise.

## CONFIGURABLE QUERIES
All configurable queries can be set in [sql] section. Sequence of rows in selects are mandatory.

All default queries noted here are noted for MySQL. Actual time and time addition are selected for default queries during initialization.

delete_phone

Deletes phone from database. Default value:

```
DELETE FROM phones WHERE IMEI = %I
```

insert_phone

Inserts phone to database. Default value:

```
INSERT INTO phones (IMEI, ID, Send, Receive, InsertIntoDB, TimeOut, Client, Battery, Signal)
VALUES (%I, %P, %1, %2, NOW(), (NOW() + INTERVAL 10 SECOND) + 0, %N, -1, -1)
```

Query specific parameters:

%1

enable send (yes or no) - configuration option Send

%2

enable receive (yes or no) - configuration option Receive

save_inbox_sms_select

Select message for update delivery status. Default value:

```
SELECT ID, Status, SendingDateTime, DeliveryDateTime, SMSCNumber FROM sentitems
WHERE DeliveryDateTime IS NULL AND SenderID = %P AND TPMR = %t AND DestinationNumber = %R
```

save_inbox_sms_update_delivered

Update message delivery status if message was delivered. Default value:

```
UPDATE sentitems SET DeliveryDateTime = %C, Status = %1, StatusError = %e WHERE ID = %2 AND TPMR = %t
```

Query specific parameters:

%1

delivery status returned by GSM network

%2

ID of message

save_inbox_sms_update

Update message if there is an delivery error. Default value:

```
UPDATE sentitems SET Status = %1, StatusError = %e WHERE ID = %2 AND TPMR = %t
```

Query specific parameters:

%1

delivery status returned by GSM network

%2

ID of message

save_inbox_sms_insert

Insert received message. Default value:

```
INSERT INTO inbox (ReceivingDateTime, Text, SenderNumber, Coding, SMSCNumber, UDH,
Class, TextDecoded, RecipientID) VALUES (%d, %E, %R, %c, %F, %u, %x, %T, %P)
```

update_received

Update statistics after receiving message. Default value:

```
UPDATE phones SET Received = Received + 1 WHERE IMEI = %I
```

refresh_send_status

Update messages in outbox. Default value:

```
UPDATE outbox SET SendingTimeOut = (NOW() + INTERVAL 60 SECOND) + 0
WHERE ID = %1 AND (SendingTimeOut < NOW() OR SendingTimeOut IS NULL)
```

The default query calculates sending timeout based on LoopSleep value.

Query specific parameters:

%1

ID of message

find_outbox_sms_id

Find sms messages for sending. Default value:

```
SELECT ID, InsertIntoDB, SendingDateTime, SenderID FROM outbox
WHERE SendingDateTime < NOW() AND SendingTimeOut <  NOW() AND
SendBefore >= CURTIME() AND SendAfter <= CURTIME() AND
( SenderID is NULL OR SenderID = '' OR SenderID = %P ) ORDER BY InsertIntoDB ASC LIMIT %1
```

Query specific parameters:

%1

limit of sms messages sended in one walk in loop

find_outbox_body

Select body of message. Default value:

```
SELECT Text, Coding, UDH, Class, TextDecoded, ID, DestinationNumber, MultiPart,
RelativeValidity, DeliveryReport, CreatorID FROM outbox WHERE ID=%1
```

Query specific parameters:

%1

ID of message

find_outbox_multipart

Select remaining parts of sms message. Default value:

```
SELECT Text, Coding, UDH, Class, TextDecoded, ID, SequencePosition
FROM outbox_multipart WHERE ID=%1 AND SequencePosition=%2
```

Query specific parameters:

%1

ID of message

%2

Number of multipart message

delete_outbox

Remove messages from outbox after threir successful send. Default value:

```
DELETE FROM outbox WHERE ID=%1
```

Query specific parameters:

%1

ID of message

delete_outbox_multipart

Remove messages from outbox_multipart after threir successful send. Default value:

```
DELETE FROM outbox_multipart WHERE ID=%1
```

Query specific parameters:

%1

ID of message

create_outbox

Create message (insert to outbox). Default value:

```
INSERT INTO outbox (CreatorID, SenderID, DeliveryReport, MultiPart,
InsertIntoDB, Text, DestinationNumber, RelativeValidity, Coding, UDH, Class,
TextDecoded) VALUES (%1, %P, %2, %3, NOW(), %E, %R, %V, %c, %u, %x, %T)
```

Query specific parameters:

%1

creator of message

%2

delivery status report - yes/default

%3

multipart - FALSE/TRUE

%4

Part (part number)

%5

ID of message

create_outbox_multipart

Create message remaining parts. Default value:

```
INSERT INTO outbox_multipart (SequencePosition, Text, Coding, UDH, Class,
TextDecoded, ID) VALUES (%4, %E, %c, %u, %x, %T, %5)
```

Query specific parameters:

%1

creator of message

%2

delivery status report - yes/default

%3

multipart - FALSE/TRUE

%4

Part (part number)

%5

ID of message

add_sent_info

Insert to sentitems. Default value:

```
INSERT INTO sentitems (CreatorID,ID,SequencePosition,Status,SendingDateTime,
SMSCNumber, TPMR, SenderID,Text,DestinationNumber,Coding,UDH,Class,TextDecoded,
InsertIntoDB,RelativeValidity)
VALUES (%A, %1, %2, %3, NOW(), %F, %4, %P, %E, %R, %c, %u, %x, %T, %5, %V)
```

Query specific parameters:

%1

ID of sms message

%2

part number (for multipart sms)

%3

message state (SendingError, Error, SendingOK, SendingOKNoReport)

%4

message reference (TPMR)

%5

time when inserted in db

update_sent

Update sent statistics after sending message. Default value:

```
UPDATE phones SET Sent= Sent + 1 WHERE IMEI = %I
```

refresh_phone_status

Update phone status (battery, signal). Default value:

```
UPDATE phones SET TimeOut= (NOW() + INTERVAL 10 SECOND) + 0,
Battery = %1, Signal = %2 WHERE IMEI = %I
```

Query specific parameters:

%1

battery percent

%2

signal percent

update_retries

Update number of retries for outbox message. The interval can be configured by RetryTimeout.

```
UPDATE outbox SET SendngTimeOut = (NOW() + INTERVAL 600 SECOND) + 0,
Retries = %2 WHERE ID = %1
```

Query specific parameters:

%1

message ID

%2

number of retries

## AUTHOR
Michal Čihař <michal@cihar.com>

## COPYRIGHT
2009-2015, Michal Čihař <michal@cihar.com>

branch: sisyphus


gammu-smsd-tables

title: gammu-smsd-tables(7)

text:
# gammu-smsd-tables(7)

## NAME
gammu-smsd-tables - description of tables for database backends of gammu-smsd(1)

The backends themselves are described in their sections, this document describes general database structure and required tables.

More SMS daemons can share single database. If you do not specify PhoneID in their configuration, all are treated equally and you have no guarantee which one sends outgoing message. If you configure PhoneID and use it when inserting message to the outbox table (gammu-smsd-inject does this), each SMS daemon will have separate outbox queue. See also smsd-multi.

## RECEIVING OF MESSAGES
Received messages are stored in inbox table.

## TRANSMITTING OF MESSAGES
Transmitted messages are read from table outbox and possible subsequent parts of the same message from outbox_multipart.

## DESCRIPTION OF TABLES

### gammu
Table holding single field Version - version of a database schema. See History of database structure for details what has changed.

### inbox
Table where received messages will be stored.

Fields description:

UpdatedInDB (timestamp)

when somebody (daemon, user, etc.) updated it

ReceivingDateTime (timestamp)

when SMS was received

Text (text)

encoded SMS text (for all SMS)

SenderNumber (varchar(20))

decoded SMS sender number

Coding (enum('Default_No_Compression', 'Unicode_No_Compression', '8bit', 'Default_Compression', 'Unicode_Compression'))

SMS text coding

UDH (text)

encoded User Data Header text

SMSCNumber (varchar(20))

decoded SMSC number

Class (integer)

SMS class or -1 (0 is flash SMS, 1 is normal one, 127 is USSD)

TextDecoded (varchar(160))

decoded SMS text (for Default Alphabet/Unicode SMS)

ID (integer unsigned)

SMS identificator (for using with external applications)

RecipientID (text)

which Gammu daemon has added it

Processed (enum('false', 'true'))

you can use for marking, whether SMS was processed or not

Status (integer)

Status of incoming message. Currently only used for Class 127 (USSD) messages with following meaning:

1

Unknown status.

2

No action is needed, maybe network initiated USSD.

3

Reply is expected.

4

USSD dialog terminated.

5

Another client replied.

6

Operation not supported.

7

Network timeout.

New in version 1.38.5.

### outbox
Messages enqueued for sending should be placed in this table. If message is multipart, subsequent parts are stored in table outbox_multipart.

Fields description:

UpdatedInDB (timestamp)

when somebody (daemon, user, etc.) updated it

InsertIntoDB (timestamp)

when message was inserted into database

SendingDateTime (timestamp)

set it to some value, when want to force sending after some planned time

SendBefore (time)

Send message before specified time, can be used to limit messages from being sent in night. Default value is 23:59:59 New in version 1.29.90.

SendAfter (time)

Send message after specified time, can be used to limit messages from being sent in night. Default value is 00:00:00 New in version 1.29.90.

Text (text)

SMS text encoded using hex values in proper coding. If you want to use TextDecoded field, keep this NULL (or empty).

DestinationNumber (varchar(20))

recipient number

Coding (enum('Default_No_Compression', 'Unicode_No_Compression', '8bit', 'Default_Compression', 'Unicode_Compression'))

SMS text coding

UDH (text)

User Data Header encoded using hex values which will be used for constructing the message. Without this, message will be sent as plain text.

Class (integer)

SMS class or -1 (0 is normal SMS, 1 is flash one, 127 is USSD)

TextDecoded (varchar(160))

SMS text in "human readable" form

ID (integer unsigned)

SMS/SMS sequence ID Please note that this number has to be unique also for sentitems table, so reusing message IDs might not be a good idea.

MultiPart (enum('false','true'))

info, whether there are more SMS from this sequence in outbox_multipart

RelativeValidity (integer)

SMS relative validity like encoded using GSM specs

SenderID (text)

which SMSD instance should send this one sequence, see PhoneID and smsd-multi. If blank, first SMSD who sees this message first will process it.

SendingTimeOut (timestamp)

used by SMSD instance for own targets

DeliveryReport (enum('default','yes','no'))

when default is used, Delivery Report is used or not according to SMSD instance settings; yes forces Delivery Report.

CreatorID (text)

identification of program created the message

Retries (integer)

number of attempted retries when sending this message

Priority (integer)

priority of message, messages with higher priority are processed first

Status (enum('SendingOK', 'SendingOKNoReport', 'SendingError', 'DeliveryOK', 'DeliveryFailed', 'DeliveryPending', 'DeliveryUnknown', 'Error', 'Reserved'))

Status of message sending. SendingError means that phone failed to send the message, Error indicates some other error while processing message.

SendingOK

Message has been sent, waiting for delivery report.

SendingOKNoReport

Message has been sent without asking for delivery report.

SendingError

Sending has failed.

DeliveryOK

Delivery report arrived and reported success.

DeliveryFailed

Delivery report arrived and reports failure.

DeliveryPending

Delivery report announced pending deliver.

DeliveryUnknown

Delivery report reported unknown status.

Error

Some other error happened during sending (usually bug in SMSD).

Reserved

Initial value, meaning the status has not been set.

New in version 1.38.5.

StatusCode (integer)

GSM status code New in version 1.38.5.

### outbox_multipart
Data for outgoing multipart messages.

Fields description:

ID (integer unsigned)

the same meaning as values in outbox table

Text (text)

the same meaning as values in outbox table

Coding (enum('Default_No_Compression', 'Unicode_No_Compression', '8bit', 'Default_Compression', 'Unicode_Compression'))

the same meaning as values in outbox table

UDH (text)

the same meaning as values in outbox table

Class (integer)

the same meaning as values in outbox table

TextDecoded (varchar(160))

the same meaning as values in outbox table

ID (integer unsigned)

the same meaning as values in outbox table

SequencePosition (integer)

info, what is SMS number in SMS sequence (start at 2, first part is in outbox table).

Status (enum('SendingOK', 'SendingOKNoReport', 'SendingError', 'DeliveryOK', 'DeliveryFailed', 'DeliveryPending', 'DeliveryUnknown', 'Error', 'Reserved'))

Status of message sending. SendingError means that phone failed to send the message, Error indicates some other error while processing message.

SendingOK

Message has been sent, waiting for delivery report.

SendingOKNoReport

Message has been sent without asking for delivery report.

SendingError

Sending has failed.

DeliveryOK

Delivery report arrived and reported success.

DeliveryFailed

Delivery report arrived and reports failure.

DeliveryPending

Delivery report announced pending deliver.

DeliveryUnknown

Delivery report reported unknown status.

Error

Some other error happened during sending (usually bug in SMSD).

Reserved

Initial value, meaning the status has not been set.

New in version 1.38.5.

StatusCode (integer)

GSM status code New in version 1.38.5.

### phones
Information about connected phones. This table is periodically refreshed and you can get information such as battery or signal level from here.

Fields description:

ID (text)

PhoneID value

UpdatedInDB (timestamp)

when this record has been updated

InsertIntoDB (timestamp)

when this record has been created (when phone has been connected)

TimeOut (timestamp)

when this record expires

Send (boolean)

indicates whether SMSD is sending messages, depends on configuration directive Send

Receive (boolean)

indicates whether SMSD is receiving messages, depends on configuration directive Receive

IMEI (text)

IMEI of phone

IMSI (text)

SIM IMSI

Client (text)

client name, usually string Gammu with version

Battery (integer)

battery level in percent (or -1 if unknown)

Signal (integer)

signal level in percent (or -1 if unknown)

Sent (integer)

Number of sent SMS messages (SMSD does not reset this counter, so it might overflow).

Received (integer)

Number of received SMS messages (SMSD does not reset this counter, so it might overflow).

### sentitems
Log of sent messages (and unsent ones with error code). Also if delivery reports are enabled, message state is updated after receiving delivery report.

Fields description:

UpdatedInDB (timestamp)

when somebody (daemon, user, etc.) updated it

InsertIntoDB (timestamp)

when message was inserted into database

SendingDateTime (timestamp)

when message has been sent

DeliveryDateTime (timestamp)

Time of receiving delivery report (if it has been enabled).

Status (enum('SendingOK', 'SendingOKNoReport', 'SendingError', 'DeliveryOK', 'DeliveryFailed', 'DeliveryPending', 'DeliveryUnknown', 'Error'))

Status of message sending. SendingError means that phone failed to send the message, Error indicates some other error while processing message.

SendingOK

Message has been sent, waiting for delivery report.

SendingOKNoReport

Message has been sent without asking for delivery report.

SendingError

Sending has failed.

DeliveryOK

Delivery report arrived and reported success.

DeliveryFailed

Delivery report arrived and reports failure.

DeliveryPending

Delivery report announced pending deliver.

DeliveryUnknown

Delivery report reported unknown status.

Error

Some other error happened during sending (usually bug in SMSD).

StatusError (integer)

Status of delivery from delivery report message, codes are defined in GSM specification 03.40 section 9.2.3.15 (TP-Status).

Text (text)

SMS text encoded using hex values

DestinationNumber (varchar(20))

decoded destination number for SMS

Coding (enum('Default_No_Compression', 'Unicode_No_Compression', '8bit', 'Default_Compression', 'Unicode_Compression'))

SMS text coding

UDH (text)

User Data Header encoded using hex values

SMSCNumber (varchar(20))

decoded number of SMSC, which sent SMS

Class (integer)

SMS class or -1 (0 is normal SMS, 1 is flash one, 127 is USSD)

TextDecoded (varchar(160))

SMS text in "human readable" form

ID (integer unsigned)

SMS ID

SenderID (text)

which SMSD instance sent this one sequence, see PhoneID

SequencePosition (integer)

SMS number in SMS sequence

TPMR (integer)

Message Reference like in GSM specs

RelativeValidity (integer)

SMS relative validity like encoded using GSM specs

CreatorID (text)

copied from CreatorID from outbox table

StatusCode (integer)

GSM status code New in version 1.38.5.

## HISTORY OF DATABASE STRUCTURE
NOTE:

Testing versions (see versioning) do not have to keep same table structure as final releases. Below mentioned versions are for informational purposes only, you should always use stable versions in production environment.

History of schema versions:

17

- Added Status field to outbox and outbox_multipart.

- Added StatusCode field to sentitems, outbox and outbox_multipart.

- Added Status field to inbox.

Changed in version 1.38.5.

16

- Removed unused daemons, pbk and pbk_groups tables.

- Added primary key to the gammu table.

- Added Priority field to the outbox.

- Added IMSI field to the phones.

Changed in version 1.37.90.

15

Added Retries field to the outbox. Changed in version 1.36.7.

14

Added NetCode and NetName fields. Changed in version 1.34.0.

13

Added SendBefore and SendAfter fields. Changed in version 1.29.90.

Also PostgreSQL fields are now case sensitive (same as other backends).

Changed in version 1.29.93.

12

the changes only affect MySQL structure changing default values for timestamps from 0000-00-00 00:00:00 to CURRENT_TIMESTAMP() by using triggers, to update to this version, just execute triggers definition at the end of SQL file. Changed in version 1.28.94.

11

all fields for storing message text are no longer limited to 160 chars, but are arbitrary length text fields. Changed in version 1.25.92.

10

DeliveryDateTime is now NULL when message is not delivered, added several indexes Changed in version 1.22.95.

9

added sent/received counters to phones table Changed in version 1.22.93.

8

Signal and battery state are now stored in database. Changed in version 1.20.94.

7

Added CreatorID to several tables. Changed in version 1.07.00.

6

Many fields in outbox can now be NULL. Changed in version 1.06.00.

5

Introduced daemons table and various other changes. Changed in version 1.03.00.

3

Introduced phones table and various other changes. Changed in version 0.98.0.

## EXAMPLES

### Creating tables
SQL scripts to create all needed tables for most databases are included in Gammu documentation (docs/sql). As well as some PHP scripts interacting with the database.

For example to create SQLite tables, issue following command:

```
sqlite3 smsd.db < docs/sql/sqlite.sql
```

### Injecting a message using SQL
To send a message, you can either use gammu-smsd-inject, which does all the magic for you, or you can insert the message manually. The simplest example is short text message:

```
INSERT INTO outbox (

    DestinationNumber,

    TextDecoded,

    CreatorID,

    Coding
) VALUES (

    '800123465',

    'This is a SQL test message',

    'Program',

    'Default_No_Compression'
);
```

Please note usage of TextDecoded field, for Text field, you would have to hex encode the unicode text:

```
INSERT INTO outbox (

    DestinationNumber,

    Text,

    CreatorID,

    Coding
) VALUES (

    '800123465',

    '005400680069007300200069007300200061002000530051004c002000740065007300740020006d006500730073006100670065',

    'Program',

    'Default_No_Compression'
);
```

### Injecting long message using SQL
Inserting multipart messages is a bit more tricky, you need to construct also UDH header and store it hexadecimally written into UDH field. Unless you have a good reason to do this manually, use gammu-smsd-inject, C library (SMSD_InjectSMS()) or Python library (gammu.smsd.SMSD.InjectSMS()).

For long text message, the UDH starts with 050003 followed by byte as a message reference (you can put any hex value there, but it should be different for each message, D3 in following example), byte for number of messages (02 in example, it should be unique for each message you send to same phone number) and byte for number of current message (01 for first message, 02 for second, etc.).

In most cases, the multipart message has to be class 1.

For example long text message of two parts could look like following:

```
INSERT INTO outbox (

    CreatorID,

    MultiPart,

    DestinationNumber,

    UDH,

    TextDecoded,

    Coding,

    Class
) VALUES (

    'Gammu 1.23.91',

    'true',

    '123465',

    '050003D30201',

    'Mqukqirip ya konej eqniu rejropocejor hugiygydewl tfej nrupxujob xuemymiyliralj. Te tvyjuh qaxumur ibewfoiws zuucoz tdygu gelum L ejqigqesykl kya jdytbez',

    'Default_No_Compression',

    1
)
INSERT INTO outbox_multipart (

    SequencePosition,

    UDH,

    Class,

    TextDecoded,

    ID,

    Coding,

    Class
) VALUES (

    2,

    '050003D30202',

    'u xewz qisubevumxyzk ufuylehyzc. Nse xobq dfolizygqysj t bvowsyhyhyemim ovutpapeaempye giuuwbib.',

    <ID_OF_INSERTED_RECORD_IN_OUBOX_TABLE>,

    'Default_No_Compression',

    1
)
```

NOTE:

Adding UDH means that you have less space for text, in above example you can use only 153 characters in single message.

## AUTHOR
Michal Čihař <michal@cihar.com>

## COPYRIGHT
2009-2015, Michal Čihař <michal@cihar.com>


ggz

package: ggz-base-libs

title: ggz(7)

summary: The GGZ Gaming Zone

text:
# ggz(7)

## NAME
ggz - The GGZ Gaming Zone

## DESCRIPTION
The GGZ Gaming Zone is a standards-conforming free online gaming infrastructure which provides many applications and games to people who like to play on the internet or in local networks. GGZ, how the (recursive) acronym is called, is available for many computer systems. This document focuses on the installations on Linux, BSD and Unix. On such systems, GGZ-powered games often ship with the KDE and GNOME games packages, and most distributors also include all components as released by the GGZ project.

## APPLICATIONS
GGZ is available on several platforms. A multitude of programs is available to the user, and even more which operate on the system level or are used by developers and administrators. Users will most likely want to connect to a GGZ server on the internet, such as ggz://live.ggzgamingzone.org, to play games against other people. Core clients are used to perform this task. Functional clients exist in the form of kggz for the K Desktop Environment (KDE), ggz-gtk for GNOME or XFCE users, and ggz-txt for people who prefer command-line applications. Of course, the clients are not bound to a specific desktop, but the choices above will likely be influenced by the level of integration. In particular, the GNOME client is often found embedded in GGZ-enabled games of the GNOME project. A client under development is the SDL-based víbora. Furthermore, a Java-based client and applet exists as well. Running ggz will automatically select a suitable core client depending on the desktop environment.

Special clients exist in the form of ggzap, a quick-launcher for the KDE panel, and ggz-wrapper which is used for launching GGZ games from the command line and instant messenger applications.

## GAMES
Games are usually launched by the GGZ server, with corresponding game clients running on the user's desktop. Plenty of games are available for GGZ, most of them coming from the GGZ project itself but several independent game projects do now provide GGZ support. Game clients are implemented using multiple toolkits, some of which stem from certain desktop environments. However, all games work equally well under all desktops, it's just a matter of personal choice which of them are to be installed - having all of them is just fine.

While some GGZ game clients are suited for online gaming only, others also run locally like normal games happen to do. Those will be found in the desktop's application menu.

## FILES
The following layout can vary from site to site, depending on the completeness of a GGZ installation and the operating system distribution in use. It adheres to the File Hierarchy Standard (FHS) as much as possible.

/usr/bin

GGZ applications, tools, and the games which provide single player mode.

/usr/lib/ggz(d)

GGZ game clients and servers.

/usr/share/ggz(d)

Data files for game clients and servers.

/etc/ggz.modules

Game module registry for game clients.

/etc/ggzd

Configuration for the GGZ server, including rooms and game types.

## CONFORMING TO
GGZ Design Document, available at http://www.ggzgamingzone.org/docs/design/

GGZ Main Client-Server Protocol Reference, available at http://www.ggzgamingzone.org/docs/design/mainspec/

GGZ Client-Client Protocol Reference, available at http://www.ggzgamingzone.org/docs/design/clientspec/

GGZ Server-Server Protocol Reference, available at http://www.ggzgamingzone.org/docs/design/serverspec/

GGZ URI specification

Freedesktop.org specifications for desktop integration of games and applications, more information at http://www.freedesktop.org/

File Hierarchy Standard for unix-derived operating systems, at http://www.pathname.com/fhs/

## AUTHORS
The GGZ Development Team <ggz-dev@mail.ggzgamingzone.org>

## SEE ALSO
kggz(6), ggz-gtk(6), ggz-txt(6), ggz-java(6)


gitcli

package: git-core

title: gitcli(7)

summary: Git command\-line interface and conventions

text:
# gitcli(7)

## NAME
gitcli - Git command-line interface and conventions

## SYNOPSIS
gitcli

## DESCRIPTION
This manual describes the convention used throughout Git CLI.

Many commands take revisions (most often "commits", but sometimes "tree-ish", depending on the context and command) and paths as their arguments. Here are the rules:

•Options come first and then args. A subcommand may take dashed options (which may take their own arguments, e.g. "--max-parents 2") and arguments. You SHOULD give dashed options first and then arguments. Some commands may accept dashed options after you have already given non-option arguments (which may make the command ambiguous), but you should not rely on it (because eventually we may find a way to fix these ambiguities by enforcing the "options then args" rule).

•Revisions come first and then paths. E.g. in git diff v1.0 v2.0 arch/x86 include/asm-x86, v1.0 and v2.0 are revisions and arch/x86 and include/asm-x86 are paths.

•When an argument can be misunderstood as either a revision or a path, they can be disambiguated by placing -- between them. E.g. git diff -- HEAD is, "I have a file called HEAD in my work tree. Please show changes between the version I staged in the index and what I have in the work tree for that file", not "show the difference between the HEAD commit and the work tree as a whole". You can say git diff HEAD -- to ask for the latter.

•Without disambiguating --, Git makes a reasonable guess, but errors out and asks you to disambiguate when ambiguous. E.g. if you have a file called HEAD in your work tree, git diff HEAD is ambiguous, and you have to say either git diff HEAD -- or git diff -- HEAD to disambiguate.

•Because -- disambiguates revisions and paths in some commands, it cannot be used for those commands to separate options and revisions. You can use --end-of-options for this (it also works for commands that do not distinguish between revisions in paths, in which case it is simply an alias for --). When writing a script that is expected to handle random user-input, it is a good practice to make it explicit which arguments are which by placing disambiguating -- at appropriate places.

•Many commands allow wildcards in paths, but you need to protect them from getting globbed by the shell. These two mean different things:

```
$ git restore *.c
$ git restore \*.c
```

The former lets your shell expand the fileglob, and you are asking the dot-C files in your working tree to be overwritten with the version in the index. The latter passes the *.c to Git, and you are asking the paths in the index that match the pattern to be checked out to your working tree. After running git add hello.c; rm hello.c, you will not see hello.c in your working tree with the former, but with the latter you will.

•Just as the filesystem . (period) refers to the current directory, using a . as a repository name in Git (a dot-repository) is a relative path and means your current repository.

Here are the rules regarding the "flags" that you should follow when you are scripting Git:

•Splitting short options to separate words (prefer git foo -a -b to git foo -ab, the latter may not even work).

•When a command-line option takes an argument, use the stuck form. In other words, write git foo -oArg instead of git foo -o Arg for short options, and git foo --long-opt=Arg instead of git foo --long-opt Arg for long options. An option that takes optional option-argument must be written in the stuck form.

•Despite the above suggestion, when Arg is a path relative to the home directory of a user, e.g. ~/directory/file or ~u/d/f, you may want to use the separate form, e.g. git foo --file ~/mine, not git foo --file=~/mine. The shell will expand ~/ in the former to your home directory, but most shells keep the tilde in the latter. Some of our commands know how to tilde-expand the option value even when given in the stuck form, but not all of them do.

•When you give a revision parameter to a command, make sure the parameter is not ambiguous with a name of a file in the work tree. E.g. do not write git log -1 HEAD but write git log -1 HEAD --; the former will not work if you happen to have a file called HEAD in the work tree.

•Many commands allow a long option --option to be abbreviated only to their unique prefix (e.g. if there is no other option whose name begins with opt, you may be able to spell --opt to invoke the --option flag), but you should fully spell them out when writing your scripts; later versions of Git may introduce a new option whose name shares the same prefix, e.g. --optimize, to make a short prefix that used to be unique no longer unique.

## ENHANCED OPTION PARSER
From the Git 1.5.4 series and further, many Git commands (not all of them at the time of the writing though) come with an enhanced option parser.

Here is a list of the facilities provided by this option parser.

### Magic Options
Commands which have the enhanced option parser activated all understand a couple of magic command-line options:

-h

gives a pretty printed usage of the command.

```
$ git describe -h
usage: git describe [<options>] <commit-ish>*

   or: git describe [<options>] --dirty

    --contains            find the tag that comes after the commit

    --debug               debug search strategy on stderr

    --all                 use any ref

    --tags                use any tag, even unannotated

    --long                always use long format

    --abbrev[=<n>]        use <n> digits to display SHA-1s
```

Note that some subcommand (e.g. git grep) may behave differently when there are things on the command line other than -h, but git subcmd -h without anything else on the command line is meant to consistently give the usage.

--help-all

Some Git commands take options that are only used for plumbing or that are deprecated, and such options are hidden from the default usage. This option gives the full list of options.

### Negating options
Options with long option names can be negated by prefixing --no-. For example, git branch has the option --track which is on by default. You can use --no-track to override that behaviour. The same goes for --color and --no-color.

### Options trump configuration and environment
When there is a configuration variable or an environment variable that tweak the behaviour of an aspect of a Git command, and also a command line option that tweaks the same, the command line option overrides what the configuration and/or environment variable say.

For example, the user.name configuration variable is used to specify the human-readable name used by the git commit command to record the author and the committer name in a newly created commit. The GIT_AUTHOR_NAME environment variable, if set, takes precedence when deciding what author name to record. The --author=<author> command line option of the git commit command, when given, takes precedence over these two sources of information.

### Aggregating short options
Commands that support the enhanced option parser allow you to aggregate short options. This means that you can for example use git rm -rf or git clean -fdx.

### Abbreviating long options
Commands that support the enhanced option parser accepts unique prefix of a long option as if it is fully spelled out, but use this with a caution. For example, git commit --amen behaves as if you typed git commit --amend, but that is true only until a later version of Git introduces another option that shares the same prefix, e.g. git commit --amenity option.

### Separating argument from the option
You can write the mandatory option parameter to an option as a separate word on the command line. That means that all the following uses work:

```
$ git foo --long-opt=Arg
$ git foo --long-opt Arg
$ git foo -oArg
$ git foo -o Arg
```

However, this is NOT allowed for switches with an optional value, where the stuck form must be used:

```
$ git describe --abbrev HEAD     # correct
$ git describe --abbrev=10 HEAD  # correct
$ git describe --abbrev 10 HEAD  # NOT WHAT YOU MEANT
```

## NOTES ON FREQUENTLY CONFUSED OPTIONS
Many commands that can work on files in the working tree and/or in the index can take --cached and/or --index options. Sometimes people incorrectly think that, because the index was originally called cache, these two are synonyms. They are not — these two options mean very different things.

•The --cached option is used to ask a command that usually works on files in the working tree to only work with the index. For example, git grep, when used without a commit to specify from which commit to look for strings in, usually works on files in the working tree, but with the --cached option, it looks for strings in the index.

•The --index option is used to ask a command that usually works on files in the working tree to also affect the index. For example, git stash apply usually merges changes recorded in a stash entry to the working tree, but with the --index option, it also merges changes to the index as well.

git apply command can be used with --cached and --index (but not at the same time). Usually the command only affects the files in the working tree, but with --index, it patches both the files and their index entries, and with --cached, it modifies only the index entries.

See also https://lore.kernel.org/git/7v64clg5u9.fsf@assigned-by-dhcp.cox.net/ and https://lore.kernel.org/git/7vy7ej9g38.fsf@gitster.siamese.dyndns.org/ for further information.

Some other commands that also work on files in the working tree and/or in the index can take --staged and/or --worktree.

•--staged is exactly like --cached, which is used to ask a command to only work on the index, not the working tree.

•--worktree is the opposite, to ask a command to work on the working tree only, not the index.

•The two options can be specified together to ask a command to work on both the index and the working tree.

## GIT
Part of the git(1) suite