10

I have code

system("reboot") 

The reboot command works in the terminal, but even if I run the app as root, the operation is still denied. Has anyone found any way that works, or can explain a bit about SBSetting's reboot, which makes me curious?

Nate
  • 31,017
  • 13
  • 83
  • 207
philions
  • 186
  • 1
  • 1
  • 10

5 Answers5

26

I have finally found a way to programmatically restart an iOS device without rooting a device!!!! The command line tool to restart an iOS device is called libimobiledevice:

http://krypted.com/mac-os-x/use-libimobiledevice-to-view-ios-logs/

It is truly amazing. One snag I ran into while installing was trying to install this line:

brew install -v --devel --fresh automake autoconf libtool wget libimobiledevice

However I got around the install problem by running this line:

brew install -v --fresh automake autoconf libtool wget libimobiledevice

After that problem, I followed the rest of the instructions and voila!

Most of the commands can be found on this page: http://krypted.com/uncategorized/command-line-ios-device-management/

The magic command that restarts the iOS device is:

idevicediagnostics restart

What is truly amazing about this tool is not only restarting an iOS device but also outputting iOS device logs to mac's terminal app using the following command:

idevicesyslog
Cœur
  • 37,241
  • 25
  • 195
  • 267
Ray
  • 501
  • 4
  • 9
9

I figured out a way to do it, although it's a bit convoluted. The problem is that even if you setup your app to run as root, when you make system() calls, you're apparently still limited to user mobile privileges. Since mobile cannot call reboot (successfully), this doesn't work.

The way I got around this problem is to take advantage of a new feature that SBSettings supports. SBSettings has a privileged daemon process that runs. It allows you to plug in your own commands, by simply writing a script (or other executable) and dumping it in the appropriate directory (/var/mobile/Library/SBSettings/Commands). Once you then restart the sbsettingsd process, you can get it to run your script by posting a notification. If you name your script

com.mycompany.reboot

then from within your app, you can execute this code:

#import <notify.h>

notify_post("com.mycompany.reboot");

Then, you make com.mycompany.reboot a simple shell script like this:

#!/bin/sh
reboot

And make sure to chmod 755 on your com.mycompany.reboot script. The full details of this SBSettings command feature can be found here:

http://thebigboss.org/guides/sbsettings-toggle-spec (see Calling External Functions and Scripts ...)

Anyway, it does require your app to depend on SBSettings, but it's a free app, and most users would probably want to have it anyway. For now, it accomplishes the goal of rebooting (or anything else that requires root access) programmatically, via notify_post().

Nate
  • 31,017
  • 13
  • 83
  • 207
  • this is great! worked as soon as i chmod 755 the file but I am still curious as to how when you sudo "make package" for a tweak how to have that .deb install the script in the correct directory so I do not have to manually – FreeAppl3 Aug 11 '12 at 22:18
  • 1
    @FreeAppl3, you can see [this about building Debian packages](http://tldp.org/HOWTO/html_single/Debian-Binary-Package-Building-HOWTO/). Basically, you would just build your package, with a `./var/mobile/Library/SBSettings/Commands/com.mycompany.reboot` file and directory structure. Or, you could just place the com.mycompany.reboot script at the root of your app (with Info.plist, Default.png, etc.), and use the DEBIAN/postinst script to copy /Applications/MyAppName.app/com.mycompany.reboot to /var/mobile/Library/SBSettings/Commands. Either should work. – Nate Aug 11 '12 at 23:35
  • While SBSettings is not installed on iPhone, how can I run command with root privilege for a user app? – moligaloo Feb 28 '14 at 10:47
4

This answer might feel hacky to some but I have not found a better solution on how to restart an iOS device that has not been jailbroken so here goes my answer:

In order to restart a device from the command line I do some prep work:

  • Connect device to computer
  • Add iTunes shortcut to your dock
  • Select spotlight and search for an application called Automator [must have Xcode installed in order to launch Automator!]
  • When Automator launches, select the Application option
  • Select the record button to start recording following actions
  • Select the iTunes shortcut
  • Select your device from the Device options
  • Select the Restore Backup... button
  • Select the Restore button
  • Select the stop button on the Automator app to stop recording.
  • From the Automator application, select File from the top bar and Save your newly recorded app to a location of your choosing

At this point you have an app file that will execute the steps mentioned above. I tend to leave iTunes open as it will always have the iOS device hooked up and ready to be accessed. When iTunes is closed and relaunched, the device takes time to fully connect with iTunes and this tends to break the flow of the Automator app.

At this point I can go into a terminal, go to the location of the app file and run the following command [EXAMPLE]:

open automator.app (replace 'automator.app' with the name of your file)

If you are like me and your are running this command in jenkins, you will need to run the following commands:

  1. open [location]/[your_app_name.app]
  2. sleep 30

For some reason, the automator app needs the sleep time to complete all the recorded actions.

Also, I am sure you can also write an applescript to do all of this but I hate applescript and took the easy way out!

Ray
  • 501
  • 4
  • 9
  • 2
    It's the great irony of stackoverflow that some of the hardest won comments are by far the most valuable but yet 0 upvotee; while questions people could easily google the answer to have something like 300 upvotes. – Blaze Jan 23 '14 at 06:27
  • This does restart the device, however recent updates to iOS and iTunes make it so that the user has to click though instruction and setup up screens on the device. This makes it hard for true automation – stepheaw Jul 11 '18 at 18:11
2

did you try NSTask: Execute a terminal command from a Cocoa app

Community
  • 1
  • 1
Travis Worm
  • 166
  • 8
  • NSTask *task = [[NSTask alloc]init]; NSArray *arr = [[NSArray alloc]initWithObjects:@"reboot",nil]; [task setArguments:arr]; [task launch]; does it correct? I root app, but got "cannot execute binary file" message. – philions Jun 22 '11 at 01:25
  • change folder to /sbin/reboot – philions Jun 22 '11 at 02:31
  • @NoahWitherspoon, `NSTask` is available, but it's private. You just have to include the header in your project yourself (generated, or copied from somewhere else). I know the OP didn't specify that this was for a jailbroken phone at the time of your comment, but I leave my comment for others who might benefit from `NSTask`. – Nate Feb 12 '13 at 09:26
  • I try the solution of NSTask but I get this error "reboot: Operation not permitted" how can I fix that?plz – Dhekra Zaied Jan 26 '15 at 09:16
2

This is not possible if the app is running in its sandbox. on a jailbroken phone you might be able to execute the reboot shell command.

Cocoanetics
  • 8,171
  • 2
  • 30
  • 57
  • Then you need to find a way to switch to user root, because only this is allowed to perform the reboot shell command. But that's a different question. – Cocoanetics Jun 21 '11 at 07:57
  • Just having a jailbreak app run as root is not enough. system("/sbin/reboot") will yield the following error in the console log, even for an app running as root: Mon Jun 27 21:19:01 iPhone-3G UIKitApplication:com.companyname.AppName[0xaf3d][438] : reboot: Operation not permitted – Nate Jun 28 '11 at 04:25
  • 1
    Nope. There is no 'shutdown' in iOS. There is /sbin/reboot, and that does what you'd expect from the command line. But, if you use the system call from inside an app (even running as root), you get "operation not permitted". – Nate Jun 28 '11 at 05:18