[Q] My code doesn't run in init.rc - Android Q&A, Help & Troubleshooting

how can I solve that problem?
I write the code in init.rc:
Code:
mv /com.anddoes.launcher_preferences.xml /data/data/com.anddoes.launcher/shared_prefs/
it returns such error:
<3>[ 0.640121] init: /init.rc: 351: invalid command 'mv'​
I tried both to write a script and to move toolbox with mv to the system root, but it returns the same error.
All the necessary folders exist

MaxiManBW said:
how can I solve that problem?
I write the code in init.rc:
Code:
mv /com.anddoes.launcher_preferences.xml /data/data/com.anddoes.launcher/shared_prefs/
it returns such error:
<3>[ 0.640121] init: /init.rc: 351: invalid command 'mv'​
I tried both to write a script and to move toolbox with mv to the system root, but it returns the same error.
All the necessary folders exist
Click to expand...
Click to collapse
init.rc is not a shell script, but a command language for the init process. Use can use the "exec" command to execute the mv command, see the docs below. Remember to use full paths.
Code:
Android Init Language
---------------------
The Android Init Language consists of four broad classes of statements,
which are Actions, Commands, Services, and Options.
All of these are line-oriented, consisting of tokens separated by
whitespace. The c-style backslash escapes may be used to insert
whitespace into a token. Double quotes may also be used to prevent
whitespace from breaking text into multiple tokens. The backslash,
when it is the last character on a line, may be used for line-folding.
Lines which start with a # (leading whitespace allowed) are comments.
Actions and Services implicitly declare a new section. All commands
or options belong to the section most recently declared. Commands
or options before the first section are ignored.
Actions and Services have unique names. If a second Action or Service
is declared with the same name as an existing one, it is ignored as
an error. (??? should we override instead)
Actions
-------
Actions are named sequences of commands. Actions have a trigger which
is used to determine when the action should occur. When an event
occurs which matches an action's trigger, that action is added to
the tail of a to-be-executed queue (unless it is already on the
queue).
Each action in the queue is dequeued in sequence and each command in
that action is executed in sequence. Init handles other activities
(device creation/destruction, property setting, process restarting)
"between" the execution of the commands in activities.
Actions take the form of:
on <trigger>
<command>
<command>
<command>
Services
--------
Services are programs which init launches and (optionally) restarts
when they exit. Services take the form of:
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
Options
-------
Options are modifiers to services. They affect how and when init
runs the service.
critical
This is a device-critical service. If it exits more than four times in
four minutes, the device will reboot into recovery mode.
disabled
This service will not automatically start with its class.
It must be explicitly started by name.
setenv <name> <value>
Set the environment variable <name> to <value> in the launched process.
socket <name> <type> <perm> [ <user> [ <group> ] ]
Create a unix domain socket named /dev/socket/<name> and pass
its fd to the launched process. <type> must be "dgram", "stream" or "seqpacket".
User and group default to 0.
user <username>
Change to username before exec'ing this service.
Currently defaults to root. (??? probably should default to nobody)
Currently, if your process requires linux capabilities then you cannot use
this command. You must instead request the capabilities in-process while
still root, and then drop to your desired uid.
group <groupname> [ <groupname> ]*
Change to groupname before exec'ing this service. Additional
groupnames beyond the (required) first one are used to set the
supplemental groups of the process (via setgroups()).
Currently defaults to root. (??? probably should default to nobody)
oneshot
Do not restart the service when it exits.
class <name>
Specify a class name for the service. All services in a
named class may be started or stopped together. A service
is in the class "default" if one is not specified via the
class option.
onrestart
Execute a Command (see below) when service restarts.
Triggers
--------
Triggers are strings which can be used to match certain kinds
of events and used to cause an action to occur.
boot
This is the first trigger that will occur when init starts
(after /init.conf is loaded)
<name>=<value>
Triggers of this form occur when the property <name> is set
to the specific value <value>.
device-added-<path>
device-removed-<path>
Triggers of these forms occur when a device node is added
or removed.
service-exited-<name>
Triggers of this form occur when the specified service exits.
Commands
--------
exec <path> [ <argument> ]*
Fork and execute a program (<path>). This will block until
the program completes execution. It is best to avoid exec
as unlike the builtin commands, it runs the risk of getting
init "stuck". (??? maybe there should be a timeout?)
export <name> <value>
Set the environment variable <name> equal to <value> in the
global environment (which will be inherited by all processes
started after this command is executed)
ifup <interface>
Bring the network interface <interface> online.
import <filename>
Parse an init config file, extending the current configuration.
hostname <name>
Set the host name.
chdir <directory>
Change working directory.
chmod <octal-mode> <path>
Change file access permissions.
chown <owner> <group> <path>
Change file owner and group.
chroot <directory>
Change process root directory.
class_start <serviceclass>
Start all services of the specified class if they are
not already running.
class_stop <serviceclass>
Stop all services of the specified class if they are
currently running.
domainname <name>
Set the domain name.
insmod <path>
Install the module at <path>
mkdir <path> [mode] [owner] [group]
Create a directory at <path>, optionally with the given mode, owner, and
group. If not provided, the directory is created with permissions 755 and
owned by the root user and root group.
mount <type> <device> <dir> [ <mountoption> ]*
Attempt to mount the named device at the directory <dir>
<device> may be of the form [email protected] to specify a mtd block
device by name.
<mountoption>s include "ro", "rw", "remount", "noatime", ...
setkey
TBD
setprop <name> <value>
Set system property <name> to <value>.
setrlimit <resource> <cur> <max>
Set the rlimit for a resource.
start <service>
Start a service running if it is not already running.
stop <service>
Stop a service from running if it is currently running.
symlink <target> <path>
Create a symbolic link at <path> with the value <target>
sysclktz <mins_west_of_gmt>
Set the system clock base (0 if system clock ticks in GMT)
trigger <event>
Trigger an event. Used to queue an action from another
action.
write <path> <string> [ <string> ]*
Open the file at <path> and write one or more strings
to it with write(2)
Properties
----------
Init updates some system properties to provide some insight into
what it's doing:
init.action
Equal to the name of the action currently being executed or "" if none
init.command
Equal to the command being executed or "" if none.
init.svc.<name>
State of a named service ("stopped", "running", "restarting")
Example init.conf
-----------------
# not complete -- just providing some examples of usage
#
on boot
export PATH /sbin:/system/sbin:/system/bin
export LD_LIBRARY_PATH /system/lib
mkdir /dev
mkdir /proc
mkdir /sys
mount tmpfs tmpfs /dev
mkdir /dev/pts
mkdir /dev/socket
mount devpts devpts /dev/pts
mount proc proc /proc
mount sysfs sysfs /sys
write /proc/cpu/alignment 4
ifup lo
hostname localhost
domainname localhost
mount yaffs2 [email protected] /system
mount yaffs2 [email protected] /data
import /system/etc/init.conf
class_start default
service adbd /sbin/adbd
user adb
group adb
service usbd /system/bin/usbd -r
user usbd
group usbd
socket usbd 666
service zygote /system/bin/app_process -Xzygote /system/bin --zygote
socket zygote 666
service runtime /system/bin/runtime
user system
group system
on device-added-/dev/compass
start akmd
on device-removed-/dev/compass
stop akmd
service akmd /sbin/akmd
disabled
user akmd
group akmd
Debugging notes
---------------
By default, programs executed by init will drop stdout and stderr into
/dev/null. To help with debugging, you can execute your program via the
Andoird program logwrapper. This will redirect stdout/stderr into the
Android logging system (accessed via logcat).
For example
service akmd /system/bin/logwrapper /sbin/akmd

kuisma said:
init.rc is not a shell script, but a command language for the init process. Use can use the "exec" command to execute the mv command, see the docs below. Remember to use full paths.
Code:
Android Init Language
---------------------
The Android Init Language consists of four broad classes of statements,
which are Actions, Commands, Services, and Options.
All of these are line-oriented, consisting of tokens separated by
whitespace. The c-style backslash escapes may be used to insert
...........................................
Click to expand...
Click to collapse
I created script and put it to /system folder
Then call it with:
Code:
service my_script /system/my_script.sh
class main
oneshot
and again received an error: <3>[ 61.921627] init: cannot find '/system/my_script.sh', disabling 'my_script'

