OSDN Git Service

db refactorings
authorKoushik Dutta <koushd@gmail.com>
Tue, 5 Mar 2013 23:59:01 +0000 (15:59 -0800)
committerKoushik Dutta <koushd@gmail.com>
Tue, 5 Mar 2013 23:59:01 +0000 (15:59 -0800)
Change-Id: I19a1f067f0c59517afaeaf844621de5409f9c24e

13 files changed:
Superuser/jni/su/db.c
Superuser/jni/su/su.h
Superuser/res/layout-land/log_item.xml [new file with mode: 0644]
Superuser/res/layout-v14/notification_toggle.xml [new file with mode: 0644]
Superuser/res/layout/log_item.xml
Superuser/res/layout/notification_toggle.xml [new file with mode: 0644]
Superuser/res/layout/policy_header.xml [moved from Superuser/res/layout/policy_fragment.xml with 58% similarity]
Superuser/src/com/koushikdutta/superuser/LogFragmentInternal.java
Superuser/src/com/koushikdutta/superuser/SuReceiver.java
Superuser/src/com/koushikdutta/superuser/db/SuDatabaseHelper.java
Superuser/src/com/koushikdutta/superuser/db/SuperuserDatabaseHelper.java
Superuser/src/com/koushikdutta/superuser/db/UidPolicy.java
Superuser/src/com/koushikdutta/superuser/util/SuHelper.java

