X-Git-Url: http://git.joshuawise.com/dumload.git/blobdiff_plain/0763e16da0e84b68e675fbf61342dd1e47755f47..2d9208e3a28b1aedc5e9063d96a3f6750633bd57:/src/com/joshuawise/dumload/Uploader.java?ds=inline diff --git a/src/com/joshuawise/dumload/Uploader.java b/src/com/joshuawise/dumload/Uploader.java index 489040b..e7725e9 100644 --- a/src/com/joshuawise/dumload/Uploader.java +++ b/src/com/joshuawise/dumload/Uploader.java @@ -1,37 +1,70 @@ package com.joshuawise.dumload; import java.io.InputStream; +import java.io.OutputStream; -import com.jcraft.jsch.*; -import java.lang.Boolean; - -import android.app.Activity; -import android.app.Service; -import android.content.Intent; +import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; +import android.app.Service; import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; -import android.os.IBinder; -import android.widget.TextView; -import android.widget.Toast; -import android.util.Log; -import android.app.NotificationManager; -import android.app.Notification; import android.os.Handler; -import android.os.Messenger; +import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Messenger; import android.os.SystemClock; +import android.preference.PreferenceManager; +import android.util.Log; +import android.widget.RemoteViews; +import android.widget.Toast; + +import com.jcraft.jsch.Channel; +import com.jcraft.jsch.ChannelExec; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Session; +import com.jcraft.jsch.UIKeyboardInteractive; +import com.jcraft.jsch.UserInfo; public class Uploader extends Service implements Runnable, UserInfo, UIKeyboardInteractive { private Uri uri; private String homedir; private Thread me; private static final int HELPME_ID = 1; + private RemoteViews remote; + private int thenotifid; + private Notification thenotif; + private String headline; + private String dest; + + private InputStream is; public Object _theObject; + private void sayNullNotification(final String scroller, final String headline, final String description) + { + int bogon = (int)SystemClock.elapsedRealtime(); + NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); + Notification notification = new Notification(R.drawable.icon, scroller, System.currentTimeMillis()); + + Intent intent = new Intent(this, NotifSlave.class); + + intent.setAction("com.joshuawise.dumload.NotifSlave"); + /* no extras to make the notifslave die */ + intent.setData((Uri.parse("suckit://"+SystemClock.elapsedRealtime()))); + + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0); + notification.defaults |= Notification.DEFAULT_VIBRATE; + notification.flags |= Notification.FLAG_AUTO_CANCEL; + notification.setLatestEventInfo(getApplicationContext(), headline, description, contentIntent); + + mNotificationManager.notify(bogon, notification); + } + private Object /* pick one type, and fixate on it */ dance(final String type, final String text) /* for inside the thread */ { final Uploader thisupl = this; @@ -64,7 +97,7 @@ public class Uploader extends Service implements Runnable, UserInfo, UIKeyboardI PendingIntent contentIntent = PendingIntent.getActivity(thisupl, 0, intent, 0); notification.defaults |= Notification.DEFAULT_VIBRATE; - notification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; + notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; notification.setLatestEventInfo(getApplicationContext(), "I've been had!", "Dumload needs your input.", contentIntent); Log.e("Dumload.Uploader[thread]", "Notifying..."); @@ -145,36 +178,191 @@ public class Uploader extends Service implements Runnable, UserInfo, UIKeyboardI for (i = 0; i < prompt.length; i++) { responses[i] = (String) dance("password", "[" + dest + "]\n" + prompt[i]); + if (responses[i] == null) + return null; } return responses; } - @Override + private void expect_ack(InputStream in) throws Exception, java.io.IOException + { + int b = in.read(); + + if (b == -1) + { + throw new Exception("unexpected EOF from remote end"); + } + + if (b == 1 /* error */ || b == 2 /* fatal error */) + { + StringBuffer sb = new StringBuffer(); + int c = 0; + + while ((c = in.read()) != '\n') + sb.append((char)c); + + throw new Exception("error from remote end: " + sb.toString()); + } + } + + private void set_up_notif(final String _headline) + { + NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); + thenotif = new Notification(R.drawable.icon, headline, System.currentTimeMillis()); + thenotifid = (int)SystemClock.elapsedRealtime(); + + Intent intent = new Intent(this, NotifSlave.class); + + headline = _headline; + + intent.setAction("com.joshuawise.dumload.NotifSlave"); + /* no extras to make the notifslave die */ + intent.setData((Uri.parse("suckit://"+SystemClock.elapsedRealtime()))); + + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0); + thenotif.defaults |= 0; + thenotif.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; + + remote = new RemoteViews(getPackageName(), R.layout.textnotif); + remote.setImageViewResource(R.id.image, R.drawable.icon); + remote.setTextViewText(R.id.headline, headline); + remote.setTextViewText(R.id.status, "Beginning upload..."); + thenotif.contentView = remote; + thenotif.contentIntent = contentIntent; + + mNotificationManager.notify(thenotifid, thenotif); + } + + private void destroy_notif() + { + NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); + mNotificationManager.cancel(thenotifid); + } + + private void update_notif(String text) + { + NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); + + remote = new RemoteViews(getPackageName(), R.layout.textnotif); + remote.setImageViewResource(R.id.image, R.drawable.icon); + remote.setTextViewText(R.id.headline, headline); + remote.setTextViewText(R.id.status, text); + thenotif.contentView = remote; + + mNotificationManager.notify(thenotifid, thenotif); + } + + private void update_notif(int n, int total) + { + NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); + + remote = new RemoteViews(getPackageName(), R.layout.progressnotif); + remote.setImageViewResource(R.id.image, R.drawable.icon); + remote.setTextViewText(R.id.headline, headline); + remote.setProgressBar(R.id.status, total, n, false); + thenotif.contentView = remote; + + mNotificationManager.notify(thenotifid, thenotif); + } + public void run() { Looper.prepare(); Log.e("Dumload.Uploader[thread]", "This brought to you from the new thread."); + set_up_notif("Dumload upload: " + dest); + try { + say("Uploading "+(Integer.toString(is.available()))+" bytes"); + + update_notif("Connecting..."); + JSch jsch = new JSch(); jsch.setKnownHosts(homedir + "/known_hosts"); - Session s = jsch.getSession("joshua", "nyus.joshuawise.com", 22); + try { + jsch.addIdentity(homedir + "/id_dsa"); + } catch (java.lang.Exception e) { + } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + String server = prefs.getString("server", "").trim(); + String userName = prefs.getString("userName", "").trim(); + Integer port = prefs.getInt("serverPort", 22); + Log.d("dbg", userName + "@" + server + ":" + port); + Session s = jsch.getSession(userName, server, port); s.setUserInfo(this); s.connect(); Channel channel = s.openChannel("exec"); - ((ChannelExec)channel).setCommand("echo foo > /tmp/lol"); + ((ChannelExec)channel).setCommand("scp -t "+dest); channel.connect(); - dance("message", "done"); - + OutputStream scp_out = channel.getOutputStream(); + InputStream scp_in = channel.getInputStream(); + + update_notif("Starting send..."); + + /* Okay, BS out of the way. Now go send the file. */ + expect_ack(scp_in); + + String stfu; + if (dest.lastIndexOf("/") > 0) + stfu = dest.substring(dest.lastIndexOf("/") + 1); + else + stfu = dest; + + scp_out.write(("C0644 " + (Integer.toString(is.available())) + " "+stfu+"\n").getBytes()); + scp_out.flush(); + + expect_ack(scp_in); + + int total, nbytes; + total = is.available(); + nbytes = 0; + int len; + byte[] buf = new byte[4096]; + while ((len = is.read(buf, 0, buf.length)) > 0) + { + scp_out.write(buf, 0, len); + nbytes += len; + update_notif(nbytes, total); + } + + is.close(); + + update_notif("Finishing file transfer..."); + + scp_out.write("\0".getBytes()); + scp_out.flush(); + + expect_ack(scp_in); + channel.disconnect(); + + update_notif("Preparing to resize image..."); + + channel = s.openChannel("exec"); + ((ChannelExec)channel).setCommand("pscale "+dest); + channel.connect(); + + scp_in = channel.getInputStream(); + + update_notif("Resizing image..."); + while ((len = scp_in.read(buf, 0, buf.length)) > 0) + ; + + channel.disconnect(); + update_notif("Upload complete."); + + sayNullNotification("Dumload upload complete: " + dest, "Upload complete", "Uploaded: " + dest); + s.disconnect(); - } catch (JSchException e) { + } catch (Exception e) { Log.e("Dumload.uploader[thread]", "JSchException: "+(e.toString())); + sayNullNotification("Dumload upload failed", "Upload failed", e.toString()); } + destroy_notif(); Log.e("Dumload.uploader[thread]", "And now I'm back to life!"); } @@ -187,8 +375,10 @@ public class Uploader extends Service implements Runnable, UserInfo, UIKeyboardI public void onStart(Intent i, int startId) { uri = i.getData(); + dest = i.getStringExtra("com.joshuawise.dumload.dest"); homedir = getApplicationContext().getFilesDir().getAbsolutePath(); int shits = 0; + int giggles = 1; super.onStart(i, startId); @@ -196,12 +386,12 @@ public class Uploader extends Service implements Runnable, UserInfo, UIKeyboardI Log.e("Dumload.Uploader", "My path is "+homedir); try { - InputStream is = getContentResolver().openInputStream(uri); - shits = is.available(); + is = getContentResolver().openInputStream(uri); } catch (Exception e) { + say("Failed to open input file."); + return; } - say("Your shit was "+(Integer.toString(shits))+" bytes long"); me = new Thread(this, "Uploader thread"); me.start();