MaxiManBW said:
I created script and put it to /system folder
Then call it with:
Code:
service my_script /system/my_script.sh
class main
oneshot
and again received an error: <3>[ 61.921627] init: cannot find '/system/my_script.sh', disabling 'my_script'
Click to expand...
Click to collapse
Is you script executable and begins with the line "#!/system/bin/sh"?

kuisma said:
Is you script executable and begins with the line "#!/system/bin/sh"?
Click to expand...
Click to collapse
Yes!
just in case, I used chmod 777 and first line begins with the line "#!/system/bin/sh".
Error no longer appears, but script doesn't work:
Code:
#!/system/bin/sh
if [-a /com.anddoes.launcher_preferences.xml]
cp /com.anddoes.launcher_preferences.xml /data/data/com.anddoes.launcher/shared_prefs/
rm /com.anddoes.launcher_preferences.xml
fi
I may be wrong calling service?
Code:
service my_script /system/my_script.sh
class main
oneshot

MaxiManBW said:
Yes!
just in case, I used chmod 777 and first line begins with the line "#!/system/bin/sh".
Error no longer appears, but script doesn't work:
Code:
#!/system/bin/sh
if [-a /com.anddoes.launcher_preferences.xml]
cp /com.anddoes.launcher_preferences.xml /data/data/com.anddoes.launcher/shared_prefs/
rm /com.anddoes.launcher_preferences.xml
fi
I may be wrong calling service?
Code:
service my_script /system/my_script.sh
class main
oneshot
Click to expand...
Click to collapse
I guess cp works, but not rm? Root is remounted read-only quite early in init.rc
Edit: Also, I've told you to use full paths. And that if-syntax...? It's sure not standard shell test syntax.

MaxiManBW said:
how can I solve that problem?
I write the code in init.rc:
Code:
mv /com.anddoes.launcher_preferences.xml /data/data/com.anddoes.launcher/shared_prefs/
it returns such error:
<3>[ 0.640121] init: /init.rc: 351: invalid command 'mv'​
I tried both to write a script and to move toolbox with mv to the system root, but it returns the same error.
All the necessary folders exist
Click to expand...
Click to collapse
Did it work?
I think init.rc only understands absolute paths... I mean, replacing mv with the below might work.
/system/bin/mv XXX YYY
-pradeep.
---------- Post added at 03:41 PM ---------- Previous post was at 03:16 PM ----------
kuisma said:
I guess cp works, but not rm? Root is remounted read-only quite early in init.rc
Edit: Also, I've told you to use full paths. And that if-syntax...? It's sure not standard shell test syntax.
Click to expand...
Click to collapse
I have a similar question regarding init.rc.
I am trying to run a native application (which downloads the wifi firmware to dongle). I need this to be done before the wifi driver module is insmod'ed. Accordingly, I have an entry in init.rc with 'exec' command to run it -- at the end of "on init" section.
exec /system/bin/downloader -n /system/etc/wifi/xyz.nvm /system/etc/wifi/fake.trx
This command doesn't seem to run although I don't see any errors in the boot log.
I also tried a combination of 'service' commands like:
service downloader /system/bin/downloader -n /system/etc/wifi/xyz.nvm /system/etc/wifi/fake.trx
disabled
oneshot
Same result: no error in the bootlog but firmware not downloaded.
Any idea what might be wrong with the commands here? I am on JB-MR1.
-pradeep.

Gurumath said:
Did it work?
I think init.rc only understands absolute paths... I mean, replacing mv with the below might work.
/system/bin/mv XXX YYY
-pradeep.
---------- Post added at 03:41 PM ---------- Previous post was at 03:16 PM ----------
I have a similar question regarding init.rc.
I am trying to run a native application (which downloads the wifi firmware to dongle). I need this to be done before the wifi driver module is insmod'ed. Accordingly, I have an entry in init.rc with 'exec' command to run it -- at the end of "on init" section.
exec /system/bin/downloader -n /system/etc/wifi/xyz.nvm /system/etc/wifi/fake.trx
This command doesn't seem to run although I don't see any errors in the boot log.
I also tried a combination of 'service' commands like:
service downloader /system/bin/downloader -n /system/etc/wifi/xyz.nvm /system/etc/wifi/fake.trx
disabled
oneshot
Same result: no error in the bootlog but firmware not downloaded.
Any idea what might be wrong with the commands here? I am on JB-MR1.
-pradeep.
Click to expand...
Click to collapse
So here is the thing I read somewhere that exec are just added for show and they don't actually work
I am not entirely sure of the above statement, but what I am sure of is that you can write a script and add it to the init.rc to get your work done
---------- Post added at 10:26 AM ---------- Previous post was at 10:16 AM ----------
kuisma said:
I guess cp works, but not rm? Root is remounted read-only quite early in init.rc
Edit: Also, I've told you to use full paths. And that if-syntax...? It's sure not standard shell test syntax.
Click to expand...
Click to collapse
It is not about the wrong service being called.
It is the fact that the service has been defined but you need to call the service at some instant by adding the command
'start yourServiceName'
That is if you want to start your service at boot time, you will need to add the following lines
on property:sys.boot_completed=1
start my_script
Here is a full version of a script that I wrote, this was to toggle wifi at regular interval of time
My Shell Script - init.custom.sh
#!/system/bin/sh
while true; do
svc wifi disable
sleep 10
svc wifi enable
sleep 60
done
My Code inside init.rc
service custom /system/bin/init.custom.sh
user root
oneshot
on property:sys.boot_completed=1
write /sys/block/mmcblk0/queue/scheduler cfq ## This was already present
start custom
I know this is a very late reply, but I started exploring these things recently.
Hope this helps someone.

Related

[FAQ][A] About Contacts Import/Export, Backup/Restore and Data/Sync

