public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: cagney@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: Create an "int pid" free and logged frysk.sys.ptrace package.
Date: Tue, 12 Feb 2008 16:11:00 -0000	[thread overview]
Message-ID: <20080212161126.4099.qmail@sourceware.org> (raw)

The branch, master has been updated
       via  4b59e4b5813d22018d7bb5e75d484826f5b59f79 (commit)
      from  d25bf85036ec9bd992ee2f356a614d4bf4e051ff (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 4b59e4b5813d22018d7bb5e75d484826f5b59f79
Author: Andrew Cagney <cagney@redhat.com>
Date:   Tue Feb 12 11:05:08 2008 -0500

    Create an "int pid" free and logged frysk.sys.ptrace package.
    
    frysk-sys/frysk/rsl/ChangeLog
    2008-02-12  Andrew Cagney  <cagney@redhat.com>
    
    	* Log.java: Add more log methods.
    
    frysk-sys/frysk/sys/ptrace/Changelog
    2008-02-12  Andrew Cagney  <cagney@redhat.com>
    
    	* TestAddressSpace.java: Extract from frysk.sys.TestPtrace.
    	* TestPtrace.java: Extract from frysk.sys.TestPtrace.
    	* AddressSpace.java: Extract from frysk.sys.Ptrace.
    	* RegisterSet.java: Extract from frysk.sys.Ptrace.
    	* Ptrace.java: Extract from frysk.sys.Ptrace.
    	* cni/Ptrace.hxx: New.
    	* cni/AddressSpace.cxx: Extract from frysk/sys/cni/Ptrace.cxx.
    	* cni/RegisterSet.cxx: Extract from frysk/sys/cni/Ptrace.cxx.
    	* cni/Ptrace.cxx: Extract from frysk/sys/cni/Ptrace.cxx.

-----------------------------------------------------------------------

Summary of changes:
 frysk-sys/frysk/rsl/ChangeLog                      |    4 +
 frysk-sys/frysk/rsl/Log.java                       |   38 +++
 frysk-sys/frysk/sys/ptrace/AddressSpace.java       |  160 +++++++++++
 frysk-sys/frysk/sys/ptrace/ChangeLog               |   18 ++
 frysk-sys/frysk/sys/ptrace/Ptrace.java             |  148 ++++++++++
 .../{ChildFactory.java => ptrace/RegisterSet.java} |   71 +++--
 .../TestAddressSpace.java}                         |  285 ++++++--------------
 frysk-sys/frysk/sys/ptrace/TestPtrace.java         |  152 +++++++++++
 frysk-sys/frysk/sys/ptrace/cni/AddressSpace.cxx    |  189 +++++++++++++
 frysk-sys/frysk/sys/ptrace/cni/Ptrace.cxx          |  153 +++++++++++
 .../frysk/sys/ptrace/cni/Ptrace.hxx                |   10 +-
 .../cni/RegisterSet.cxx}                           |   79 +++---
 frysk-sys/frysk/sys/ptrace/package.html            |    7 +
 13 files changed, 1048 insertions(+), 266 deletions(-)
 create mode 100644 frysk-sys/frysk/sys/ptrace/AddressSpace.java
 create mode 100644 frysk-sys/frysk/sys/ptrace/ChangeLog
 create mode 100644 frysk-sys/frysk/sys/ptrace/Ptrace.java
 copy frysk-sys/frysk/sys/{ChildFactory.java => ptrace/RegisterSet.java} (63%)
 copy frysk-sys/frysk/sys/{TestPtrace.java => ptrace/TestAddressSpace.java} (57%)
 create mode 100644 frysk-sys/frysk/sys/ptrace/TestPtrace.java
 create mode 100644 frysk-sys/frysk/sys/ptrace/cni/AddressSpace.cxx
 create mode 100644 frysk-sys/frysk/sys/ptrace/cni/Ptrace.cxx
 copy frysk-core/prog/terminated/infloop.c => frysk-sys/frysk/sys/ptrace/cni/Ptrace.hxx (96%)
 copy frysk-sys/frysk/sys/{cni/ChildFactory.cxx => ptrace/cni/RegisterSet.cxx} (64%)
 create mode 100644 frysk-sys/frysk/sys/ptrace/package.html

