Monday, July 2, 2018

Mounting an iPhone to Linux Mint as an external drive to copy images and videos

 

Phone: iPhone SE
Operating System: Linux Mint 18.1(should work in Ubuntu as well)

It is done by compiling most of the sources yourself.
Only one library - usbmuxd - must be installed as root
All others are installed in the home account.

Install necessary software for building the source packages.

To check-out and compile the needed packages from source, you have to install git first.

Open a terminal and do the following:

:~$ sudo apt-get install -y git
:~$ sudo apt-get install -y build-essential
:~$ sudo apt-get install -y libtool m4 automake
:~$ sudo apt-get install -y libfuse-dev

All new commands to mount and unmount the file-system of your iPhone, will be installed in the sub-directory "${HOME}/usr/bin/".

Create the sub-directory to store the source files of the packages to be compiled:

:~$ mkdir -p "$HOME/usr/src"

Set all required environment variables to ensure to build the packages from source as desired:

 
:~$ export PKG_CONFIG_PATH="${HOME}/usr/lib/pkgconfig:${PKG_CONFIG_PATH}"
:~$ export CPATH="${HOME}/usr/include:${CPATH}"
:~$ export MANPATH="${HOME}/usr/share/man:${MANPATH}"
:~$ export PATH="${HOME}/usr/bin:${PATH}"
:~$ export LD_LIBRARY_PATH="${HOME}/usr/lib:${LD_LIBRARY_PATH}"

Now put the last two export statements into your .bashrc, to be loaded every time you open a new terminal, otherwise you must type:

:~$ export PATH="${HOME}/usr/bin:${PATH}"
:~$ export LD_LIBRARY_PATH="${HOME}/usr/lib:${LD_LIBRARY_PATH}"

whenever you open a new terminal.

Clone all needed repositories from Github.

:~$ cd ~/usr/src
:~$ for x in libplist libusbmuxd usbmuxd libimobiledevice ifuse; do git clone https://github.com/libimobiledevice/${x}.git;done


Build and install the packages in the following order.

Build libplist
:~$ cd ~/usr/src/libplist
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && make install

Build libusbmuxd
:~$ cd ~/usr/src/libusbmuxd
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && make install

Build libimobiledevice
:~$ cd ~/usr/src/libimobiledevice
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && make install

Build usbmuxd
(The package usbmuxd must be installed with administrative rights, because it needs write access to "/lib/udev/rules.d" and "/lib/systemd/system")
:~$ cd ~/usr/src/usbmuxd
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && sudo make install

Build ifuse
:~$ cd ~/usr/src/ifuse
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && make install


TESTING

It's assumed that you put the two exports into your ~/.bashrc as mentioned above.
Open a new terminal.

Connect your iPhone

Create a mount point, where you want the content of your iPhone to appear.

:~$ mkdir -p ~/usr/mnt


Connect your iPhone to the computer and try to pair the iPhone with your computer.

:~$ idevicepair pair


If error occurs during validation, please enter the passcode on the device and retry. A trust dialog will be appeared on your device. You have to accept it as well

:~$ idevicepair pair


After successfully pairing the device, mount the file-system of your iPhone and check the content

:~$ ifuse ~/usr/mnt/
:~$ ls ~/usr/mnt/


To safely disconnect your iPhone, you have to unmount the file-system in ~/usr/mnt first with fusermount.

:~$ fusermount -u ~/usr/mnt


Now, you can plug-off your iPhone again.


ERRORS AND SOLUTIONS

(1) configure: error:
OpenSSL support explicitly requested but OpenSSL could not be found

:~$ sudo apt-get install libssl-dev

(2) configure: error:
Could not link test program to Python. Maybe the main Python library has been installed in some non-standard library path. If so, pass it to configure, via the LDFLAGS environment variable.
Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
(You probably have to install the development version of the Python package for your distribution.  The exact name of this package varies among them.)

:~$ sudo apt-get install python-dev


Tuesday, January 30, 2018

Completion Award for Oracle MOOC: SQL Fundamentals (2018)

Monday, August 22, 2016

RESTful Web Services in Java

Read about REST here...
In the example program REST is implemented using Jersey Framework.
Download Jersey framework from here...
I used Dynamic Web Project in Eclipse for coding. Extract jersey zip file and copy all the .jar files from api, ext, lib folders to WebContent/WEB-INF/lib folder.

Employee.java
 
package in.theinsanetechie.rest;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "employee")
public class Employee implements Serializable {

 private static final long serialVersionUID = 1L;
 private int empcode;
 private String name;
 private String designation;
 private float basicpay;
 
 public Employee() {  
 }
 
 public Employee(int empcode, String name, String designation, float basicpay) {
  super();
  this.empcode = empcode;
  this.name = name;
  this.designation = designation;
  this.basicpay = basicpay;
 }

 public int getEmpcode() {
  return empcode;
 }
 
 @XmlElement
 public void setEmpcode(int empcode) {
  this.empcode = empcode;
 }
 
 public String getName() {
  return name;
 }
 
 @XmlElement
 public void setName(String name) {
  this.name = name;
 }
 