All About Contacts Import/Export, Backup/Restore and Data/Sync
Last Change: 2011-12-29
Content:
Details about how to backup and restore Contacts on the
Samsung Galaxy S I & II, including data storage info.
Summary:
Backing up and restoring your contacts on the latest Android OS
based phones is a nightmare as long as you do not want to use
automatic sync via Google or Outlook Express. In fact without
paying money for some specialized Application to do it properly
for you, it is a mess. Here I feel Samsung have really failed.
Why there isn't already a built-in simple-to-use contact backup
functionality, that doesn't depend on Google, Kies, Bluetooth
or other net-based service, is way beyond me.
Anyway, here is my attempt to remedy this situation and the
various options you have to backup and restore all your contacts
without:
a) using Google, Microsoft, Kies or other wireless protocol and
b) paying for specialized applications or software.
To simplify this exercise (a lot) we will assume that we would be
satisfied with backup and restore of only the most essential information.
This means (for me):
- first_name
- last_name
- primary_phone
- primary_email
So let's see how far we can get...
NOTE:
a) All of this tutorial assumes you have a rooted phone and
that you are operating as the root user (su)!
b) AOS phones doesn't generally come with the SQLite3
command-line binary, so this have to be installed manually!
Keywords:
Contacts, Restore, CSV, vCard, SQL,
Backup, Data, Sync, SQLite3, Import, Export, VCF
​Content​ - Introduction
- Remounting /system as Read/Write
- Installing the SQLite Command-Line Interpreter
- SQLite3 Install Script
- Contacts Database & Storage-Location:
- Contacts DB Location List
- Direct Manipulation of the Contacts Database
- Other Contact Import / Export Applications
- Help Needed!​Introduction​Essentially there are only 4 different ways to backup your Android contacts.
1. By using a backup application like Kies or 3rd party one from Android Market.
2. By syncing your contacts to your Google account.
3. By copying the entire "Contacts" database to your PC.
4. By exporting only the relevant data directly on your phone, using SQLite.
In this post I will only talk about the last 2 options, with focus on (4) as it applies to (3) as well.
​Remounting /system as Read/Write​Any manipulation of the system partitions and the root directory require WRITE permission to the file-system. To find out, just use the mount command and look for the "rw" label in the filesystem description of the / and /system partitions. For example:
Code:
# mount
...
rootfs / rootfs ro,relatime 0 0
/dev/block/mmcblk0p9 /system ext4 ro,relatime,barrier=1,data=ordered 0 0
/dev/block/mmcblk0p10 /data ext4 rw,nosuid,nodev,noatime,...,discard 0 0
/dev/block/mmcblk0p4 /mnt/.lfs j4fs rw,relatime 0 0
/dev/block/vold/179:11 /mnt/sdcard vfat rw,dirsync,...,utf8,...,discard 0 0
...
See the "rw" following "/system ext4" and "/data ext4" above?
Yes? Good, you can skip to the next section!
No? Then you need to remount the filesystem as READ/WRITE.
("rw" = "Read AND Write" and "ro" = "Read Only".)
!! However, this may depend on your model AND on how you connected your phone to USB. You can enter the phone directly without using the "file-transfer" mode in which case you may or may not have RW, but if you select to use "file-transfer" (aka. USB-disk mode) you may only get RO. In some cases the /mnt/sdcard is simply never mounted. Try and test! [*** check this! ***]
The way to get RW, is to remap the "physical" device (disk) location to the system partition you are interested in. The tricky part is knowing the physical device name of your system disk which may not always be the same as indicated from the mount command. If not, try to inspect the boot-log messages with the "motd" command, or inspecting the file "/init.rc" for the details of everything that is mounted upon boot. (Boot-log messages are normally enabled in most stock Kernels, but not necessarily in modded ROM's.)
For the SGS-2 which uses the EXT4 filesystem, I had to use:
Code:
mount -o remount,rw -t ext4 /dev/block/mmcblk0p9 /system
For the SGS-1 when using an RFS based AOS, I had to use:
Code:
mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
To undo this you just replace "rw" with "ro" in the statements above. Although this is not necessary, since it will be automatically reverted after next reboot, which is recomended anyway after manually editing any system DB.
​Installing the SQLite Command-Line Interpreter​Most phones doesn't come with the SQLite3 command-line interpreter/interface (CLI) installed, unless they are rooted with a heavily modded ROM. The CLI is needed to manually access the SQLite Contacts database. Thus you need to check that it is not already installed and install it manually, if it is not. The binary (sqlite3) is normally located in either /system/bin or /system/xbin. To check if you have it, try the following command:
Code:
find / -iname '*sqlite*'
If it fails to return the files shown below, you need to install the SQLite3 binary AND possibly the relevant library files. You should already have most of the required library (lib*.so) files, as they are constantly used by the system, so look for them first! The files you need are:
/system/bin/sqlite3
/system/lib/libsqlite.so
/system/lib/libsqlite_jni.so
If the binary is compiled from CyanogenMod sources, you will also need the following:
/system/lib/libncurses.so
In the worst case you can go through the exercise to compile the SQLite3 sources for the MIPS32 chipset by yourself. [http://www.sqlite.org/] Also it's worth to note that some custom ROM's now include the latest compiled version. When you have the binary you just put it on your SD card and copy it to the root file system binary directory. Many ROM's and rooted phones use an additional directory /system/xbin where you can put your own binaries. If this directory (and path variable) is not already present, use:
Code:
cp <path_to_your_sqlite3_binary> /system/bin/sqlite3
chmod 4755 /system/bin/sqlite3
chown root.shell /system/bin/sqlite3
(Note that this version of chown uses a "." in the "user.group" specification.)
Do the same for the library files, if they are missing. You should now be able to run SQLite3:
Code:
# sqlite3 -version
3.6.22
Everything OK? Good!
​SQLite3 Install Script​!!MODIFY FIRST!!
Code:
#!/bin/sh
# squint.sh - sqlite3 install script for rooted Androids
#
#-rwsr-sr-x root shell 22228 2011-11-10 12:53 /system/bin/su
#-rwsr-xr-x root shell 1075144 2011-12-15 16:55 /system/xbin/busybox
#-rw-r--r-- root root 322120 2011-09-14 14:45 /system/lib/libsqlite.so
# Go to your "sqlite" folder on your (internal) SD card:
cd /mnt/sdcard/sqlite/
cp sqlite3 /system/xbin/sqlite3
chmod 4755 /system/xbin/sqlite3
chown root.shell /system/xbin/sqlite3
cp ./lib/libncurses.so /system/lib/libncurses.so
chmod 644 /system/lib/libncurses.so
chown root.root /system/lib/libncurses.so
Contacts Database & Storage-Location​Apparently the SQLite3 database used to store the Contacts data is located in different parts on different Android models [?] and different Android OS versions. I have not been able to verify this, as I don't have access to these phones, but from from reading various forum posts for other phones this seem to be the case.
The way you can check is by looking for the raw database file on your system. On the phones I have, the location can be found here:
SGS-1 (2.3.6): /dbdata/databases/com.android.providers.contacts/contacts.db
SGS-2 (2.3.4): /data/data/com.android.providers.contacts/databases/contacts2.db
It may be important to notice that the "com.android.providers.contacts" part of this path, is actually referring to the particular "Contacts.apk" application that is installed in your phone. Therefore this location can differ from other versions of that application and thus also your phone model and OS version. In addition note that the /data and /dbdata or "whatever" partitions may be mounted on a different block device, as noted in the first section above. For example, on my SGS-2, I had /data mounted on /dev/block/mmcblk0p10 .
The more intelligent way is to look for all .db files on you system by doing some shell magic:
Code:
find / -iname '*.db'
But today, almost every application is using a database to save information, so to narrow down the long list, filter your search with "ontact":
Code:
find /system -iname '*.db' |grep ontact
Contacts DB Location List​GT-I9000 (2.3.6): /dbdata/databases/com.android.providers.contacts/contacts.db
GT-I9100 (2.3.4): /data/data/com.android.providers.contacts/databases/contacts2.db
[I'd like to keep this list updated with other models and AOS versions, so please let me know what you have.]
​Direct Manipulation of the Contacts Database​In order to make any changes to any information contained in the database, you need to have write permissions set on the the relevant partition(s) as explained above. Remount as needed.
If you for some crazy reason need to replace/restore your entire contact database with another one. (This is strongly discouraged!) You also need to make sure that the one you replace with have both the same ownership (chown) and permissions (chmod) as the original one.
Next, let's open the contacts database:
Code:
# cd /data/data/com.android.providers.contacts/databases
# sqlite3 contacts2.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .databases
.databases
seq name file
--- --------------- ----------------------------------------------------------
0 main /data/data/com.android.providers.contacts/databases/contacts2.db
sqlite> .tables
.tables
_sync_state settings
_sync_state_metadata speed_dial
accounts status_updates
activities v1_settings
agg_exceptions view_contacts
android_metadata view_contacts_restricted
calls view_data
contact_entities_view view_data_restricted
contact_entities_view_restricted view_groups
contacts view_raw_contacts
data view_raw_contacts_restricted
groups view_v1_contact_methods
mimetypes view_v1_extensions
name_lookup view_v1_group_membership
nickname_lookup view_v1_groups
packages view_v1_organizations
phone_lookup view_v1_people
properties view_v1_phones
raw_contacts view_v1_photos
sqlite> SELECT _id,name, number FROM view_v1_phones;
[...]
To output the result as a CSV table to a file called "my_contacts_db.csv" with the first row containing the (column) headers and bailing out on errors, do this:
Code:
sqlite> .bail ON
sqlite> .headers ON
sqlite> .mode csv
sqlite> .output my_contacts_db.csv
sqlite> SELECT _id,name, number FROM view_v1_phones;
sqlite> .output stdout
sqlite> .quit
As you can see, if we had known the precise query statements we would have already been done with our export. But the Contacts.db tables are rather complex for our purposes of simply extracting the most relevant contact information. I lazily gave up after trying some basic SQL select statements...
[So yeah, please send me a good SQL statement for selecting and printing only the basics as a CSV!]
The AOS java API for using the contacts are MUCH simpler to use than the needed SQLite statements, for doing the extractions/replacements. But then you also need to write the program.
http://www.higherpass.com/Android/Tutorials/Working-With-Android-Contacts/
There are many such programs out there, but very few who does the job well. (Everybody want to make money!) So try some Google-Fu on sites such as:
http://www.sourceforge.com/
http://code.google.com/
http://www.github.com/
http://www.stackexchange.com/
http://grepcode.com/
and use the keywords in the top of this document.
​Other Contact Import / Export Applications​But I'm not a Java Programmer. (What?!!) So instead I had a look at the most simple applications for exporting and importing you contacts. Being reasonably paranoid as a person, I did not trust huge multifunction backup-applications, knowing that they are full of adware, spyware and other "things" we may not like. With these limits I knew that any such application should not be much larger than 100 kilobytes.
I found 4 small applications (and one very large) on the Market that I tested:1. Contacts CSV Export (93 K)
https://market.android.com/details?id=dutchandroid.contacts.export
(contacts.export-1060-1.060.apk, dutchandroid.contacts.export)
2. Contacts Backup Trial (168K)
https://market.android.com/details?id=com.saturnat.android.contactsbackup.trial
(contactsbackup.trial-34-2.9.5.apk, com.saturnat.android.contactsbackup.trial)
3. Import Contacts (56 K)
https://market.android.com/details?id=org.waxworlds.edam.importcontacts
(import-contacts_1.1.apk, org.waxworlds.edam.importcontacts)
4. Offline Contacts Sync (27 K)
https://market.android.com/details?id=com.beforemadness
(offlineContactsSync.apk, com.beforemadness)
5. GO Contacts EX (2.7 M!)
https://market.android.com/details?id=com.jbapps.contactpro​(1) Is a flexible lightweight CSV contacts exporter. You can manually choose CSV delimiters (",;TAB" etc) or choose a standard (Mozilla, Hotmail and Outlook etc.) CSV format.
(2) $$$, Is buggy with a no-sense UI, doesn't catch Email addresses, don't let you choose filename, and contain trackers from Facebook and Mixpanel. Limited trial to 10 contacts and 3 days before expiration.
(3) Only imports vCard (.vcf) files. One-by-one or scan a directory. Ask's what to do (skip,merge,replace) with duplicates.
(4) No-sense UI. Has export function but it is not working. And import is only working partially.
(5) Exports all contacts to a single vCard file, but missed my Emails. Nice merge and batch-delete functionality. Nice interface, and works. However, this app is huge, and god knows what other bloat junk it contains.
​Other Useful Links​[1] http://www.sqlite.org/
[2] http://www.androidadb.com/source/pl...ndroid/contacts/ImportVCardActivity.java.html
[3] http://grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/
[4] sed Tutorial: http://www.grymoire.com/Unix/Sed.html
​
Help Needed!​If you have any detailed knowledge about where and how the relevant contact data is stored on your device, please let me know and include details such as:
- Your phone model number
- Your general Android OS version [Settings --> About Phone ]
- Your phone firmware version (PDA / PHONE / CSC) ["dial" --> *#1234#]
- The precise location of the contacts database file
E.g.
GT-I9100, Gingerbread 2.3.4, XWKI4/XXKI1/OXX KI2 (SEB)
/dbdata/databases/com.android.providers.contacts/contacts.db
If you have already been poking around your OS it would also be helpful to know:
- The version and type of database used (SQLite3 etc.)
- The particular DB tables used to obtain:
+ First Name
+ Last Name
+ Phone Number "1"
+ Email "1"
Here I have written "1" to signify the primary number used. I have refrained from using more details as this, as I consider this minimal but sufficient for backing up and restoring my contacts.
​
Some useful SQLite queries​
Code:
sqlite3 -csv contacts2.db "SELECT _id,name,primary_email,number FROM view_v1_phones;"
sqlite3 -csv contacts2.db "SELECT _id,mimetype_id,raw_contact_id,data1 FROM data;"
sqlite3 -csv contacts2.db "SELECT _id,display_name FROM raw_contacts WHERE account_type='vnd.sec.contact.phone';"
sqlite3 -csv contacts2.db "SELECT data1 FROM data WHERE raw_contact_id=112 AND mimetype_id=5;"
sqlite3 -csv -header contacts2.db "SELECT _id,package_id,mimetype_id,raw_contact_id,is_primary,is_super_primary,data_version,data1,data2,data3 FROM data WHERE raw_contact_id=21;"
sqlite3 -csv -header contacts2.db "SELECT _id,package_id,mimetype_id,raw_contact_id,is_primary,is_super_primary,data_version,data1,data2,data3 FROM data WHERE is_primary=0 AND data_version=0;"
#SELECT data1 FROM data WHERE raw_contact_id=140 AND mimetype_id=1;
#SELECT data1 FROM data WHERE raw_contact_id=140 AND mimetype_id=5 AND data2=2;
#SELECT data1 FROM data WHERE raw_contact_id=112 AND mimetype_id=5 AND data2=7;
#SELECT data1 FROM data WHERE raw_contact_id=112 AND mimetype_id=5 AND data2=1;
If this helped you in any way, please hit the THANK YOU button! ​
The Android contacts-database extraction script
This script is based on one that I found for extracting Facebook contacts into a CSV file, here: http://forum.xda-developers.com/showthread.php?t=1170765 I then modified and improved this script to suit my own purposes, but I am very grateful to whoever created it in the first place. (There is no reliable reference to the origin of this.)
However, there are two very useful things I found and included in this script.
1) You can extract contacts from other applications using that same database file, by modifying the "java-path-identifyer" accordingly.
Code:
Specify the application used for organizing the data:
-----------------------------------------------------------
vnd.sec.contact.phone - Default Android phone book
com.facebook.auth.login - Facebook contacts
2) The sed pipe used to replace carrige-returns (new-lines, \n) from any output stream, with a comma ",".
Code:
sed ':a;N;$!ba;s/\n/,/g'
Explanation:
Create and label a register via :a
Append the current and next line to the register via N
If we are before the last line, branch (b) to the created
register (a) with $!ba ( "$!" means not to do it on the
last line, as there should be one final newline).
Use global match (/g) to substitute (s) every newline (\n)
with a comma on the pattern space, which is the contents
of the (a) register. (I.e. The whole input stream.)
Here is the script:
Code:
#!/bin/sh
# contex.sh - Extracts the Name,Phone,Email from the Android Contact Database
#==============================================================================
# Last Change: 2011-12-29
# Name: Android DB Contacts Exporter
#
# Description: Extracts contacts from the Android contacts database
# to a CSV file for import into other contact list tools.
#
# Usage: ./contex.sh <output_filename> &
#
# How to use:
#
# 1. Copy your Android Contacts Database to your computer:
# adb pull /data/data/com.android.providers.contacts/databases/contacts2.db ./
# 2. Run this file from the same directory as contacts2.db
# ./contex.sh output_filename.csv
#
# System Requirements: sh, sqlite3, sed
#
# Additional Notes:
#
# 1. This script is very slow, please be patient!
#
# 2. The sed sequence to replace the end on line (\n) with a comma (,)
# from a list, but avoiding \n on the last line is:
#
# sed ':a;N;$!ba;s/\n/,/g'
# --- OR ---
# sed '{:q;N;s/\n//g;t q}'
#
# 3. Only numbers that are of the types: HOME, MOBILE, WORK and OTHER
# get extracted in this script. These types are specified by the
# "data2" field in the "data" table.
#
#==============================================================================
echo; echo "Android contacts backup script started with PID: $$ "; echo;
DATE=`date +%G%m%d`
#----------------------------------------------------------
# Input and Output files:
#----------------------------------------------------------
CONTACTSDB="./contacts2.db"
if [ ! -f "$CONTACTSDB" ]
then
echo "Contacts Database file: $CONTACTSDB not found. Exiting."; echo
exit 1
fi
OUTFILE=$1
if [ -z "$OUTFILE" ]
then
OUTFILE="contex_backup_${DATE}.csv"
fi
echo "Contacts backup file: $OUTFILE "; echo
if [ -f "$OUTFILE" ]
then
echo "Contacts Backup file: $OUTFILE already exist. Exiting."; echo
exit 1
fi
#----------------------------------------------------------
# Write the Table Header:
#----------------------------------------------------------
echo "First Name,Last Name,E-mail,Mobile Phone,Home Phone,Work Phone,Other Phone" >> $OUTFILE
#----------------------------------------------------------
# Setting up SQLite command and mode:
#----------------------------------------------------------
#CMD="sqlite3 -bail -noheader -csv"
CMD="sqlite3";
#----------------------------------------------------------
# Get the raw IDs of all contacts:
#----------------------------------------------------------
RAWID_LIST=`$CMD $CONTACTSDB "SELECT _id from raw_contacts WHERE account_type='vnd.sec.contact.phone'"`
#echo "$RAWID_LIST"
#----------------------------------------------------------
# Loop through the IDs and extract all necessary data
#----------------------------------------------------------
for RAWID in $RAWID_LIST; do
# Get the First_Name and Last_Name in one query:
# NOTE: Need to remove occasional CTRL-M's with sed.
NAME=`$CMD -csv $CONTACTSDB "SELECT data2, data3 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=6;" | sed ':a;N;$!ba;s/\n//g'`
# Get the Email address:
# NOTE: This will simply append multiple email adresses to one long string, with ";" separator!
EMAIL=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=1;" | sed ':a;N;$!ba;s/\n/;/g'`
# Here we get the "Home", "Mobile", Work" and "Other" (labeled) phone numbers.
# NOTE: Each of these may return multiple responses, so we need to convert new-lines (\n) to ",".
HPHONE=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=5 AND data2=1;" | sed ':a;N;$!ba;s/\n/,/g'`;
MPHONE=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=5 AND data2=2;" | sed ':a;N;$!ba;s/\n/,/g'`;
WPHONE=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=5 AND data2=3;" | sed ':a;N;$!ba;s/\n/,/g'`;
OPHONE=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=5 AND data2=7;" | sed ':a;N;$!ba;s/\n/,/g'`;
PHONES="$MPHONE,$HPHONE,$WPHONE,$OPHONE";
# If at least one main field is found then write the CSV line
if [ -n "$NAME" ] || [ -n "$EMAIL" ] || [ -n "$PHONES" ]; then
#echo "ID: $RAWID"
echo -n "$NAME,$EMAIL,$PHONES" >> $OUTFILE
echo >> $OUTFILE
fi
done
echo 'Done.'
NOW YOU CAN HIT THE THANK YOU BUTTON!​
reserved for me 2!
Thanks for this write up. I found my stuck after upgrading a friends phone from 2.2 firmware to CM10 with 4.1 firmware. We made a full backup with TitaniumBackup but it would import the contacts properly. I pulled the contacts2.db from the backup file and used your script to get the data out.
I did have to make some changes to the mimetypes in the SQLs but apart from that everything worked perfectly. I think the mimetypes may have changed between android versions.
The modified portion of the script:
Code:
# Get the First_Name and Last_Name in one query:
# NOTE: Need to remove occasional CTRL-M's with sed.
NAME=`$CMD -csv $CONTACTSDB "SELECT data2, data3 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=5;" | sed ':a;N;$!ba;s/\n//g'`
# Get the Email address:
# NOTE: This will simply append multiple email adresses to one long string, with ";" separator!
EMAIL=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=1;" | sed ':a;N;$!ba;s/\n/;/g'`
# Here we get the "Home", "Mobile", Work" and "Other" (labeled) phone numbers.
# NOTE: Each of these may return multiple responses, so we need to convert new-lines (\n) to ",".
HPHONE=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=6 AND data2=1;" | sed ':a;N;$!ba;s/\n/,/g'`;
MPHONE=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=6 AND data2=2;" | sed ':a;N;$!ba;s/\n/,/g'`;
WPHONE=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=6 AND data2=3;" | sed ':a;N;$!ba;s/\n/,/g'`;
OPHONE=`$CMD $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=6 AND data2=7;" | sed ':a;N;$!ba;s/\n/,/g'`;
PHONES="$MPHONE,$HPHONE,$WPHONE,$OPHONE";
Thanks so much for your post.
I can't thank you enough for this information!
My S2 died on me a month back, and the only backup of my contacts (which are not synced on Gmail) were an old TB backup from April 2012. At least thanks to this knowledge I know what and where to look for!
Thanks a lot
Help request with command
Hello.
I am trying to convert a recovered contacts database from contacts2.db to Google compatible cvs file with sqlite3.exe.
The recovered database came from a Samsung N7000 and it is composed as follow in the table data:
SELECT "_id", "package_id", "mimetype_id", "raw_contact_id", "is_primary", "is_super_primary", "data_version", "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9", "data10", "data11", "data12", "data13", "data14", "data15", "data_sync1", "data_sync2", "data_sync3", "data_sync4", "is_read_only" FROM "data";
There are 2 lines for a single contact. mimetype_id 6 is the line of the name in data1; mimetype_id 5 is the line of the number in data1
Is there a command to properly export that database? I have no skills in programming and scripting.
I have to complete an import of a database to a new android phone from a N7000 old contacts2.db :crying:
Just to say that the code
Code:
SELECT "_id", "package_id", "mimetype_id", "raw_contact_id", "is_primary", "is_super_primary", "data_version", "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9", "data10", "data11", "data12", "data13", "data14", "data15", "data_sync1", "data_sync2", "data_sync3", "data_sync4", "is_read_only" FROM "data";
gives something like that:
5406,,5,2335,0,0,0,349563erased for privacy,2,
5407,,6,2335,0,0,0,"federico agronomo",federico,agronomo
And so on...
Since I have no skills in developing and scripting, is there anybody how can help me extracting universal VCF from that N7000 sql contacts2.db specific database? I can send it to you by eMail if you write to me in pvt. I'll apprecciated.
I did a lot of tests, but I can not create a proper query or run a proper script.
I was able only to extract the database in a way like the one mentioned. I have quite 1000 contacts :crying:
Thank you in any way for help.
Kind regards.
THREAD CLOSED!
There are now hundreds of contacts & backup Apps on Google Play, so I'm closing this old thread.
But here are a few free ones that I really like:
Contact Backup & Restore Gmail
Super Backup : SMS & Contacts
MCBackup - My Contacts Backup
They should be able to export to CSV, VCF and XML files...
ENJOY!

[Q] Help with ADB or rather a simple command. Im confused!!

Ok, so basically Im trying to extract data from my contacts2.db file.
Ive managed to copy it out of the hidden data folder on my GalaxySII onto my PC HDD. Now i need to run a script to extract the data. The thing is, im baffled how to do this.
Im a n00b when it comes to ADB, but i managed to drop the script and the copied contact2.db file into a test folder on my device, i managed to use the terminal emulator to browse to the directory and run the command but I get: 'Permission Denied' when I run the script. Ive tried changing the permissions on the file via my SII but to no avail.
So, im following the instructions I have via my PC:
== Usage ==
Copy your Android contacts database to your computer:
adb pull /data/data/com.android.providers.contacts/databases/contacts2.db ./
Run this file from the same directory as contacts2.db
./fb-extract.sh
Import csv to an address book of your choice
Now ive got the db, but how do I run the script. Ive tried to load adb emulator but have no idea what im doing there. Ive tried to use the adb command but again, no idea.
Can someone give me a brief, and quick step-by-step way to run this script on my contacts file so I can extract the data I want please.
Thanks muchly....
-=stylus=-
What are you trying to accomplish? The instructions say you should be running the shell script on the PC, not the phone. But you can't just natively run shell scripts in Windows, which I presume is what you're using. You'd need Cygwin or similar assuming you're averse to Linux, and possibly other stuff, depending on what the script is doing.
That fb-script you're trying to run is probably extracting the data with sqlite3. So you need to have the sqlite3 binary available where you are running the script (phone or computer). There are many things which can go wrong, first step would be to paste the content of fb-extract.sh here.
Ah, yes sorry. Im trying to extract all email addresses from my contacts on my phone. Facebook syncs with your Android device and adds all the email addresses registered with your contacts.
The script I have should extract all this data out:
(Not sure if Im allow to post code but)
#! /bin/sh
###########################################
#
# Android DB contacts exporter (proof-of-concept)
# 2011-01-06
#
# Extracts "certain contacts" from the Android contacts database to a CSV file
# for import into other contact list tools.
#
#
# == Usage ==
#
# 1) Copy your Android contacts database to your computer
# adb pull /data/data/com.android.providers.contacts/databases/contacts2.db ./
# 2) Run this file from the same directory as contacts2.db
# ./fb-extract.sh
# 3) Import csv to an address book of your choice
#
# == Notice ==
#
# This is a proof of concept script. Use at your own risk and check
# with laws and terms of service regarding data usage.
#
###########################################
# In and out files
CONTACTSDB="./contacts2.db"
OUTFILE="./contacts_fb.csv"
# Write table header
echo "First Name,Last Name,E-mail Address,Mobile Phone,Home Phone" >> $OUTFILE
# Get the raw IDs of all facebook contacts
RAWID_LIST=`sqlite3 $CONTACTSDB "SELECT _id from raw_contacts WHERE account_type='com.facebook.auth.login'"`
# Loop through the IDs and extract necessary data
for RAWID in $RAWID_LIST; do
# Get the first and last names
NAME=`sqlite3 $CONTACTSDB "SELECT data2, data3 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=7"`
FNAME=`echo $NAME | awk '{split($0,a,"|"); print a[1]}'`
LNAME=`echo $NAME | awk '{split($0,a,"|"); print a[2]}'`
# Get the email address
EMAIL=`sqlite3 $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=1"`
# Get the phone numbers (mobile & other). Convert international Japanese # to local using `sed`
MPHONE=`sqlite3 $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=5 AND data2=2" | sed 's/^81\([0-9]\{7,\}\)/0\1/'`
OPHONE=`sqlite3 $CONTACTSDB "SELECT data1 FROM data WHERE raw_contact_id=$RAWID AND mimetype_id=5 AND data2=7" | sed 's/^81\([0-9]\{7,\}\)/0\1/'`
# If at least one info field was set then write the csv line
if [ -n "$EMAIL" ] || [ -n "$MPHONE" ] || [ -n "$OPHONE" ]; then
echo "$FNAME,$LNAME,$EMAIL,$MPHONE,$OPHONE" >> $OUTFILE
fi
done
Now like I said, I have the contacts2.db file, I just am not sure how to go about running this script on it to accomplish my task.
I understand a bit of coding but not much so bear with me.
-=stylus=-
Well, it's obvious you have to run it on a Linux/Android system with /bin/sh and sqlite3 binaries. So, probably better to run it on your phone. But first, you need to have the sqlite3 binary from somewhere, as it's not shipped by default.
Get SuperOneClick and extract it; in the Dependencies folder you'll find the sqlite3 file.
Push it to the phone from your computer (these commands are run in command prompt):
Code:
C:\> adb remount /system
C:\> adb push /path/to/sqlite3 /system/xbin/sqlite3
Check the sqlite3 binary is present in the system path and available:
Code:
C:\> adb shell
[email protected]# which sqlite3
/system/xbin/sqlite3
Now you can run your script. With adb shell, run the script on your phone in the same folder where you have the .db file. Should create a new CSV file which can be pulled to your computer.
Now i just get the error message:
./fb-extract.sh: cannot execute - permission denied
chmod 777 fb-extract.sh
Depending on what folder you're in, you may need to remount r/w too.
And make sure you're not having the two files on a partition mounted with noexec
I wish I was good at this stuff....
Ok, its in a folder:
/sdcard/test
contents of this folder are:
contacts2.db
fb-extract.sh
Ive run the 'chmod 777 fb-extract.sh' command but still permission denied.
Should I put it in a different folder and run it? Is there a better way?
Sorry for my lack of knowledge here but no idea what remount r/w (well other than remount read/write) is or how to do it. How do I know if ive got it on a partition mounted with noexec?
In "adb shell":
Code:
[email protected] # mount | grep sdcard
and post the output. If you see a "noexec" flag, then it doesn't allow you to exec anything from the sdcard. You could try after that
Code:
[email protected] # mount -o remount,exec /sdcard
and try the script again.
I think im losing the will to live guys ha ha ha!!!
Ok the output was:
Code:
a/local/bin:$PATH <
[email protected]:/ $ su
[email protected]:/ # mount | grep sdcard
/dev/block/vold/259:3 on /mnt/sdcard type vfat (rw,dirsync,nosuid,nodev,noexec,noatime,nodiratime,uid=1000,gid=1015,fmask=0002,dmask=0002,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)
tmpfs on /mnt/sdcard/external_sd type tmpfs (rw,dirsync,nosuid,nodev,noexec,noatime,nodiratime,size=0k,mode=755,gid=1000)
tmpfs on /mnt/sdcard/usbStorage type tmpfs (rw,dirsync,nosuid,nodev,noexec,noatime,nodiratime,size=0k,mode=755,gid=1000)
/dev/block/vold/179:25 on /mnt/sdcard/external_sd type vfat (rw,dirsync,nosuid,nodev,noexec,noatime,nodiratime,uid=1000,gid=1023,fmask=0002,dmask=0002,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)
tmpfs on /mnt/sdcard/external_sd/.android_secure type tmpfs (ro,relatime,size=0k,mode=000) [email protected]:/ # mount -o remount,exec /sdcard
mount: can't find /sdcard in /proc/mounts
1|[email protected]:/#
Now im doing all this using terminal emulator on my phone. Thats the same as adb right? Still getting permission denied though.
You would think extracting email addresses from your contacts list was easy!
/mnt/sdcard type vfat (rw,dirsync,nosuid,nodev,noexec
This is what I was saying before.
On your phone with adb:
Code:
[email protected] # mount -o rw,remount /mnt/sdcard
and then you should be able to execute the script.
Well, it's difficult because it wasn't designed to be used that way (although what you are trying to do is quite simple). It would have been easier to sync your contacts with Google and download the CSV from Google Contacts' web interface.
Nope. Still cant do it.. still permission denied.
I cant sync with Google, create a vcard or anything. The facebook emails are protected somehow. If you export your contacts list to any file, it leaves all the facebook emails out!
Agghhhhhhh!
Thanks for all your help though. Much appreciated!!!

Problems with cron

Hi, I have made cron work on my 7" china tablet, it runs almost like I'd like it to..
I've made a passwd file in /etc with the following contents:
Code:
root:x:0:0::/data/cron:/system/bin/bash
I've made a symlink from /system/bin to /bin
And I've made a crontab file with the following line in it:
Code:
* * * * * /system/xbin/cat /sys/class/power_supply/battery/capacity > /dev/ttyACM0
Now the problem.. Cron runs fine, running the small bash code every minute, but..
ttyACM0 is a serial line to a microController - but the problem is that nothing is received on the controller, despite the cron running the script.
now if I LS /dev/tty* I get the following:
Code:
[email protected]:/ # ls /dev/ttyA* -l
ls /dev/ttyA* -l
crw------- root root 166, 0 2013-09-07 13:11 ttyACM0
-rw-rw-rw- root root 3 2013-09-07 13:14 ttyACM0
[email protected]:/ #
The cron creates an identical file in /dev and write it's data to this file, and not the *real* ttyACM0 serial..
I start the crond service in init.rc like this:
Code:
service crond /system/xbin/crond -c /data/cron
user root
disabled
oneshot
on property:dev.bootcomplete=1
.
.
start crond
If I change the cronscript to output to a flat file somewhere else (like /data/test_output), I can see the file with LS, but I'm not able to delete it nor cat it.
What's going on?
I need this to work in order to trigger a charger once the battery goes too low, and turn it off again once it has reached a given threshold. Not being able to send a simple command via serial really offsides this project.
Please help
Could it be that the cron job starts before the /dev/ttyACM0 is created?
hmm, I'll try and delay it a bit..
Made a simple check for if the device exists or not. if [ -c /dev/ttyACM0 ]This solves the problem.

ssh: No controlling tty

I have a rooted a GT-I9195 (SGS4-mini) done with CF-Auto-Root and the latest Busybox. I then decided to use the "Ssh server" from The Olive Tree, since it is simple, small, free, but unfortunately have ads. For on-device/local shell, I use the Android Terminal Emulator and everything works great, including su and shell environment.
However, I have a really strange bahaviour when connecting using ssh via WiFi, and trying to su.
First when connecting via ssh, I get the following message.
Code:
[SIZE=2]$ ssh -2 -4 -t [email protected] -p 50555
Authenticated with partial success.
[email protected]'s password:
/system/bin/sh: No controlling tty: open /dev/tty: No such device or address
/system/bin/sh: can't find tty fd
/system/bin/sh: warning: won't have full job control
[email protected]:/ $[/SIZE]
I have Googled this and there's little useful info. On one site they even say:
Code:
[SIZE=2]Getting a controlling tty
[B]How does one get a controlling terminal? [COLOR=Red]Nobody knows[/COLOR], this is a great mystery.[/B]
The System V approach is that the first tty opened by the process
becomes its controlling tty. The BSD approach is that one has to
explicitly call
ioctl(fd, TIOCSCTTY, ...);
to get a controlling tty.
Linux tries to be compatible with both, as always, and this results in
a very obscure complex of conditions. Roughly:
The [B]TIOCSCTTY [/B]ioctl will give us a controlling tty, provided that (i)
the current process is a session leader, and (ii) it does not yet have
a controlling tty, and (iii) maybe the tty should not already control
some other session; if it does it is an error if we aren't root, or we
steal the tty if we are all-powerful.
Opening some terminal will give us a controlling tty, provided that
(i) the current process is a session leader, and (ii) it does not yet
have a controlling tty, and (iii) the tty does not already control
some other session, and (iv) the open did not have the [B]O_NOCTTY[/B] flag,
and (v) the tty is not the foreground VT, and (vi) the tty is not the
console, and (vii) maybe the tty should not be master or slave pty.
[/SIZE]
Now this is not the end of the world, if it was not that it doesn't understand normal terminal control characters and in addition, when I do su, I loose the command prompt. However, using the "-i" (interactive) switch gets me the "#" prompt, but environment is still completely messed up:
Code:
[SIZE=2][email protected]:/ $ [B]su -c /system/bin/sh -i[/B]
/system/bin/sh: No controlling tty: open /dev/tty: No such device or address
/system/bin/sh: can't find tty fd
/system/bin/sh: warning: won't have full job control
[email protected]:/ #[/SIZE]
I've never had or seen this issue before. Any ideas?
(Also, where would I put a source to my .bashrc and make sure it runs when su'ing or ssh?)
PS. The phone is using a stock 4.2.2 SELinux kernel.
Code:
[SIZE=2]Device: Samsung Galaxy S4 Mini LTE (GT-I9195)
Board/Platform: MSM8930AB (Snapdragon 400)
Baseband: I9195XXUBML4
Kernel: 3.4.0-2340422
[email protected] #1
Build: JDQ39.I9195XXUBML4
SE: SEPF_GT-I9195_4.2.2_0022
ro.build.date: Sat Dec 21 01:46:00 KST 2013
ro.build.description: serranoltexx-user 4.2.2 JDQ39 I9195XXUBML4
[/SIZE]
I still have no idea of what's causing those error messages above, also because logcat is not telling us anything interesting either. Only as Warning from "System.err", but without any useful information. However, I have got some improvement in the terminal behavior when doing the initial ssh connection.
One problem seem to be that the TERM environment variable was copied from local machine (PC side) to remote server (Android phone), thus giving TERM=cygwin to the Android shell. This can be disabled or changed as follows.
Some relevant SSH options:
Code:
[SIZE=2]
-e escape_char
Sets the escape character for sessions with a pty (default: `~'). The escape
character is only recognized at the beginning of a line. The escape charac-
ter followed by a dot (`.') closes the connection; followed by control-Z sus-
pends the connection; and followed by itself sends the escape character once.
Setting the character to "none" disables any escapes and makes the session
fully transparent.
-T Disable pseudo-tty allocation.
-t Force pseudo-tty allocation. This can be used to execute arbitrary screen-
based programs on a remote machine, which can be very useful, e.g. when
implementing menu services. Multiple -t options force tty allocation, even
if ssh has no local tty.
[/SIZE]
Some relevant SSH -o options:
Code:
[SIZE=2][B]RequestTTY[/B]
Specifies whether to request a pseudo-tty for the session. The argument may
be one of: "no" (never request a TTY), "yes" (always request a TTY when stan-
dard input is a TTY), "force" (always request a TTY) or "auto" (request a TTY
when opening a login session). This option mirrors the -t and -T flags for
ssh(1).
[B]
SendEnv[/B]
Specifies what variables from the local environ(7) should be sent to the
server. Note that environment passing is only supported for protocol 2. The
server must also support it, and the server must be configured to accept
these environment variables. Refer to AcceptEnv in sshd_config(5) for how to
configure the server. Variables are specified by name, which may contain
wildcard characters. Multiple environment variables may be separated by
whitespace or spread across multiple SendEnv directives. The default is not
to send any environment variables.
[/SIZE]
So by using the ssh -T option (which is equivalent to using '-o RequestTTY="no"'), we are disabling "pseudo-tty allocation" which doesn't work anyway, but with the effect of not forwarding local TERM to server, and thus setting it to default "vt100" which accepts backspace (but not insert). But a better way is to actually set the TERM variable on our own. This is done by simply adding it as a prefix to the ssh command like this:
Code:
[SIZE=2]TERM=[B]vt220[/B] ssh -t [email protected] -p 50555[/SIZE]
(This effectively, but temporarily overrides the local TERM value and forwards it to remote server shell.)
RanTime!
Since Google intruduced the SELinux/SEAndroid features, they have essentially fukced up the entire AOS ecosystem as based on good-old normal Linux environments and all the years of standards therein. Basically nothing works as before and as logically intended or preferred and I bet from now on, developers will have to spend a significant and expensive time, on just trying to setup their various developer environments and jump through the hoops of dikchead Google engineers, rather than on actual developing. A very sad story all thanks to the populist "security" eye-candy marketing.
The SU time!
Apparently after having read about the various quirks and issues in using an SELinux Enforced based AOS {4}, it seem that the issue from OP is probably due to one of 3 things or a combination thereof.
My su binary (SuperSU 1.94) is not yet handling SElinux properly
The SSHd server is not handling SELinux properly
Lack of properly set SSH and SHELL environment files on the server side
As for (1) I just have to wait and see. For (2) we can only test with other SSHd servers/solutions which I don't know what to use. (They're all, either not free or full of ads. WTF!) And finally, for (3) we can only test, since I don't have the source code...
Unfortunately listing the SuperSU (1.94) command line options is not very helpful, since they're rather poorly explained. While some of the option themselves just doesn't work (for me). It would have been great if @Chainfire could write a more detailed how-to {2} for all these options, but then again we should be extremely grateful he's written anything at all.
Code:
[SIZE=2]Usage: su [options] [--] [-] [LOGIN] [--] [args...]
------------------------------------------------------------------------------------
Options:
-c, --command COMMAND pass COMMAND to the invoked shell
-cn, --context CONTEXT switch to SELinux CONTEXT before invoking
-h, --help display this help message and exit
-, -l, --login pretend the shell to be a login shell
-m, -p,
-mm, --mount-master connect to a shell that can manipulate the
master mount namespace - requires su to be
running as daemon, must be first parameter
--preserve-environment do not change environment variables
-s, --shell SHELL use SHELL instead of the default detected shell
-v, --version display public version and exit
-V display internal version and exit
Usage#2: su LOGIN COMMAND...
Usage#3: su {-d|--daemon|-ad|--auto-daemon|-r|--reload}
auto version starts daemon only on SDK >= 18 or
if SELinux is set to enforcing
Usage#4: su {-i|--install|-u|--uninstall}
perform post-install / pre-uninstall maintenance
[/SIZE]
References:
[1] [Chainfire G+] Next Android version: even more breakage
[2] [Chainfire] How-To SU (Guidelines for problem-free su usage)
[3] SuperSU Download
[4] [Google] Validating Security-Enhanced Linux in Android
From THIS very old post by @mirabilos , it is possible that command-line TAB-completion and up-arrow is not working on all mksh binaries. So perhaps we just need a new static mksh binary installed?
Tab expansion is pretty broken on BSD with xterm and GNU screen, but the same seems to work better on ssh’ing out to Linux, I wonder why, since all software involved is the same… except tput though. But it works like that and is usable. With post-R40 mksh, you can get about with even less hacks (more similarity to AT&T ksh).
Click to expand...
Click to collapse
However, this still doesn't explain why I have no controlling tty for ssh sessions.
Also I tested a new and different SSH server called SSHelper, which has more features and is better maintained, without ads, but is also 6 times larger at ~ 6MB, because of included OpenSSH, FTP and webserver log functionality. When logging in via ssh I get:
Code:
...
Server refused to allocate pty
Followed by an empty non-responsive connection.
Is this the same as […]this problem elsewhere? Man, I'm searching for ideas and keep coming back to your questions all over the 'net
To clarify, I talked to someone at Google; they renamed mksh into just sh lately, but this should have no adverse effect. They currently ship R48 and “would have updated it if I knew there was a new version”. That being said, the code of the shell itself is not at fault here.
The “no controlling tty” message here is a red herring: you do not have access to a tty at all, let alone a ctty
As I said elsewhere, use “ssh -t” and either change the SELinux policies to allow pty/tty pair allocation, or disable it (possibly set it into permissive mode).
@mirabilos: Yes, thanks for that info. I haven't updated this thread since I started it, in anticipation of a writeup about SELinux. However, that proves to be a little over my head, so it will take some time. What is clear though, is that the above problem is connected with the SEAndroid protection mechanisms, which in turn have been mangled and incorporated into Samsungs KNOX.
Also I have been busy making the SSHelper support thread:
[APP][INFO|SUPPORT] SSHelper (The free Android SSH Server Application)
There I have also added a small section about mksh.
@ E:V:A - I recently put together a little package containing all necessary bins/scripts to create a SSH server (via dropbear and dropbearkey) (properly secured, not public) and connect with a SSH client (ssh). The package also contains bins/scripts to create a Telnet server (via utelnetd) and connect with Telnet client (via "static busybox" telnet). Everything works with superuser that I've tested. Linked in my signature and attached to post as well.
Instructions (for anyone who sees this and would like a guide)::
Basically just extract it anywhere with:
Code:
tar -xf easy.ssh.and.telnetz.clients+servers.tar.gz
(if it's in /sdcard/Download which is probable, do "cd /sdcard/Download" then run the above)
Change directory inside the folder:
Code:
cd ./ssh.telnetz
There are 6 scripts: ssh.start(connect to ssh server via ssh), sshd.start(create ssh server), ssh.kill(kill ssh processes and remove ssh server keys), and... 3x telnet scripts for the telnet equivalents.
Running scripts and optional parameters:
Code:
./telnetd.start [ shell ]
e.g. TELNET_PORT=8080 ./telnetd.start /system/bin/mksh
./telnet.start [ ip port ]
e.g. ./telnet.start 192.168.0.3 8080
./sshd.start [ <dropbear_flags_and_options ]
e.g. ./sshd.start (default port is 8090)
./ssh.start [ ip port shell ]
e.g. ./ssh.start 192.168.0.3 8090 /system/bin/mksh
Default ip is the loopback 127.0.0.1 so you can test running a server and connecting to it on your phone at the same time. Just change params as described above to connect from/to your phone (phone is client/server).
***As far as I have tested on Android 4.4.4, this works perfectly as root or restricted user. You can get a su'd ssh shell by starting the sshd.start with /system/xbin/su or just entering su after you've connected as a restricted user.***
I've finally found a work-around for the crippled /dev/pts job-control and su combination. There are two small problems that combines to this issue.
1. The SELinux policy is screwed up by Samsung. And others?
2. The /dev/pts is mounted wrong by default.
The work-around:
Make sure you're device is already in Enforcing mode, so that you get the proper su prompt (#).
1. Open terminal session 1.
Code:
[SIZE=2]
## On Terminal 1
ssh -2 [email protected] -p 2222
$ su -c /system/bin/sh -i
# su 0 setenforce 0
# umount /dev/pts
# su -cn u:r:init:s0 -c "busybox mount -t devpts -o rw,seclabel,relatime,mode=620,gid=5 devpts /dev/pts"[/SIZE]
2. Now go to Terminal 2 and login:
Code:
[SIZE=2]## On terminal 2
ssh -2 [email protected] -p 2222
$
[/SIZE]
(You now have job-control but no su possibility.)
3. Now go back to Terminal 1 and enable Enforcing mode:
Code:
[SIZE=2]## On Terminal 1
# su 0 setenforce 1
[/SIZE]
4. Now go back to Terminal 2 and escalate to su:
Code:
[SIZE=2]## On terminal 2
$ su -c /system/bin/sh -i
# [/SIZE]
Unfortunately if you exit the su (#) shell, you'll have to repeat steps 2-4 of the procedure.

Hacking android, got "system" user, but not root, how to escalate privilege?

Hacking android, got "system" user, but not root, how to escalate privilege?
Hello, i am new to XDA. I am trying to jail-break my android device:
Android 5.1.1, Linux 3.10.49
This device is a rare brand and have no any unlock & flash mechanism.
Currently i have successfully got "system" user (UID 1000) by using a preinstalled DEBUGGABLE system app.
This user can only change /data directory etc, it can not change any file owned by root.
So any help to escalate "system" user to root user will be very appreciate.
the result of command "id":
Code:
uid=1000(system)
gid=1000(system)
groups=1000(system)
1007(log)
1010(wifi)
1015(sdcard_rw)
1021(gps)
1023(media_rw)
1028(sdcard_r)
3001(net_bt_admin)
3002(net_bt)
3003(inet)
3004(net_raw)
3005(net_admin)
3006(net_bw_stats)
3009(qcom_diag)
9997(everybody)
41000(u0_a31000)
context=u:r:system_app:s0
This account can change /data/system/packages.xml etc, but can not change /system/*, nor chown/mount.....
It's CapBound is 0, too strict. And also can not disable SELinux.
Can anyone help me?
----------------------- PS: share how i get system user privilege, maybe helpful to others -----------------------
In a word, just use jdb to attache to the app then print new java.lang.Runtime().exec("sh /sdcard/my.sh").
First, i found a package appeared in Android Device Monitor's debuggable app list, e.x. com.example.app.
Then i use
Code:
pm dump com.example.app
got confirmed it use system UID, then
Code:
run-as com.example.app
but failed due to "Package not found", i don't know why.
Then i try to use JDWP way.
Get the debuggable process ID:
Code:
$ adb jdwp
9424
$ adb forward tcp:8600 jdwp:9424
$ jdb -attach localhost:8600
> threads
group system:
(java.lang.Thread)0x2a86 Signal Catcher ...
(java.lang.Thread)0x2a87 FinalizerWatchdogDaemon ...
...
group main:
(java.lang.Thread)0x2a8d main ...
(java.lang.Thread)0x2a8e Binder_1 ...
...
> thread 0x2a8d
main[1] stepi
>
stepi completed: "thread=main", android.os.MessageQueue.next()、row=145 bci=22
main[1] > print new java.lang.Runtime().exec("sh /sdcard/qj.sh")
There are some files need be upload(adb push .... ) before run the last command.
/sdcard/qj.sh:
Code:
date > /sdcard/log
cp -f /sdcard/busybox /data/ 2>> /sdcard/log || exit 1
chmod 4777 /data/busybox 2>> /sdcard/log || exit 1
(while true; do /data/busybox nc -l -p 7777 -e sh; done) >> /sdcard/log 2>&1 &
echo server OK >> /sdcard/log
/sdcard/busybox:
this file can be found at busybox.net/downloads/binaries/latest, choose ARM7v.
The above jdb command "print new java.lang.Runtime().exec("sh /sdcard/qj.sh")" will create a shell server listening at 7777 port, bridge input/output to sh.
So, to connect to the shell server,
Code:
adb forward tcp:7777 tcp:7777
nc localhost 7777
then in this connection, input shell command.
Sorry: i forgot a very important step: to run the "print new ...." statement, i have to turn on screen, even touch the app so can be trapped into jdb.
---------That's all------------

Categories

Resources