First 500 lines of diff:
diff --git a/frysk-sys/frysk/rsl/ChangeLog b/frysk-sys/frysk/rsl/ChangeLog
index a2997cf..204f238 100644
--- a/frysk-sys/frysk/rsl/ChangeLog
+++ b/frysk-sys/frysk/rsl/ChangeLog
@@ -1,3 +1,7 @@
+2008-02-12  Andrew Cagney  <cagney@redhat.com>
+
+	* Log.java: Add more log methods.
+
 2008-02-11  Andrew Cagney  <cagney@redhat.com>
 
 	* Log.java (prefixTime()): Print time in DAY HH:MM:SS.mmm format;
diff --git a/frysk-sys/frysk/rsl/Log.java b/frysk-sys/frysk/rsl/Log.java
index 1ddfa73..dd0bdf4 100644
--- a/frysk-sys/frysk/rsl/Log.java
+++ b/frysk-sys/frysk/rsl/Log.java
@@ -363,6 +363,11 @@ public final class Log {
 	    return;
 	prefix(); print(p1); print(p2); print(p3); suffix();
     }
+    public void log(String p1, Object p2, String p3, long p4) {
+	if (!logging)
+	    return;
+	prefix(); print(p1); print(p2); print(p3); print(p4); suffix();
+    }
     public void log(String p1, Object p2, String p3, Object p4) {
 	if (!logging)
 	    return;
@@ -400,6 +405,11 @@ public final class Log {
 	    return;
 	prefix(self); print(p1); print(p2); suffix();
     }
+    public void log(Object self, String p1, Object p2, String p3) {
+	if (!logging)
+	    return;
+	prefix(self); print(p1); print(p2); print(p3); suffix();
+    }
     public void log(Object self, String p1, int p2, String p3, char p4) {
 	if (!logging)
 	    return;
@@ -415,9 +425,37 @@ public final class Log {
 	    return;
 	prefix(self); print(p1); print(p2); print(p3); print(p4); suffix();
     }
+    public void log(Object self, String p1, Object p2, String p3, long p4, String p5) {
+	if (!logging)
+	    return;
+	prefix(self); print(p1); print(p2); print(p3); print(p4); print(p5); suffix();
+    }
+
+    // 6 parameters
+    public void log(Object self, String p1, Object p2, String p3, long p4, String p5, long p6) {
+	if (!logging)
+	    return;
+	prefix(self); print(p1); print(p2); print(p3); print(p4); print(p5); print(p6); suffix();
+    }
     public void log(Object self, String p1, Object p2, String p3, Object p4, String p5, Object p6) {
 	if (!logging)
 	    return;
 	prefix(self); print(p1); print(p2); print(p3); print(p4); print(p5); print(p6); suffix();
     }
+
+    // 9 parameters
+    public void log(Object self, String p1, Object p2, String p3, long p4, String p5, int p6, String p7, int p8, String p9) {
+	if (!logging)
+	    return;
+	prefix(self); print(p1); print(p2); print(p3); print(p4); print(p5); print(p6); print(p7); print(p8); print(p9); suffix();
+    }
+    public void log(Object self, String p1, Object p2, String p3, long p4, String p5, long p6, String p7, int p8, String p9) {
+	if (!logging)
+	    return;
+	prefix(self); print(p1); print(p2); print(p3); print(p4); print(p5); print(p6); print(p7); print(p8); print(p9); suffix();
+    }
+
+    // 11 parameters
+    public void log(Object self, String p1, Object p2, String p3, long p4, String p5, Object p6, String p7, int p8, String p9, int p10, String p11) {
+    }
 }
diff --git a/frysk-sys/frysk/sys/ptrace/AddressSpace.java b/frysk-sys/frysk/sys/ptrace/AddressSpace.java
new file mode 100644
index 0000000..499009e
--- /dev/null
+++ b/frysk-sys/frysk/sys/ptrace/AddressSpace.java
@@ -0,0 +1,160 @@
+// This file is part of the program FRYSK.
+// 
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+// 
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+// 
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.sys.ptrace;
+
+import frysk.rsl.Log;
+import frysk.sys.ProcessIdentifier;
+
+/**
+ * A ptrace address space, that can be peeked or poked a "word" at
+ * a time.
+ */
+public class AddressSpace {
+    private static final Log fine = Log.fine(AddressSpace.class);
+
+    private final long length;
+    private final String name;
+    private final int ptPeek;
+    private final int ptPoke;
+
+    AddressSpace(long length, String name, int ptPeek, int ptPoke) {
+	this.name = super.toString() + ":" + name;
+	this.length = length;
+	this.ptPeek = ptPeek;
+	this.ptPoke = ptPoke;
+    }
+
+    public String toString() {
+	return name;
+    }
+    public long length() {
+	return length;
+    }
+
+    /**
+     * Fetch a byte at ADDR of process PID.
+     */
+    public int peek(ProcessIdentifier pid, long addr) {
+	fine.log(this, "peek", pid, "addr", addr, "...");
+	int ret = peek(pid.intValue(), addr);
+	fine.log("... peek", pid, "returns", ret);
+	return ret;
+    }
+    private native int peek (int pid, long addr);
+
+    /**
+     * Store the byte at ADDR of process PID.
+     */
+    public void poke(ProcessIdentifier pid, long addr, int data) {
+	fine.log(this, "poke", pid, "addr", addr, "data", (long) data);
+	poke(pid.intValue(), addr, data);
+    }
+    private native void poke(int pid, long addr, int data);
+
+    /**
+     * Transfer data between the local BYTES array and process PID.
+     * Up to LENGTH bytes are copied, starting at OFFSET in the BYTES
+     * array.
+     *
+     * This is a target oriented transfer; hence LENGTH as an address
+     * sized quantity is a long..
+     */
+    public int transfer(ProcessIdentifier pid, long addr, long length,
+			byte[] bytes, int offset, boolean write) {
+	fine.log(this, "transfer", pid, "addr", addr, "length", length,
+		 "offset", offset, write ? "write ..." : "read ...");
+	int size;
+	if (offset >= 0 && length >= 0) {
+	    if (offset + length > bytes.length)
+		size = bytes.length - offset;
+	    else
+		size = (int) length;
+	} else {
+	    size = -1; // triggers exception
+	}
+	transfer(write ? ptPoke : ptPeek, pid.intValue(), addr,
+		 bytes, offset, size);
+	return size;
+    }
+
+    /**
+     * Fetch up-to LENGTH bytes starting at ADDR of process PID,
+     * store them in BYTES, starting at OFFSET.
+     */
+    public void peek(ProcessIdentifier pid, long addr,
+		     byte[] bytes, int offset, int length) {
+	transfer(pid, addr, bytes, offset, length, false);
+    }
+
+    /**
+     * Store up-to LENGTH bytes starting at ADDR of process PID,
+     * get values from BYTES, starting at OFFSET.
+     */
+    public void poke(ProcessIdentifier pid, long addr,
+		     byte[] bytes, int offset, int length) {
+	transfer(pid, addr, bytes, offset, length, true);
+    }
+    
+    /**
+     * Transfer data between the local BYTES array and process PID.
+     * Locally the data starts at OFFSET and goes for LENGTH bytes.
+     *
+     * This is a host oriented transfer; hence LENGTH is an int.
+     */
+    public void transfer(ProcessIdentifier pid, long addr,
+			 byte[] bytes, int offset, int length,
+			 boolean write) {
+	fine.log(this, "transfer", pid, "addr", addr,
+		 "offset", offset, "length", length,
+		 write ? "write ..." : "read ...");
+	transfer(write ? ptPoke : ptPeek, pid.intValue(), addr,
+		 bytes, offset, length);
+    }
+    private native final void transfer(int op, int pid, long addr,
+				       byte[] bytes, int offset, int length);
+
+    private static native AddressSpace text();
+    private static native AddressSpace data();
+    private static native AddressSpace usr();
+
+    public static final AddressSpace TEXT = text();
+    public static final AddressSpace DATA = data();
+    public static final AddressSpace USR = usr();
+}
diff --git a/frysk-sys/frysk/sys/ptrace/ChangeLog b/frysk-sys/frysk/sys/ptrace/ChangeLog
new file mode 100644
index 0000000..17228ee
--- /dev/null
+++ b/frysk-sys/frysk/sys/ptrace/ChangeLog
@@ -0,0 +1,18 @@
+2008-02-12  Andrew Cagney  <cagney@redhat.com>
+
+	* TestAddressSpace.java: Extract from frysk.sys.TestPtrace.
+	* TestPtrace.java: Extract from frysk.sys.TestPtrace.
+	* AddressSpace.java: Extract from frysk.sys.Ptrace.
+	* RegisterSet.java: Extract from frysk.sys.Ptrace.
+	* Ptrace.java: Extract from frysk.sys.Ptrace.
+	* cni/Ptrace.hxx: New.
+	* cni/AddressSpace.cxx: Extract from frysk/sys/cni/Ptrace.cxx.
+	* cni/RegisterSet.cxx: Extract from frysk/sys/cni/Ptrace.cxx.
+	* cni/Ptrace.cxx: Extract from frysk/sys/cni/Ptrace.cxx.
+\f
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/frysk-sys/frysk/sys/ptrace/Ptrace.java b/frysk-sys/frysk/sys/ptrace/Ptrace.java
new file mode 100644
index 0000000..aa5b3b8
--- /dev/null
+++ b/frysk-sys/frysk/sys/ptrace/Ptrace.java
@@ -0,0 +1,148 @@
+// This file is part of the program FRYSK.
+// 
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+// 
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+// 
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.sys.ptrace;
+
+import frysk.rsl.Log;
+import frysk.sys.ProcessIdentifier;
+import frysk.sys.Signal;
+
+/**
+ * Trace a process.
+ */
+
+public class Ptrace {
+    private static final Log fine = Log.fine(Ptrace.class);
+
+    /**
+     * Attach to the process specified by PID.
+     */
+    public static void attach(ProcessIdentifier pid) {
+	fine.log("attach", pid);
+	attach(pid.intValue());
+    }
+    private static native void attach(int pid);
+
+    /**
+     * Detach from the process specified by PID.
+     */
+    public static void detach(ProcessIdentifier pid, Signal signal) {
+	fine.log("detach", pid, "signal", signal);
+	detach(pid.intValue(), signal.intValue());
+    }
+    private static native void detach(int pid, int sig);
+
+    /**
+     * Single-step (instruction step) the process specified by PID, if
+     * SIG is non-zero, deliver the signal.
+     */
+    public static void singleStep(ProcessIdentifier pid, Signal signal) {
+	fine.log("signleStep", pid, "signal", signal);
+	singleStep(pid.intValue(), signal.intValue());
+    }
+    private static native void singleStep(int pid, int sig);
+
+    /**
+     * Continue the process specified by PID, if SIG is non-zero,
+     * deliver the signal.
+     */
+    public static void cont(ProcessIdentifier pid, Signal signal) {
+	fine.log("cont", pid, "signal", signal);
+	cont(pid.intValue(), signal.intValue());
+    }
+    private static native void cont(int pid, int signal);
+
+    /**
+     * Continue the process specified by PID, stopping when there is a
+     * system-call; if SIG is non-zero deliver the signal.
+     */
+    public static void sysCall(ProcessIdentifier pid, Signal signal) {
+	fine.log("sysCall", pid, "signal", signal);
+	sysCall(pid.intValue(), signal.intValue());
+    }
+    private static native void sysCall(int pid, int sig);
+
+    /**
+     * Fetch the auxilary information associated with PID's last WAIT
+     * event.
+     */ 
+    public static long getEventMsg(ProcessIdentifier pid) {
+	fine.log("getEventMsg", pid, "...");
+	long ret = getEventMsg(pid.intValue());
+	fine.log("... getEventMsg", pid, "returns", ret);
+	return ret;
+    }
+    private static native long getEventMsg(int pid);
+
+    /**
+     * Set PID's trace options.  OPTIONS is formed by or'ing the
+     * values returned by the option* methods below.
+     */
+    public static void setOptions(ProcessIdentifier pid, long options) {
+	fine.log("setOptions", pid, "options", options);
+	setOptions(pid.intValue(), options);
+    }
+    private static native void setOptions (int pid, long options);
+
+    /**
+     * Return the bitmask for enabling clone tracing.
+     */
+    public static final long OPTION_CLONE = optionTraceClone();
+    private static native long optionTraceClone();
+    /**
+     * Return the bitmask for enabling fork tracing.
+     */
+    public static final long OPTION_FORK = optionTraceFork();
+    private static native long optionTraceFork();
+    /**
+     * Return the bitmask for enabling exit tracing.
+     */
+    public static final long OPTION_EXIT = optionTraceExit();
+    private static native long optionTraceExit();
+    /**
+     * Return the bitmask for enabling SYSGOOD(?} tracing.
+     */ 
+    public static final long OPTION_SYSGOOD = optionTraceSysgood();
+    private static native long optionTraceSysgood();
+    /**
+     * Return the bitmask for enabling exec tracing.
+     */
+    public static final long OPTION_EXEC = optionTraceExec();
+    private static native long optionTraceExec();
+}
diff --git a/frysk-sys/frysk/sys/ChildFactory.java b/frysk-sys/frysk/sys/ptrace/RegisterSet.java
similarity index 63%
copy from frysk-sys/frysk/sys/ChildFactory.java
copy to frysk-sys/frysk/sys/ptrace/RegisterSet.java
index 8be6ea1..62a452c 100644
--- a/frysk-sys/frysk/sys/ChildFactory.java
+++ b/frysk-sys/frysk/sys/ptrace/RegisterSet.java
@@ -1,11 +1,11 @@
 // This file is part of the program FRYSK.
-//
+// 
 // Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-//
+// 
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
 // the Free Software Foundation; version 2 of the License.
-//
+// 
 // FRYSK is distributed in the hope that it will be useful, but
 // WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -37,36 +37,51 @@
 // version and license this file solely under the GPL without
 // exception.
 
-package frysk.sys;
+package frysk.sys.ptrace;
+
+import frysk.rsl.Log;
+import frysk.sys.ProcessIdentifier;
+
+/**
+ * A ptrace register set that is transfered to/from PID in bulk.
+ */
+public class RegisterSet {
+    private static final Log fine = Log.fine(RegisterSet.class);
+
+    private final int ptLength;
+    private final int ptGet;
+    private final int ptSet;
+
+    RegisterSet(int ptLength, int ptGet, int ptSet) {
+	this.ptLength = ptLength;
+	this.ptGet = ptGet;
+	this.ptSet = ptSet;
+    }
 
-public class ChildFactory {
-    /**
-     * Create a child process (direct decendant of this process) that
-     * redirects its I/O to REDIRECT, and executes EXEC.
-     *
-     * Private.
-     */
-    private static native ProcessIdentifier child(Redirect redirect,
-						  Execute exec);
     /**
-     * Create a child wired to IO redirect, running exec.
-     *
-     * Package private.
+     * Return the size of the register set in bytes.
      */
-    public static ProcessIdentifier create(Redirect redirect, Execute exec) {
-	return child(redirect, exec);
+    public int length() {
+	return ptLength;
     }
+
     /**
-     * Create a child wired to nothing; STDIN is closed, STDOUT/ERROR
-     * are the same as for this process.
+     * Fetch PID's register set into DATA.
      */
-    public static ProcessIdentifier create(Execute exec) {
-	return create(new Redirect() {
-		protected void reopen() {
-		    FileDescriptor.in.close ();


hooks/post-receive
--
frysk system monitor/debugger


                 reply	other threads:[~2008-02-12 16:11 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080212161126.4099.qmail@sourceware.org \
    --to=cagney@sourceware.org \
    --cc=frysk-cvs@sourceware.org \
    --cc=frysk@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).