]> Joshua Wise's Git repositories - dumload.git/blob - src/com/joshuawise/dumload/Uploader.java
Implement the mechanics of scp.
[dumload.git] / src / com / joshuawise / dumload / Uploader.java
1 package com.joshuawise.dumload;
2
3 import java.io.InputStream;
4 import java.io.OutputStream;
5
6 import com.jcraft.jsch.*;
7 import java.lang.Boolean;
8
9 import android.app.Activity;
10 import android.app.Service;
11 import android.content.Intent;
12 import android.app.PendingIntent;
13 import android.content.Context;
14 import android.net.Uri;
15 import android.os.Bundle;
16 import android.os.IBinder;
17 import android.widget.TextView;
18 import android.widget.Toast;
19 import android.util.Log;
20 import android.app.NotificationManager;
21 import android.app.Notification;
22 import android.os.Handler;
23 import android.os.Messenger;
24 import android.os.Looper;
25 import android.os.Message;
26 import android.os.SystemClock;
27
28 public class Uploader extends Service implements Runnable, UserInfo, UIKeyboardInteractive {
29         private Uri uri;
30         private String homedir;
31         private Thread me;
32         private static final int HELPME_ID = 1;
33         
34         private InputStream is;
35         
36         public Object _theObject;
37
38         private Object /* pick one type, and fixate on it */ dance(final String type, final String text)        /* for inside the thread */
39         {
40                 final Uploader thisupl = this;
41                 final Message msg = Message.obtain();
42                 
43                 /* t(*A*t) */
44                 Thread t = new Thread() {
45                         public void run() {
46                                 Looper.prepare();
47                                 int bogon = (int)SystemClock.elapsedRealtime();
48                                 
49                                 NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
50                                 Notification notification = new Notification(R.drawable.icon, "Dumload prompt", System.currentTimeMillis());
51                                 
52                                 Handler h = new Handler() {
53                                         public void handleMessage(Message M) {
54                                                 msg.copyFrom(M);
55                                                 Looper.myLooper().quit();
56                                         }
57                                 };
58                                 Messenger m = new Messenger(h);
59                                 
60                                 Intent intent = new Intent(thisupl, NotifSlave.class);
61                                         
62                                 intent.setAction("com.joshuawise.dumload.NotifSlave");
63                                 intent.putExtra("com.joshuawise.dumload.returnmessenger", m);
64                                 intent.putExtra("com.joshuawise.dumload.reqtype", type);
65                                 intent.putExtra("com.joshuawise.dumload.prompt", text);
66                                 intent.setData((Uri.parse("suckit://"+SystemClock.elapsedRealtime())));
67                                 
68                                 PendingIntent contentIntent = PendingIntent.getActivity(thisupl, 0, intent, 0);
69                                 notification.defaults |= Notification.DEFAULT_VIBRATE;
70                                 notification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
71                                 notification.setLatestEventInfo(getApplicationContext(), "I've been had!", "Dumload needs your input.", contentIntent);
72                                 
73                                 Log.e("Dumload.Uploader[thread]", "Notifying...");
74                                 
75                                 mNotificationManager.notify(bogon, notification);
76                                 
77                                 Log.e("Dumload.Uploader[thread]", "About to go to 'sleep'...");
78                                 Looper.loop();
79                                 Log.e("Dumload.Uploader[thread]", "And we're alive!");
80                                         
81                                 Log.e("Dumload.Uploader[thread]", "result was: "+(Integer.toString(msg.arg1)));
82                                 
83                                 mNotificationManager.cancel(bogon);
84                         }
85                 };
86                 
87                 t.start();
88                 try {
89                         t.join();
90                 } catch (Exception e) {
91                         return null;
92                 }
93                 
94                 if (type.equals("yesno"))
95                         return new Boolean(msg.arg1 == 1);
96                 else if (type.equals("message"))
97                         return null;
98                 else if (type.equals("password")) {
99                         if (msg.arg1 == 0)
100                                 return null;
101                         Bundle b = msg.getData();
102                         return b.getString("response");
103                 } else
104                         return null;
105         }
106         
107         /* UserInfo bits */
108         String _password = null;
109         public String getPassword()
110         {
111                 return _password;
112         }
113         public boolean promptPassword(String message)
114         {
115                 _password = (String)dance("password", message); 
116                 return (_password != null);
117         }
118         
119         String _passphrase = null;
120         public String getPassphrase()
121         {
122                 return _passphrase;
123         }
124         public boolean promptPassphrase(String message)
125         {
126                 _passphrase = (String)dance("password", message); 
127                 return (_passphrase != null);
128         }
129         
130         public boolean promptYesNo(String str)
131         {
132                 return ((Boolean)dance("yesno", str)).booleanValue();
133         }
134         
135         public void showMessage(String str)
136         {
137                 dance("message", str);
138         }
139         
140         public String[] promptKeyboardInteractive(String dest, String name, String instr, String[] prompt, boolean[] echo)
141         {
142                 int i;
143                 String [] responses = new String[prompt.length];
144                 
145                 Log.e("Dumload.Uploader", "dest: "+dest);
146                 Log.e("Dumload.Uploader", "name: "+name);
147                 Log.e("Dumload.Uploader", "instr: "+instr);
148                 for (i = 0; i < prompt.length; i++)
149                 {
150                         responses[i] = (String) dance("password", "[" + dest + "]\n" + prompt[i]);
151                 }
152                 return responses;
153         }
154         
155         private void expect_ack(InputStream in) throws Exception, java.io.IOException
156         {
157                 int b = in.read();
158                 
159                 if (b == -1)
160                 {
161                         throw new Exception("unexpected EOF from remote end");
162                 }
163                 
164                 if (b == 1 /* error */ || b == 2 /* fatal error */)
165                 {
166                         StringBuffer sb = new StringBuffer();
167                         int c = 0;
168                         
169                         while ((c = in.read()) != '\n')
170                                 sb.append((char)c);
171                         
172                         throw new Exception("error from remote end: " + sb.toString());
173                 }
174         }
175         
176         @Override
177         public void run()
178         {
179                 Looper.prepare();
180                 
181                 Log.e("Dumload.Uploader[thread]", "This brought to you from the new thread.");
182                 
183                 try {
184                         say("Uploading "+(Integer.toString(is.available()))+" bytes");
185                 
186                         JSch jsch = new JSch();
187                         jsch.setKnownHosts(homedir + "/known_hosts");
188                         Session s = jsch.getSession("joshua", "nyus.joshuawise.com", 22);
189                         s.setUserInfo(this);
190                         s.connect();
191                         
192                         Channel channel = s.openChannel("exec");
193                         ((ChannelExec)channel).setCommand("scp -t /tmp/lol");
194                         channel.connect();
195                         
196                         OutputStream scp_out = channel.getOutputStream();
197                         InputStream scp_in = channel.getInputStream();
198                         
199                         /* Okay, BS out of the way.  Now go send the file. */
200                         expect_ack(scp_in);
201                         
202                         scp_out.write(("C0644 " + (Integer.toString(is.available())) + " lol\n").getBytes());
203                         scp_out.flush();
204                         
205                         expect_ack(scp_in);
206                         
207                         int len;
208                         byte[] buf = new byte[4096];
209                         while ((len = is.read(buf, 0, buf.length)) > 0)
210                                 scp_out.write(buf, 0, len);
211                         
212                         is.close();
213                         
214                         scp_out.write("\0".getBytes());
215                         scp_out.flush();
216                         
217                         expect_ack(scp_in);
218                         
219                         dance("message", "done");
220
221                         channel.disconnect();
222                         s.disconnect();
223                 } catch (Exception e) {
224                         Log.e("Dumload.uploader[thread]", "JSchException: "+(e.toString()));
225                 }
226                 
227                 Log.e("Dumload.uploader[thread]", "And now I'm back to life!");
228         }
229         
230         private void say(String s) {
231                 Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
232         }
233         
234         @Override
235         public void onStart(Intent i, int startId)
236         {
237                 uri = i.getData();
238                 homedir = getApplicationContext().getFilesDir().getAbsolutePath();
239                 int shits = 0;
240                 
241                 super.onStart(i, startId);
242                 
243                 Log.e("Dumload.Uploader", "Started.");
244                 Log.e("Dumload.Uploader", "My path is "+homedir);
245                 
246                 try {
247                         is = getContentResolver().openInputStream(uri);
248                 } catch (Exception e) {
249                         say("Failed to open input file.");
250                         return;
251                 }
252                 
253                 
254                 me = new Thread(this, "Uploader thread");
255                 me.start();
256         }
257         
258         @Override
259         public IBinder onBind(Intent i) {
260                 Log.e("Dumload.Uploader", "bound");
261                 
262                 return null;
263         }
264 }
This page took 0.038029 seconds and 4 git commands to generate.