1. 2

    May be 2020 Microsoft will open source it :P

    1.  

      It’s a good joke because it’s plausible :)

      Joke’s aside, at this point that could have serious implications for both microsoft and apple. To this day, I am not convinced that present day workstation operative systems offers are much better than what Windows XP could offer. I am including OSX and popular linux distros. Microsoft spend more than a decade pushing users away from it.

      If it were to be made open source, it could be turned into a serious product with a strong value offer.

      1.  

        I think this leak will expose the bad code quality of the windows os and will lead to windows’ further demise :D I’m very excited to see in-depth analyses and may be Microsoft may just surprise me.

        1. 15

          The Windows 2000 source was leaked years ago. IIRC, the users of kuro5hin actually thought it was good quality, with extreme compatibility requirements dragging it down.

          People at Microsoft aren’t stupid, as much as Unix programmers like to think.

          1. 5

            People examining the code in 4chan threads seem to agree, the code looks to be of a decent quality. Some acummulated 4chan findings can be found here(warning - it’s 4chan, even if there is no nsfw content on that board).

            1.  

              Here’s an archived version, in case anyone wants to peruse after the thread is pruned.

            2.  

              Do you have a link for that? I think thatd an interesting read. I believe many proprietary software is of bad code quality. That has nothing to with stupidity, but with the corporate culture and business requirements.

              1.  

                Sure.

                1.  

                  Thanks!

          2.  

            Getting all license holders to agree to open source would be tricky. It’s been a while since I looked at the Windows license screen for XP but I suspect MS paid for licenses for a number of applications and libraries.

            1.  

              Yeah, Citrix source permeates anything to do with multiple users, and IE started out life as a licensed program. Getting rid of licensing accessories is easy, but core components, not so much.

        1. 6

          This language is really hitting the sweet spot of productivity. High level and joyful to work with but retaining c-like efficiency/speed. And they have been putting focus on the right things people want thesen days: easy to use http libraries, support for popular databases, JSON support, etc. I personally would prefer they would have mimicked python instead of ruby as I find objectively simpler and more pragmatic even.

          This story really illustrates the mood of crystal and it’s community: let’s do something to the point, keep it simple and reasonable on resource usage. Kind of a grassroots take on software, but benifiting from decades of advancements and nice things.

          As for keeping the code Hiden… Let go… Just release it… It is just a weekend project. Don’t be so possessive over it. You’re very likely getting less for it than if you would just release it.

          1. 10

            I submitted this because this is the second time in the week I’ve seen other posts recommending moving the sshd listening port to an unprivileged port and I think this is always a terrible idea.

            1. 43

              Now, back to SSH: when we start SSH on port 22, we know for a fact that this is done by root or a root-process since no other user could possibly open that port. But what happens when we move SSH to port 2222? This port can be opened without a privileged account, which means I can write a simple script that listens to port 2222 and mimics SSH in order to capture your passwords. And this can easily be done with simple tools commonly available on every linux system/server. So running SSH on a non-privileged port makes it potentially LESS secure, not MORE. You have no way of knowing if you are talking to the real SSH server or not. This reason, and this reason alone makes it that you should NEVER EVER use a non-privileged port for running your SSH server.

              The author is suggesting trusting port 22 because it is a “root” process.There is a “way of knowing if you are talking to the real SSH server or not”, and it’s actually one of SSHs features since its first release. I would trust any port, no matter the “privilege level” required to listen on that port, for a single reason: I trust the SSH server based on its fingerprint, not on its listening port; and I know that my server’s key data is only readable by root, it has been like this in almost all SSH default installations for the last 20 years.

              Now, let’s pretend you STILL want to move the port away because you get so many attacks on your SSH port. First of all: are you able to logon as root? If so, fix that now. Secondly: are you using passwords? If so, fix that now and change into public key authentication.

              I want to move the port away because of the insane amount of traffic that I have to pay for (if I rent a server, VPS, or anything similar which bills me on network egress/ingress). Disabling password access (for any user) will not make dumb port scans and SSH fingerprinters stop looking at my SSH banner and then decide, based on this information, to just try out username/password combinations, even when my server rejects this authentication method.

              The rest of the arguments are personal opinion.

              1. 8

                the insane amount of traffic that I have to pay for

                how much money per month do you estimate you were paying for to handle traffic from people attempting to ssh into a given node?

                1. 3

                  About 2 euro cents a month, per host.

                  1. 1

                    the question is: how many resources of concurrent connections does this take, which are completely unnecessary and are filling your logs

                    1. 3

                      Clearly not enough to make log tuning worthwhile.

                      A lot of these blanket statements ignore the fact that action or inaction is perfectly reasonable dependent on threat model. But of course, most people making blanket statements aren’t applying a threat model when doing so.

                  2. 7

                    Besides, by this reasoning creating a connection to the many many services that run on port >1024 is a bad idea too. Connect to MySQL on 3306? Oh noes! Have your app run on localhost:8080 and a proxy on *:80? Oh noes!

                    1. 2

                      Please move your MySQL port to 306 and launch MySQL as root.

                      1. 1

                        call me crazy but I don’t think “you risk an attacker accessing your database” and “you risk an attacker having a shell to do whatever they want” are really equivalent.

                        1. 1

                          Well, the DB in most cases have much more value to the attacker than your machine, so I would say, that from the pragmatic viewpoint, DB is more likely to be targeted.

                      2. 6

                        This was basically what I was going to say.

                        If a server can somehow knock down sshd, listen on the same unrestricted port, they still would have to present the appropriate hostkeys.

                        Even then, LSM’s like SELinux, etc can put restrictions on who can name_bind on any port you want. only caveat is that you have to write the policy for it. I am strongly against the >1024 privileged ports restriction in the era of LSMs.

                        1. 1

                          I am strongly against the >1024 privileged ports restriction in the era of LSMs.

                          Can you expand?

                          1. 1

                            With LSM you can disable opening any port by all applications and then allow opening ports per application. So on server it allows for much greater security, as you can directly list which application will be able to open connections (and even make it so no port requires super user, as application/user combo will be handled by LSM).

                            1. 1

                              This is an argument for LSM-based port binding policies, not against the <1024 requires root policy. Unless the two are mutually exclusive?

                        2. 2

                          I trust the SSH server based on its fingerprint

                          I very rarely know the fingerprint of a server before connecting to it.

                          For my most commonly used hosts, I can look it up with a little bit of work (sourcehut, github, gitlab) but of those, only github made it easy to find and verify. For a lot of hosts in a corporate cloud though, the instances are torn down and replaced so often that host-based keys are essentially meaningless.

                          1. 7

                            If you’re not verifying host keys, you’re basically trusting the network - but you don’t, otherwise you could use telnet instead of ssh.

                            Maybe look into SSH host key signing, so you just need one public signing key to verify that the host has been provisioned by a trusted entity.

                            1. 3

                              It is also possible to use ssh with kerberos. Then you know that the server is the correct one. Even without ssh-fingerprints.

                            2. 5

                              You should really start checking the fingerprints. Ignoring that crucial step is how you get hacked. There are way more attack vectors than you can think of. An attacker could get in, for example through your jobs documentation intranet and modify an ip on a document. Or for example, if a DNS server of yours is compromised. If you use password authentication in these situations, you are essentially let the attacker in all servers you have access to.

                              Other comments already pointed out viable solutions. You should adopt one of them or simply start checking the fingerprints. What you are doing is dangerous.

                              1. 6

                                The “implied trust on first use”-model works well enough for many – though perhaps not all – purposes. It’s the “host fingerprint changed”-warning that provides almost all of the security.

                                1. 2

                                  Most of the security no doubt. Almost all… That is debatable. If something happens once every 1000 would you not care to protect against it because you already provided 99.9% of the security?

                                  What security is in essence, is accounting for the unlikely yet exploitable cases. You look at that attack vectors as a corner case until it is not a corner case anymore. This is how security threats evolve.

                                  1. 1

                                    The thing is, what is the attack vector here, and how do you really protect from it? In your previous post you mentioned modifying the internal documentation to change the IP; but where do you get the host key? From the same internal documentation? Won’t the attacker be able to change that, too?

                                    You can use SSHFP records; but of course an attacker can potentially get access to the DNS too, as you mentioned.

                                    The thing is that good distribution of these fingerprints is not a trivial problem if you’re really worried about these kind of attacks. Are they unfeasible? Certainly not, and if you’re working for a bank, CA registrar, or anything else that has high security requirements you should probably think about all of this. But most of us don’t, and the difficulty of pulling all of this off effectively is so high that most of us don’t really need to worry about it.

                                    We don’t lock our houses with vault doors; a regular door with a regular lock is a “good enough” trade-off for most cases. If you’re rich you may want to have something stronger, and if you’re a bank you want the best. But that’s not most of us.

                                    1. 1

                                      The attack vector is making you believe you are initially trusting the host you think you know, but it is in fact another host.

                                      But you are right, it you misguide a user into connecting to another host, you could also show him another fingerprint and trick them into believing itnid legit too. Fingerprints are just a huge number usually displayed as an unintelligible string of chars. It’s not like the user recognise them by heart.

                                      I do check them if I change computer, or if l connect to a knowm machine I ask a coleage to verify it. But I’ll agree that it.s a trade off and that maybe it.s ok for most people to just trust.

                          2. 3

                            I think this post and discussion around it is a waste of time. Right now, wasting my time. But I wanted to come here and proclaim in spectrum of terrible ideas, it doesn’t even register. Do you have scale that starts at terrible and then just goes to some k multiple of terrible?

                            I moved my ssh port in like 2002 (the year) , and you know what, I no longer had to see 150+ log messages a day about failed logins, it went to zero. Like 1-1. Mission Accomplished.

                            Please enumerate all the other terrible ideas I shouldn’t follow, might be a good list.

                            edit, btw, I am just poking good terrible fun at you.

                          1. 6

                            Did Haskell die? When was the peak?

                            1. 25

                              The article focuses on followers, which is a strange metric to focus on.

                              github primarily allows physically separated developers, sometimes from different organizations, to collaborate on code.

                              As a side effect, github offers the possibility to show a portfolio of work. This is possible for people whose work/study allows them to show the work they did publicly including collaboration.

                              If a person does have material on github and points to it on their resume, you can get an idea of their working style, and some of their personality from this portfolio. It may help you to filter candidates and to think of things to ask them in the interview that will spark a nice discussion.

                              Once, in an interview I had a nice discussion with a total stranger about an orbital simulator I’ve worked on for many years, totally unrelated to the work at hand.

                              If the candidate doesn’t have a github portfolio, it is what it is and you’ll just have to ask them about what they like to code in the interview.

                              Like everything else, a github portfolio is just one piece of evidence to a future colleague’s fit for a job. It’s neither a necessary piece of evidence, nor a sufficient one, to hinge a hiring decision on.

                              1. 4

                                “a (github) portfolio is just one piece of evidence to a future colleague’s fit for a job. It’s neither a necessary piece of evidence, nor a sufficient one, to hinge a hiring decision on.”

                                I absolutely agree, it can add the necessary part of the information, but it certainly does not help to draw the whole personality profile of the candidate, it is necessary to evaluate many more factors.

                                1. 3

                                  They did include this footnote:

                                  There isn’t an API to get the contribution activity in the last year from GitHub. Instead, people seem to get the timeline image as an SVG (like hitting this endpoint https://github.com/users/benfred/contributions), and then parse the SVG to get the number of contributions. I almost went with this hack for this post but hit some problems with CORS restrictions from loading this in the browser. I could have written a proxy to host the requests, but it was getting silly so went with the number of followers instead.

                                  1. 10

                                    One thing I usually did when evaluating candidate is to search for “site:github.com username commented on”. That will give some ideas on the candidate communication style as we go through his interaction on github discussing bugs, suggesting new features or debating on some technical arguments.

                                    1. 2

                                      This is not a bad idea! I just checked some of people I like to work with and the results were great. In case a person did not have any interactions you have to rely on other means.

                                    2. 2

                                      Confused. Why would anyone care about those silly metrics when you can look directly at the code they have written? It’s not GitHub, it’s what you put in there. You could host your code on another website, including one that you own, if you have one.

                                      “Why won’t your CV help you with hiring”…It sure depends on its contents…?

                                      1. 1

                                        99% of the code I have written is not available for review for you. How do we proceed?

                                        1. 3

                                          Certainly not by counting GitHub stars or followers.

                                          You either have the code to show or you don’t. It’s up to you to prove yourself as a candidate. I would certainly not hire you based a social network metrics.

                                          If you want to know that the most followed person on GitHub says about that (I learned this in this entry):

                                          Talk is cheap, show me the code.

                                      2. 2

                                        There is an API to get contributions. I keep a log in Vim, and I’ve configured it so that pressing F5 inserts a markdown-formatted list of my GitHub contributions since the last time I pressed F5 (https://github.com/talex5/get-activity). I haven’t tried getting a whole year’s worth, but I don’t see why it wouldn’t work.

                                    1. 10

                                      I wondered for a while whether this article was sarcasm. Really.

                                      This is a well known problem (which I believe has a name, but I can’t find it any more): one might add more cases, and one might add more functions. If we expect to add more cases, subtype polymorphism makes it easier: just add one class. If we expect to add more functions however, if/else/switch work better: we just add one function, that goes through all cases. If we add a case when using if/else/switch, we must go through all occurrences. If we add a function when using polymorphism, we must go through all subclasses.

                                      Neither approach is strictly superior to the other. It really depends how your program will end up evolving, which is not easy to predict.

                                      Incidentally, in the programs I worked with, I observed that we tend to add functions more often than we add cases. Possibly because I tend to consider possible cases fairly carefully from the outset, I don’t know. Anyway, that’s one reason I tend to prefer if/else/switch. Other reasons being reduced boilerplate, and my FP background.

                                      1. 5

                                        I think you’re referring to the expression problem and agree. It’s not a be-all, end-all solution for the reasons described.

                                        1. 2

                                          Oh thank you, that’s the one!

                                        2. 4

                                          If we expect to add more cases, subtype polymorphism makes it easier: just add one class.

                                          This is not true. You can never just add one class, because somewhere you need the reference to when that class will be used. Usually this means adding a value to an enumeration or a map. Which is no different than adding a switch branch. Adding a class introduces way more boilerplate than adding a switch case.

                                          In languages which treat functions as first class citizens, you can just map the case subject to a function reference. No boilerplate required. Or you could use pattern matching in languages that have it.

                                          OOP people will have a hard time to accept that something with such a fancy name as polymorophism is really nothing special.

                                          1. 2

                                            Let me be clear: I do believe that most of the time, class hierarchy are on the poor end of the Expression Problem (thanks @prussian for finding the term for me!). I agree they usually involve much more boilerplate than switch cases. And first class functions does make subtype polymorphism mostly unnecessary.

                                            My point here is, how many pieces of code do you need to touch when you add a case? If you use an enumeration or sum type, you need to modify every switch statement. With a class hierarchy on the other hand, those switch statements are replaced by virtual function calls. You don’t need to modify those when you add another class to the hierarchy. You just need to add a class.

                                            Now for this new class to have an effect, you do need to instantiate it somewhere. The same is true of enumerations though, you need to produce that new value if you want it to have any purpose. As far as I know, whether you use a class hierarchy or an enumeration type doesn’t change the number of producers you need to add. Since it makes no meaningful difference, I tend to ignore that part.

                                            1. 1

                                              My point here is, how many pieces of code do you need to touch when you add a case?

                                              The exact same in both cases. You need to add a class or function and you need to add the resolving key to the enum/set/whatever. If you are talking about using integers or strings to resolve you.re pushing resolution condition validation to runtime and at that point you have no reason to use a switch at all even in non OOP languages as they have plenty of ways to reference functions at runtime, by name for example.

                                              you need to modify every switch statement.

                                              You absolutely don’t. Where did you get that from? Which language are you talking about?

                                              With a class hierarchy on the other hand, those switch statements are replaced by virtual function calls. You don’t need to modify those when you add another class to the hierarchy. You just need to add a class.

                                              This is what I am negating. You also need to modify the type that you use a subject to the switch, not only to produce it.

                                              What do you use as switch subject? An integer or string that takes any arbitrary value, or a predefined set/enumeration? There is no gain from using polymorphism in either case.

                                              As you noted, look at the code around you class instantiation. How can it possibly be different than the switch?

                                              Check “strategy pattern” on Rosetta code, Wikipedia, etc. For examples in virtually every language out there.

                                              An enumeration doesn’t replace a class hierarchy. The enumeration should be there in both cases as a lookup key. What the class hierarchy replaces is a function resolution mechanism. It is in no way less complex nor does it require to change the code in less places than other strategy pattern syntaxes.

                                              It is this sort of myth that made OOP so popular. People accepted an alleged advantage when in fact there was none.

                                              The one advantage I know if is the ability to pass a scope around with simple syntax. Obviously, people have abused this convenience to the point not making it a disadvantage.

                                              1. 2

                                                I should have given an example from the outset. I’ll use C++ which I’m familiar with. First, the enumeration example:

                                                enum FooBar { Foo, Bar, };
                                                
                                                void lowercase(Foobar v) {
                                                    switch (v) {
                                                    case Foo: printf("foo");
                                                    case Bar: printf("bar");
                                                    }
                                                }
                                                void uppercase(Foobar v) {
                                                    switch (v) {
                                                    case Foo: printf("FOO");
                                                    case Bar: printf("BAR");
                                                    }
                                                }
                                                

                                                Then the class hierarchy:

                                                class FooBar {
                                                    virtual void lowercase();
                                                    virtual void uppercase();
                                                };
                                                class Foo : public FooBar {
                                                    void lowercase() { printf("foo"); }
                                                    void uppercase() { printf("FOO"); }
                                                };
                                                class Bar : public FooBar {
                                                    void lowercase() { printf("bar"); }
                                                    void uppercase() { printf("BAR"); }
                                                };
                                                

                                                Okay, now we have the foundations. Note that I have not shown where lowercase() and uppercase() might be called, because we don’t care (modifications below won’t affect those). Nor did I show how and where values of type FooBar might be produced, because again, existing instantiations won’t need to be touched.

                                                Now let’s add a function, say, rot13(). First on the enum case:

                                                enum FooBar { Foo, Bar, };
                                                
                                                void lowercase(Foobar v) {
                                                    switch (v) {
                                                    case Foo: printf("foo");
                                                    case Bar: printf("bar");
                                                    }
                                                }
                                                void uppercase(Foobar v) {
                                                    switch (v) {
                                                    case Foo: printf("FOO");
                                                    case Bar: printf("BAR");
                                                    }
                                                }
                                                // New function (only modification)
                                                void rot13(Foobar v) {
                                                    switch (v) {
                                                    case Foo: printf("sbb");
                                                    case Bar: printf("one");
                                                    }
                                                }
                                                

                                                So, we just added one function, we didn’t touch the rest of the code. Now the class hierarchy:

                                                class FooBar {
                                                    virtual void lowercase();
                                                    virtual void uppercase();
                                                    virtual void rot13();  // new function
                                                };
                                                class Foo : public FooBar {
                                                    void lowercase() { printf("foo"); }
                                                    void uppercase() { printf("FOO"); }
                                                    void rot13()     { printf("sbb"); } // new function
                                                };
                                                class Bar : public FooBar {
                                                    void lowercase() { printf("bar"); }
                                                    void uppercase() { printf("BAR"); }
                                                    void rot13()     { printf("one"); } // new function
                                                };
                                                

                                                Here however, we needed to update the base class, and every single derived class so rot13() actually means something in every case. Not nice that a simple addition required us to update the code all over the place. Enums win this one.

                                                Now let’s try to add a new type of FooBar instead (another case if you will). First with the enums:

                                                enum FooBar { Foo, Bar, Baz, }; // new case
                                                
                                                void lowercase(Foobar v) {
                                                    switch (v) {
                                                    case Foo: printf("foo");
                                                    case Bar: printf("bar");
                                                    case Baz: printf("baz"); // new case
                                                    }
                                                }
                                                void uppercase(Foobar v) {
                                                    switch (v) {
                                                    case Foo: printf("FOO");
                                                    case Bar: printf("BAR");
                                                    case Baz: printf("BAZ"); // new case
                                                    }
                                                }
                                                

                                                Hmm, that’s not so good here: we had to update the base type, but more importantly, we needed to update every single switch case, so they could handle that new possibility (Baz). Let’s try that with the class hierarchy:

                                                class FooBar {
                                                    virtual void lowercase();
                                                    virtual void uppercase();
                                                };
                                                class Foo : public FooBar {
                                                    void lowercase() { printf("foo"); }
                                                    void uppercase() { printf("FOO"); }
                                                };
                                                class Bar : public FooBar {
                                                    void lowercase() { printf("bar"); }
                                                    void uppercase() { printf("BAR"); }
                                                };
                                                // New class (only modification)
                                                class Baz : public FooBar {
                                                    void lowercase() { printf("baz"); }
                                                    void uppercase() { printf("BAZ"); }
                                                };
                                                

                                                What do you know, we just added a class! No need to edit the code all over, the whole change is nicely concentrated on one place. Classes win that one.


                                                You can clearly see that depending on the nature of the edit (adding a function or a case), and the choice of construct (enums or classes), the number of piece of code you touch is not the “exact same” at all.

                                                1. 2

                                                  The code samples are not feature equivalent. You omitted the part where you instantiate the classes which needs to use the very same enumeration and a switch/if.else. That is precisely my point. OOP didn’t buy you any advantage in this case.

                                                  1. 1

                                                    The code samples are not feature equivalent.

                                                    Show me the difference, then.

                                                    You omitted the part where you instantiate the classes which […]

                                                    Which nothing. Those values could come from anywhere, from hard coded constants to the result of parsing. In many many cases, there’s no need to go through an enum.

                                                    Now let’s add that oh so important code I omitted. Let’s instantiate two enum values on the heap:

                                                    FooBar *f = new Foo;
                                                    FooBar *b = new Bar;
                                                    

                                                    Easy, right? Now let’s see how we would have instantiated classes:

                                                    Foobar *f = new Foo;
                                                    Foobar *b = new Bar;
                                                    

                                                    It’s the exact same code.

                                                    […] which needs to use the very same enumeration and a switch/if.else.

                                                    Okay, okay. Forgive the interruption. You say I need something. Let me show you code where you don’t. So…

                                                    std::vector<FooBar*> parseFooBar(std::string s)
                                                    {
                                                        std::vector<FooBar*> fbv;
                                                        for (char c : s) {
                                                            switch (c) {
                                                            case "f": fbv.push_back(new Foo); break;
                                                            case "F": fbv.push_back(new Foo); break;
                                                            case "b": fbv.push_back(new Bar); break;
                                                            case "B": fbv.push_back(new Bar); break;
                                                            default: ; // do nothing
                                                            }
                                                        }
                                                        return fbv;
                                                    }
                                                    

                                                    Voilà, we’ve just instantiated FooBar class elements without going through an enumeration type. Q.E.D. (Note that the exact same code would work if we were instantiating an enumeration instead of classes. I must insist: there really is no difference there.)

                                        1. 17

                                          Thank you so much for this. Those were the days. When software aimed to the general crowds were making huge leaps in all fronts at insane speed. So much nostalgia, a couple of my favourite skins are featured at the top.

                                          The MP3 explosion in 98-99 was crazy. While online video got into our lives incrementally over the course of two decades, the introduction of mp3 was metheoric. In mater of months, almost anyone could download, store or even produce sound files just with their computer. Allo of this at a perfectly fine quality taking up 10 times less disk space than with previous formats.

                                          A couple of years after windows xp is released, polished with all the features the user wanted: an image viewer, the reference web browser at the time, a media player and an email client. What happened? Why did the industry stop giving the people what they want and need? Where, when and why did we lost track?

                                          Winamp is still to this day my favourite piece of software. Fast, light, pragmatic, feature rich, resource efficient, configurable. It really whips the llama’s ass!

                                          1. 1

                                            It really was fantastic! How would one go about making winamp-inspired software today I wonder… What UI library or toolkit (if any) makes it possible (if not easy) to make such fun, lightweight, powerful interfaces? The playfulness is sorely missed in todays desktop software.

                                            1. 1

                                              I think this kind of creative play is still possible in web development if you’re willing to eschew all the performance-optimizing complexity, deep state graph management, and avoidance of “ugly” hacks like table layouts and single-browser CSS that big FE frameworks + UI toolkits bring with them. Just throw down some markup and styling and bang on some JS until it all hangs together. (Odds are even without strict adherence to web standards your random demo will still work in mainstream browsers 5-10 years hence, which is more than you can say for most desktop app “skins”.)

                                              Beyond that, some experiments with one of the WebGL+Canvas-targeting immediate-mode UI toolkits popular around these parts and /r/rust might be just the thing the get the creativity flowing if you want an even more open sandbox. :)

                                              1. 1

                                                I do use tables for layout, but otherwise agree. My sites work in mosaic, Netscape, ie, and modern chrome too

                                              2. 1

                                                FWIW I still use Winamp on Windows and Audacious, an OSS clone, on Linux! Audacious is pretty nice, though it has a perplexing implementation that relies heavily on dbus.

                                                1. 1

                                                  XMMS could be skinned, probably x11amp as well. To answer your question I guess Gtk offers this ability

                                              1. 20

                                                Kudos to the original author, not only for the high quality original content but for the creative use of phpBB as their blogging platform. Not only does this give simple content mark up, inline attachments and search for free, it also provides an all in one user commenting and subscription mailing capability by changing some basic forum settings, great idea!

                                                Another pleasant side effect is that it didn’t bring my current gen CPU to its knees rendering drop shadows, rounded corners and scrolling effects! :D

                                                1. 2

                                                  Agner’s been using forum software for his blog for a long time, although oddly enough the move to phpBB is recent (2019). From 2009–2019 he used a more minimalist forum that I don’t recognize. Possibly his own software?

                                                  1. 2

                                                    Interesting, the generator suggests AForum 1.4.2, but didn’t find anything further.

                                                    I first hosted and managed phpBB back in 2001, which is I guess why I find its use here so refreshing between the posts about frameworks and ways to bring back ‘the old web’.

                                                    With all the content management systems and hosted solutions out there, phpBB is a great example of an opensource community and product that has provided a reliable platform and consistent migration path for user owned, self hosted content for close to 20 years.

                                                    Sure it’s using PHP, which appears increasingly out of vogue with the modern wave a web development. But the stack is so ubiquitous it can be hosted reliably for pocket change.

                                                  2. 1

                                                    this is such a cool idea, i wonder why i haven’t seen it before. gotta investigate if it will work for me.

                                                    also it didn’t have a full screen banner image to scroll past, just a little BBS menu.

                                                    1. 5

                                                      i wonder why i haven’t seen it before.

                                                      I take it you didn’t surf the web much 10-15 years ago. Web forums software was king and there was all sorts of usage in all creative ways. With forum software authors themselves encourage such creative use and always pointing out that you could use it as a blog, a news site, issue tracker, an archive front end, etc.

                                                      Back in the day, I had this private phpbb forum in which I would archive thousands of posts per day I scrapped from a curated list of blogs via RSS. PHPbb shipped with its own custom made full text index. Searching large corpus was a breeze.

                                                      Good memories.

                                                      1. 2

                                                        The PHP forum wars of the 00’s is an era that shouldn’t be forgotten! and phpBB survived through it all.

                                                        Not only the inbuilt full text searching, the built in template and caching engine is also worth a mention.. a great piece of work that dramatically dropped resource usage in tightly packed shared hosting environments.

                                                    2. 1

                                                      Not a fan of php, but no complaints about the simplicity of the page phpbb generates.

                                                      1. 1

                                                        It made so much sense to me that I didn’t realize at all I was looking at an instance of phpBB.

                                                        Awesome idea.

                                                      1. 3

                                                        I do not want to be too negative nor sound condescending. But OP is just confused about his shell syntax and named parameter passing conventions/traditions.

                                                        The pipe is interpreted as an Unix pipe by the shell. There is absolutely nothing to fix on the tree utility on that regard. OP should absolutely read about quoting on his shell manual and use it.

                                                        Parameter parsing also does what is expected. Assembling a list by passing the same parameter many times is by no means the expected nor logical behaviour.

                                                        1. 3

                                                          There is at least one other GNU tool I can think of off the top of my head that builds a list when passed the same flag multiple times. Namely, GCC’s search path can be extended by passing -I<dir> any number of times.

                                                          Personally, I think it’s reasonable to complain about how a tool’s interface interacts with the shell it’s used in. Bash is, after all, also a GNU tool.

                                                          1. 3

                                                            Hi, OP here!

                                                            Yes, accepting the same arg several times to build up a list is a pattern we see also elsewhere, but don’t expect consistency from command line args, ever! For example, gcc will accept stuff like -Iblah with no space between flag and directory, but GNU tree insists on having a space between the flag and the pattern.

                                                        1. 8

                                                          This is an over simplification of a a whole set of details that vary case by case. JSON supports only maps, lists and basic types, all of which trivially mapped into built in data structures of virtually any high level general purpose programming language. That’s fine and straightforward. But in the case of SQL, I’ll argue that your program doesn’t, and practicality won’t effectively, have awareness of an SQL ‘thing’ other than that string being a string. Perhaps with typed placeholders but that is all. There are attempts to parse the syntax but they are never 100% mirroring the parser of the RDBMS. And even if they would, you would still have the semantics left, and even if you theoreticaly would reach semantic validation pairity with your RDBMS, you would still need to validate the queries against your schema. At this point you have built an RDBMs minus the storage engine and a couple of other piecees, and should ask yourself why you are using an RDBMS.

                                                          The post is well intended and has good theoretical advice but lacks engineering insight. Creating types for everything and nothing and expecting to be able to have a bullet proof validation for things like SQL is a fast way to build an horrible over complicated API no one likes to use. Even things like URLs and CSV files are decievingly complex with tons of corner cases and pitfalls. You are better off using them as strings and write your own validation on the stricter side for your specific case.

                                                          1. 7

                                                            I’m not even convinced that inconsistent style warrants discussion. Is there any evidence that mixed-style code is significantly harder to read? I think compared to things like good documentation and naming whether it’s

                                                            void frobnicate(foo* bar) {
                                                            ...
                                                            

                                                            or

                                                            void frobnicate(foo* bar) 
                                                            {
                                                            ...
                                                            

                                                            isn’t going to slow me down at all.

                                                            Either way, automatic reformatting is indeed probably be a good solution.

                                                            1. 20

                                                              I personally disagree — inconsistently formatted code causes me significant distraction. Yes, even braces on the “wrong” line.

                                                              I mostly wish that weren’t the case, of course. OTOH, though, if that part of my brain were “fixed”, it seems likely it’d reduce my ability to be the “details person” on my team that catches all the little typos/subtle logic bugs before they ship.

                                                              1. 4

                                                                I think it’s less in the example you give (which is pretty straightforward) and more calling out something like this:

                                                                void frobnicate(foo* bar)  {
                                                                   if (abc) 
                                                                   {
                                                                       } else if (def) {
                                                                   if (ghi) {
                                                                       }  
                                                                   }
                                                                

                                                                If you have enough indentation, I find it confusing.

                                                                1. 4

                                                                  I agree. Ultimately it’s a non important detail. We all have preferences and different styles have their advantages and disadvantages. Hence the reason they exist. I’ve seen this taking 25-75% or the effort and time put into reviewing code. Often above 50%. Whatever importance this has, it is tiny when compared to what the code actually does, regardless whatever style it is written in.

                                                                  1. 3

                                                                    For me, it’s like reading a novel vs a variety of websites with different styles. I can surely get through either, but the former’s consistency reduces my effort significantly.

                                                                    1. 3

                                                                      Is there any evidence that mixed-style code is significantly harder to read?

                                                                      Speaking as someone who actually has worked on code with inconsistent formatting … not really, no. Usually.

                                                                      On one project I worked on, each developer largely kept to their own directories, so everyone just kept to their own preferred style. Later in the project, though, we all finished the main work and started venturing outside of our little fiefdoms to fix bugs and whatnot. I would painstakingly write in the formatting style of whatever file I was in, at first, but then I noticed that nobody else seemed to be doing that, and over time you would see more and more places where the formatting style would abruptly shift for five lines. I found this deeply ugly, but apparently it didn’t bother the others enough to stop doing it. (Indeed, one engineer joked that it provided an instant fingerprint of who touched the code last, without having to look at version control.) So, it was annoying to me, but it didn’t really slow down comprehension.

                                                                      However, another project I worked on was run by a bunch of novice engineers with no consistent style. One day I wasted a bunch of time trying to debug a very long function before finally realizing that, through the course of modifying the code, the indentation had gotten out of sync with the braces depth, meaning that the end of an if block was actually dozens of lines off from where I had been reading. Only the lack of a consistent style (and primitive text editors) made such a glaring mistake possible.

                                                                      So, I’m more inclined to say: it doesn’t matter, until it does.

                                                                      1. 3

                                                                        Agreed. A sufficiently advanced code base will contain not only mixed formatting but mixed programming styles. Some parts will favor composition over inheritance, another might’ve been written in a semi-functional style.

                                                                        Yet other parts of the code will have been written at a time when certain language features weren’t available, like Java Collections or unique_ptr. It’s your job to read and understand all of them.

                                                                        If inconsistency is something you can’t tolerate, then you’ll have a long and unproductive career ahead of you. Maybe programming isn’t the right job for you?

                                                                        1. 2

                                                                          I agree it’s a small thing, but it’s the principle that’s important.

                                                                          Consistency only works if you’re consistent with it. :)

                                                                        1. 2

                                                                          Because it actually believes you meant what you said. Because a programmer is a kind of professional who tells computers what to do, not the other way around.

                                                                          1. 11

                                                                            Software flaws have real material costs which often manifest as sprawling negative externalities, and C makes writing complex software without these flaws basically impossible. Consider the costs of heartbleed, the Cloudflare memory disclosure bug, or every bug in SMS/MMS parsing that can brick users’ phones.

                                                                            Professionals in other lines of work use tools that prevent mistakes all the time, refusing to use tools that let you work safely because you need to stroke your ego is amateur hour.

                                                                            1. 6

                                                                              With that argumentation you can throw out all of the PLT advancements of the last decades (type systems, formal verification, contracts, …) because why would anyone need that if the computer already does what I say? I vehemently disagree with you, making the computer “do what I say” is not enough to produce working and correct software in any non-trivial capacity.

                                                                              1. 1

                                                                                No, not at all. There are many great advances out there to make it easier to say what you mean, all of which are valuable. But, once you’ve laid that framework, once you’ve defined the language, if the programmer says something that can be given a valid interpretation within the documented rules of the game, it’s the computer’s responsibility to do exactly that thing.

                                                                                (Having tools that check for mistakes, i.e. linters, is of course fair game.)

                                                                              2. 5

                                                                                which is why we all write assembly, instead of using languages that might rewrite our code behind our back or check whether we made one mistake in thousands of lines of code, being professionals who by definition are all knowing and error-free.

                                                                                1. 1

                                                                                  Only when it comes in handy :)

                                                                                2. 2

                                                                                  Totally underrated view.

                                                                                  I personally didn’t sign up for this mindset that everyone just writes buggy code (read:low quality code) and the we throw linters, static analysis tools, compiler warnings and whatnot at it. Then quality should mysticaly spring to life like ghosts separating from dead bodies in horror movies, I suppose.

                                                                                  There must be a limit to how many errors are reasonable. “There’s no bug free code” doesn’t mean that anything goes.

                                                                                1. 9

                                                                                  If only one could write a piece of software for fun, as a hobby, as an exercise, as a learning tool, or simply because they need it… And just publish it in case it is useful to other people…

                                                                                  Instead we have silly one liners like left-pad packed as a library with a license.

                                                                                  When did this happen? When did hackers stopped hacking to engage in this licensing silliness?

                                                                                  No offense to OP, but reading “I will explain why this matters” made me yawn.

                                                                                  I could write an essay on why one don’t care, but that would kind of disprove my point. I’ll brew some coffee and work on a side project of mine instead.

                                                                                  1. 14

                                                                                    I don’t see where your complaint is coming from. Plenty of people write code as a hobby, for learning purposes, or “just because”, and then release it just in case anybody wants to use it. That’s probably 95% of GitHub projects.

                                                                                    But a project that’s actively seeking out users (as JSHint seems to be), isn’t being release “just in case it’s useful to other people”. If they want more users, they need to have a license that users are comfortable with. It’s always worked that way.

                                                                                    1. 4

                                                                                      It was not intended to be a complaint. More of a lament maybe. I too am guilty and am part of those 95%. Was just challenging the meaning and even the usefulness of the whole thing. Not trying to blame anyone or a specific group of people in particular. Although the other comment that mentioned the FSF did make me giggle.

                                                                                      Somewhere along the way, we let a too large slice of our energy to be directed towards what is ultimately irrelevant from a hacker’s perspective.

                                                                                      Imagine you visit your grandmother and she cooks your favourite dish the way she did since your childhood. That is all you would want, I’m sure you wouldn’t want a lecture about the legalities of the recipe before you can touch the food.

                                                                                      1. 7

                                                                                        Imagine you visit your grandmother and she cooks your favourite dish the way she did since your childhood. That is all you would want, I’m sure you wouldn’t want a lecture about the legalities of the recipe before you can touch the food.

                                                                                        I mean, true, but food enjoys this privilege because recipes are still not covered by copyright. There are no people being sued (under copyright law) for having cooked a recipe.

                                                                                    2. 9

                                                                                      When did this happen? When did hackers stopped hacking to engage in this licensing silliness?

                                                                                      Well, the FSF was founded in 1985…

                                                                                      1. 3

                                                                                        When did this happen? When did hackers stopped hacking to engage in this licensing silliness?

                                                                                        Licensing is itself an opportunity for hacking - the GNU GPL is itself a rather clever hack of the intellectual property law system.

                                                                                        I wouldn’t call software licensing “silliness” in any case - the legal terms under which software can be distributed is within the legitimate purview of people who care about writing software.

                                                                                        1. 3

                                                                                          And just publish it in case it is useful to other people…

                                                                                          So long as it has a license that allows those other people to use it, this seems like the whole point? There are only like three real choices (GPL-or-so, ISC-or-so, Apache-or-so) for a hobby project, just roll the dice (or follow your principles if you have some) and copy the same COPYING file into every project. Doesn’t seem like a massive burden?

                                                                                        1. 1

                                                                                          This looks like nice work. Can you run down when you might prefer to use this versus fff versus ranger? I feel like most times where I’d want this, I’ve got curses and python, so I’d just use ranger. Which makes me think I’m missing something.

                                                                                          1. 4

                                                                                            This is great for smaller environments which may not have bash, ncurses, python, etc. There’s a Linux distribution that will be putting it in their initrd for example. It’s also good for environments where disk space is limited. I also personally no longer use bash so I’ve ported everything I use over to POSIX shell or C.

                                                                                            Edit: Should also mention that it’s all contained in a single file and there’s no compilation step necessary!

                                                                                            1. 1

                                                                                              There’s a Linux distribution that will be putting it in their initrd for example.

                                                                                              Just curious, which Linux distro would that be? :)

                                                                                              1. 1

                                                                                                Including it in initrd hadn’t occurred to me. It seems especially useful for that.

                                                                                                Does it work well with the ash that busybox ships?

                                                                                                1. 1

                                                                                                  Yes it does. It should work in all POSIX shells. If not, that’s a bug. :)

                                                                                              2. 2

                                                                                                Don’t know if Dylan will agree, but I like to think it’s less about “needing” this, and more about how creative you can get with limited resources—Creative limitation. It’s a really fun exercise in programming. For me, personally, I like trying to (re)write most of my tooling in pure bash—no external programs called whatsoever. And shfm, I feel, was something born out of the idea that fff (pure bash) could possibly be simplified further (POSIX sh).

                                                                                                1. 3

                                                                                                  The need is deceivingly greater than it might occur to most people. Many systems don’t have much of what the average shell user is used to. NASes, plug computers, microcomputers, or even containers. Buying into tens or even hundreds of megabytes of dependencies always comes with considerable costs. An usually ignored downside of dependencies is their hit on software longevity.

                                                                                                  This adds a great deal of ergonomics and convenience in the form of a simple text file, that works has tiny dependencies. Even ncurses is left outside the dependency list. If you are in an unix shell and can open a socket to a remote internet location, you can use this. And most likely will be able to do so for many years to come.

                                                                                              1. 1

                                                                                                Is it just me or are this and the article this replies to, essentially arguing for the opposite nor that their titles claim?

                                                                                                1. 12

                                                                                                  “You don’t know what you’re doing” is not an insult, it’s a give-or-take statement of fact. People need to stop taking things so personally. Your essay ends with “Make it bug free”. I would guess the industry average is something like 10 bugs for every 1,000 lines of code… Most people thinking of rolling their own crypto, history shows, do not know what they’re doing, lest it wouldn’t be an oft-repeated warning.

                                                                                                  1. 9

                                                                                                    “You don’t know what you’re doing” is not an insult, it’s a give-or-take statement of fact. People need to stop taking things so personally.

                                                                                                    I despise the current culture of deeming everything as possible offensive as much as the other guy. But that is not the issue. Who asserts who gets to say that to whom? Because if someone asks a simple question on stackoverflow they must absolutely be a noob… (/sarcasm). Perhaps the number one expert in information theory in the world never bothered with cryptography particularly and just feels like throwing a simple question. Or perhaps the question is just decisively more complicated than a bunch of one line replies.

                                                                                                    The noob that committed the heresy of pushing their own implementation of rc4 to github must absolutely be pointed out that “thou shall not roll their own crypto”! Ever! Light that holly fire!

                                                                                                    Seriously. The problem with such condescending “statements of fact” is not that they are insulting. The problem is that they are gratuitous assertions of own expertise, 99% of the times with no leg to stand on.

                                                                                                    Furthermore, the well established libraries out there were written by someone. How dare they rolled their own cryptos? Oh.. they are the experts…. ok… how did they become the experts? By writing them?

                                                                                                    When someone states that something “is difficult to understand”, it is more likely that they are the ones that don’t understand it, rather than the person they are talking to.

                                                                                                    1. 3

                                                                                                      The noob that committed the heresy of pushing their own implementation of rc4 to github must absolutely be pointed out that “thou shall not roll their own crypto”! Ever! Light that holly fire!

                                                                                                      Are they using that implementation of RC4 in a piece of software used by a community or paying customers? The crypto being broken or buggy doesn’t matter in a vacuum, it’s also about where and/or why the cryptography is being deployed.

                                                                                                      Seriously. The problem with such condescending “statements of fact” is not that they are insulting. The problem is that they are gratuitous assertions of own expertise, 99% of the times with no leg to stand on.

                                                                                                      I disagree. If I say to someone “don’t try to build a nuclear reactor with americium stolen from fire alarms”, I’m not saying “I’m an expert in radiation and nuclear reactor construction”, I’m saying “from what I’ve seen and heard from the experts, that is a terrible idea”.

                                                                                                      how did they become the experts? By writing them?

                                                                                                      By learning enough to feel competent in writing libraries. Keep in mind, “well established” libraries are the crème de la crème of the n-hundred libraries you will find on Github or wherever, they’re not just random libraries someone decided to put together one day but well-designed, thought out pieces on software developed from a position of deep understanding.

                                                                                                      When someone states that something “is difficult to understand”, it is more likely that they are the ones that don’t understand it, rather than the person they are talking to.

                                                                                                      Maybe. Other situations include: One does understand it, they both understand it, or neither of them under it.

                                                                                                      1. 3

                                                                                                        Seriously. The problem with such condescending “statements of fact” is not that they are insulting. The problem is that they are gratuitous assertions of own expertise, 99% of the times with no leg to stand on.

                                                                                                        It’s true some people are doing this. But mostly what is happening is locals repeating a cultural warning. The locals have no special expertise and don’t think they do. But they know a lot of people have been killed at that beach over there – they may not know why, exactly – and they’re passing the information along.

                                                                                                        This seems like a very good thing to me.

                                                                                                        People who are truly interested in digging into the matter deeper, like the OP, can do so.

                                                                                                      2. 9

                                                                                                        Statements of fact can be insulting, but that can still be effective. Shaming someone into stopping what they are doing can and does work to some extent. Make them look like an idiot, and that would at least deter others from using their work, if they don’t stop altogether.

                                                                                                        People who don’t know what they are doing are generally not even aware of what they should know. Like someone inventing their own cipher without even thinking of authentication. Why? Because they are treating cryptography like a soft magic system. They think they can get away with whatever they come up with because they don’t know how rigid the rules actually are.

                                                                                                        Modern cryptographic primitives and constructions are actually one of the easiest thing to make bug free. Constant time code have extremely predictable code paths, that only depend on the length of its parameters. It’s stupidly easy to test. There are some caveats of course (modular arithmetic, being clever with elliptic curves), but if you do the simple thing and imitate existing designs, there isn’t much room for error. “Bug free” is quite possible.

                                                                                                      1. 3

                                                                                                        I put together this command line tool so I could easily extract data from webpages on my scripts:

                                                                                                        https://github.com/plainas/tq

                                                                                                        I added JSON encoding so I can reliably feed its output to other tools without shell escaping pitfalls.

                                                                                                        1. 1

                                                                                                          Ah, cool! I think I landed on tq when I was researching tools on GitHub.

                                                                                                          I added JSON encoding so I can reliably feed its output to other tools without shell escaping pitfalls.

                                                                                                          I would be interested in any guidance on what to look out for. I’m still not 100% comfortable with shells, so I’m not sure what some common pitfalls are. Initially, the query language used $ instead of @ for selecting HTML attributes, but was quickly disabused of this idea when I tried to write my first query string at the command line…

                                                                                                          1. 2

                                                                                                            There is no formal concept of collection when passing data through a pipe. Unix tradition resources to the convention of one element per line. But this means that your data can’t contain line separators. Json en encoding solves this problem.

                                                                                                            tq has has a flag to JSON encode each entry and separate them by a newline separator. This way, you can safely squeeze arbitrary multilne text into each element, because newlines are json-encoded.

                                                                                                            Using stdin to pass this data is otherwise surprise-free. On the other hand, passing data as args is probably impossible to cover all cases. At least for the most common shells we all use. There is shell expansions, which you already mentioned. Variable expansions, escape sequences, command substitution, built in shell syntax such as < or & and the worst of all: quoting. I don’t know a safe way of feeding data into xargs that is bullet proof.

                                                                                                            1. 1

                                                                                                              Thank you for the details. I was curious to read more on the topic, and I landed on this summary. Yikes!

                                                                                                        1. 5

                                                                                                          Because of struggling with learning jq, I’ve created fx (https://github.com/antonmedv/fx) which uses JavaScript (which I know enough).

                                                                                                          1. 2

                                                                                                            Interesting. I usually pipe JSON to “gron | percol”. The result key is usually (not always) ready to feed to jq as a selector.

                                                                                                            Fx is somewhat the same idea.

                                                                                                          1. 4

                                                                                                            It is not really accurate to call it “left-pad incident” it is a fiasco. Not an incident. Incident implies a unpredictable and unexpected error. Anyone looking at the dependency tree of most JavaScript projects and not expecting exactly what happenned had some really weird beliefs.

                                                                                                            The week before the whole left pad fiasco, a coworker of mine age 50+ had his first exposure to JavaScript. His reaction was disbelief. His words were: “you have to download the internet because of some dependency, one of these days, somebody will delete a popular module and everything will break”. The obvious turned out to be true… Obviously.

                                                                                                            1. 5

                                                                                                              My experience with it has been extremely negative. Have been working with it for the past few years in three companies I consulted for. In one instance, they replaced two rest APIs running on EC2 with handrolled redundancy and zero downtime automated deployments using only AWS CLI and a couple of tiny shellscripts with a kubernetes cluster. Server costs jumped 2000% (not a typo) and downtimes became an usual thing for all sorts of unknown reasons that often took hours for the “expert” proponents of kubernetes to figure out.

                                                                                                              There’s probably not so many alternatives to it, but for the very narrow spectrum of problems it solves for a given company, you would probably build whatever you need more reliably and elegantly without bringing in a gigantic amount of complexity and computing power overhead.

                                                                                                              Is running containers on servers such a big problem to solve? Is dynamically and programatically routing hostnames to services so difficult? Is it so difficult to put a couple of replicas of a service behind a load balancer and redeploy them one at a time with live checks so the service never goes down? Is creation of resources such as VMs, container instances, storage volumes, etc. on cloud services on build time such a difficult thing?

                                                                                                              Frankly, I find the answer to all these questions to be ‘No’. Maybe you just hired code monkeys capable of imitating whatever the current hype is, rather than skilled engineers / hackers. If you are thinking of the famous Virdning’s first rule of programming then my suggestion to you is: Create an Erlang/OTP cluster instead. It is much simpler, sane, and straight forward. And has a better trackrecord.

                                                                                                              Furthermore, I find kubernetes badly engineered on the surface. Grep your service name on your yaml files and you will get 10-30 hits. That alone is screams of bad design. Also, why are the yaml manifest so intricated tree structures? When did we forget that complex config structures are an horrible idea that has caused endless suffering? Why are they not simple flat configs? Why isn’t the canonical case achieve with the defaults requiring zero configuration?

                                                                                                              I get that it is hip, and probably 50%+ of all developers in the world praise “from google” as the pinnacle of software, but it is just a piece of software with very questionable quality and certainly over-estimated utility.

                                                                                                              It is so complicated to run, that people think they sound smart by saying: “never host it yourself!”. Yet services like GCP have embarrassingly long downtimes. In several instances bring people’s services down for hours.

                                                                                                              I do like people to use it, it means easier to beat competition.