]> Joshua Wise's Git repositories - dumload.git/blame - src/com/joshuawise/dumload/Uploader.java
Implement the mechanics of scp.
[dumload.git] / src / com / joshuawise / dumload / Uploader.java
CommitLineData
0763e16d
JW
1package com.joshuawise.dumload;
2
3import java.io.InputStream;
035767ac 4import java.io.OutputStream;
0763e16d
JW
5
6import com.jcraft.jsch.*;
7import java.lang.Boolean;
8
9import android.app.Activity;
10import android.app.Service;
11import android.content.Intent;
12import android.app.PendingIntent;
13import android.content.Context;
14import android.net.Uri;
15import android.os.Bundle;
16import android.os.IBinder;
17import android.widget.TextView;
18import android.widget.Toast;
19import android.util.Log;
20import android.app.NotificationManager;
21import android.app.Notification;
22import android.os.Handler;
23import android.os.Messenger;
24import android.os.Looper;
25import android.os.Message;
26import android.os.SystemClock;
27
28public 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
035767ac
JW
34 private InputStream is;
35
0763e16d
JW
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
035767ac
JW
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
0763e16d
JW
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 {
035767ac
JW
184 say("Uploading "+(Integer.toString(is.available()))+" bytes");
185
0763e16d
JW
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");
035767ac 193 ((ChannelExec)channel).setCommand("scp -t /tmp/lol");
0763e16d
JW
194 channel.connect();
195
035767ac
JW
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
0763e16d
JW
219 dance("message", "done");
220
221 channel.disconnect();
222 s.disconnect();
035767ac 223 } catch (Exception e) {
0763e16d
JW
224 Log.e("Dumload.uploader[thread]", "JSchException: "+(e.toString()));
225 }
226
0763e16d
JW
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 {
035767ac 247 is = getContentResolver().openInputStream(uri);
0763e16d 248 } catch (Exception e) {
035767ac
JW
249 say("Failed to open input file.");
250 return;
0763e16d
JW
251 }
252
0763e16d
JW
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.045361 seconds and 4 git commands to generate.