 public String getDesignation() {
  return designation;
 }
 
 @XmlElement
 public void setDesignation(String designation) {
  this.designation = designation;
 }
 
 public float getBasicpay() {
  return basicpay;
 }
 
 @XmlElement
 public void setBasicpay(float basicpay) {
  this.basicpay = basicpay;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Employee other = (Employee) obj;
  if (Float.floatToIntBits(basicpay) != Float
    .floatToIntBits(other.basicpay))
   return false;
  if (designation == null) {
   if (other.designation != null)
    return false;
  } else if (!designation.equals(other.designation))
   return false;
  if (empcode != other.empcode)
   return false;
  if (name == null) {
   if (other.name != null)
    return false;
  } else if (!name.equals(other.name))
   return false;
  return true;
 }

}


EmployeeAccessObject.java
 
package in.theinsanetechie.rest;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class EmployeeAccessObject {

 private String fileName = "Employee.dat";
 
 @SuppressWarnings("unchecked")
 public List getFullList() {
  List list = null;
  File file = new File(fileName);
  try {
   if (file.exists()) {
    FileInputStream fileInputStream = new FileInputStream(file);
    ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
    list = (List) objectInputStream.readObject();
    objectInputStream.close();
   } else{
    Employee employee = new Employee(1001, "The Insane Techie", "Dev", 99999.99f);
    list = new ArrayList();
    list.add(employee);
    saveList(list);
   }
   
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }
  
  return list;
 }
 
 public Employee get(int empcode) {
  List list = getFullList();
  
  for (Employee temp : list) {
   if (temp.getEmpcode() == empcode) {
    return temp;
   }
  }
  
  return null;
 }
 
 public boolean addToList(Employee emp){
  List list = getFullList();
  boolean exists = false;
  for(Employee temp: list){
   if(temp.getEmpcode() == emp.getEmpcode()){
    exists = true;
    break;
   }
  }  
  if(!exists){
   list.add(emp);
   saveList(list);
   return true;
  }
  return false;
 }
 
 public boolean updateList(Employee emp){
  List list = getFullList();
  for(Employee temp: list){
   if(temp.getEmpcode() == emp.getEmpcode()){
    int index = list.indexOf(temp);   
    list.set(index, emp);
    saveList(list);
    return true;
   }
  }  
  return false;
 }

 public boolean deleteFromList(int empcode){
  List list = getFullList();

  for(Employee temp: list){
   if(temp.getEmpcode() == empcode){
    int index = list.indexOf(temp);   
    list.remove(index);
    saveList(list);
    return true;   
   }
  }  
  return false;
 }
 
 private void saveList(List list) {
  
  File file = new File(fileName);
  try {
   FileOutputStream fileOutputStream = new FileOutputStream(file);
   ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
   objectOutputStream.writeObject(list);
   objectOutputStream.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  
 }
}


EmployeeService.java
 
package in.theinsanetechie.rest;

import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

@Path("/EmployeeService")
public class EmployeeService {

 EmployeeAccessObject accessObject = new EmployeeAccessObject();
 private static final String SUCCESS = "success";
 private static final String FAILURE = "failure";


 @GET
 @Path("/employees")
 @Produces(MediaType.APPLICATION_XML)
 public List getFullList(){
  return accessObject.getFullList();
 }

 @GET
 @Path("/employees/{empcode}")
 @Produces(MediaType.APPLICATION_XML)
 public Employee get(@PathParam("empcode") int empcode){
  return accessObject.get(empcode);
 }

 @PUT
 @Path("/employees")
 @Produces(MediaType.APPLICATION_XML)
 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
 public String add(@FormParam("empcode") int empcode,
   @FormParam("name") String name,
   @FormParam("designation") String designation,
   @FormParam("basicpay") float basicpay,
   @Context HttpServletResponse servletResponse) throws IOException{
  Employee emp = new Employee(empcode, name, designation, basicpay);
  boolean result = accessObject.addToList(emp);
  if(result == true){
   return SUCCESS;
  }
  return FAILURE;
 }

 @POST
 @Path("/employees")
 @Produces(MediaType.APPLICATION_XML)
 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
 public String update(@FormParam("empcode") int empcode,
   @FormParam("name") String name,
   @FormParam("designation") String designation,
   @FormParam("basicpay") float basicpay,
   @Context HttpServletResponse servletResponse) throws IOException{
  Employee emp = new Employee(empcode, name, designation, basicpay);
  boolean result = accessObject.updateList(emp);
  if(result == true){
   return SUCCESS;
  }
  return FAILURE;
 }

 @DELETE
 @Path("/employees/{empcode}")
 @Produces(MediaType.APPLICATION_XML)
 public String deleteUser(@PathParam("empcode") int empcode){
  boolean result = accessObject.deleteFromList(empcode);
  if(result == true){
   return SUCCESS;
  }
  return FAILURE;
 }

 @OPTIONS
 @Path("/employees")
 @Produces(MediaType.APPLICATION_XML)
 public String getSupportedOperations(){
  return "GET, PUT, POST, DELETE";
 }
}


WebServiceTester.java
 
package in.theinsanetechie.rest;

import java.util.List;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;

public class WebServiceTester  {

 private Client client;
 private String REST_SERVICE_URL = "http://localhost:8080/EmployeeManagement/rest/EmployeeService/employees";
 private static final String SUCCESS="success";
 private static final String PASS = "pass";
 private static final String FAIL = "fail";

 private void init(){
  this.client = ClientBuilder.newClient();
 }

 public static void main(String[] args){
  
  WebServiceTester tester = new WebServiceTester();  
  tester.init();
  tester.testGetFullList();
  tester.testGet();
  tester.testUpdate();
  tester.testAdd();
  tester.testDelete();
 }
 
 private void testGetFullList(){
  GenericType> list = new GenericType>() {};
  List employees = client
    .target(REST_SERVICE_URL)
    .request(MediaType.APPLICATION_XML)
    .get(list);
  String result = PASS;
  if(employees.isEmpty()){
   result = FAIL;
  }
  System.out.println("Test case name: testGetFullList, Result: " + result );
 }

 private void testGet(){
  Employee sampleEmp = new Employee();
  sampleEmp.setEmpcode(1001);

  Employee emp = client
    .target(REST_SERVICE_URL)
    .path("/{empcode}")
    .resolveTemplate("empcode", 1001)
    .request(MediaType.APPLICATION_XML)
    .get(Employee.class);
  String result = FAIL;
  if(sampleEmp != null && sampleEmp.getEmpcode() == emp.getEmpcode()){
   result = PASS;
  }
  System.out.println("Test case name: testGet, Result: " + result );
 }

 private void testUpdate(){
  Form form = new Form();
  form.param("empcode", "1001");
  form.param("name", "Dhanoop Bhaskar");
  form.param("designation", "Computer Scientist");
  form.param("basicpay", "100000.00f");

  String callResult = client
    .target(REST_SERVICE_URL)
    .request(MediaType.APPLICATION_XML)
    .post(Entity.entity(form,
      MediaType.APPLICATION_FORM_URLENCODED_TYPE),
      String.class);
  String result = PASS;
  if(!SUCCESS.equals(callResult)){
   result = FAIL;
  }

  System.out.println("Test case name: testUpdate, Result: " + result );
 }
 
 private void testAdd(){
  Form form = new Form();
  form.param("empcode", "1002");
  form.param("name", "The Insane Techie");
  form.param("designation", "Computer Scientist");
  form.param("basicpay", "100000.00f");

  String callResult = client
    .target(REST_SERVICE_URL)
    .request(MediaType.APPLICATION_XML)
    .put(Entity.entity(form,
      MediaType.APPLICATION_FORM_URLENCODED_TYPE),
      String.class);

  String result = PASS;
  if(!SUCCESS.equals(callResult)){
   result = FAIL;
  }

  System.out.println("Test case name: testAdd, Result: " + result );
 }
 
 private void testDelete(){
  String callResult = client
    .target(REST_SERVICE_URL)
    .path("/{empcode}")
    .resolveTemplate("empcode", 1002)
    .request(MediaType.APPLICATION_XML)
    .delete(String.class);

  String result = PASS;
  if(!SUCCESS.equals(callResult)){
   result = FAIL;
  }

  System.out.println("Test case name: testDelete, Result: " + result );
 }
}


web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>Employee Management</display-name>
    <servlet>
        <servlet-name>Jersey RESTful Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>jersey.config.server.provider.packages</param-name>
                <param-value>in.theinsanetechie.rest</param-value>
            </init-param>
        </servlet>
    <servlet-mapping>
    <servlet-name>Jersey RESTful Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

Tuesday, June 14, 2016

The Insane Techie - Android App



Launched an android app for the blog on 07th June 2016.

Get it from google play store...

Tips for using the app
  • Use in landscape mode while viewing the code snippets.
  • For convenience, I have added major categories as separate feeds in the app (as an update on 08th June 2016).
  • Use Help section for updates about the app.
Thanks :)

Wednesday, March 9, 2016

Installing and Configuring phpMyAdmin in Ubuntu/Linux Mint


Install phpmyadmin
sudo apt-get install phpmyadmin

Configure phpmyadmin
sudo dpkg-reconfigure -plow phpmyadmin

Then select Apache 2 for the webserver you wish to configure.

Try hitting the URL http://localhost/phpmyadmin/

If this does not work, then you have to include the phpMyAdmin-shipped Apache configuration into Apache:

sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf.d/phpmyadmin.conf
sudo /etc/init.d/apache2 reload

Since Ubuntu 13.10 (Saucy Salamander), Apache no longer loads configuration files from the /etc/apache2/conf.d directory.
Instead, they are placed in the /etc/apache2/conf-available directory which is managed with the a2enconf command.
Therefore, if you need to manually include the phpMyAdmin-shipped Apache configuration file, you must run the following:

sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
sudo a2enconf phpmyadmin
sudo /etc/init.d/apache2 reload

Contact Form

Name

Email *

Message *

The Insane Techie - Android App

Launched an android app for the blog on 07th June 2016. Get it from google play store... Tips for using the app Use in landscape mo...