index 0922d06..06ea4a5 100644 (file)
@@ -49,8 +49,8 @@ static int database_callback(void *v, int argc, char **argv, char **azColName){
             }
         }
         else if (strcmp(azColName[i], "command") == 0) {
-            // null command means to match all commands (whitelist all from uid)
-            command_match = argv[i] == NULL || strcmp(argv[i], get_command(&(data->ctx->to))) == 0;
+            // null or empty command means to match all commands (whitelist all from uid)
+            command_match = argv[i] == NULL || strlen(argv[i]) == 0 || strcmp(argv[i], get_command(&(data->ctx->to))) == 0;
         }
         else if (strcmp(azColName[i], "until") == 0) {
             if (argv[i] != NULL) {
index f0485cb..b589145 100644 (file)
@@ -70,7 +70,7 @@
 #define xstr(a) str(a)
 #define str(a) #a
 
-#define VERSION_CODE 4
+#define VERSION_CODE 5
 #define VERSION xstr(VERSION_CODE) " " REQUESTOR
 
 #define PROTO_VERSION 1
diff --git a/Superuser/res/layout-land/log_item.xml b/Superuser/res/layout-land/log_item.xml
new file mode 100644 (file)
index 0000000..082af7c
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:paddingEnd="@dimen/section_padding"
+    android:paddingStart="@dimen/section_padding"
+    android:paddingBottom="@dimen/log_item_padding"
+    android:paddingTop="@dimen/log_item_padding" >
+
+    <include layout="@layout/log_item_base" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/Superuser/res/layout-v14/notification_toggle.xml b/Superuser/res/layout-v14/notification_toggle.xml
new file mode 100644 (file)
index 0000000..c0119e1
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Switch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/notification"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+ />
\ No newline at end of file
index ad75258..572ab4c 100644 (file)
@@ -3,7 +3,8 @@
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
-    android:paddingLeft="@dimen/section_padding"
+    android:paddingEnd="?attr/listItemMarginHorizontal"
+    android:paddingStart="?attr/listItemMarginHorizontal"
     android:paddingBottom="@dimen/log_item_padding"
     android:paddingTop="@dimen/log_item_padding" >
 
diff --git a/Superuser/res/layout/notification_toggle.xml b/Superuser/res/layout/notification_toggle.xml
new file mode 100644 (file)
index 0000000..8831d1d
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/notification"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+ />
\ No newline at end of file
similarity index 58%
rename from Superuser/res/layout/policy_fragment.xml
rename to Superuser/res/layout/policy_header.xml
index dbff589..5cd9760 100644 (file)
@@ -6,8 +6,8 @@
     android:padding="@dimen/section_padding" >
 
     <LinearLayout
-        android:id="@+id/title_container"
-        android:layout_width="fill_parent"
+        android:id="@+id/policy_header"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical" >
 
     </LinearLayout>
 
     <LinearLayout
+        android:id="@+id/notification_container"
         android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="vertical" >
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
 
-        <LinearLayout
-            android:layout_width="match_parent"
+        <TextView
+            style="@android:style/TextAppearance.Medium"
+            android:layout_width="0dp"
             android:layout_height="wrap_content"
-            android:orientation="horizontal" >
-
-            <TextView
-                style="@android:style/TextAppearance.Medium"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:paddingBottom="@dimen/section_padding"
-                android:paddingLeft="@dimen/section_padding"
-                android:text="@string/logs" />
-
-            <include
-                android:layout_weight="@dimen/golden_ratio"
-                layout="@layout/log_toggle" />
-        </LinearLayout>
-
-        <ListView
-            android:id="@+id/listview"
-            android:layout_width="fill_parent"
-            android:layout_height="0dp"
             android:layout_weight="1"
-            android:scrollbars="none" />
+            android:paddingBottom="@dimen/section_padding"
+            android:paddingLeft="@dimen/section_padding"
+            android:text="@string/notifications" />
 
-        <TextView
-            android:id="@+id/empty"
-            android:layout_width="fill_parent"
-            android:layout_height="0dp"
-            android:layout_gravity="center"
-            android:layout_weight="1"
-            android:gravity="center"
-            android:orientation="vertical"
-            android:textAppearance="@android:style/TextAppearance.Medium"
-            android:visibility="gone" />
+        <include
+            android:layout_weight="@dimen/golden_ratio"
+            layout="@layout/notification_toggle" />
     </LinearLayout>
 
     <LinearLayout
-        android:id="@+id/footer_container"
-        android:layout_width="fill_parent"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="vertical" />
+        android:orientation="horizontal" >
+
+        <TextView
+            style="@android:style/TextAppearance.Medium"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:paddingBottom="@dimen/section_padding"
+            android:paddingLeft="@dimen/section_padding"
+            android:text="@string/logs" />
+
+        <include
+            android:layout_weight="@dimen/golden_ratio"
+            layout="@layout/log_toggle" />
+    </LinearLayout>
 
 </LinearLayout>
\ No newline at end of file
index 12afd13..e7a0719 100644 (file)
@@ -18,8 +18,11 @@ package com.koushikdutta.superuser;
 
 import java.util.ArrayList;
 
+import android.content.Context;
 import android.os.Bundle;
+import android.text.TextUtils;
 import android.text.format.DateFormat;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -84,16 +87,14 @@ public class LogFragmentInternal extends BetterListFragmentInternal {
     protected int getListItemResource() {
         return R.layout.log_item;
     }
-    
-    @Override
-    protected int getListFragmentResource() {
-        return R.layout.policy_fragment;
-    }
-    
+
     @Override
     protected void onCreate(Bundle savedInstanceState, View view) {
         super.onCreate(savedInstanceState, view);
         
+        LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        getListView().addHeaderView(inflater.inflate(R.layout.policy_header, null));
+        
         getFragment().setHasOptionsMenu(true);
         
         if (up == null) {
@@ -118,7 +119,7 @@ public class LogFragmentInternal extends BetterListFragmentInternal {
             name.setText(up.name);
             
             ((TextView)view.findViewById(R.id.uid_header)).setText(Integer.toString(up.desiredUid));
-            ((TextView)view.findViewById(R.id.command_header)).setText(up.command == null ? getString(R.string.all_commands) : up.command);
+            ((TextView)view.findViewById(R.id.command_header)).setText(TextUtils.isEmpty(up.command) ? getString(R.string.all_commands) : up.command);
             String app = up.username;
             if (app == null || app.length() == 0)
                 app = String.valueOf(up.uid);
@@ -130,12 +131,11 @@ public class LogFragmentInternal extends BetterListFragmentInternal {
             logs = SuperuserDatabaseHelper.getLogs(getActivity(), up, -1);
         }
         else {
-            view.findViewById(R.id.title_container).setVisibility(View.GONE);
+            setEmpty(R.string.no_logs);
+            view.findViewById(R.id.policy_header).setVisibility(View.GONE);
             logs = SuperuserDatabaseHelper.getLogs(getActivity());
         }
         
-        setEmpty(R.string.no_logs);
-        
         for (LogEntry log: logs) {
             final String date = time.format(log.getDate());
             String title = date;
@@ -155,24 +155,43 @@ public class LogFragmentInternal extends BetterListFragmentInternal {
             });
         }
 
-        final CompoundButton cb = (CompoundButton)view.findViewById(R.id.logging);
-        cb.setOnClickListener(new OnClickListener() {
+        final CompoundButton logging = (CompoundButton)view.findViewById(R.id.logging);
+        logging.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (up == null) {
+                    Settings.setLogging(getActivity(), logging.isChecked());
+                }
+                else {
+                    up.logging = logging.isChecked();
+                    SuDatabaseHelper.setPolicy(getActivity(), up);
+                }
+            }
+        });
+        if (up == null) {
+            logging.setChecked(Settings.getLogging(getActivity()));
+        }
+        else {
+            logging.setChecked(up.logging);
+        }
+
+        final CompoundButton notification = (CompoundButton)view.findViewById(R.id.notification);
+        notification.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
                 if (up == null) {
-                    Settings.setLogging(getActivity(), cb.isChecked());
                 }
                 else {
-                    up.logging = cb.isChecked();
+                    up.notification = notification.isChecked();
                     SuDatabaseHelper.setPolicy(getActivity(), up);
                 }
             }
         });
         if (up == null) {
-            cb.setChecked(Settings.getLogging(getActivity()));
+            view.findViewById(R.id.notification_container).setVisibility(View.GONE);
         }
         else {
-            cb.setChecked(up.logging);
+            notification.setChecked(up.notification);
         }
     }
 }
