]> andersk Git - moira.git/blob - webmoira/mit/moira/MoiraServlet.java
5ad55ef5e34b6ec3201bf120f403cea7ee37c428
[moira.git] / webmoira / mit / moira / MoiraServlet.java
1 package mit.moira;
2
3 import javax.servlet.*;
4 import javax.servlet.http.*;
5 import java.io.*;
6 import java.util.*;
7 import java.sql.SQLException;
8 import java.sql.ResultSet;
9 import java.sql.ResultSetMetaData;
10 import java.text.SimpleDateFormat;
11 import java.util.Date;
12 import java.util.ResourceBundle;
13
14 public class MoiraServlet extends HttpServlet {
15     static final String MOIRA_SERVER = "moira.mit.edu";
16     Kticket kt = new Kticket("jis5", "foobar", "ATHENA.MIT.EDU");
17     boolean ktinit = false;
18     private static final int MAXDISPLAY = 10;
19     Hashtable FileParts = new Hashtable();
20     Hashtable FileTimes = new Hashtable();
21     static final SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
22     static final int KE_RD_AP_BADD = 39525414; // This is a kludge
23
24
25     public synchronized void service(HttpServletRequest request, HttpServletResponse response) {
26         System.err.println("MoiraSerlvet: Service");
27         System.err.println("---------------------");
28
29         if (!ktinit) {          // Once only initialization
30             ktinit = true;
31             Thread t = new Thread(kt);
32             t.start();
33         }
34
35         String msg = null;
36
37         Hashtable qv = new Hashtable();
38
39         String modifier = "";
40
41         try {                   // Get Parameters
42             Enumeration e = request.getParameterNames();
43             while (e.hasMoreElements()) {
44                 String pname = (String)e.nextElement();
45                 String [] pvaluearray = request.getParameterValues(pname);
46                 String pvalue = "";
47                 if (pvaluearray.length > 1) {
48                     for (int i = 0; i < pvaluearray.length; i++)
49                         pvalue += pvaluearray[i];
50                 } else pvalue = pvaluearray[0];
51                     
52                 System.err.println(pname + " = " + pvalue);
53                 qv.put(pname, pvalue);
54             }
55
56             modifier = (String)qv.get("modifier");
57             if (modifier == null) modifier = "";
58
59             if (modifier.equals("showform")) {
60                 do_showform(qv, request, response);
61                 return;
62             } else if (modifier.equals("showurl")) {
63                 do_showurl(qv, request, response);
64                 return;
65             } else if (modifier.equals("makesession")) {
66                 request.getSession(true);
67                 return;
68             }
69
70             String operation = (String) qv.get("operation");
71             if (operation == null) {
72                 try {
73                     DataOutputStream out = new DataOutputStream(response.getOutputStream());
74                     response.setContentType("text/html");
75                     if (modifier.equals("getfile"))
76                         out.writeBytes("You need to select an operation from the list on the left!");
77                     else if (modifier.equals("displayonly"))
78                         out.writeBytes("error");
79                     else if (modifier.equals("getlistname")) {
80                         out.writeBytes(do_getlistinput(qv, request, response));
81                     }
82                     out.flush();
83                 } catch (Exception ee) {
84                     ee.printStackTrace();
85                 }
86                 return;
87             }
88             if (operation.charAt(operation.length()-2) == '\r') // Trim newline stuff
89                 operation = operation.substring(0, operation.length() - 2);
90             if (modifier.equals("getlistname")) {
91                 msg = do_getlistinput(qv, request, response);
92                 if (msg.equals("")) return;
93             } else if (modifier.equals("getfile")) {
94                 msg = getfile(operation);
95             } else if (operation.equals("getmembers")) {
96                 if (modifier.equals("displayonly")) {
97                     msg = "show members";
98                 } else
99                     msg = do_getmembers(qv, request, response);
100                 if (msg.equals("")) return;
101             } else if (operation.equals("addfinal")) {
102                 if (modifier.equals("displayonly")) {
103                     msg = "added members";
104                 } else
105                     msg = do_addfinal(qv, request, response);
106                 if (msg.equals("")) return;
107             } else if (operation.equals("editme")) {
108                 if (modifier.equals("displayonly")) {
109                     msg = "add or remove yourself from a list";
110                 } else
111                     msg = do_editme(qv, request, response);
112                 if (msg.equals("")) return;
113             } else if (operation.equals("removemembers")) {
114                 if (modifier.equals("displayonly")) {
115                     msg = "edit/remove members";
116                 } else 
117                     msg = do_removemembers(qv, request, response);
118                 if (msg.equals("")) return;
119             } else if (operation.equals("delmembers")) {
120                 if (modifier.equals("displayonly")) {
121                     msg = "edit/remove members";
122                 } else 
123                     msg = do_delmember(qv, request, response);
124                 if (msg.equals("")) return;
125             } else if (operation.equals("delconfirm")) {
126                 if (modifier.equals("displayonly")) {
127                     msg = "member deleted";
128                 } else 
129                     msg = do_delconfirm(qv, request, response);
130                 if (msg.equals("")) return;
131             } else if (operation.equals("addmember")) {
132                 if (modifier.equals("displayonly")) {
133                     msg = "add member(s)";
134                 } else
135                     msg = do_addmember(qv, request, response);
136                 if (msg.equals("")) return;
137             } else if (operation.equals("addme")) {
138                 if (modifier.equals("displayonly")) {
139                     msg = "added to list";
140                 } else
141                     msg = do_addremme(qv, request, response, true);
142             } else if (operation.equals("delme")) {
143                 if (modifier.equals("displayonly")) {
144                     msg = "removed from list";
145                 } else
146                     msg = do_addremme(qv, request, response, false);
147             } else if (operation.equals("displaylistinfo")) {
148                 if (modifier.equals("displayonly")) {
149                     msg = "display list characteristics";
150                 } else
151                     msg = do_showlistinfo(qv, request, response);
152             } else if (operation.equals("updatelistinfo")) {
153                 if (modifier.equals("displayonly")) {
154                     msg = "update list characteristics";
155                 } else
156                     msg = do_updatelistinfo(qv, request, response);
157             } else if (operation.equals("updatelistinfoconf")) {
158                 if (modifier.equals("displayonly")) {
159                     msg = "update list characteristics";
160                 } else
161                     msg = do_updatelistinfoconf(qv, request, response);
162             } else {
163                 sendError("Unimplemented Operation: " + (String)qv.get("operation"), response, true);
164                 return;
165             }
166
167         } catch (AuthenticationError e) {
168             msg = "<b>" + e.getMessage() + "</b><p>\r\n";
169         } catch (Exception e) {
170             msg += "<h1>Error during Processing</h1>\r\n";
171             msg += "Please try again later</HTML>\r\n";
172             e.printStackTrace();
173         }
174     
175         try {
176             DataOutputStream out = new DataOutputStream(response.getOutputStream());
177             response.setContentType("text/html");
178             if (!MOIRA_SERVER.equals("moira.mit.edu") && modifier.equals(""))
179                 out.writeBytes("<font color=red>Moira Server: " + MOIRA_SERVER + "<br></font>\r\n");
180             out.writeBytes(msg);
181             out.flush();
182         } catch (Exception e) {
183             e.printStackTrace();
184         }
185     
186     }
187     void sendError(String message, HttpServletResponse response, boolean showheader) {
188         String msg;
189         if (showheader) {
190             msg = "<HTML><TITLE>Error</TITLE></HEAD><BODY BGCOLOR=#FFFFFF>\r\n";
191             msg += "<H1>Error</H1>\r\n";
192             msg += message;
193             msg += "<p></body></html>\r\n";
194         } else msg = "<b>" + message + "</b>";
195         try {
196             DataOutputStream out = new DataOutputStream(response.getOutputStream());
197             response.setContentType("text/html");
198             out.writeBytes(msg);
199             out.flush();
200         } catch (Exception e) {
201             e.printStackTrace();
202         }
203     }
204
205     /**
206      * Authenticate the user.
207      *
208      * @param request The HttpServlet request object
209      * @return String value of the Kerberos username who owns this request
210      * @exception AuthenticationError if authentication cannot be performed
211      */
212     String do_authentication(HttpServletRequest request) throws AuthenticationError {
213
214         // Attempt to obtain authenticated username from the session
215
216         HttpSession session = request.getSession(true);
217         String kname = (String) session.getValue("kname");
218         if (kname != null) return (kname);
219
220         String client_email = (String)request.getAttribute("org.apache.jserv.SSL_CLIENT_EMAIL");
221         if (client_email == null)
222             throw new AuthenticationError("You must use a Certificate to access this service.");
223         
224         // Need to remove the @MIT.EDU portion
225         int i = client_email.indexOf('@');
226         if (i == -1)
227             throw new AuthenticationError("Malformed or non-MIT Certificate, shouldn't happen!");
228         if (!client_email.substring(i+1).equals("MIT.EDU"))
229             throw new AuthenticationError("Certificate Email Address must end in MIT.EDU");
230         kname = client_email.substring(0, i);
231         session.putValue("kname", kname);
232         return (kname);
233     }
234
235     String do_getmembers(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
236         String kname = do_authentication(request);
237
238         String msg = null;
239         String arg = (String) qv.get("list");
240         if (arg == null || arg.equals("")) {
241             msg = "<p>Argument is required</p>";
242             return (msg);
243         }
244         
245         // Obtain the list of members stashed in the session object
246         // If this is the first call to do_getmembers for this list,
247         // we won't have one in which case we will obtain it from Moira
248         // below
249
250         String list = "";
251         Member [] members = null;
252         HttpSession session = request.getSession(true);
253         if (session != null) {
254             list = (String)session.getValue("list");
255             if (list == null) list = "";
256             members = (Member []) session.getValue("members");
257         }
258         if (!list.equals(arg)) // Different list from argument, new session
259             members = null;     // Force obtaining members from Moira
260
261         // Determine offset of list to view
262         int offset = 0;
263         String tmp = (String)qv.get("offset");
264         if (tmp != null)
265             offset = Integer.parseInt(tmp);
266
267         boolean showall = false;
268         if (offset < 0) showall = true;
269
270         if (members == null) {
271             Moira mc = null;
272             try {
273                 mc = connect();
274                 mc.proxy(kname);
275                 members = mc.get_members_of_list(arg);
276                 mc.done();      // Done will disconnect
277                 mc = null;
278                 if (members != null)
279                     session.putValue("members", members);
280                 session.putValue("list", arg);
281             } catch (MoiraException m) {
282                 try {
283                     msg = "<P><b>\r\n";
284                     msg += m.getMessage();
285                     msg += "</b></P>\r\n";
286                     msg += "<!\r\n";
287                     CharArrayWriter err = new CharArrayWriter();
288                     PrintWriter perr = new PrintWriter(err);
289                     m.printStackTrace(perr);
290                     perr.flush();
291                     msg += err.toString();
292                     msg += "!>\r\n";
293                     return (msg);
294                 } catch (Exception e) {
295                     e.printStackTrace();
296                 }
297             } finally {
298                 if (mc != null) mc.done();
299             }
300         }
301
302         // Do the actual display of the members
303         if (members ==  null)
304             return("<b>No members for list " + arg + "</b>");
305             
306         msg = "<table border=0>\r\n";
307         msg += "<tr><td>&nbsp;</td><td><table border=1 cellpadding=2>\r\n";
308         msg += "<tr><td colspan=2><b>Members of list: " + arg + "</b></td></tr>\r\n";
309         int len = offset + MAXDISPLAY;
310         if (len > members.length) len = members.length;
311         if (showall) {
312             offset = 0;
313             len = members.length;
314         }
315         for (int i = offset; i < len; i++) {
316             msg += "<tr><td>" + members[i].getMemberType() + "</td>";
317             msg += "<td>" + quote(members[i].getMemberId()) + "</td></tr>\r\n";
318         }
319         msg += "</table></td><td>&nbsp;</td></tr><tr>\r\n";
320         if ((offset > 0) && !showall) {
321             msg += "<td width=50><form method=POST action=\"" +
322                 response.encodeUrl("showresult.jhtml") + "\">\r\n";
323             msg += "<input type=hidden name=operation value=getmembers>";
324             msg += "<input type=hidden name=offset value=\"" + (offset - MAXDISPLAY) + "\">\r\n";
325             msg += "<input type=hidden name=list value=\"" + arg + "\">";
326             msg += "<input type=submit value=\"Previous\"></form></td>\r\n";
327         } else
328             msg += "<td width=50>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>";
329         if (!showall && ((offset > 0) || (members.length > len))) {
330             msg += "<td width=50><form method=POST action=\"" +
331                 response.encodeUrl("showresult.jhtml") + "\">\r\n";
332             msg += "<input type=hidden name=operation value=getmembers>";
333             msg += "<input type=hidden name=offset value=\"-1\">";
334             msg += "<input type=hidden name=list value=\"" + arg + "\">";
335             msg += "<input type=submit value=\"Show All\"></form></td>\r\n";
336         } else
337             msg += "<td width=50>&nbsp;</td>";
338         if (members.length > len && !showall) {
339             msg += "<td width=50><form method=POST action=\"" +
340                 response.encodeUrl("showresult.jhtml") + "\">\r\n";
341             msg += "<input type=hidden name=operation value=getmembers>";
342             msg += "<input type=hidden name=offset value=\"" + (offset + MAXDISPLAY) + "\">\r\n";
343             msg += "<input type=hidden name=list value=\"" + arg + "\">";
344             msg += "<input type=submit value=\"Next\"></form></td>\r\n";
345         } else
346             msg += "<td width=50>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>";
347         msg += "</tr>\r\n";
348         msg += "</table>\r\n";
349         return (msg);
350     }
351
352     void do_showform(Hashtable qv, HttpServletRequest request, HttpServletResponse response) {
353         String server = request.getServerName();
354         if (server.indexOf(".") == -1)
355             server += ".mit.edu"; // MIT Specific kludge!!! XXX
356         String msg = "<form method=post action=\"" + response.encodeUrl("https://" + server + ":445/moira/showresult.jhtml") + "\">";
357         try {
358             DataOutputStream out = new DataOutputStream(response.getOutputStream());
359             response.setContentType("text/html");
360             out.writeBytes(msg);
361             out.flush();
362         } catch (Exception e) {
363             e.printStackTrace(); // Nothing else I can do here
364         }
365     }
366         
367     void do_showurl(Hashtable qv, HttpServletRequest request, HttpServletResponse response) {
368         HttpSession session = request.getSession(true); // Sigh, have to create the session here if it doesn't already exist.
369         String msg = "<a href=\"" + response.encodeUrl((String)qv.get("url"))
370             + "\">";
371         try {
372             DataOutputStream out = new DataOutputStream(response.getOutputStream());
373             response.setContentType("text/html");
374             out.writeBytes(msg);
375             out.flush();
376         } catch (Exception e) {
377             e.printStackTrace(); // Nothing else I can do here
378         }
379     }
380
381     String do_getlistinput(Hashtable qv, HttpServletRequest request, HttpServletResponse response) {
382         HttpSession session = request.getSession(false);
383         String list = null;
384         list = (String) qv.get("list");
385         if ((list == null) && (session != null)) list = (String) session.getValue("list");
386         if (list == null) list = "";
387         return("<input name=list value=\"" + list + "\" length=15 size=12 maxlength=40>\r\n");
388     }
389
390     String do_addmember(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
391         String msg = "";
392         String list = (String) qv.get("list");
393         if (list == null || list.equals("")) {
394             msg = "<p>Argument is required</p>";
395             return (msg);
396         }
397         
398         String kname = do_authentication(request);
399
400         HttpSession session = request.getSession(true);
401
402         Moira mc = null;
403         ListInfo li = null;
404         try {
405             mc = connect();
406             mc.proxy(kname);
407             li = mc.get_list_info(list);
408         } catch (MoiraException m) {
409             msg += "Error getting list info: " + m.getMessage();
410                     msg += "<!\r\n";
411             CharArrayWriter err = new CharArrayWriter();
412             PrintWriter perr = new PrintWriter(err);
413             m.printStackTrace(perr);
414             perr.flush();
415             msg += err.toString();
416             msg += "!>\r\n";
417             return (msg);
418         } finally {
419             if (mc != null) mc.done();
420         }
421
422         String list_description = "";
423         if (li != null) list_description = descript(li.description);
424
425         msg += "<form method=post action=\"" +
426             response.encodeUrl("showresult.jhtml") + "\">\r\n";
427         msg += "        <table border=1 cellpadding=2>\r\n          <tr> \r\n            <td colspan=2> \r\n              <p><b>Add member(s) to list " + list + "<br>\r\n</b>Description: " + list_description + "<br>\r\n                (you may enter more than one member of the same type by listing \r\n                each member on its own line)</p>\r\n            </td>\r\n          </tr>\r\n          <tr> \r\n            <td> \r\n              <select name=type>\r\n                <option value=\"USER\" selected>user</option>\r\n                <option value=\"STRING\">string</option>\r\n                <option value=\"LIST\">list</option>\r\n              </select>\r\n            </td>\r\n            <td> \r\n              <textarea name=\"member\" cols=\"20\" rows=\"4\"></textarea>\r\n            </td>\r\n          </tr>\r\n        </table>\r\n";
428         msg += "<input type=hidden name=list value=\"" + list + "\">\r\n";
429         msg += "<input type=hidden name=operation value=addfinal>\r\n";
430         msg += "<input type=submit name=submit value=\"Add Member(s)\">\r\n";
431         session.putValue("list", list);
432         session.removeValue("members"); // In case we had them from old list
433         return (msg);
434     }
435
436     String do_editme(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
437         String msg = null;
438         String arg = (String) qv.get("list");
439         if (arg == null || arg.equals("")) {
440             msg = "<p>Argument is required</p>";
441             return (msg);
442         }
443         
444         String kname = do_authentication(request);
445
446         HttpSession session = request.getSession(true);
447
448         Moira mc = null;
449         boolean found = false;
450         boolean sublists = false;
451         Member [] members = null;
452         try {
453             mc = connect();
454             mc.proxy(kname);
455             members = mc.get_members_of_list(arg);
456             if (members != null) {
457                 for (int i = 0; i < members.length; i++) {
458                     if (members[i].getMemberId().equals(kname)) {
459                         found = true;
460                         if (sublists) break;
461                     }
462                     if (members[i].getMemberType().equals("LIST")) {
463                         sublists = true;
464                         if (found) break;
465                     }
466                 }
467             }
468         } catch (MoiraException m) {
469             try {
470                 msg = "<P><b>\r\n";
471                 msg += m.getMessage();
472                 msg += "</b></P>\r\n";
473                 msg += "<!\r\n";
474                 CharArrayWriter err = new CharArrayWriter();
475                 PrintWriter perr = new PrintWriter(err);
476                 m.printStackTrace(perr);
477                 perr.flush();
478                 msg += err.toString();
479                 msg += "!>\r\n";
480                 return (msg);
481             } catch (Exception e) {
482                 e.printStackTrace();
483             }
484         } finally {
485             if (mc != null) mc.done();
486         }
487         msg = "You are " + (found ? "" : "not ") + "a member of the list <b>" + arg + "</b>.<br>\r\n";
488         if (!found && sublists)
489             msg += "Note: You may be a member of a sublist of <b>" + arg + "</b>. You may wish to check the sublists by using the <b>show list members</b> function.<br>\r\n";
490         msg += "<form method=POST action=\"" + response.encodeUrl("showresult.jhtml") + "\">\r\n";
491         msg += "<input type=hidden name=list value=\"" + arg + "\">\r\n";
492         if (found)
493             msg += "<input type=hidden name=operation value=delme>\r\n";
494         else
495             msg += "<input type=hidden name=operation value=addme>\r\n";
496         msg += "<input name=submit type=submit value=\"" + (found ? "Remove Me" : "Add Me") + "\">\r\n";
497         msg += "</form>";
498         if (members != null) {
499             session.putValue("list", arg);
500             session.putValue("members", members);
501         }
502         return (msg);
503     }
504
505     String do_addremme(Hashtable qv, HttpServletRequest request, HttpServletResponse response, boolean add) throws AuthenticationError {
506         HttpSession session = request.getSession(false); // Better be one
507         if (session == null) {
508             return("<p>Could not proceed, has it been 30 minutes since you last interaction. If so, back up and try again.</p>");
509         }
510
511         String kname = do_authentication(request);
512
513         String msg = null;
514         String listname = (String) session.getValue("list");
515         if (listname == null) {
516             return("<p>Could not find list name (shouldn't happen).</p>");
517         }
518         Moira mc = null;
519         try {
520             mc = connect();
521             mc.proxy(kname);
522             if (!add) 
523                 mc.delete_member_from_list(listname, "USER", kname);
524             else
525                 mc.add_member_to_list(listname, "USER", kname);
526         } catch (MoiraException m) {
527             msg = "<p><b>Unable to " + (add? "add" : "remove") + " you " + (add? "to" : "from") +  " the " + listname + " list.<br>\r\n";
528             msg += "The error from Moira was: " + m.getMessage() + "</b></p>";
529             msg += "<!\r\n";
530             CharArrayWriter err = new CharArrayWriter();
531             PrintWriter perr = new PrintWriter(err);
532             m.printStackTrace(perr);
533             perr.flush();
534             msg += err.toString();
535             msg += "!>\r\n";
536             return (msg);
537         } finally {
538             if (mc != null) mc.done();
539         }
540         if (add) msg = "You have been added to the <b>" + listname + "</b> list.";
541         else msg = "You have been removed from the <b>" + listname + "</b> list.";
542         return (msg);
543     }
544
545     String do_removemembers(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
546         Delmember [] del = null;
547         String msg = null;
548         String arg = (String) qv.get("list");
549         if (arg == null || arg.equals("")) {
550             msg = "<p>Argument is required</p>";
551             return (msg);
552         }
553         
554         String kname = do_authentication(request);
555
556         HttpSession session = request.getSession(true);
557
558         Moira mc = null;
559         try {
560             mc = connect();
561             mc.proxy(kname);
562             Member [] members = mc.get_members_of_list(arg);
563             if (members == null) {
564                 return("<P><b>No such list or empty list</b></p>.");
565             }
566             del = new Delmember[members.length];
567             for (int i = 0; i < members.length; i++) {
568                 del[i] = new Delmember(members[i]);
569             }
570             mc.done();
571             mc = null;
572             session.putValue("list", arg);
573             session.removeValue("members"); // In case left over from previous call
574             session.putValue("delmembers", del);
575         } catch (MoiraException m) {
576             try {
577                 msg = "<P><b>\r\n";
578                 msg += m.getMessage();
579                 msg += "</b></P>\r\n";
580                 msg += "<!\r\n";
581                 CharArrayWriter err = new CharArrayWriter();
582                 PrintWriter perr = new PrintWriter(err);
583                 m.printStackTrace(perr);
584                 perr.flush();
585                 msg += err.toString();
586                 msg += "!>\r\n";
587             } catch (Exception e) {
588                 e.printStackTrace();
589             }
590             return(msg);
591         } finally {
592             if (mc != null) mc.done();
593         }
594         return (do_remdisplay(qv, request, response, del, 0));
595     }
596
597     String do_remdisplay(Hashtable qv, HttpServletRequest request, HttpServletResponse response, Delmember [] del, int offset) {
598         // Offset = -1 means show everybody
599         boolean showall = false;
600         if (offset < 0) {
601             showall = true;
602             offset = 0;
603         }
604         String msg = "<h2>Select Members to Delete</h2>\r\n";
605         if (((offset > 0) || del.length > MAXDISPLAY) && !showall)
606             msg += "<p><font color=red>Note: Selections are remembered when you select the \"Previous\" and \"Next Buttons\".</font></p>\r\n";
607         msg += "<form method=POST action=\"" +
608             response.encodeUrl("showresult.jhtml") + "\">\r\n";
609         msg += "<table border=0><tr><td></td><td>\r\n";
610         msg += "<table border=1 cellpadding=2>\r\n";
611         int len;
612         if (showall) len = del.length;
613         else len = offset + MAXDISPLAY;
614         if (del.length < len)
615             len = del.length;
616         for (int i = offset; i < len; i++) {
617             msg += "<tr><td><input type=checkbox name=selected value=\" " + i + "\"";
618             if (del[i].marked) msg += " checked";
619             msg += "></td><td>" + del[i].member.getMemberType() + "</td>";
620             msg += "<td>" + quote(del[i].member.getMemberId()) + "</td></tr>\r\n";
621         }
622         msg += "</table></td>\r\n";
623         msg += "<td><input type=hidden name=operation value=delmembers></td></tr>\r\n";
624         if (offset > 0)
625             msg += "<td><input type=submit name=dodel value=\"Previous\"></td>";
626         else
627             msg += "<td width=50>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>";
628         if (!showall && (del.length > MAXDISPLAY))
629             msg += "<td><input type=submit name=dodel value=\"Show All\"></td>";
630         else msg += "<td width=50>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>";
631         if (((offset + MAXDISPLAY) < del.length) && !showall)
632             msg += "<td><input type=submit name=dodel value=\"Next\"></td></tr>\r\n";
633         else msg += "<td width=50>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td></tr>\r\n";
634         msg += "<tr><td></td><td><input type=submit name=dodel value=\"Delete Selected\"></td><td></td></tr></table></form>\r\n";
635         HttpSession session = request.getSession(false);
636         session.putValue("offset", new Integer(offset));
637         return (msg);
638     }
639
640
641     String do_delmember(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
642         String kname = do_authentication(request);
643
644         HttpSession session = request.getSession(false); // Better be one
645         if (session == null) {
646             return("<p>Could not proceed, has it been 30 minutes since you last interaction. If so, back up and try again.</p>");
647         }
648
649         Delmember [] del = (Delmember []) session.getValue("delmembers");
650         if (del == null) 
651             return("<p>Could not proceed, membership list doesn't exist, this should not happen!</p>");
652         Integer OffsetO = (Integer) session.getValue("offset");
653         if (OffsetO == null) {  // Hmmm....
654             OffsetO = new Integer(0);
655         }
656         
657         int offset = OffsetO.intValue();
658
659         String dodel = (String)qv.get("dodel"); // This is the submit button
660         if (dodel == null)
661             return("<p>Could not proceed, submit button incorrect, shouldn't happen.</p>");
662
663         // Process the selections on this form
664
665         int last = offset + MAXDISPLAY;
666         if (last > del.length) last = del.length;
667         for (int i = offset; i < last; i++) // Clear marked bits for displayed
668             del[i].marked = false;          // entries
669
670         String selected = (String)qv.get("selected");
671         if (selected == null) selected = ""; // None selected
672
673         StreamTokenizer tk = new StreamTokenizer(new StringReader(selected));
674         try {
675             tk.parseNumbers();
676             while (tk.nextToken() != StreamTokenizer.TT_EOF) {
677                 if (tk.ttype != StreamTokenizer.TT_NUMBER) continue;
678                 int v = (int) tk.nval;
679                 del[v].marked = true;
680             }
681         } catch (IOException e) {
682             e.printStackTrace();
683             return("<p>Exception while processing...</p>");
684         }
685         
686         if (dodel.equals("Next"))
687             return(do_remdisplay(qv, request, response, del, offset + MAXDISPLAY));
688         if (dodel.equals("Previous"))
689             return(do_remdisplay(qv, request, response, del, offset - MAXDISPLAY));
690         if (dodel.equals("Show All"))
691             return(do_remdisplay(qv, request, response, del, -1));
692         if (!dodel.equals("Delete Selected"))
693             return("<p>Cannot proceed, bad submit value, should not happen</p>");
694         // At this point we are going to display a list of who will be
695         // deleted and offer a confirmation.
696
697         String listname = (String) session.getValue("list");
698         if (listname == null) {
699             return("<p>Could not find list name (shouldn't happen).</p>");
700         }
701
702         // Check to see if anyone will be removed
703
704         boolean havesome = false;
705         for (int i = 0; i < del.length; i++) {
706             if (del[i].marked) {
707                 havesome = true;
708                 break;
709             }
710         }
711         if (!havesome)
712             return("No members selected to be removed");
713
714         // Some will be, so throw up confirmation dialog
715
716         String msg = "<h2>Please Confirm Deletion of:</h2>\r\n";
717         msg += "<table border=1 cellpadding=2>\r\n";
718         for (int i = 0; i < del.length; i++) {
719             if (del[i].marked) {
720                 msg += "<tr><td>" + del[i].member.getMemberType() + "</td>";
721                 msg += "<td>" + quote(del[i].member.getMemberId()) + "</td></tr>\r\n";
722             }
723         }
724         msg += "</table>\r\n";
725         msg += "<form method=POST action=\"" +
726             response.encodeUrl("showresult.jhtml") + "\">\r\n";
727         msg += "<input type=hidden name=operation value=delconfirm>\r\n";
728         msg += "<input type=submit value=\"Confirm Deletion\">\r\n";
729         msg += "</form>\r\n";
730         return (msg);
731     }
732
733     String do_delconfirm(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
734
735         String kname = do_authentication(request);
736
737         String msg = "";
738
739         HttpSession session = request.getSession(false); // Better be one
740         if (session == null) {
741             return("<p>Could not proceed, has it been 30 minutes since you last interaction. If so, back up and try again.</p>");
742         }
743
744         String listname = (String)session.getValue("list");
745
746         Delmember [] del = (Delmember []) session.getValue("delmembers");
747         if (del == null)
748             return("<p>Cannot proceed, nothing to delete, shouldn't happen!</p>");
749         
750         Vector problems = new Vector();
751         Vector success = new Vector();
752
753         Moira mc = null;
754         try {
755             mc = connect();
756             mc.proxy(kname);
757             for (int i = 0; i < del.length; i++) {
758                 try {
759                     if (del[i].marked) {
760                         mc.delete_member_from_list(listname, del[i].member.getMemberType(), del[i].member.getMemberId());
761                         success.addElement(del[i].member);
762                     }
763                 } catch (MoiraException m) {
764                     problems.addElement("<tr><td>" + quote(del[i].member.getMemberId()) + "</td><td>" + m.getMessage() + "</td></tr>\r\n");
765                 }
766             }
767         } catch (MoiraException m) {
768             msg = "<p><b>" + m.getMessage() + "</b></p>";
769             msg += "<!\r\n";
770             CharArrayWriter err = new CharArrayWriter();
771             PrintWriter perr = new PrintWriter(err);
772             m.printStackTrace(perr);
773             perr.flush();
774             msg += err.toString();
775             msg += "!>\r\n";
776             return (msg);
777         } finally {
778             if (mc != null) mc.done();
779         }
780
781         msg = "";
782         if (success.size() > 0) {
783             msg += "<h2>Deleted the following:</h2>\r\n";
784             msg += "<table border=1 cellpadding=2>\r\n";
785             for (int i = 0; i < success.size(); i++) {
786                 msg += "<tr><td>" + quote(((Member)success.elementAt(i)).getMemberId()) + "</td></tr>\r\n";
787             }
788             msg += "</table>\r\n";
789         }
790         if (problems.size() > 0) {
791             msg += "<p><h2>There were difficulties removing:</h2>\r\n";
792             msg += "<table border=1 cellpadding=2>\r\n";
793             for (int i = 0; i < problems.size(); i++) {
794                 msg += (String)problems.elementAt(i);
795             }
796             msg += "</table>\r\n";
797         }
798
799         return (msg);
800     }
801
802     String do_showlistinfo(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
803
804         String kname = do_authentication(request);
805
806         String list = (String)qv.get("list");
807
808         if (list == null || list.equals("")) {
809             return("Hmmm, no list specified");
810         }
811
812         HttpSession session = request.getSession(true);
813
814         String msg = "";
815         Moira mc = null;
816         ListInfo li = null;
817         try {
818             mc = connect();
819             mc.proxy(kname);
820             li = mc.get_list_info(list);
821         } catch (MoiraException m) {
822             msg += "Error getting list info: " + m.getMessage();
823                     msg += "<!\r\n";
824             CharArrayWriter err = new CharArrayWriter();
825             PrintWriter perr = new PrintWriter(err);
826             m.printStackTrace(perr);
827             perr.flush();
828             msg += err.toString();
829             msg += "!>\r\n";
830             return (msg);
831         } finally {
832             if (mc != null) mc.done();
833         }
834         if (li == null) {
835             return("Did not find list info.");
836         }
837         msg += "<b>List: " + list + "</b><br>\r\n";
838         msg += "Description: " + descript(li.description) + "<br>\r\n";
839         if (li.maillist)
840             msg += "This list is a mailing list.<br>\r\n";
841         if (li.grouplist)
842             msg += "This list is a Group and its ID number is " + li.gid + ".<br>\r\n";
843         msg += "The Administrator of this list is the " + li.ace_type + ": " + li.ace_name + ".<br>\r\n";
844         msg += "This list is: " + mkflags(li) + ".<br>\r\n";
845         msg += "Last modification by " + li.moduser + " at " + df.format(li.modtime) + " with " + li.modwith + ".<br>\r\n";
846         return (msg);
847     }
848
849     String do_updatelistinfo(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
850
851         String kname = do_authentication(request);
852
853         String list = (String)qv.get("list");
854
855         if (list == null || list.equals("")) {
856             return("Hmmm, no list specified");
857         }
858
859         HttpSession session = request.getSession(true);
860
861         String msg = "";
862         Moira mc = null;
863         ListInfo li = null;
864         try {
865             mc = connect();
866             mc.proxy(kname);
867             li = mc.get_list_info(list);
868         } catch (MoiraException m) {
869             msg += "Error getting list info: " + m.getMessage();
870                     msg += "<!\r\n";
871             CharArrayWriter err = new CharArrayWriter();
872             PrintWriter perr = new PrintWriter(err);
873             m.printStackTrace(perr);
874             perr.flush();
875             msg += err.toString();
876             msg += "!>\r\n";
877             return (msg);
878         } finally {
879             if (mc != null) mc.done();
880         }
881         if (li == null) {
882             return("Did not find list info.");
883         }
884
885         session.putValue("listinfo", li); // Save for the confirmation call
886         session.putValue("list", list); // Save for side bar update
887         session.removeValue("members"); // In case left over...
888
889         msg += "<form method=POST action=\"" +
890             response.encodeUrl("showresult.jhtml") + "\">\r\n";
891         msg += "<input type=hidden name=operation value=updatelistinfoconf>\r\n";
892         msg += "<b>Update characteristics of list " + list + "</b><p>\r\n";
893         msg += "Is this list a maillist? <input type=radio name=maillist value=1 "
894             + (li.maillist ? "checked" : "") + ">Yes <input type=radio name=maillist value=0 " + (li.maillist ? "" : "checked") + "> No<br>\r\n";
895         // Note: We don't update group information here
896
897         msg += "Is this list a public list? <input type=radio name=public value=1 "
898             + (li.bpublic ? "checked" : "") + ">Yes <input type=radio name=public value=0 " + (li.bpublic ? "" : "checked") + "> No<br>\r\n";
899         msg += "Is this list a hidden list? <input type=radio name=hidden value=1 "
900             + (li.hidden ? "checked" : "") + ">Yes <input type=radio name=hidden value=0 " + (li.hidden ? "" : "checked") + "> No<p>\r\n";
901         
902         msg += "The Administrator for this list is<br>\r\n";
903         msg += "<select name=ace_type><option value=\"USER\"" +
904             (li.ace_type.equals("USER") ? " selected" : "") + ">user</option>" +
905             "<option value=\"LIST\"" + (li.ace_type.equals("LIST") ? " selected" : "") + ">list</option>" +
906             "<option value=\"KERBEROS\"" + (li.ace_type.equals("KERBEROS") ? " selected" : "") + ">kerberos</option></select>";
907         msg += " <input name=ace_name value=\"" + li.ace_name + "\"><br>\r\n";
908         msg += "Description:<br>\r\n";
909         msg += "<textarea name=description cols=60 rows=3>" + li.description + "</textarea><br>\r\n";
910         msg += "<input type=submit value=\"Make Update\"></form>\r\n";
911         return (msg);
912     }
913
914     String do_updatelistinfoconf(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
915
916         String kname = do_authentication(request);
917         HttpSession session = request.getSession(false); // Better be one
918         if (session == null) {
919             return("<p>Could not proceed, has it been 30 minutes since you last interaction. If so, back up and try again.</p>");
920         }
921         
922         ListInfo li = (ListInfo)session.getValue("listinfo");
923         if (li == null) {
924             return("<p>Could not proceed, could not find orignial list info, should not happen!</p>");
925         }
926         
927         String tmp = (String)qv.get("description");
928         if (tmp != null) li.description = tmp;
929         tmp = (String)qv.get("maillist");
930         if (tmp != null) {
931             if (tmp.equals("1")) li.maillist = true;
932             else li.maillist = false;
933         }
934         tmp = (String)qv.get("public");
935         if (tmp != null) {
936             if (tmp.equals("1")) li.bpublic = true;
937             else li.bpublic = false;
938         }
939         tmp = (String)qv.get("hidden");
940         if (tmp != null) {
941             if (tmp.equals("1")) li.hidden = true;
942             else li.hidden = false;
943         }
944         tmp = (String)qv.get("ace_type");
945         if (tmp != null)
946             li.ace_type = tmp;
947
948         tmp = (String)qv.get("ace_name");
949         if (tmp != null)
950             li.ace_name = tmp;
951
952         Moira mc = null;
953         try {
954             mc = connect();
955             mc.proxy(kname);
956             mc.update_list_info(li.name, li);
957         } catch (MoiraException e) {
958             String msg;
959             if (e.getMessage().startsWith("No such list")) {
960                 msg = "<p><b>Error updating " + li.name + ".<br>\r\n";
961                 msg += "The list you specified as administrator does not exist.</p>\r\n";
962             } else if(e.getMessage().startsWith("No such user")) {
963                 msg = "<p><b>Error updating " + li.name + ".<br>\r\n";
964                 msg += "The user you specified as administrator is not known to Moira.</p>\r\n";                
965             } else 
966                 msg = "<p><b>Error during update of " + li.name + ": " + e.getMessage() + "</b></p>";
967             msg += "<!\r\n";
968             CharArrayWriter err = new CharArrayWriter();
969             PrintWriter perr = new PrintWriter(err);
970             e.printStackTrace(perr);
971             perr.flush();
972             msg += err.toString();
973             msg += "!>\r\n";
974             return (msg);
975         } finally {
976             if (mc != null) mc.done();
977         }
978         String msg = "<b>Update of " + li.name + " succeeded</b><p>\r\n";
979         qv.put("list", li.name);
980         msg += do_showlistinfo(qv, request, response);
981         return (msg);
982     }
983
984     String do_addfinal(Hashtable qv, HttpServletRequest request, HttpServletResponse response) throws AuthenticationError {
985         HttpSession session = request.getSession(false); // Better be one
986         if (session == null) {
987             return("<p>Could not proceed, has it been 30 minutes since you last interaction. If so, back up and try again.</p>");
988         }
989
990         String kname = do_authentication(request);
991
992         String listname = (String) session.getValue("list");
993         if (listname == null) {
994             return("<p>Unable to find list name! (shouldn't happen).</p>");
995         }
996         String msg = "";
997         String member = (String)qv.get("member");
998         String type = (String)qv.get("type");
999         if (member == null || type == null || member.equals("")) {
1000             return("<p>No names selected to be added!</p>");
1001         }
1002         Moira mc = null;
1003         StreamTokenizer tk = null;
1004         msg += "<table border=1 cellpadding=2>\r\n";
1005         boolean addheader = false;
1006         Vector warnings = new Vector();
1007         Vector problems = new Vector();
1008         try {
1009             mc = connect();
1010             mc.proxy(kname);
1011             tk = new StreamTokenizer(new StringReader(member));
1012             mc.done();
1013             mc = null;
1014             tk.wordChars('@', '@');
1015             tk.wordChars('0', '9');
1016             tk.wordChars('_', '_');
1017             while (tk.nextToken() != StreamTokenizer.TT_EOF) {
1018                 if (tk.ttype != StreamTokenizer.TT_WORD) continue;
1019                 try {
1020
1021                     // Pre-process user input
1022                     String [] user = canonicalize(tk.sval, type);
1023
1024                     mc.add_member_to_list(listname, user[1], user[0]);
1025                     if (!addheader) {
1026                         msg += "<tr><td>Added to list</td></tr>\r\n";
1027                         addheader = true;
1028                     }
1029                     msg += "<tr><td>" + user[1] + "</td><td>" + user[0] + "</td></tr>\r\n";
1030                     if (user.length > 2)
1031                         warnings.addElement(user[2]);
1032                 } catch (MoiraException e) {
1033                     String err = "<tr><td>" + tk.sval + "</td><td>" + e.getMessage() + "</td></tr>\r\n";
1034                     problems.addElement(err);
1035                 }
1036             }
1037             if (!addheader)     // We didn't seem to be able to add anyone
1038                 msg += "<tr><td>No one added!</td></tr>\r\n";
1039             msg += "</table>\r\n";
1040             mc.disconnect();
1041             mc = null;
1042         } catch (MoiraException e) {
1043             if (tk != null)
1044                 msg = "<p><b>Error adding " + tk.sval + ": " + e.getMessage() + "</b></p>";
1045             else
1046                 msg = "<p><b>Error during add: " + e.getMessage() + "</b></p>";
1047             msg += "<!\r\n";
1048             CharArrayWriter err = new CharArrayWriter();
1049             PrintWriter perr = new PrintWriter(err);
1050             e.printStackTrace(perr);
1051             perr.flush();
1052             msg += err.toString();
1053             msg += "!>\r\n";
1054             return (msg);
1055         } catch (IOException e) {
1056             e.printStackTrace(); // Shouldn't happen
1057         } finally {
1058             if (mc != null) mc.done();
1059         }
1060         if (problems.size() != 0) {
1061             msg += "<p>There were difficulties adding the following users:<br>\r\n";
1062             msg += "<table border=1 cellpadding=2>\r\n";
1063             for (int i = 0; i < problems.size(); i++)
1064                 msg += problems.elementAt(i);
1065             msg += "</table>\r\n";
1066         }
1067         if (warnings.size() != 0) {
1068             msg += "<p>The following warnings were generated:<br>\r\n";
1069             msg += "<table border=1 cellpadding=2>\r\n";
1070             for (int i = 0; i < warnings.size(); i++)
1071                 msg += "<tr><td>" + warnings.elementAt(i) + "</td></tr>\r\n";
1072             msg += "</table>\r\n";
1073         }
1074         return (msg);
1075     }
1076
1077     String getfile(String operation) {
1078         ResourceBundle bd = null;
1079         try {
1080             bd = ResourceBundle.getBundle("mit.moira.FileParts");
1081         } catch (java.util.MissingResourceException e) {
1082             return("Cannot find FileParts.properties");
1083         }
1084         if (bd == null) return("Cannot find FileParts.properties!");
1085         String filename = null;
1086         try {
1087             filename = bd.getString(operation);
1088         } catch (java.util.MissingResourceException e) {
1089             return("Cannot find file for operation: " + operation);
1090         }
1091         if (filename == null) {
1092             return("Cannot find file for operation: " + operation);
1093         }
1094         File file = new File(filename);
1095         if (!file.isFile()) return("Cannot file file: " + filename);
1096         long filemodtime = file.lastModified();
1097         Long cachemodtime = (Long) FileTimes.get(filename);
1098         if (cachemodtime == null || filemodtime > cachemodtime.longValue()) {
1099             // Need to fetch the file into the cache
1100             byte [] buffer = null;
1101             try {
1102                 BufferedInputStream input = new BufferedInputStream(new FileInputStream(filename));
1103                 buffer = new byte[input.available()];
1104                 input.read(buffer);
1105                 input.close();
1106             } catch (FileNotFoundException f) {
1107                                 // Should never happen given check above
1108             } catch (IOException e) {
1109                 return("IO Error Reading: " + filename);
1110             }
1111             String data = new String(buffer);
1112             data += "\r\n<!-- FileName: " + filename + "-->\r\n";
1113             FileTimes.put(filename, new Long(filemodtime));
1114             FileParts.put(filename, data);
1115             return (data);
1116         } else {
1117             return ((String)FileParts.get(filename));
1118         }
1119     }
1120
1121     String mkflags(ListInfo li) {
1122         String retval = "";
1123         int state = 0;
1124         if (!li.hidden) {
1125             retval = "visible";
1126             state = 1;
1127         }
1128         if (!li.bpublic) {
1129             switch (state) {
1130             case 0:
1131                 retval = "private";
1132                 state = 1;
1133                 break;
1134             case 1:
1135                 retval = "private and " + retval;
1136                 state = 2;
1137                 break;
1138             case 2:
1139                 retval = "private, " + retval;
1140             }
1141         }
1142         if (li.active) {
1143             switch (state) {
1144             case 0:
1145                 retval = "active";
1146                 state = 1;
1147                 break;
1148             case 1:
1149                 retval = "active and " + retval;
1150                 state = 2;
1151                 break;
1152             case 2:
1153                 retval = "active, " + retval;
1154             }
1155         }
1156         return (retval);
1157     }
1158
1159     /**
1160      * pre-process user input. Mostly this catches cases where the
1161      * incorrect type is used to add someone to a list.
1162      *
1163      * @param user String or Userid being proposed for an add
1164      * @param type Either LIST,STRING or USER
1165      * @return an array of elements. The first is the user portion followed by the type and an optional warning message.
1166      */
1167
1168     private String [] canonicalize(String user, String type) throws MoiraException {
1169         int i;
1170         String [] retval = null;
1171         if (type.equals("STRING")) {
1172             i = user.indexOf('@');
1173             if (i != -1) {
1174                 String host = user.substring(i + 1);
1175                 if (host.equalsIgnoreCase("mit.edu")) {
1176                     retval = new String[3];
1177                     retval[0] = user.substring(0, i);
1178                     retval[1] = "USER";
1179                     retval[2] = "Converted " + user + " to userid " + retval[0];
1180                     return (retval);
1181                 }
1182                 // Don't convert
1183                 retval = new String[2];
1184                 retval[0] = user;
1185                 retval[1] = "STRING";
1186                 return (retval);
1187             } else { // No @ sign
1188                 throw new MoiraException("STRING (mailing list entries) must have an \'@\' in them!");
1189             }
1190         } else if (type.equals("USER")) {
1191             i = user.indexOf('@');
1192             if (i != -1) {
1193                 String host = user.substring(i + 1);
1194                 if (host.equalsIgnoreCase("mit.edu")) {
1195                     retval = new String[3];
1196                     retval[0] = user.substring(0, i);
1197                     retval[1] = "USER";
1198                     retval[2] = "Converted " + user + " to userid " + retval[0];
1199                     return (retval);
1200                 }
1201                 throw new MoiraException("USER types must not have \'@\'s in them!");
1202             }
1203             retval = new String[2];
1204             retval[0] = user;
1205             retval[1] = type;
1206             return (retval);
1207         } else if (type.equals("LIST")) {
1208             i = user.indexOf('@');
1209             if (i == -1) {      // No '@' sign, just process normally
1210                 retval = new String[2];
1211                 retval[0] = user;
1212                 retval[1] = type;
1213                 return (retval);
1214             } else {
1215                 String host = user.substring(i + 1);
1216                 if (host.equalsIgnoreCase("mit.edu")) { // trim mit.edu
1217                     retval = new String[3];
1218                     retval[0] = user.substring(0, i);
1219                     retval[1] = "LIST";
1220                     retval[2] = "Converted " + user + " to list named " + retval[0];
1221                     return (retval);
1222                 } else
1223                     throw new MoiraException("LIST types may not contain \'@\'s in them!");
1224             } 
1225         } else { // Just pass through everything else for now
1226             retval = new String[2];
1227             retval[0] = user;
1228             retval[1] = type;
1229             return (retval);
1230         }
1231     }
1232
1233     /**
1234      * Remove &lt;SCRIPT&gt; tags from input String
1235      *
1236      * @param input String to check out
1237      * @return String with &lt;SCRIPT&gt; tag removed
1238      */
1239     private String descript(String input) {
1240         String lc = input.toLowerCase();
1241         int i = lc.indexOf("<scri");
1242         int j = lc.lastIndexOf("</scri");
1243         int len = input.length();
1244         if (i == -1) return (input); // Nothing to do.
1245         else if (j == -1) {     // No closing script tag
1246             return (input.substring(0, i));
1247         } else {
1248             return (input.substring(0, i) + input.substring(j));
1249         }
1250     }
1251
1252     /**
1253      * Shutdown the servlet
1254      *
1255      */
1256     public void destroy() {
1257         super.destroy();
1258         kt.destroy();
1259     }
1260
1261
1262     /**
1263      * Connect to the Moira Server. Special case the error KE_RD_AP_BADD.
1264      * This error occurs if the tickets we have contain the wrong IP address.
1265      * This can happen if we are on a multi-homed system. If this happens,
1266      * get new tickets and try again. If we exceed the loop count, throw
1267      * an exception (sigh).
1268      *
1269      * @return A Moira Connection Object
1270      * @exception MoiraException on any error
1271      */
1272     protected Moira connect() throws MoiraException {
1273         Moira retval = null;
1274         boolean error = true;
1275         int count = 0;
1276         try {
1277             while (count++ < 10) {      // Got to stop at some point!
1278                 retval = Moira.getInstance(MOIRA_SERVER);           
1279                 retval.connect();
1280                 try {
1281                     retval.auth();
1282                     error = false;
1283                     return (retval); // No exception, return. yeah!
1284                 } catch (MoiraException m) {
1285                     if ((m.getCode() != KE_RD_AP_BADD) || (count > 8)) {
1286                         throw m;        // Re-throw if not the error we expect or we are looping
1287                     }
1288                 }
1289                 if (retval != null) {
1290                     retval.done();
1291                     retval = null;
1292                 }
1293                 System.err.println("MoiraServlet: Forced Renewal...");
1294                 kt.renew();             // Renew tickets
1295             }
1296             // Fell through, count exceeded
1297             throw new MoiraException("Cannot authenticate successfully to Moira");
1298         } finally {
1299             if (error && (retval != null)) retval.done();
1300         }
1301     }
1302
1303     public static String quote(String value) {
1304         if (value.indexOf('<') == -1 &&
1305             value.indexOf('>') == -1) return (value); // Nothing to quote
1306         StringBuffer buf = new StringBuffer(value.length() + 10);
1307         for (int i = 0; i < value.length(); i++) {
1308             char c = value.charAt(i);
1309             if (c != '<' && c != '>') buf.append(c);
1310             else {
1311                 if (c == '<') buf.append("&lt;");
1312                 if (c == '>') buf.append("&gt;");
1313             }
1314         }
1315         return (new String(buf));
1316     }
1317 }
1318
1319 class Delmember {
1320     boolean marked = false;
1321     Member member = null;
1322
1323     Delmember(Member m) {
1324         member = m;
1325     }
1326 }
This page took 0.137586 seconds and 3 git commands to generate.