[PATCH 2/3] Implement mountee startup.
* mount.c (mountee_node): New variable. (mountee_root): Likewise. (mountee_started): Likewise. (start_mountee): New function (based on node_set_translator in nsmux). (setup_unionmount): New function. * mount.h (mountee_root): New variable. (mountee_started): Likewise. (start_mountee): New function. (setup_unionmount): New function. * netfs.c (netfs_validate_stat): Start the mountee at the first invocation. --- Hello, On Tue, Nov 17, 2009 at 09:07:05PM +0100, olafbuddenha...@gmx.net wrote: > On Tue, Nov 17, 2009 at 11:51:21AM +0200, unlimitedscol...@gmail.com > wrote: > > On Thu, Nov 05, 2009 at 12:29:54PM +0100, olafbuddenha...@gmx.net > > wrote: > > > > Perhaps you didn't expect the previous version to be final either -- > > > if this is the case, please pretend I never said anything about this > > > ;-) > > > > Well, I didn't expect the previous version to be final :-) But that's > > not a problem :-) I wonder, whether this version is final, though?.. > > Err... but you haven't sent the current version either :-) OK :-) I'm sending the latest version, which, apparently, is the final. > > Namely, the sentence now looks like this: ``This node is based on the > > netnode of the root node (it is essentially a clone of the root node), > > because in this way unionfs appears as the underlying translator to > > the mountee.'' > > "Because" is not the right word here; and "in this way" is also not > correct English I think... Just say "so that" or so. http://thesaurus.reference.com/browse/in+this+way http://forum.wordreference.com/showthread.php?t=1099748 Sorry, could not resist :-) However, I completely agree that ``so that'' sounds much better and I've changed the comment accordingly. Regards, scolobb --- mount.c | 142 +++ mount.h | 17 netfs.c |7 +++ 3 files changed, 166 insertions(+), 0 deletions(-) diff --git a/mount.c b/mount.c index 7bc1fb8..1419339 100644 --- a/mount.c +++ b/mount.c @@ -22,8 +22,150 @@ #define _GNU_SOURCE +#include +#include + #include "mount.h" +#include "lib.h" /* The command line for starting the mountee. */ char * mountee_argz; size_t mountee_argz_len; + +/* The node the mountee is sitting on. */ +node_t * mountee_node; + +mach_port_t mountee_root; + +int mountee_started = 0; + +/* Starts the mountee (given by `argz` and `argz_len`), attaches it to + the node `np` and opens a port `port` to the mountee. */ +error_t +start_mountee (node_t * np, char * argz, size_t argz_len, mach_port_t * port) +{ + error_t err; + mach_port_t underlying_port; + + mach_port_t mountee_control; + + /* Identity information about the unionfs process (for + fsys_getroot). */ + uid_t * uids; + size_t nuids; + + gid_t * gids; + size_t ngids; + + /* The retry information returned by fsys_getroot. */ + string_t retry_name; + mach_port_t retry_port; + + /* Fetch the effective UIDs of the unionfs process. */ + nuids = geteuids (0, 0); + if (nuids < 0) +return EPERM; + uids = alloca (nuids * sizeof (uid_t)); + + nuids = geteuids (nuids, uids); + assert (nuids > 0); + + /* Fetch the effective GIDs of the unionfs process. */ + ngids = getgroups (0, 0); + if (ngids < 0) +return EPERM; + gids = alloca (ngids * sizeof (gid_t)); + + ngids = getgroups (ngids, gids); + assert (ngids > 0); + + /* Opens the port on which to set the mountee. */ + error_t open_port (int flags, mach_port_t * underlying, +mach_msg_type_name_t * underlying_type, task_t task, +void *cookie) + { +err = 0; + +/* The protid which will contain the port to the node on which the + mountee will be sitting. */ +struct protid * newpi; + +struct iouser * unionfs_user; + +/* Initialize `unionfs_user` with the effective UIDs and GIDs of + the unionfs process. */ +err = iohelp_create_complex_iouser (&unionfs_user, uids, nuids, gids, ngids); +if (err) + return err; + +/* Create a port to node on which the mountee should sit (np). */ +newpi = netfs_make_protid + (netfs_make_peropen (np, flags, NULL), unionfs_user); +if (!newpi) + { + iohelp_free_iouser (unionfs_user); + return errno; + } + +*underlying = underlying_port = ports_get_send_right (newpi); +*underlying_type = MACH_MSG_TYPE_COPY_SEND; + +ports_port_deref (newpi); + +return err; + }/*open_port */ + + /* Start the translator. The value 6 for the timeout is the one + found in settrans. */ + err = fshelp_start_translator (open_port, NULL, argz, argz, argz_len, +6, &mountee_control); + if (err) +return err; + + /* Attach the mountee to the port opened in the previous call. */ + err = file_set_translator (underlying_port, 0, FS_TRANS_SET, 0, argz, +argz_len, mountee_control, MACH_MSG_TYPE_COPY_SEND); +
Re: [PATCH 3/3] Add the mountee to the list of merged filesystems.
Hello, On Tue, Nov 17, 2009 at 09:51:26PM +0100, olafbuddenha...@gmx.net wrote: > > I only glanced over the patch this time, no full review... Considering > how often I looked at it already, I doubt that I would find anything new > -- diminishing returns etc. :-) > > I'd say this patch series is finally ready to go... Great! :-) I'll soon be pushing it to the unionmount branch in the unionfs.git repository, then. Regards, scolobb
[PATCH] Implement the sync libnetfs stubs.
* netfs.c (netfs_attempt_sync): Sync every directory associated with the supplied node. (netfs_attempt_syncfs): Send file_syncfs to every directory maintained by unionfs. --- Hello, On Tue, Nov 17, 2009 at 09:58:15PM +0100, olafbuddenha...@gmx.net wrote: > On Tue, Nov 17, 2009 at 12:30:56PM +0200, Sergiu Ivanov wrote: > > On Fri, Nov 06, 2009 at 09:58:31AM +0100, olafbuddenha...@gmx.net > > wrote: > > > > Well, did you actually test how it behaves with really readonly > > > filesystems? (Most notably that it doesn't return an error status?) > > > > As an example of a readonly filesystem I took xmlfs and took a glance > > at it's implementation of netfs sync stubs. And then it flashed in my > > mind that all implementations of sync stubs that I've seen and which > > did nothing returned 0. I can't remember this being specified as a > > convention somewhere, though. > > OK, misunderstanding here: I didn't mean translators that do not > implement writing -- I meant filesystems *mounted* readonly. Ah, I see. I did the following: # settrans -a tmp /hurd/ext2fs /dev/hd2 ext2fs: /dev/hd2: warning: FILESYSTEM NOT UNMOUNTED CLEANLY; PLEASE fsck ext2fs: /dev/hd2: warning: MOUNTED READ-ONLY; MUST USE `fsysopts --writable' $ settrans -a foo unionfs tmp $ syncfs foo $ syncfs foo/home/scolobb (As a special note I remark that foo/home/scolobb does exist.) The first warning by ext2fs is due to the fact that I actually remounted the (already mounted) /home partition. (I hope I haven't screwed things up.) The second one shows that the filesystem has been mounted read-only. I guess this is what you mean. First of all, syncfs foo invokes netfs_attempt_syncfs, wherein all calls to file_syncfs happily return 0. On the other hand, syncfs foo/home/scolobb also invokes netfs_attempt_syncfs (not netfs_attempt_sync as I would suppose). To invoke netfs_attempt_sync, I sketched the following simple program: #define _GNU_SOURCE 1 #include #include #include #include int main (void) { mach_port_t p = file_name_lookup ("foo/home/", O_READ, 0); file_sync (p, 1, 0); mach_port_deallocate (mach_task_self (), p); return 0; } /* main */ Which did cause invocation of netfs_attempt_sync and I could see that file_sync also returns 0 when invoked on a port to a read-only filesystem. Thus, if I did everything correctly, it seems that we have no problems syncing really read-only filesystems either. > > + /* The index of the currently analyzed filesystem. */ > > + int i = 0; > > You forgot to change it for the second loop... Ah, yes :-( Fixed. Regads, scolobb --- netfs.c | 81 -- 1 files changed, 78 insertions(+), 3 deletions(-) diff --git a/netfs.c b/netfs.c index 89d1bf6..4c9f9a3 100644 --- a/netfs.c +++ b/netfs.c @@ -1,5 +1,6 @@ /* Hurd unionfs - Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. + Written by Moritz Schulte . This program is free software; you can redistribute it and/or @@ -282,7 +283,45 @@ error_t netfs_attempt_sync (struct iouser *cred, struct node *np, int wait) { - return EOPNOTSUPP; + /* The error we are going to report back (last failure wins). */ + error_t final_err = 0; + + /* The information about the currently analyzed filesystem. */ + ulfs_t * ulfs; + + /* The index of the currently analyzed filesystem. */ + int i; + + mutex_lock (&ulfs_lock); + + /* Sync every directory associated with `np`. + + TODO: Rewrite this after having modified ulfs.c and node.c to + store the paths and ports to the underlying directories in one + place, because now iterating over both lists looks ugly. */ + i = 0; + node_ulfs_iterate_unlocked (np) + { +error_t err; + +/* Get the information about the current filesystem. */ +err = ulfs_get_num (i, &ulfs); +assert (!err); + +/* Since `np` may not necessarily be present in every underlying + directory, having a null port is perfectly valid. */ +if (node_ulfs->port != MACH_PORT_NULL) + { + err = file_sync (node_ulfs->port, wait, 0); + if (err) + final_err = err; + } + +++i; + } + + mutex_unlock (&ulfs_lock); + return final_err; } /* This should sync the entire remote filesystem. If WAIT is set, @@ -290,7 +329,43 @@ netfs_attempt_sync (struct iouser *cred, struct node *np, error_t netfs_attempt_syncfs (struct iouser *cred, int wait) { - return 0; + /* The error we are going to report back (last failure wins). */ + error_t final_err = 0; + + /* The information about the currently analyzed filesystem. */ + ulfs_t * ulfs; + + /* The index of the currently analyzed filesystem. */ + int i; + + mutex_lock (&ulfs_lock); + + /* Sync every unioned directory maintained by unionfs. + + TODO: Rewrite this after having modifi
Re: learning curve
This is ridiculous. I am going to unsubscribe from bug-hurd the next time I see such an off-topic thread again. Michael On Thu, Nov 19, 2009 at 08:24:21AM +0100, Arne Babenhauserheide wrote: > Am Dienstag, 17. November 2009 22:38:39 schrieb olafbuddenha...@gmx.net: > > The problem with learning bit by bit is that you only look up things if > > you want to do something new. You never get a complete picture; you > > never learn how you could do things more efficiently, and/or with better > > result; and you often pick up really bad practices. > > I tend to disagree here, too. > > You do pick up back practise if you only check what is absolutely necessary > to > get the task at hand done (as I often do for shell scripting). > > If you check deeper issues when you need them, you understand something new > and you learn to work more efficiently. > > Look for example at the Mercurial guide I wrote. At first you only learn to > commit and read your log. At that point you already understand that Mercurial > tracks your changes - and after using it a bit, you also get a feeling for > what commit does. > > Then you learn how to do nonlinear development, branching and merging at > will. > Committing is already natural at that point, so you only enhance what you > already know by heart. > > And after that you learn that working together with others is simply > nonlinear > development by exchanging "commits" between repositories. > > > In really complex areas that becomes even more evident. > > One example: I'm studying physics, and I learned this summer with the Feynman > lectures, which hammer home the point that statistics tell us that the > distribution of particles with certain energies is exp(-E/kT) - that's "e" to > the potential of minus the energy divided by the temperature (and the > Boltzmann constant). He explains that for gases at first (energy distribution > in different heights - only from gravity and random movement energy). The > distribution says "this many particles with Energy E are there". > > At that point he never talks about the difference between bose particles and > fermi particles. He also doesn't try to give the whole mechanism, but rather > gives a central part of the whole picture. > > Now when I got to learning suprafluids and stuff, it was quite easy to > understand what their slightly different distribution does: > > 1 / (exp(E/kT) - 1) > > That's almost exp( - E/kT), but for low energies it goes to infinity - > because > the lowest state of a suprafluid can be shared by an arbitrary high number of > particles - if you only manage to take away enough energy from them. That's > why it can crawl over walls, ignores rotations of the container and such. > > To really see the implications of that, you already need to know about , > Heisenbergs uncertainty relation for the gaussian distribution of energies, > quantum mechanics, energy barriers and stuff. But you don't need to > understand > that to grasp the basic law exp(-E/kt). > > And really understanding the basic law makes it much easier to understand > more > complex stuff later on - understanding everything at once is just not > feasible > for the vast majority of physics students. > When you already know exp(-E/kT), many later things are "wow, it's really > easy > to see how that works - just a small alteration to the basic distribution". > > (there are more basic principles in physics than this, but that's one which > currently fascinates me; it is so easy - once you udnerstand it :) > And Feynman really manages to make physics sound as fascinating as it is, > while keeping it easy to understand). > > To organize learning that way makes for a very efficient learning curve. > > (actually he starts with "all matter is made of atoms (as long as we don't > look to deep)" and "we begin with small lies which make it easier to > understand the basics - but we tell you which laws are final (to our current > knowledge) and which are simplifications we'll have to revise" and goes > onward > from that). > > > In either case, you can't seriously argue that it's demanding too much, > > that everyone learning how to set the text color, should also learn how > > to set the background color at the same time, and vice versa... > > And the button color, and the text field color (almost no site changes that), > ... > > What's missing there is a way to adapt to user settings. What you describe is > binary again: Either set all or nothing. But that means that it doesn't > integrate at all or integrates completely - without middle ground. > > But we already had that part of the discussion... > > Best wishes, > Arne > > PS: I think that this can be relevant to the Hurd, because the learning curve > is something which also affects every program, translator usage, etc. - and > so > it affects how easy it is for people to switch to the Hurd.
Re: Adding entries to a directory
Hi, On Wed, Nov 18, 2009 at 08:03:30PM +0200, Sergiu Ivanov wrote: > On Wed, Nov 18, 2009 at 10:21:13AM +0100, Carl Fredrik Hammar wrote: > > On Wed, Nov 18, 2009 at 12:15:16AM +0200, Sergiu Ivanov wrote: > > > On Tue, Nov 17, 2009 at 10:29:40PM +0100, Carl Fredrik Hammar wrote: > > > > > > > > 1. Alice opens unionfs directory > > > > 2. unionfs opens unioned directories using Bob's credentials > > > > 3. unionfs restricts auth of directories to Alice's credentials > > > > 4. Alice adds entry > > > > 5, unionfs adds entry to whichever directory gets new entries > > > > > > > > Notice how unionfs doesn't need to check whether Alice is permitted to > > > > add the entry. It simply relies on that the unioned directory does it. > > > > > > I see. The check is ``done'' by the directory, and unionfs simply > > > tries adding the entry and stops whenever a directory accepts the > > > entry or when it finished traversing the list of directories. > > > > I imagined that you'd only try to add an entry to one of the unioned > > directories, otherwise it is hard to predict where the entry will > > eventually be placed. > > This is how unionfs does the things now: it tries to look up the > filename with O_CREAT under every unioned directory and stops at the > first directory which returns no error or an error different from > ENOENT. Oh, ok. It still doesn't seem right to me though. > > > unionfs does not proxy ports to normal files. The necessity of > > > reauthentication arises from the fact that the credentials associated > > > with the port unionfs returns may not be the same as those of the > > > client, but only a subset of them, right? > > > > Yes, but I also think that it should be possible to forward a not yet > > authenticated port without risking privilege escalation. That is, if you > > return an authenticated port, a proxy might think it is safe to return the > > port to its own client, which would leak the proxies access to its client. > > Hm, interesting. Are you talking about that type of proxies which > have broader permissions than their clients? In this case I'd say it > is the proxy's responsibility to think of security and give out to the > clients unauthenticated ports. Well that applies to any proxy really. What I'm talking about unauthenticated ports vs. ports restricted with clients credentials. > > I'm not entirely sure if this isn't a rule I just made up myself, but > > it seems natural to assume that a port returned with FS_RETRY_REAUTH > > should be unauthenticated. > > The comment to FS_RETRY_REAUTH in hurd/hurd_types.h says ``Retry after > reauthenticating retry port''. However, the only moment when unionfs > (and libnetfs, IIRC) returns FS_RETRY_REAUTH is when the ``..'' > filename is requested. In this case the shadow_root_parent from the > peropen structure is returned as the retry port, but I cannot tell > whether it is unauthenticated. It should return FS_RETRY_REAUTH when it returns a port to non-directory nodes as well, or atleast that is how translator transitions are currently handled in the Hurd. (See my ``Solving firmlink problem using io_restrict_auth mail'' for alternative inspired by this discussion) > So, I'd rather say that it is okay to > assume that the port returned with FS_RETRY_REAUTH is unauthenticated, > but it might not be true. Actually, it doesn't really matter, since > you are anyway bound to do reauthentication. Yes, but you aren't forced to do reauthentication if you return a port that is already authenticated. That's the problem. Regards, Fredrik
Solving the firmlink problem with io_restrict_auth (was Re: Adding entries to a directory)
Hi, On Tue, Nov 17, 2009 at 08:55:38PM +0100, olafbuddenha...@gmx.net wrote: > On Tue, Nov 17, 2009 at 01:15:59PM +0100, Carl Fredrik Hammar wrote: > > > If run by any other user then it can only recreate the intersection of > > credentials between unionfs and the client. This isn't ideal, but it > > does ensure that unionfs doesn't accidentally grant the client any new > > permissions by mistake. > > Actually I think this is just right... Whenever a client accesses a > resource through a translator, it should be restricted not only by its > own access, but also the translator's access. Well, this naturally happens as the translator cannot possibly provide more access then it already has. > It is actually a problem that this policy is not followed whenever an > intermediate translator hands out a "real" port to another translator, > and the client reauthenticates it. (The so-called "firmlink problem".) Having a ``proxy'' do an io_restrict_auth before passing on a port has actually far reaching consequences. Remember that firmlink is only an odd use of the regular hand-off protocol when going from one translator to another, so using this policy throughout the Hurd would mean we go from a peer-to-peer authority scheme to a very hierachical one, where each step from one translator to another can only mean less authority for the client. Note also that the fact that servers return an already authenticated but restricted port that would solve the firmlink problem, rather the client must refuse to reauthenticate ports on the server's request, otherwise a malicious server could still trick the client. Does this mean that the auth server isn't needed any more? No, there is still one case this doesn't cover: to extend the clients authority, with setauth or the password server. To do this the client must reauthenticate all open ports in order for its new credentials to take effect. Also to do this properly we need to improve io_restrict_auth so it restricts the allowed operations to the intersection of the allowed operations of two sets of credentials, and not just to the operations allowed of the intersection of two sets of credentials. I'm not sure if switching to such an authority scheme is a good idea overall, but I do think it would indeed solve the firmlink problem. Regards, Fredrik
Re: Adding entries to a directory
Hello, On Thu, Nov 19, 2009 at 03:22:42PM +0100, Carl Fredrik Hammar wrote: > On Wed, Nov 18, 2009 at 08:03:30PM +0200, Sergiu Ivanov wrote: > > On Wed, Nov 18, 2009 at 10:21:13AM +0100, Carl Fredrik Hammar wrote: > > > > > > I imagined that you'd only try to add an entry to one of the unioned > > > directories, otherwise it is hard to predict where the entry will > > > eventually be placed. > > > > This is how unionfs does the things now: it tries to look up the > > filename with O_CREAT under every unioned directory and stops at the > > first directory which returns no error or an error different from > > ENOENT. > > Oh, ok. It still doesn't seem right to me though. Well, I can remember suggestions of implementing several strategies, including adding a file to all directories, adding it to the first directory that accepts it and some other. IIRC, this is how unionfs is implemented on other systems (at least, WRT deleting entries). > > > I'm not entirely sure if this isn't a rule I just made up myself, but > > > it seems natural to assume that a port returned with FS_RETRY_REAUTH > > > should be unauthenticated. > > > > The comment to FS_RETRY_REAUTH in hurd/hurd_types.h says ``Retry after > > reauthenticating retry port''. However, the only moment when unionfs > > (and libnetfs, IIRC) returns FS_RETRY_REAUTH is when the ``..'' > > filename is requested. In this case the shadow_root_parent from the > > peropen structure is returned as the retry port, but I cannot tell > > whether it is unauthenticated. > > It should return FS_RETRY_REAUTH when it returns a port to non-directory > nodes as well, or atleast that is how translator transitions are > currently handled in the Hurd. (See my ``Solving firmlink problem using > io_restrict_auth mail'' for alternative inspired by this discussion) Well, doing a simple search for FS_RETRY_REAUTH in unionfs/netfs.c shows me only two entries, the ones I've already told you about. However, I do understand your idea about returning unauthenticated ports and I agree that it does improve security. > > So, I'd rather say that it is okay to > > assume that the port returned with FS_RETRY_REAUTH is unauthenticated, > > but it might not be true. Actually, it doesn't really matter, since > > you are anyway bound to do reauthentication. > > Yes, but you aren't forced to do reauthentication if you return a port > that is already authenticated. That's the problem. Ah, sure. I was thinking about ideal good programs. Regards, scolobb
Re: learning curve
Hi Michal, Did you read till the "PS"? I spent some time thinking whether to send this reply to the list or only to Olaf, but I decided to send it to the list, because the learning curve also applies to documentation of the Hurd - the Hurd also offers concepts which are new to many people. For example it is relevant to the question how translator usage can easily be described. To recap what the equivalent of the examples would be for a translator (as well as I can currently do that): - basic principle: A translator creates or modifies a node in the filesystem. $ settrans -ac hello /hurd/hello $ cat hello "Hello Hurd!" $ settrans -g hello # -a: active -> start it at once # -c: create the node, in this case the pseudo-file "hello". # -g: remove a translator: "go away" - second part: On parts of the filesystem which you can modify, you can make the translators permanent. We call that a passive translator, because they only get activated when the filesystem node gets touched. $ settrans -c hello /hurd/hello $ cat hello "Hello Hurd!" $ reboot $ cat hello "Hello Hurd!" # not specifying "-a" creates a passive translator # which stays in the filesystem over reboots. # It can only be removed with "settrans -g" $ settrans -g hello ... That way we can archieve a smooth learning curve, when we search for the basic principles which people need to know about translators. I don't know, if the two I named are the most basic principles people need to know (the ones which help them best to udnerstand later parts), but I hope they are close. One important question I see is "how and when to show people easily what it means, that translators can use capabilites - and what options that gives a developer or user." -> how to show people in a motivated and simple way what it means to go beyond POSIX access control? What basics should they already know when they learn about that? How can we teach them these basics while at the same time keeping the learning interesting? Best wishes, Arne PS: I didn't use translators in the example, because I wasn't certain if I could find the best way to provide a smooth learning curve with these. So I used two things where I felt surer that what I say is mostly correct. Am Donnerstag, 19. November 2009 10:40:57 schrieb Michael Banck: > This is ridiculous. I am going to unsubscribe from bug-hurd the next > time I see such an off-topic thread again. > > Michael > On Thu, Nov 19, 2009 at 08:24:21AM +0100, Arne Babenhauserheide wrote: -snip- > > PS: I think that this can be relevant to the Hurd, because the learning > > curve is something which also affects every program, translator usage, > > etc. - and so it affects how easy it is for people to switch to the Hurd. signature.asc Description: This is a digitally signed message part.
Re: learning curve
On Thu, Nov 19, 2009 at 06:16:07PM +0100, Arne Babenhauserheide wrote: > I spent some time thinking whether to send this reply to the list or only to > Olaf, but I decided to send it to the list, because the learning curve also > applies to documentation of the Hurd - the Hurd also offers concepts which > are > new to many people. I said it before, and I'll say it again now: the Hurd does not need more users, it does not even need a lot more developers, it just need a few *really smart* developers. You don't get really smart developers by trashing up your development list with 200-mail threads about mercurial vs. git vs. cvs or the merits of light or dark backgrounds in CSS. I rest my case now. Michael
Re: learning curve
Am Donnerstag, 19. November 2009 20:16:32 schrieb Michael Banck: > the Hurd does not need > more users, it does not even need a lot more developers, it just need a > few *really smart* developers. How do you get these really smart developers interested in the Hurd? - Arne signature.asc Description: This is a digitally signed message part.
Re: website: background color in css
Hi, On Tue, Nov 17, 2009 at 08:11:54PM +0100, Arne Babenhauserheide wrote: > Am Dienstag, 17. November 2009 00:35:30 schrieb > olafbuddenha...@gmx.net: > > It's actually perfectly OK to override text colors for emphasis in > > specific bits of text -- if you also override the background color > > *for these same bits of text*. The rest of the page can keep default > > colors for both text and background. > > > > Too bad that hardly any web author sticks to this simple rule. > > I tried that, and it looks really horrible - far worse than without > background, because you get a snippet of white background in a dark > text. I don't consider that horrible. Anyways, you can't expect perfect aesthetics in view of varying defaults. It's not the web author's responsibility to make it look nice for people choosing unusual defaults. (Or with different levels of functionality implemented by browsers.) It's the web author's responsibility to keep it *usable* no matter what the defaults/functionality, though. -antrik-
Hurdish Desktop (was: OT: automation)
Hi, On Tue, Nov 17, 2009 at 09:34:28PM +0100, Arne Babenhauserheide wrote: > Am Montag, 16. November 2009 23:25:16 schrieb olafbuddenha...@gmx.net: > > Still not sure what you want to know. Are you asking for a technical > > design description? For a roadmap? Or yet something else?... > > I just meant the question as a prompt to you, no explicit roadmap > request or similar, just a "you have an idea, and I'm sure you also > have ideas how to go about that" (for example the things you do with > netrik). So a roadmap. I think I might have mentioned it at some point already: I have two different ideas for a possible approach. One is to built it up from the bottom: once I have KGI, build a console/windowing system based on that; then infrastructure components like the the text viewing widget, and the universal shell; and finally application plugins using these for web browsing, mail, IRC and so on. The other idea is to start from netrik as it is, turning it to the desired design bit by bit, implementing the necessary infrastructure along the way; and finally start adding other application plugins. -antrik-