index b44b803..6733c58 100644 (file)
@@ -59,18 +59,8 @@ public class SuReceiver extends BroadcastReceiver {
         le.username = fromName;
         le.date = (int)(System.currentTimeMillis() / 1000);
         le.getPackageInfo(context);
-        // wait a bit before logging... lots of concurrent su requests at the same time
-        // cause a db lock
-        // TODO: this hack should no longer be necessary
-        new Handler().postDelayed(new Runnable() {
-            public void run() {
-                try {
-                    SuperuserDatabaseHelper.addLog(context, le);
-                }
-                catch (Exception e) {
-                }
-            };
-        }, 5000L);
+
+        UidPolicy u = SuperuserDatabaseHelper.addLog(context, le);
 
         String toast;
         if (UidPolicy.ALLOW.equals(action)) {
@@ -80,6 +70,9 @@ public class SuReceiver extends BroadcastReceiver {
             toast = context.getString(R.string.superuser_denied, le.getName());
         }
 
+        if (u != null && !u.notification)
+            return;
+
         switch (Settings.getNotificationType(context)) {
         case Settings.NOTIFICATION_TYPE_NOTIFICATION:
             NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
index 7626283..388970b 100644 (file)
@@ -23,9 +23,10 @@ import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
+import android.text.TextUtils;
 
 public class SuDatabaseHelper extends SQLiteOpenHelper {
-    private static final int CURRENT_VERSION = 4;
+    private static final int CURRENT_VERSION = 6;
     Context mContext;
     public SuDatabaseHelper(Context context) {
         super(context, "su.sqlite", null, CURRENT_VERSION);
@@ -40,7 +41,7 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
     @Override
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
         if (oldVersion == 0) {
-            db.execSQL("create table if not exists uid_policy (logging integer, desired_name text, username text, policy text, until integer, command text, uid integer, desired_uid integer, package_name text, name text, primary key(uid, command, desired_uid))");
+            db.execSQL("create table if not exists uid_policy (logging integer, desired_name text, username text, policy text, until integer, command text not null, uid integer, desired_uid integer, package_name text, name text, primary key(uid, command, desired_uid))");
             // skip past to v4, as the next migrations have legacy tables, which were moved
             oldVersion = 4;
         }
@@ -62,7 +63,7 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
                     SuperuserDatabaseHelper.addLog(superuser, log);
                 }
                 
-                Cursor c = db.query("settings", null, null,null, null, null, null);
+                Cursor c = db.query("settings", null, null, null, null, null, null);
                 while (c.moveToNext()) {
                     String key = c.getString(c.getColumnIndex("key"));
                     String value = c.getString(c.getColumnIndex("value"));
@@ -86,16 +87,42 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
             db.execSQL("drop table if exists settings");
             oldVersion = 4;
         }
+        
+        if (oldVersion == 4) {
+            db.execSQL("alter table uid_policy add column notification integer");
+            db.execSQL("update uid_policy set notification = 1");
+            oldVersion = 5;
+        }
+        
+        if (oldVersion == 5) {
+            // fix bug where null commands are unique from other nulls. eww!
+            ArrayList<UidPolicy> policies = getPolicies(db);
+            db.delete("uid_policy", null, null);
+            for (UidPolicy policy: policies) {
+                setPolicy(db, policy);
+            }
+            oldVersion = 6;
+        }
     }
-
     public static void setPolicy(Context context, UidPolicy policy) {
-        SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
-        
         policy.getPackageInfo(context);
-
+        SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
+        try {
+            setPolicy(db, policy);
+        }
+        finally {
+            db.close();
+        }
+    }
+    public static void setPolicy(SQLiteDatabase db, UidPolicy policy) {
         ContentValues values = new ContentValues();
         values.put("logging", policy.logging);
+        values.put("notification", policy.notification);
         values.put("uid", policy.uid);
+        // nulls are considered unique, even from other nulls. blerg.
+        // http://stackoverflow.com/questions/3906811/null-permitted-in-primary-key-why-and-in-which-dbms
+        if (policy.command == null)
+            policy.command = "";
         values.put("command", policy.command);
         values.put("policy", policy.policy);
         values.put("until", policy.until);
@@ -105,28 +132,28 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
         values.put("desired_name", policy.desiredName);
         values.put("username", policy.username);
         db.replace("uid_policy", null, values);
-        db.close();
     }
 
-    static UidPolicy getPolicy(Context context, Cursor c) {
+    static UidPolicy getPolicy(Cursor c) {
         UidPolicy u = new UidPolicy();
         u.getUidCommand(c);
         u.policy = c.getString(c.getColumnIndex("policy"));
         u.until = c.getInt(c.getColumnIndex("until"));
         u.logging = c.getInt(c.getColumnIndex("logging")) != 0;
+        u.notification = c.getInt(c.getColumnIndex("notification")) != 0;
         return u;
     }
     
-    public static ArrayList<UidPolicy> getPolicies(Context context) {
+    
+    public static ArrayList<UidPolicy> getPolicies(SQLiteDatabase db) {
         ArrayList<UidPolicy> ret = new ArrayList<UidPolicy>();
-        SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
         
         db.delete("uid_policy", "until > 0 and until < ?", new String[] { String.valueOf(System.currentTimeMillis()) });
         
         Cursor c = db.query("uid_policy", null, null, null, null, null, null);
         try {
             while (c.moveToNext()) {
-                UidPolicy u = getPolicy(context, c);
+                UidPolicy u = getPolicy(c);
                 ret.add(u);
             }
         }
@@ -135,14 +162,23 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
         }
         finally {
             c.close();
-            db.close();
         }
         return ret;
     }
 
+    public static ArrayList<UidPolicy> getPolicies(Context context) {
+        SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
+        try {
+            return getPolicies(db);
+        }
+        finally {
+            db.close();
+        }
+    }
+
     public static void delete(Context context, UidPolicy policy) {
         SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
-        if (policy.command != null)
+        if (!TextUtils.isEmpty(policy.command))
             db.delete("uid_policy", "uid = ? and command = ? and desired_uid = ?", new String[] { String.valueOf(policy.uid), policy.command, String.valueOf(policy.desiredUid) });
         else
             db.delete("uid_policy", "uid = ? and desired_uid = ?", new String[] { String.valueOf(policy.uid), String.valueOf(policy.desiredUid) });
@@ -152,13 +188,13 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
     public static UidPolicy get(Context context, int uid, int desiredUid, String command) {
         SQLiteDatabase db = new SuDatabaseHelper(context).getReadableDatabase();
         Cursor c;
-        if (command != null)
+        if (!TextUtils.isEmpty(command))
             c = db.query("uid_policy", null, "uid = ? and command = ? and desired_uid = ?", new String[] { String.valueOf(uid), command, String.valueOf(desiredUid) }, null, null, null);
         else
             c = db.query("uid_policy", null, "uid = ? and desired_uid = ?", new String[] { String.valueOf(uid), String.valueOf(desiredUid) }, null, null, null);
         try {
             if (c.moveToNext()) {
-                return getPolicy(context, c);
+                return getPolicy(c);
             }
         }
         finally {
@@ -167,5 +203,4 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
         }
         return null;
     }
-    private static final String LOGTAG = "SuReceiver";
 }
index 71adca4..7e1ed01 100644 (file)
@@ -23,6 +23,7 @@ import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
+import android.text.TextUtils;
 
 import com.koushikdutta.superuser.util.Settings;
 
@@ -40,12 +41,12 @@ public class SuperuserDatabaseHelper extends SQLiteOpenHelper {
     @Override
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
         if (oldVersion == 0) {
-            db.execSQL("create table if not exists log (id integer primary key autoincrement, desired_name text, username text, uid integer, desired_uid integer, command text, date integer, action text, package_name text, name text)");
+            db.execSQL("create table if not exists log (id integer primary key autoincrement, desired_name text, username text, uid integer, desired_uid integer, command text not null, date integer, action text, package_name text, name text)");
             db.execSQL("create index if not exists log_uid_index on log(uid)");
             db.execSQL("create index if not exists log_desired_uid_index on log(desired_uid)");
             db.execSQL("create index if not exists log_command_index on log(command)");
             db.execSQL("create index if not exists log_date_index on log(date)");
-            db.execSQL("create table if not exists settings (key TEXT PRIMARY KEY, value TEXT)");
+            db.execSQL("create table if not exists settings (key text primary key not null, value text)");
             oldVersion = 1;
         }
     }
@@ -62,7 +63,7 @@ public class SuperuserDatabaseHelper extends SQLiteOpenHelper {
     public static ArrayList<LogEntry> getLogs(SQLiteDatabase db, UidPolicy policy, int limit) {
         ArrayList<LogEntry> ret = new ArrayList<LogEntry>();
         Cursor c;
-        if (policy.command != null)
+        if (!TextUtils.isEmpty(policy.command))
             c = db.query("log", null, "uid = ? and desired_uid = ? and command = ?", new String[] { String.valueOf(policy.uid), String.valueOf(policy.desiredUid), policy.command }, null, null, "date DESC", limit == -1 ? null : String.valueOf(limit));
         else
             c = db.query("log", null, "uid = ? and desired_uid = ?", new String[] { String.valueOf(policy.uid), String.valueOf(policy.desiredUid) }, null, null, "date DESC", limit == -1 ? null : String.valueOf(limit));
@@ -123,6 +124,10 @@ public class SuperuserDatabaseHelper extends SQLiteOpenHelper {
     static void addLog(SQLiteDatabase db, LogEntry log) {
         ContentValues values = new ContentValues();
         values.put("uid", log.uid);
+        // nulls are considered unique, even from other nulls. blerg.
+        // http://stackoverflow.com/questions/3906811/null-permitted-in-primary-key-why-and-in-which-dbms
+        if (log.command == null)
+            log.command = "";
         values.put("command", log.command);
         values.put("action", log.action);
         values.put("date", log.date);
@@ -134,32 +139,40 @@ public class SuperuserDatabaseHelper extends SQLiteOpenHelper {
         db.insert("log", null, values);
     }
     
-    public static void addLog(Context context, LogEntry log) {
-        if (!Settings.getLogging(context))
-            return;
-        
-        SQLiteDatabase db = new SuDatabaseHelper(context).getReadableDatabase();
-        Cursor c = db.query("uid_policy", null, "uid = ? and command = ? and desired_uid = ?", new String[] { String.valueOf(log.uid), log.command, String.valueOf(log.desiredUid) }, null, null, null, null);
+    public static UidPolicy addLog(Context context, LogEntry log) {
+        // nulls are considered unique, even from other nulls. blerg.
+        // http://stackoverflow.com/questions/3906811/null-permitted-in-primary-key-why-and-in-which-dbms
+        if (log.command == null)
+            log.command = "";
+
+        // grab the policy and add a log
+        UidPolicy u = null;
+        SQLiteDatabase su = new SuDatabaseHelper(context).getReadableDatabase();
+        Cursor c = su.query("uid_policy", null, "uid = ? and (command = ? or command = ?) and desired_uid = ?", new String[] { String.valueOf(log.uid), log.command, "", String.valueOf(log.desiredUid) }, null, null, null, null);
         try {
             if (c.moveToNext()) {
-                UidPolicy u = SuDatabaseHelper.getPolicy(context, c);
-                if (!u.logging) {
-                    db.close();
-                    return;
-                }
+                u = SuDatabaseHelper.getPolicy(c);
             }
         }
         finally {
             c.close();
-            db.close();
+            su.close();
         }
 
-        db = new SuperuserDatabaseHelper(context).getReadableDatabase();
+        if (u != null && !u.logging)
+            return u;
+
+        if (!Settings.getLogging(context))
+            return u;
+
+        SQLiteDatabase superuser = new SuperuserDatabaseHelper(context).getWritableDatabase();
         try {
-            addLog(db, log);
+            addLog(superuser, log);
         }
         finally {
-            db.close();
+            superuser.close();
         }
+        
+        return u;
     }
 }
index 8d14cfe..1269822 100644 (file)
@@ -28,6 +28,7 @@ public class UidPolicy extends UidCommand {
     public String policy;
     public int until;
     public boolean logging = true;
+    public boolean notification = true;
     public Date getUntilDate() {
         return new Date((long)until * 1000);
     }
index 09ea5c5..03555e1 100644 (file)
@@ -17,7 +17,7 @@ public class SuHelper {
             throw new Exception("unknown su");
         
         String[] parts = result.split(" ");
-        if (!"4".equals(parts[0]))
+        if (!"5".equals(parts[0]))
             throw new Exception("binary is old");
     }