From 54947f15c294a2c4311c94a18004d157fe424465 Mon Sep 17 00:00:00 2001 From: Yorhel Date: Mon, 29 Jan 2018 14:32:46 +0100 Subject: [PATCH] Whole bunch of changes and releases --- dat/doc | 4 + dat/doc-funcweb | 571 +++++++++++++++++++++++++++++++++ dat/dump | 2 +- dat/ncdc | 9 +- dat/ncdu | 10 +- dat/ncdu-changelog | 9 + dat/ncdu-jsonfmt | 48 ++- dat/ncdu-man | 33 +- dat/ncdu-scr | 18 +- dat/nginx-confgen | 54 ++++ dat/nginx-confgen-changelog | 8 + dat/nginx-confgen-man | 285 ++++++++++++++++ dat/tuwf | 12 +- dat/tuwf-changelog | 7 + download/TUWF-1.1.tar.gz.asc | 16 + download/TUWF-1.1.tar.gz.md5 | 1 + download/TUWF-1.1.tar.gz.sha1 | 1 + download/code/awshrink | 166 ++++++++++ download/code/bbcode.c | 330 +++++++++++++++++++ download/code/echoserv.c | 180 +++++++++++ download/code/grenamr-0.1.pl | 248 ++++++++++++++ download/code/mdc2-parse.pl | 150 +++++++++ download/code/nccolour.c | 99 ++++++ download/code/vinfo.c | 326 +++++++++++++++++++ download/code/yapong-0.01.c | 342 ++++++++++++++++++++ download/code/yapong.c | 335 +++++++++++++++++++ download/ncdu-1.13.tar.gz.asc | 16 + download/ncdu-1.13.tar.gz.md5 | 1 + download/ncdu-1.13.tar.gz.sha1 | 1 + img/ncduconfirm-2.png | Bin 0 -> 42545 bytes img/ncdudone-2.png | Bin 0 -> 24131 bytes img/ncduhelp1-2.png | Bin 0 -> 32518 bytes img/ncduhelp2-2.png | Bin 0 -> 26289 bytes img/ncduinfo-2.png | Bin 0 -> 36225 bytes img/ncduscan-2.png | Bin 0 -> 15540 bytes index.cgi | 27 +- 36 files changed, 3269 insertions(+), 40 deletions(-) create mode 100644 dat/doc-funcweb create mode 100644 dat/nginx-confgen create mode 100644 dat/nginx-confgen-changelog create mode 100644 dat/nginx-confgen-man create mode 100644 download/TUWF-1.1.tar.gz.asc create mode 100644 download/TUWF-1.1.tar.gz.md5 create mode 100644 download/TUWF-1.1.tar.gz.sha1 create mode 100644 download/code/awshrink create mode 100644 download/code/bbcode.c create mode 100644 download/code/echoserv.c create mode 100644 download/code/grenamr-0.1.pl create mode 100644 download/code/mdc2-parse.pl create mode 100644 download/code/nccolour.c create mode 100644 download/code/vinfo.c create mode 100644 download/code/yapong-0.01.c create mode 100644 download/code/yapong.c create mode 100644 download/ncdu-1.13.tar.gz.asc create mode 100644 download/ncdu-1.13.tar.gz.md5 create mode 100644 download/ncdu-1.13.tar.gz.sha1 create mode 100644 img/ncduconfirm-2.png create mode 100644 img/ncdudone-2.png create mode 100644 img/ncduhelp1-2.png create mode 100644 img/ncduhelp2-2.png create mode 100644 img/ncduinfo-2.png create mode 100644 img/ncduscan-2.png diff --git a/dat/doc b/dat/doc index 2dfbc0d..ac48c15 100644 --- a/dat/doc +++ b/dat/doc @@ -8,6 +8,10 @@ rare occasions are published on this page. =over +=item C<2017-05-28 > - L + +The title says it all. + =item C<2014-07-29 > - L A long rant about IPC systems. diff --git a/dat/doc-funcweb b/dat/doc-funcweb new file mode 100644 index 0000000..cdc1d48 --- /dev/null +++ b/dat/doc-funcweb @@ -0,0 +1,571 @@ +An Opinionated Survey of Functional Web Development + +=pod + +(Published on B<2017-05-28>.) + +=head1 Intro + +TL;DR: In this article I provide an overview of the frameworks and libraries +available for creating websites in statically-typed functional programming +languages. + +I recommend you now skip directly to the next section, but if you're interested +in some context and don't mind a rant, feel free to read on. :-) + +B<< >> + +When compared to native desktop application development, web development just +sucks. Native development is relatively simple with toolkits such as +L, L and others: You have +convenient widget libraries, and you can describe your entire application, from +interface design to all behavioural aspects, in a single programming language. +You're also largely free to structure code in whichever way makes most sense. +You can describe what a certain input field looks like, what happens when the +user interacts with it and what will happen with the input data, all succinctly +in a single file. There are even drag-and-drop UI builders to speed up +development. + +Web development is the exact opposite of that. There are several different +technologies you're forced to work with even when creating the most mundane +website, and there's a necessary but annoying split between code that runs on +the server and code that runs in the browser. Creating a simple input field +requires you to consider and maintain several ends: + +=over + +=item + +The back end (server-side code) that describes how the input field interacts +with the database. + +=item + +Some JavaScript code to describe how the user can interact with the input +field. + +=item + +Some CSS to describe what the input field looks like. + +=item + +And then there's HTML to act as a glue between the above. + +=back + +In many web development setups, all four of the above technologies are +maintained in different files. If you want to add, remove or modify an input +field, or just about anything else on a page, you'll be editing at least four +different files with different syntax and meaning. I don't know how other +developers deal with this, but the only way I've been able to keep these places +synchronized is to just edit one or two places, test if it works in a browser, +and then edit the other places accordingly to fix whatever issues I find. This +doesn't always work well: I don't get a warning if I remove an HTML element +somewhere and forget to also remove the associated CSS. Heck, in larger +projects I can't even tell whether it's safe to remove or edit a certain line +of CSS because I have no way to know for sure that it's not still being used +elsewhere. Perhaps this particular case can be solved with proper organization +and discipline, but similar problems exist with the other technologies. + +Yet despite that, why do I still create websites in my free time? Because it is +the only environment with high portability and low friction - after all, pretty +much anyone can browse the web. I would not have been able to create a useful +"L" any other way than through a +website. And the entire purpose of L is to +provide quick access to man pages from anywhere, which is not easily possible +with native applications. + +B<< >> + +Fortunately, I am not the only one who sees the problems with the "classic" +development strategy mentioned above. There are many existing attempts to +improve on that situation. A popular approach to simplify development is the +L (SPA). The +idea is to move as much code as possible to the front end, and keep only a +minimal back end. Both the HTML and the entire behaviour of the page can be +defined in the same language and same file. With libraries such as +L and browser support for L, the +split between files described above can be largely eliminated. And if +JavaScript isn't your favorite language, there are many alternative languages +that compile to JavaScript. (See L for +an excellent series of articles on that topic). + +While that approach certainly has the potential to make web development more +pleasant, it has a very significant drawback: Performance. For some +applications, such as web based email clients or CRM systems, it can be +perfectly acceptable to have a megabyte of JavaScript as part of the initial +page load. But for most other sites, such as this one, or the two sites I +mentioned earlier, or sites like Wikipedia, a slow initial page load is +something I consider to be absolutely unacceptable. The web can be really fast, +and developer laziness is not a valid excuse to ruin it. (If you haven't seen +or read L yet, please do so now). + +I'm much more interested in the opposite approach to SPA: Move as much code as +possible to the back end, and only send a minimal amount of JavaScript to the +browser. This is arguably how web development has always been done in the past, +and there's little reason to deviate from it. The difference, however, is that +people tend to expect much more "interactivity" from web sites nowadays, so the +amount of JavaScript is increasing. And that is alright, so long as the +JavaScript doesn't prevent the initial page from loading quickly. But this +increase in JavaScript does amplify the "multiple files" problem I ranted about +earlier. + +So my ideal solution is a framework where I can describe all aspects of a site +in a single language, and organize the code among files in a way that makes +sense to me. That is, I want the same kind of freedom that I get with native +desktop software development. Such a framework should run on the back end, and +automatically generate efficient JavaScript and, optionally, CSS for the front +end. As an additional requirement (or rather, strong preference), all this +should be in a statically-typed language - because I am seemingly incapable of +writing large reliable applications with dynamic typing - and in a language +from functional heritage - because programming in functional languages has +spoiled me. + +I'm confident that what I describe is possible, and it's evident that I'm not +the only person to want this, as several (potential) solutions like this do +indeed exist. I've been looking around for these solutions and have +experimented with a few that looked promising. This article provides an +overview of what I have found so far. + +=head1 OCaml + +My adventure began with L. It's been a few years +since I last used OCaml for anything, but development on the language and its +ecosystem have all but halted. L +has been a great resource to get me up to speed again. + +=head2 Ocsigen + +For OCaml there is one project that has it all: L. +It comes with an OCaml to JavaScript compiler, a web server, several handy +libraries, and a L to put everything +together. Its L allows you to mix +front and back end code, and you can easily share code between both ends. The +final result is a binary that runs the server and a JavaScript file that +handles everything on the client side. + +The framework comes with an embedded DSL with which you can conveniently +generate HTML without actually typing HTML. And best of all, this DSL works on +both the client and the server: On the server side it generates an HTML string +that can be sent to the client, and running the same code on the client side +will result in a DOM element that is ready to be used. + +Ocsigen makes heavy use of the OCaml type system to statically guarantee the +correctness of various aspects of the application. The HTML DSL ensures not +only that the generated HTML well-formed, but also prevents you from +incorrectly nesting certain elements and using the wrong attributes on the +wrong elements. Similarly, an HTML element generated on the server side can be +referenced from client side code without having to manually assign a unique ID +to the element. This prevents accidental typos in the ID naming and guarantees +that the element that the client side code refers to actually exists. URL +routing and links to internal pages are also checked at compile time. + +Ocsigen almost exactly matches what I previously described as the perfect +development framework. Unfortunately, it has a few drawbacks: + +=over + +=item + +The generated JavaScript is quite large, a bit over 400 KiB for an hello world. +In my brief experience with the framework, this also results in a noticeably +slower page load. I don't know if it was done for performance purposes, but +subsequent page views are per default performed via in-browser XHR requests, +which do not require that all the JavaScript is re-parsed and evaluated, and is +thus much faster. This, however, doesn't work well if the user opens pages in +multiple tabs or performs a page reload for whatever reason. And as I +mentioned, I care a lot about the initial page loading time. + +=item + +The framework has a steep learning curve, and the available documentation is by +far not complete enough to help you. I've found myself wondering many times how +I was supposed to use a certain API and have had to look for example code for +enlightenment. At some point I ended up just reading the source code instead of +going for the documentation. What doesn't help here is that, because of the +heavy use of the type system to ensure code correctness, most of the function +signatures are far from intuitive and are sometimes very hard to interpret. +This problem is made even worse with the generally unhelpful error messages +from the compiler. (A few months with L and +its excellent error messages has really spoiled me on this aspect, I suppose). + +=item + +I believe they went a bit too far with the compile-time verification of certain +correctness properties. Apart from making the framework harder to learn, it +also increases the verbosity of the code and removes a lot of flexibility. For +instance, in order for internal links to be checked, you have to declare your +URLs (or I, as they call it) somewhere central such that the view +part of your application can access it. Then elsewhere you have to register a +handler to that service. This adds boilerplate and enforces a certain code +structure. And the gain of all this is, in my opinion, pretty small: In the 15 +years that I have been building web sites, I don't remember a single occurrence +where I mistyped the URL in an internal link. I do suppose that this feature +makes it easy to change URLs without causing breakage, but there is a trivial +counter-argument to that: L. (Also, somewhat ironically, +I have found more dead internal links on the Ocsigen website than on any other +site I have visited in the past year, so perhaps this was indeed a problem they +considered worth fixing. Too bad it didn't seem to work out so well for them). + +=back + +Despite these drawbacks, I am really impressed with what the Ocsigen project +has achieved, and it has set a high bar for the future frameworks that I will +be considering. + + +=head1 Haskell + +I have always seen Haskell as that potentially awesome language that I just +can't seem to wrap my head around, despite several attempts in the past to +learn it. Apparently the only thing I was missing in those attempts was a +proper goal: When I finally started playing around with some web frameworks I +actually managed to get productive in Haskell with relative ease. What also +helped me this time was a practical introductory Haskell reference, L, in +addition to the more theoretical L. + +Haskell itself already has a few advantages when compared to OCaml: For one, it +has a larger ecosystem, so for any task you can think of there is probably +already at least one existing library. As an example, I was unable to find an +actively maintained SQL DSL for OCaml, while there are several available for +Haskell. Another advantage that I found where the much more friendly and +detailed error messages generated by the Haskell compiler, GHC. In terms of +build systems, Haskell has standardized on +L, which works alright most of the time. +Packaging is still often complex and messy, but it's certainly improving as +L is gaining more widespread adoption. Finally, +I feel that the Haskell syntax is slightly less verbose, and more easily lends +itself to convenient DSLs. + +Despite Haskell's larger web development community, I could not find a single +complete and integrated client/server development framework such as Ocsigen. +Instead, there are a whole bunch of different projects focussing on either the +back end or the front end. I'll explore some of them with the idea that, +perhaps, it's possible to mix and match different libraries and frameworks in +order to get the perfect development environment. And indeed, this seems to be +a common approach in many Haskell projects. + +=head2 Server-side + +Let's start with a few back end frameworks. + +=over + +=item Scotty + +L is a web framework inspired by +L. I have no experience with (web) +development in Ruby and have never used Sinatra, but it has some similarities +to what I have been using for a long time: L. + +Scotty is a very minimalist framework; It does routing (that is, mapping URLs +to Haskell functions), it has some functions to access request data and some +functions to create and modify a response. That's it. No database handling, +session management, HTML generation, form handling or other niceties. But +that's alright, because there are many generic libraries to help you out there. + +Thanks to its minimalism, I found Scotty to be very easy to learn and get used +to. Even as a Haskell newbie I had a simple website running within a day. The +documentation is appropriate, but the idiomatic way of combining Scotty with +other libraries is through the use of Monad Transformers, and a few more +examples in this area would certainly have helped. + +=item Spock + +Continuing with the Star Trek franchise, there's +L. Spock is very similar to Scotty, but comes with +type-safe routing and various other goodies such as session and state +management, L +protection and database helpers. + +As with everything that is (supposedly) more convenient, it also comes with a +slightly steeper learning curve. I haven't, for example, figured out yet how to +do regular expression based routing. I don't even know if that's still possible +in the latest version - the documentation isn't very clear. Likewise, it's +unclear to me what the session handling does exactly (Does it store something? +And where? Is there a timeout?) and how that interacts with CSRF protection. +Spock seems useful, but requires more than just a cursory glance. + +=item Servant + +L is another minimalist web +framework, although it is primarily designed for creating RESTful APIs. + +Servant distinguishes itself from Scotty and Spock by not only featuring +type-safe routing, it furthermore allows you to describe your complete public +API as a type, and get strongly typed responses for free. This also enables +support for automatically generated documentation and client-side API wrappers. + +Servant would be an excellent back end for a SPA, but it does not seem like an +obvious approach to building regular websites. + +=item Happstack / Snap / Yesod + +L, L and +L are three large frameworks with many +auxiliary libraries. They all come with a core web server, routing, state and +database management. Many of the libraries are not specific to the framework +and can be used together with other frameworks. I won't go into a detailed +comparison between the three projects because I have no personal experience +with any of them, and fortunately L +in 2012 - though I don't know how accurate that still is today. + +=back + +So there are a fair amount of frameworks to choose from, and they can all work +together with other libraries to implement additional functions. Apart from the +framework, another important aspect of web development is how you generate the +HTML to send to the client. In true Haskell style, there are several answers. + +For those who prefer embedded DSLs, there are +L, +L and +L. The xhtml package is not being +used much nowadays and has been superseded by BlazeHTML, which is both faster +and offers a more readable DSL using Haskell's do-notation. Lucid is heavily +inspired by Blaze, and attempts to L. Having used Lucid a bit myself, +I can attest that it is easy to get started with and pretty convenient in use. + +I definitely prefer to generate HTML using DSLs as that keeps the entire +application in a single host language and with consistent syntax, but the +alternative approach, templating, is also fully supported in Haskell. The Snap +framework comes with L, which are +run-time interpreted templates, like similar systems in most other languages. +Yesod comes with L, +which is a type-safe templating system with support for inlining the templates +in Haskell code. Interestingly, Shakespeare also has explicit support for +templating JavaScript code. Too bad that this doesn't take away the need to +write the JavaScript yourself, so I don't see how this is an improvement over +some other JavaScript solution that uses JSON for communication with the back +end. + +=head2 Client-side + +It is rather unusual to have multiple compiler implementations targeting +JavaScript for the same source language, but Haskell has three of them. All +three can be used to write front end code without touching a single line of +JavaScript, but there are large philosophical differences between the three +projects. + +=over + +=item Fay + +L compiles Haskell code directly to +JavaScript. The main advantage of Fay is that it does not come with a large +runtime, resulting small and efficient JavaScript. The main downside is that it +only L. The +result is a development environment that is very browser-friendly, but where +you can't share much code between the front and back ends. You're basically +back to the separated front and back end situation in classic web development, +but at least you can use the same language for both - somewhat. + +Fay itself doesn't come with many convenient UI libraries, but +L covers that with a +convenient HTML DSL and DOM manipulation library. + +Fay is still seeing sporadic development activity, but there is not much of a +lively community around it. Most people have moved on to other solutions. + +=item GHCJS + +L uses GHC itself to compile Haskell to a +low-level intermediate language, and then compiles that language to JavaScript. +This allows GHCJS to achieve excellent compatibility with native Haskell code, +but comes, quite predictably, at the high cost of duplicating a large part of +the Haskell runtime into the JavaScript output. The generated JavaScript code +is typically measured in megabytes rather than kilobytes, which is (in my +opinion) far too large for regular web sites. The upside of this high +compatibility, of course, is that you can re-use a lot of code between the +front and back ends, which will certainly make web development more tolerable. + +The community around GHCJS seems to be more active than that of Fay. GHCJS +integrates properly with the Stack package manager, and there are a L of libraries +available. + +=item Haste + +L provides a middle ground +between Fay and GHCJS. Like GHCJS, Haste is based on GHC, but it instead of +using low-level compiler output, Haste uses a higher-level intermediate +language. This results in good compatibility with regular Haskell code while +keeping the output size in check. Haste has a JavaScript runtime of around 60 +KiB and the compiled code is roughly as space-efficient as Fay. + +While it should be possible to share a fair amount of code between the front +and back ends, not all libraries work well with Haste. I tried to use Lucid +within a Haste application, for example, but that did not work. Apparently one +of its dependencies (probably the UTF-8 codec, as far as I could debug the +problem) performs some low-level performance optimizations that are +incompatible with Haste. + +Haste itself is still being sporadically developed, but not active enough to be +called alive. The compiler lags behind on the GHC version, and the upcoming 0.6 +version has stayed unreleased and in limbo state for at least 4 months on the +git repository. The community around Haste is in a similar state. Various +libraries do exist, such as L +(HTML DSL, Reactive UI), L +(another HTML DSL), L (yet +another HTML DSL) and +L (I another +HTML DSL), but they're all pretty much dead. + +=back + +Despite having three options available, only Haste provides enough benefit of +code reuse while remaining efficient enough for the kind of site that I +envision. Haste really deserves more love than it is currently getting. + +=head2 More Haskell + +In my quest for Haskell web development frameworks and tools, I came across a +few other interesting libraries. One of them is +L, a CSS preprocessor as a DSL. This will by +itself not solve the CSS synchronisation problem that I mentioned at the start +of this article, but it could still be used to keep the CSS closer to code +implementing the rest of the site. + +It also would not do to write an article on Haskell web development and not +mention a set of related projects: L, +L and the more recent +L. These are ambitious +efforts at building a very high-level and functional framework for both front +and back end web development. I haven't spend nearly enough time on these +projects to fully understand their scope, but I'm afraid of these being a bit +too high level. This invariably results in reduced flexibility (i.e. too many +opinions being hard-coded in the API) and less efficient JavaScript output. +Axiom being based on GHCJS reinforces the latter concern. + + +=head1 Other languages + +I've covered OCaml and Haskell now, but there are relevant projects in other +languages, too: + +=over + +=item PureScript + +L is the spiritual successor of Fay - +except it does not try to be compatible with Haskell, and in fact +L +at several points. Like Fay, and perhaps even more so, PureScript compiles down +to efficient and small JavaScript. + +Being a not-quite-Haskell language, sharing code between a PureScript front end +and a Haskell back end is not possible, the differences are simply too large. +It is, however, possible to go into the other direction: PureScript could also +run on the back end in a NodeJS environment. I don't really know how well this +is supported by the language ecosystem, but I'm not sure I'm comfortable with +replacing the excellent quality of Haskell back end frameworks with a fragile +NodeJS back end (or such is my perception, I admittedly don't have too much +faith in most JavaScript-heavy projects). + +The PureScript community is very active and many libraries are available in the +L package repository. Of note is +L, a +high-level reactive UI library. One thing to be aware of is that not all +libraries are written with space efficiency as their highest priority, the +simple L +example already compiles down to a hefty 300 KB for me. + +=item Elm + +L is similar to PureScript, but rather than trying to +be a generic something-to-JavaScript compiler, Elm focuses exclusively on +providing a good environment to create web UIs. The reactive UI libraries are +well maintained and part of the core Elm project. Elm has a strong focus on +being easy to learn and comes with good documentation and many examples to get +started with. + +=item Ur/Web + +L is an ML and Haskell inspired +programming language specifically designed for client/server programming. Based +on its description, Ur/Web is exactly the kind of thing I'm looking for: It +uses a single language for the front and back ends and provides convenient +methods for communication between the two. + +This has been a low priority on my to-try list because it seems to be primarily +a one-man effort, and the ecosystem around it is pretty small. Using Ur/Web for +practical applications will likely involve writing your own libraries or +wrappers for many common tasks, such as for image manipulation or advanced text +processing. Nonetheless, I definitely should be giving this a try sometime. + +(Besides, who still uses frames in this day and age? :-) + +=item Opa + +I'll be moving out of the functional programming world for a bit. + +L is another language and environment designed for +client/server programming. Opa takes a similar approach to "everything in +PureScript": Just compile everything to JavaScript and run the server-side code +on NodeJS. The main difference with other to-JavaScript compilers is that Opa +supports mixing back end code with front end code, and it can automatically +figure out where the code should be run and how the back and front ends +communicate with each other. + +Opa, as a language, is reminiscent of a statically-typed JavaScript with +various syntax extensions. While it does support SQL databases, its database +API seems to strongly favor object-oriented use rather than relational database +access. + +=item GWT + +Previously I compared web development to native GUI application development. +There is no reason why you can't directly apply native development structure +and strategies onto the web, and that's exactly what +L does. It provides a widget-based programming +environment that eventually runs on the server and compiles the client-side +part to JavaScript. I haven't really considered it further, as Java is not a +language I can be very productive in. + +=item Webtoolkit + +In the same vein, there's L. The name might +suggest that it is a web-based clone of Qt, and indeed that's what it looks +like. Wt is written in C++, but there are wrappers for L. None of the languages +really interest me much, however. + +That said, if I had to write a web UI for a resource-constrained device, this +seems like an excellent project to consider. + +=back + + +=head1 To conclude + +To be honest, I am a bit overwhelmed at the number of options. On the one hand, +it makes me very happy to see that a lot is happening in this world, and that +alternatives to boring web frameworks do exist. Yet after all this research I +still have no clue what I should use to develop my next website. I do like the +mix and match culture of Haskell, which has the potential to form a development +environment entirely to my own taste and with my own chosen trade-offs. On the +other hand, the client-side Haskell solutions are simply too immature and +integration with the back end frameworks is almost nonexistent. + +Almost none of the frameworks I discussed attempt to tackle the CSS problem +that I mentioned in the introduction, so there is clearly room for more +research in this area. + +There are a few technologies that I should spend more time on to familiarize +myself with. Ur/Web is an obvious candidate here, but perhaps it is possible to +create a Haskell interface to Wt. Or maybe some enhancements to the Haste +ecosystem could be enough to make that a workable solution instead. diff --git a/dat/dump b/dat/dump index 05b8605..85d00f5 100644 --- a/dat/dump +++ b/dat/dump @@ -27,7 +27,7 @@ Download: L<0.3|http://p.blicky.net/h25z8> September 2011. L gained transfer logging features, and I wrote a quick Perl script to fetch some simple statistics from -it. L (L<0.1|http://p.blicky.net/agolr>). +it. L (L<0.2|http://p.blicky.net/eu00a>, L<0.1|http://p.blicky.net/agolr>). =head2 json.mll diff --git a/dat/ncdc b/dat/ncdc index ebeaaf7..7448e75 100644 --- a/dat/ncdc +++ b/dat/ncdc @@ -49,10 +49,11 @@ L - L - L - L - -L +L - +L I have a few old packages on the L, +Service|https://build.opensuse.org/package/show/home:yorhel/ncdc>, but these are unmaintained. The static binaries are preferred. A convenient installer is available for @@ -60,10 +61,6 @@ L. =back -=cut - -[html]É - =head2 Features Common features all modern DC clients (should) have: diff --git a/dat/ncdu b/dat/ncdu index bcd92e1..848aa5f 100644 --- a/dat/ncdu +++ b/dat/ncdu @@ -13,12 +13,12 @@ POSIX-like environment with ncurses installed. =item Latest version -1.12 ([dllink ncdu-1.12.tar.gz download] +1.13 ([dllink ncdu-1.13.tar.gz download] - L) I also have convenient static binaries for Linux -L and -L. Download, +L and +L. Download, extract and run; no compilation or installation necessary (uses L). @@ -65,12 +65,16 @@ L. +A port to z/OS is available L. + =head2 Similar projects =over +=item L - Multiple user interfaces. + =item L - Quite similar to ncdu, but a different approach. =item L - Another small ncurses-based disk usage visualization utility. diff --git a/dat/ncdu-changelog b/dat/ncdu-changelog index 7db6875..3a80774 100644 --- a/dat/ncdu-changelog +++ b/dat/ncdu-changelog @@ -1,3 +1,12 @@ +1.13 - 2018-01-29 + - Add "extended information" mode and -e flag + - Add file mode, modification time and uid/gid to info window with -e + - Add experimental color support and --color flag + - Add -rr option to disable shell spawning + - Remove directory nesting limit on file import + - Fix handling of interrupts during file import + - Fix undefined behavior that triggered crash on OS X + 1.12 - 2016-08-24 - Add NCDU_SHELL environment variable - Add --confirm-quit flag diff --git a/dat/ncdu-jsonfmt b/dat/ncdu-jsonfmt index b2e35c6..5f95eeb 100644 --- a/dat/ncdu-jsonfmt +++ b/dat/ncdu-jsonfmt @@ -19,17 +19,18 @@ object is an array: =head2 Versioning -The C<< >> and C<< >> elements indicate the version of the file -format. These are numbers with accepted values in the range of -C<< 0 <= version <= 10000 >>. Major version must be C<1>, minor version is currently C<0>. The -major version should increase if backwards-incompatible changes are made -(preferably never), the minor version can be increased to indicate additions to -the existing format. +The C<< >> and C<< >> elements indicate the version of +the file format. These are numbers with accepted values in the range of C<< 0 +<= version <= 10000 >>. Major version must be C<1>. Minor version is C<0> for +ncdu 1.9 till 1.12, and C<1> since ncdu 1.13 for the addition of the extended +mode. The major version should increase if backwards-incompatible changes are +made (preferably never), the minor version can be increased to indicate +additions to the existing format. =head2 Metadata The C<< >> element is a JSON object holding whatever (short) -metadata you'd want. This block is currently (1.9-1.12) ignored by ncdu when +metadata you'd want. This block is currently (1.9-1.13) ignored by ncdu when importing, but it writes out the following keys when exporting: =over @@ -109,7 +110,7 @@ C<< 0 <= dev < 2^64 >>. Number. Inode number as reported by C. Together with the Device ID this uniquely identifies a file in this dump. In the case of hard links, two objects may appear with the same (C,C) combination. A value of 0 is -assumed if this field is absent. This is currently (ncdu 1.9-1.12) not a +assumed if this field is absent. This is currently (ncdu 1.9-1.13) not a problem as long as the C field is false, otherwise it will consider everything with the same C and empty C values as a single hardlinked file. Accepted values are in the range of C<< 0 <= ino < 2^64 >>. @@ -163,6 +164,37 @@ whatever else your system may support. If absent, C is assumed. =back +=head3 Extended information + +In addition, the following fields are exported when I +mode is enabled (available since ncdu 1.13). See the C<-e> flag in L +for details. + +=over + +=item uid + +Number, user ID who owns the file. Accepted values are in the range +C<< 0 <= uid < 2^31 >>. + +=item gid + +Number, group ID who owns the file. Accepted values are in the range +C<< 0 <= uid < 2^31 >>. + +=item mode + +Number, the raw file mode as returned by L. For Linux systems, see +L for the interpretation of this field. Accepted range: +C<< 0 <= mode < 2^16 >>. + +=item mtime + +Number, last modification time as a UNIX timestamp. Accepted range: +C<< 0 <= mtime < 2^64 >>. + +=back + =head2 Miscellaneous notes As mentioned above, file/directory names are B converted to any specific diff --git a/dat/ncdu-man b/dat/ncdu-man index f752232..3ecd28e 100644 --- a/dat/ncdu-man +++ b/dat/ncdu-man @@ -35,8 +35,8 @@ I is equivalent to C<->, the file is read from standard input. For the sake of preventing a screw-up, the current version of ncdu will assume that the directory information in the imported file does not represent the -filesystem on which the file is being imported. That is, the refresh and file -deletion options in the browser will be disabled. +filesystem on which the file is being imported. That is, the refresh, file +deletion and shell spawning options in the browser will be disabled. =item I @@ -54,6 +54,19 @@ directory with many files. 10.000 files will get you an export in the order of gzip. This scales linearly, so be prepared to handle a few tens of megabytes when dealing with millions of files. +=item -e + +Enable extended information mode. This will, in addition to the usual file +information, also read the ownership, permissions and last modification time +for each file. This will result in higher memory usage (by roughly ~30%) and in +a larger output file when exporting. + +When using the file export/import function, this flag will need to be added +both when exporting (to make sure the information is added to the export), and +when importing (to read this extra information in memory). This flag has no +effect when importing a file that has been exported without the extended +information. + =back =head2 Interface options @@ -97,6 +110,16 @@ option has no effect when C<-o> is used, because there will not be a browser interface in that case. It has no effect when C<-f> is used, either, because the deletion feature is disabled in that case anyway. +WARNING: This option will only prevent deletion through the file browser. It is +still possible to spawn a shell from ncdu and delete or modify files from +there. To disable that feature as well, pass the C<-r> option twice (see +C<-rr>). + +=item -rr + +In addition to C<-r>, this will also disable the shell spawning feature of the +file browser. + =item --si List sizes using base 10 prefixes, that is, powers of 1000 (KB, MB, etc), as @@ -108,6 +131,12 @@ prefixes, that is, powers of 1024 (KiB, MiB, etc). Requires a confirmation before quitting ncdu. Very helpful when you accidentally press 'q' during or after a very long scan. +=item --color I + +Select a color scheme. Currently only two schemes are recognized: I to +disable colors (the default) and I for a color scheme intended for dark +backgrounds. + =back =head2 Scan Options diff --git a/dat/ncdu-scr b/dat/ncdu-scr index e65e393..885caf4 100644 --- a/dat/ncdu-scr +++ b/dat/ncdu-scr @@ -1,29 +1,29 @@ =pod -Note: While these screenshots are from version 1.7, the latest version has only -little visible changes. Let me also apologize for the crappy formatting, I -should take some smaller shots next time... +These screenshots were made with ncdu 1.13 with the C<--color=dark> option. +Colors are not available in older versions and (in 1.13) still disabled by +default. =head2 Scanning... -[img scr ncduscan.png Ncdu scanning a large directory.] +[img scr ncduscan-2.png Ncdu scanning a large directory.] =head2 Done scanning -[img scr ncdudone.png Ncdu done scanning a large directory.] +[img scr ncdudone-2.png Ncdu done scanning a large directory.] =head2 Directory information -[img scr ncduinfo.png Ncdu displaying directory information.] +[img scr ncduinfo-2.png Ncdu displaying directory information.] =head2 Delete confirmation -[img scr ncduconfirm.png Ncdu asking for confirmation to delete a file.] +[img scr ncduconfirm-2.png Ncdu asking for confirmation to delete a file.] =head2 Help screen -[img scr ncduhelp1.png Ncdu help screen.] +[img scr ncduhelp1-2.png Ncdu help screen.] =head2 About screen -[img scr ncduhelp2.png Ncdu about screen.] +[img scr ncduhelp2-2.png Ncdu about screen.] diff --git a/dat/nginx-confgen b/dat/nginx-confgen new file mode 100644 index 0000000..9e72c6f --- /dev/null +++ b/dat/nginx-confgen @@ -0,0 +1,54 @@ +=pod + +nginx-confgen is a simple preprocessor and macro system for +L and nginx-like configuration files. It support +variable substitution, macro expansion and using the output of arbitrary +commands to generate config files. + +=head2 Example + + pre_set $certdir /etc/nginx-certificates/; + + # Fetch the 'resolver' from /etc/resolv.conf + pre_exec $nameserver "grep nameserver /etc/resolv.conf \\ + | head -n 1 | sed 's/^nameserver //'"; + resolver $nameserver; + + # Convenient macro to create a HTTPS virtual host + macro vhost $domain @aliases &block { + server { + listen [::]:443 ssl; + server_name $domain @aliases; + + ssl_certificate $certdir/$domain/fullchain.pem; + ssl_certificate_key $certdir/$domain/privkey.pem; + pre_if -f $certdir/$domain/ocsp.der { + ssl_stapling_file $certdir/$domain/ocsp.der; + } + + █ + } + } + + vhost example.com www.example.com { + root /var/www/example.com; + } + +See the L for more features. + + +=head2 Download + +If you're on a x86_64 Linux system, you can simply use the binary: + + curl -s https://dev.yorhel.nl/download/nginx-confgen-linux-amd64-1.1.tar.gz | tar -xzf- + ./nginx-confgen output.conf + +To compile from source, install L and run: + + git clone git://g.blicky.net/nginx-confgen.git + cd nginx-confgen + stack install + +The git repository is also available for L. diff --git a/dat/nginx-confgen-changelog b/dat/nginx-confgen-changelog new file mode 100644 index 0000000..c9a044a --- /dev/null +++ b/dat/nginx-confgen-changelog @@ -0,0 +1,8 @@ +1.1 - 2018-01-24 + - Add pre_warn directive + - Add -i/-o/-v/-h command line arguments + - Add support for custom pre_include search paths (-I flag) + - Fix handling of some common custom block directives (e.g. 'types') + +1.0 - 2018-01-19 + - Initial version diff --git a/dat/nginx-confgen-man b/dat/nginx-confgen-man new file mode 100644 index 0000000..d4efeb5 --- /dev/null +++ b/dat/nginx-confgen-man @@ -0,0 +1,285 @@ +=pod + +=head1 NAME + +nginx-confgen - A preprocessor and macro system for nginx(-like) configuration +files. + +=head1 SYNOPSIS + +nginx-confgen -i input.conf -o output.conf + +=head1 DESCRIPTION + +nginx-confgen can be used to do pre-processing for nginx configuration files +(and other configuration files with a similar syntax). It has support for +"compile-time" macro expansion and variable interpolation, which should make it +less tedious to maintain large and complex configurations. + +nginx-confgen does not currently support any command-line arguments. It simply +reads the configuration from standard input, and writes the processed +configuration to standard output. + +nginx-confgen works by parsing the input into a syntax tree, modifying this +tree, and then formatting the tree to generate the output. It is completely +oblivious to nginx contexts and directives, so it is possible to do nonsensical +transformations and generate incorrect configuration files. Comments in the +input file will not be present in the output. See also the L +below. + +B Do NOT use nginx-confgen with untrusted input, the C +directive allows, by design, arbitrary code execution. + +=head1 OPTIONS + +The following command-line options are supported: + +=over + +=item -h + +Show help text. + +=item -V, --version + +Show program version. + +=item -i I + +Use the given file name as input file. If this option is not given or set to +C<->, then the file will be read from standard input. + +=item -o I + +Write the output to the given file. If this option is not given or set to C<->, +then the file will be written to standard output. + +=item -I I + +Set the search path for I directives. This option can be given +multiple times to search several directories in order. If this option is not +given, then include files are resolved relative to the directory that +nginx-confgen is run from (i.e. C<-I .>). + +=back + + +=head1 DIRECTIVES + +nginx-confgen recognizes and interprets the following directives: + +=head2 pre_include + +Similar to the C directive in nginx, except that the file is included +during preprocessing. The included file may contain any preprocessing +directives supported by nginx-confgen. Variables and macros defined in the +included file will be available in the parent file. + +Relative paths are searched for in the directories given with the C<-I> flag. + +=head2 pre_set + +Similar to the C directive in nginx, except that variables defined with +C are resolved during preprocessing. Note that variables defined with +C are only available in the same scope as they are defined, for +example: + + pre_set $var outer; + location / { + pre_set $var inner; + # $var is now "inner" within this location block. + } + # $var is "outer" again after the location block. + +(This may change in the future) + +=head2 pre_exec + +Run a shell command, and store the output in a variable. For example, nginx +will not use your system's DNS resolution methods to resolve domain names. +Instead you need to manually set a C address. With the following hack +you can fetch the nameserver from C and use that as the +C: + + pre_exec $nameserver "grep nameserver /etc/resolv.conf \\ + | head -n 1 | sed 's/^nameserver //'"; + resolver $nameserver; + +(The C<\\> is necessary, otherwise your shell will consider the newline as a +new command). + +=head2 pre_if + +Similar to the C directive in nginx, except that this is evaluated during +preprocessing. nginx-confgen has a few warts with regards to parenthesis, +things usually work better without: + + pre_if -f $certdir/ocsp.der { + ssl_stapling on; + ssl_stapling_file $certdir/ocsp.der; + } + pre_if !-f $certdir/ocsp.der { + ssl_stapling off; + } + + # You can have different configuration depending on the name of + # the system on which nginx-confgen runs. Like... yeah. + pre_exec $hostname 'hostname'; + pre_if $hostname ~* ^proxy_for_(.+) { + proxy_pass http://$1/; + } + +=head2 pre_warn + +This directive, when interpreted, will generate a warning to the standard error +of nginx-confgen. Can be used to signal that a special configuration is being +used: + + pre_if -e /etc/offline-mode { + pre_warn "Putting website in offline mode!"; + } + +Or to warn about certain directives: + + pre_macro proxy_cache $var { + pre_warn "Using proxy_cache with $var violates company policy!"; + + # But we can output it anyway. + proxy_cache $var; + } + +=head2 macro + +Define a I, which is a configuration block that you can later refer to. +The general syntax is as follows: + + macro macro_name $var1 $var2 @remaining_vars &block_var { + # contents + } + +The optional C<@remaining_vars> argument will capture any number of variables, +and can be passed to another directive inside the macro contents. The optional +C<&block_var> allows the macro to be invoked with a block argument, which will +expand to any number of directives. Some examples: + + macro le { + location /.well-known/acme-challenge { + alias /etc/letsencrypt/challenge; + } + } + # Usage: + le; + + macro redir $path $to { + location $path { + return 301 $to; + } + } + # Usage: + redir / http://blicky.net/; + + macro vhost $primary_name @aliases &block { + server { + listen [::]:443 ssl; + server_name $primary_name @aliases; + ssl_certificate $crtdir/$primary_name/fullchain.pem; + ssl_certificate_key $crtdir/$primary_name/privkey.pem; + █ + } + } + # Usage: + vhost example.com { + root /var/www/example.com; + } + vhost example.org alias.example.org { + root /var/www/example.org; + } + +Note that these are I macros, so variable capture is predictable (but +not necessarily the most useful): + + pre_var $dest /a; + macro redir { + # This will be /a, regardless of the context in which this macro is called. + return 301 $dest; + } + # $dest is still '/a' inside the macro after this new variable definition. + pre_var $dest /b; + redir; + +Similarly, macro arguments will not be available inside C<&block> expansion or +nested macro expansion. + + +=head1 BUGS & WARTS + +nginx-confgen is a quickly written hack to solve a particular use case, it is +quite likely to have some weird behavior and bugs. Here's a few I am aware of: + +=over + +=item * + +The nginx configuration syntax is not as regular as I had hoped. It's possible +for nginx modules to extend the syntax somewhat. A good example is the I +directive in I. While nginx-confgen should be able to +handle the I directive just fine, other extensions may cause syntax +errors or will not survive a round-trip through nginx-confgen. + +This applies to all I<*_by_lua_block> directives in the I. +The I<_by_lua> directives that accept a string should work just fine. + +=item * + +Be careful with parenthesis around if statements, e.g.: + + if ($a == $b) { } + +Will get converted into: + + if "(${a}" == "${b})" { } + +Which is unlikely what you want. As a workaround, add some spaces: + + if ( $a == $b ) { } + +=item * + +Arguments to directives may get reformatted, especially if they contain a +variable. This I not matter in most cases, but in some particular +scenarios it does. Here's a few examples of reformatting: + + return 301 http://blicky.net$request_uri; + # becomes: + return 301 "http://blicky.net${request_uri}"; + + add_header Something "${header}"; + # becomes: + add_header Something $header; + +This reformatting may cause different behavior for nginx directives that do not +support variable interpolation, such as C. + +=item * + +C does not like empty strings, e.g. + + pre_if $x == "" { } + +Will throw an error, use the following instead: + + pre_if $x { } + +=item * + +The error messages aren't always helpful. + +=back + + + +=head1 AUTHOR + +nginx-confgen is written by Yoran Heling + +Web: L diff --git a/dat/tuwf b/dat/tuwf index fdc5e8c..300638d 100644 --- a/dat/tuwf +++ b/dat/tuwf @@ -39,10 +39,10 @@ information and details. =head2 Download -B 1.0 ([dllink TUWF-1.0.tar.gz download] +B 1.1 ([dllink TUWF-1.1.tar.gz download] - L) -TUWF is also available on a git repository at L. +TUWF is also available on a git repository at L. =head2 Websites using TUWF @@ -51,13 +51,13 @@ TUWF is also available on a git repository at L. =over -=item * L (the site that spawned TUWF - L) +=item * L (the site that spawned TUWF - L) -=item * L (L) +=item * L (L) -=item * L (L) +=item * L (L) -=item * L (L) +=item * L (L) =item * The website embedded in the L mixing console. diff --git a/dat/tuwf-changelog b/dat/tuwf-changelog index 999709a..cfb7203 100644 --- a/dat/tuwf-changelog +++ b/dat/tuwf-changelog @@ -1,3 +1,10 @@ +1.1 - 2017-11-26 + - Disallow exclamation mark in email address validation + - Add reqProtocol() method + - Add reqFCGI() method + - Remove 'X-Powered-By' header + - Fix handling of space character in load_recursive() + 1.0 - 2015-09-17 - !! Some backwards-imcompatible changes, marked * !! - kv_validate() improvements: diff --git a/download/TUWF-1.1.tar.gz.asc b/download/TUWF-1.1.tar.gz.asc new file mode 100644 index 0000000..8f764b0 --- /dev/null +++ b/download/TUWF-1.1.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEdEYNMrgIEOupr6LpYjlMaYwnOfoFAloaeBgACgkQYjlMaYwn +OfqtFRAA0ZXztAZ2GDb1puNXknJO1kDFam2DXUHXQvuNW9rn2I7nH0utdW/VWvt/ +vpWAyKT8kvywpK7m1JGjVj8RiE/sgncTpYi3E3H+Dv6OO0z0dEoq6VUS3Mc5Gk1b +1TclOZt3uShK9PgjGsjJZcyMGvvgXMUO/5peBlbXDgWhokfVWZrM5r58Ve+dJwQn +4s5IDjoIqZy7RuSzlhkdT661NftfWpvjvr+XMmS3kdBsiIxTUrbPnUp1T85yYslA +0UpMCnGIwYdbu1J3igAMRIRmp0ix7e4ANagh97MVeCueO6acHAYqe3uui5SHwE+7 +iuHWmyZTQtuikrZjpNBDMbQxUwk79SQaYOM5bXDn/pTTAcBm1RU2Sf3Slnk+Xlrk +kKjqgvf7qfx3zZKNMuTvxslzF4HUbE4/CB9I6Ccz4KnQ6qkyQMMPeo4ETjumCpPa +5CosdSFF4vrPHO7v6KTc2Q+l5gp4900Qb/wxydUptSJTTsCFNNRMwpkDwtSh9wfn +rU9L6vx54aem3nucqStFwe3gIkuu9NNqGCwpUu9Dga0/gnxP5i6O/bNC8MH3tnsR +yTodqjGQWsTtmpDaLnZX1TeCWCgjtVvfbrTqTUiM8l2BQnTVtgBJbGZDHnC1nCs0 +/MnIEXxfLqrWynPieeAKSuxs2zrToR9PFDuWSVs6X0oCuo8SaUI= +=9nQv +-----END PGP SIGNATURE----- diff --git a/download/TUWF-1.1.tar.gz.md5 b/download/TUWF-1.1.tar.gz.md5 new file mode 100644 index 0000000..08ef26a --- /dev/null +++ b/download/TUWF-1.1.tar.gz.md5 @@ -0,0 +1 @@ +4629606ce88c28e2ea767bf7b356fe9c TUWF-1.1.tar.gz diff --git a/download/TUWF-1.1.tar.gz.sha1 b/download/TUWF-1.1.tar.gz.sha1 new file mode 100644 index 0000000..bee79bd --- /dev/null +++ b/download/TUWF-1.1.tar.gz.sha1 @@ -0,0 +1 @@ +7f2c4018674f7009db5d3d30218d379210c3a972 TUWF-1.1.tar.gz diff --git a/download/code/awshrink b/download/code/awshrink new file mode 100644 index 0000000..f4d6f63 --- /dev/null +++ b/download/code/awshrink @@ -0,0 +1,166 @@ +#!/usr/bin/perl + +# awshrink v0.1 +# 2007-01-15 +# Yoran Heling + +# License: MIT + + + +use strict; +use warnings; +use bytes; + + + +# hash for easy lookup +my %shrinkable = ( map { $_ => 1 } qw| + DOMAIN LOGIN ROBOT WORMS EMAILSENDER EMAILRECEIVER + BROWSER UNKNOWNREFERER UNKOWNREFERERBROWSER SEREFERRALS + PAGEREFS SEARCHWORDS KEYWORDS SIDER_404 SIDER VISITOR + UNKNOWNREFERERBROWSER +|); + + + +sub getstats { # read + my $fl = shift; + my @l; + seek($fl, 0, 0); + + # get positions + while(<$fl>) { + last if /^END_MAP/; + next if !/^POS_([A-Z0-9_]+)\s+([0-9]+)\s+$/; + push(@l, [ $1, $2, 0, 0 ]); + } + + # get sizes (bytes) + @l = sort { $a->[1] <=> $b->[1] } @l; + $l[$_][2] = ($l[$_+1] ? $l[$_+1][1] : -s $fl) - $l[$_][1] + for (0..$#l); + + # get lines + for (0..$#l) { + seek $fl, $l[$_][1], 0; + <$fl> =~ /BEGIN_[A-Z0-9_]+\s+([0-9]+)/; + $l[$_][3] = $1; + } + + print " Section Size (Bytes) Lines\n"; + printf "%22s %12d %7d\n", $_->[0].($shrinkable{$_->[0]}?' ':'*'), $_->[2], $_->[3] + for (sort { $a->[2] <=> $b->[2] } @l); + print "* = not shrinkable\n"; +} + + + +sub fixmap { # read, write + my($fl, $FL) = @_; + + my $map = ''; + my @l; + seek $fl, 0, 0; + while(<$fl>) { + next if !/^BEGIN_([A-Z0-9_]+)/ || $1 eq 'MAP'; + $map .= sprintf "POS_%s %-20d\n", $1, tell($fl)-length($_); + } + + seek $fl, 0, 0; + seek $FL, 0, 0; + + my $inmap = 0; + while(<$fl>) { + if(!$inmap && !/^BEGIN_MAP/) { + print $FL $_; + next; + } + $inmap = 1; + if(/^END_MAP/) { + printf $FL "BEGIN_MAP 27\n%sEND_MAP\n", $map; + $inmap = 0; + } + } +} + + +sub shrink { # read, write, %sections->{ key = section, value = lines } + my($fh, $FH, %sec) = @_; + + seek $fh, 0, 0; + seek $FH, 0, 0; + while(<$fh>) { + if(!/^BEGIN_([A-Z0-9_]+)\s+([0-9]+)/ || !$sec{$1} || $sec{$1} >= $2) { + print $FH $_; + next; + } + my $sec = $1; + + # read entire section + my @l; + while(<$fh>) { + last if /^END_/; + s/^[\s\r\n]+//; + s/[\s\r\n]+$//; + push @l, [ split / / ]; + } + + # sort section + # DOMAIN, LOGIN, ROBOT, WORMS, EMAILSENDER. EMAILRECEIVER, + # BROWSER, UNKNOWNREFERER, UNKOWNREFERERBROWSER, SEREFERRALS, + # PAGEREFS, SEARCHWORDS, KEYWORDS, SIDER_404, SIDER -> 1 + # VISITOR -> 2 + if($sec{$sec} > 10) { # assume sorted if we only want the first ten + @l = sort { $b->[1] <=> $a->[1] } @l if $sec ne 'VISITOR'; + @l = sort { $b->[2] <=> $a->[2] } @l if $sec eq 'VISITOR'; + } + + # write section + printf $FH "BEGIN_%s %d\n", $sec, $sec{$sec}; + print $FH join(' ', @{$l[$_]})."\n" + for (0..($sec{$sec}-1)); + printf $FH "END_%s\n", $sec; + } + 1; +} + + + +sub run { + print "Usage: $@ [options] filename\n" and exit if !@ARGV; + + my $file = pop; + my $ci = 0; + my $st = 0; + + my %options; + while(local $_ = shift) { + /^-c$/ ? $ci++ : + /^-s$/ ? $st++ : + /^-([A-Za-z0-9_]+)$/ && $shrinkable{ uc($1) } ? $options{ uc($1) } = shift : + printf("Unknown option: %s\n", $_) && exit; + } + (!$options{$_} || $options{$_} !~ /^[0-9]+$/) && printf("Invalid value for -%s\n", $_) && exit + for keys %options; + + print "Nothing to do...\n" and exit if !keys %options && !$st; + + open(my $fl, '<', $file) || die $!; + my $tmpfile; + open(my $TMP, '+>', \$tmpfile); + open(my $FL, '+>', "$file~") || die $! if keys %options; + + shrink($fl, $TMP, %options) && fixmap($TMP, $FL) if keys %options; + getstats(keys %options ? $FL : $fl) if $st; + + close $fl; + close $TMP; + close $FL if keys %options; + + rename "$file~", $file if $ci; +} + + + +run @ARGV; diff --git a/download/code/bbcode.c b/download/code/bbcode.c new file mode 100644 index 0000000..62a782e --- /dev/null +++ b/download/code/bbcode.c @@ -0,0 +1,330 @@ +/* + * BBCode 2 HTML converter by //YorHel + * Copyright 2006 Y.Heling, + * License: MIT + * + * Created just to learn C, probably very ugly piece of code + * and probably with a _LOT_ of bugs... But the only way to + * learn a programming language is to code something yourself :) + */ + +#include +#include +#include +#include + +#define MAX_ARGH_SIZE 500 +#define MAX_TAG_SIZE 10 +#define MAX_NESTED_TAGS 100 + +#define TAGCHARS 28 +#define NUMBER_OF_TAGS 16 + +#define TRUE 1 +#define FALSE 0 + + +/* typedefs */ +typedef enum { + B, + I, + U, + SIZE, + COLOR, + URL, + QUOTE, + QUOTE2, + IMG, + IMG2, + EMAIL, + LIST, + LIST2, + CODE, + HTML, + UNDEF, /* hack */ +} TAGNAME; +typedef struct { + TAGNAME intags[MAX_NESTED_TAGS]; + int curtag; + char tag[MAX_TAG_SIZE]; + char argh[MAX_ARGH_SIZE]; + FILE *dest; + int inlist; + int liststart; +} PARSEINFO; /* just a hack to prevent the use of global variables */ +typedef struct { + char *bb; + char *html_s; + char *html_e; + char arg; +} TAGINFO; /* store global information about the tags */ + + +/* functions */ +void parsebbcode(FILE *, FILE *); +void converttag(PARSEINFO *); +void formattag(PARSEINFO *); +char endtags(PARSEINFO *, TAGNAME); +void convertchars(PARSEINFO *, const char *); +void convertchar(PARSEINFO *, const int); +void convertchararg(char *, int); +char istagchar(const int); +void err(const char *); + +/* global vars (only consts!) */ +const char tagchars[TAGCHARS] = "abcdefghijklmnopqrstuvwxyz/*"; +const TAGINFO taglist[NUMBER_OF_TAGS] = { /* same order as TAGNAME! */ + { "b", "", "", FALSE }, + { "i", "", "", FALSE }, + { "u", "", "", FALSE }, + { "size", "", "", TRUE }, + { "color", "", "", TRUE }, + { "url", "", "", TRUE }, + { "quote", "Quote: ", "", FALSE }, + { "quote", "%s wrote: ", "", TRUE }, + { "img", "\"\"", FALSE }, + { "img", "\"",", TRUE }, + { "email", "", "", TRUE }, + { "list", "
    ", "
", FALSE }, + { "list", "
    ", "
", TRUE }, + { "code", "Code: ", "", FALSE }, + { "html", "", "", FALSE }, + { "", "", "", FALSE }, +}; /* NOTE: not all characteristics of the BBCodes are defined above, there is also a lot of hard-coded stuff below for a few tags */ + + + +int main() { +/* printf("BBCode to HTML converter by //YorHel\n"); + printf("Copyright 2006 Y. Heling\n\n"); + + printf("* Reading & parsing bbcode...\n"); + while(1) { + FILE *file; + if((file = fopen(BBFILE, "r")) == NULL) err("Couldn't open BBFILE"); + parsebbcode(file, stdout); + fclose(file); + } + printf("\n");*/ + + parsebbcode(stdin, stdout); + + return 0; +} + + +void parsebbcode(FILE *file, FILE *dest) { + PARSEINFO pitemp; /* make sure we allocate the memory */ + PARSEINFO *pi = &pitemp; /* but we are still going to use a pointer */ + char intag = pi->inlist = pi->liststart = 0; + pi->curtag = 1; + pi->intags[0] = UNDEF; + sprintf(pi->tag, ""); + sprintf(pi->argh, ""); + pi->dest = dest; + int c; + char tmp[MAX_TAG_SIZE+MAX_ARGH_SIZE+4]; /* temp string, should be able to hold anything necessary */ + while((c = fgetc(file)) && c != EOF) { + if(intag == 0 && c == '[') { + intag = 1; + } + else if(intag == 1 && c == '=') + intag = -1; + else if(intag != 0 && c == ']') { + intag = 0; + converttag(pi); + sprintf(pi->tag, ""); + sprintf(pi->argh, ""); + } + else if(intag == 1 && strlen(pi->tag) < sizeof(pi->tag)) { + if(istagchar(c)) { + sprintf(tmp, "%c", tolower(c)); + strcat(pi->tag, tmp); + } else { + sprintf(tmp, "[%s", pi->tag); + convertchars(pi, tmp); + sprintf(pi->tag, ""); + } + } + else if(intag == 1) { + intag = 0; + sprintf(tmp, "[%s", pi->tag); + convertchars(pi, tmp); + sprintf(pi->tag, ""); + } + else if(intag == -1 && (strlen(pi->argh)+10) < sizeof(pi->argh)) { + convertchararg(tmp, c); + strcat(pi->argh, tmp); + } + else if(intag == -1) { + sprintf(tmp, "[%s=%s", pi->tag, pi->argh); + convertchars(pi, tmp); + sprintf(pi->tag, ""); + sprintf(pi->argh, ""); + intag = 0; + } + else + convertchar(pi, c); + } + /* some stuff left in the buffer */ + if(strlen(pi->tag) > 0 && strlen(pi->argh) == 0) + fprintf(dest, "[%s", pi->tag); + else if(strlen(pi->tag) > 0 && strlen(pi->argh) > 0) + fprintf(dest, "[%s=%s", pi->tag, pi->argh); + /* automatically close opened tags */ + endtags(pi, UNDEF); +} + +void converttag(PARSEINFO *pi) { + /* ignore tag if we're not allowed to nest */ + if((pi->intags[pi->curtag] == CODE && strcmp(pi->tag, "/code") != 0) + || (pi->intags[pi->curtag] == HTML && strcmp(pi->tag, "/html") != 0) + || ((pi->intags[pi->curtag] == IMG || pi->intags[pi->curtag] == IMG2) && strcmp(pi->tag, "/img"))) { + formattag(pi); + return; + } + + /* parse list items */ + if(!strcmp(pi->tag, "*") && pi->inlist) { + endtags(pi, LIST); + if(pi->inlist == pi->liststart) + fprintf(pi->dest, ""); + else + pi->liststart = pi->inlist; + fprintf(pi->dest, "
  • "); + + return; /* no need to parse more */ + } + + /* begin a tag */ + if(*pi->tag != '/') { + int i; int got = -1; + for(i=0 ; itag, taglist[i].bb)) { + got = i; + if(strlen(pi->argh) == 0 && !taglist[i].arg) + fprintf(pi->dest, "%s", taglist[i].html_s); + else if(strlen(pi->argh) > 0 && taglist[i].arg) { + if(i != LIST2) + fprintf(pi->dest, taglist[i].html_s, pi->argh); + else + fprintf(pi->dest, taglist[i].html_s, strcmp(pi->argh, "1") ? "lower-roman" : "decimal"); + } + else + got = -1; + }; + if(got != -1) { + pi->intags[++pi->curtag] = got; + if(got == LIST || got == LIST2) + pi->inlist++; + } + else + formattag(pi); + return; + } + + /* end a tag */ + else { + char *tag = pi->tag+1; /* strip the '/' */ + int i; + char got = FALSE; + for(i=0 ; idest, "%s", taglist[i].html_e); + if(pi->intags[pi->curtag] == LIST || pi->intags[pi->curtag] == LIST2) + pi->liststart = --pi->inlist; + pi->curtag--; + got = TRUE; + }; + if(!got) + formattag(pi); + } +} + +char endtags(PARSEINFO *pi, TAGNAME to) { + char s = FALSE; + if(to == QUOTE || to == LIST || to == IMG) + s = TRUE; + else if(to == QUOTE2 || to == LIST2 || to == IMG2) { + s = TRUE; + to--; + } + int i = pi->curtag; + if(to != UNDEF) + while(pi->intags[i] != to && (!s || pi->intags[i] != to+1) && i > 0) + i--; + if(i) { + while(pi->intags[pi->curtag] != to && (!s || pi->intags[pi->curtag] != (to+1)) && pi->curtag > 0) { + if(pi->intags[pi->curtag] == LIST || pi->intags[pi->curtag] == LIST2) + pi->liststart = --pi->inlist; + fprintf(pi->dest, "%s", taglist[pi->intags[pi->curtag--]].html_e); + } + return TRUE; + } + else + return FALSE; +} + +void formattag(PARSEINFO *pi) { + char tmp[MAX_TAG_SIZE+MAX_ARGH_SIZE+4]; + if(strlen(pi->argh) == 0) + sprintf(tmp, "[%s]", pi->tag); + else + sprintf(tmp, "[%s=%s]", pi->tag, pi->argh); + convertchars(pi, tmp); +} + +void convertchars(PARSEINFO *pi, const char *chars) { + int i; + for(i=0;iinlist && pi->inlist != pi->liststart) + return; + else if(pi->intags[pi->curtag] == HTML) + fprintf(pi->dest, "%c", c); + else if(pi->intags[pi->curtag] == IMG || pi->intags[pi->curtag] == IMG2) { + char tmp[10]; + convertchararg(tmp, c); + fprintf(pi->dest, tmp); + } + else if(c == '\n') + fprintf(pi->dest, "
    \n"); + else if(c == '&') + fprintf(pi->dest, "&"); + else if(c == '<') + fprintf(pi->dest, "<"); + else if(c == '>') + fprintf(pi->dest, ">"); + else + fprintf(pi->dest, "%c", c); +} + +void convertchararg(char *to, const int c) { + switch(c) { + case '\n' : + sprintf(to, ""); break; + case '&' : + sprintf(to, "&"); break; + case '"' : + sprintf(to, """); break; + default : + sprintf(to, "%c", c); + } +} + +char istagchar(const int c) { + int i; + int c2 = tolower(c); + for(i=0;i +#include +#include +#include +#include +#include +#include +#include + +#define LISTEN_PORT 1337 + +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +; +#define MAX_CONNECTIONS 10 +#define READ_BUFFER_SIZE 512 + +#define CST_FREE 0 +#define CST_READ 1 +#define CST_WRITE 2 + +typedef struct { + int fd; + char state; + char *buf; +} connections; +static connections *conns; + +void error(const char *); +void close_and_free(int); + +int main() { + printf("Simple TCP server by //YorHel\n\n"); + + printf("* Creating socket\n"); + int l; + if((l = socket(AF_INET, SOCK_STREAM, 0)) < 0) + error("Can't create socket"); + + printf("* Setting SO_REUSEADDR on main socket\n"); + int set = 1; + if(setsockopt(l, SOL_SOCKET, SO_REUSEADDR, (void *) &set, sizeof(set)) < 0) + error("Can't set SO_REUSEADDR on main socket"); + + printf("* Binding socket\n"); + struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(struct sockaddr_in)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(LISTEN_PORT); + serv_addr.sin_addr.s_addr = INADDR_ANY; + if(bind(l, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) + error("Can't bind socket"); + + printf("* Listening to socket\n"); + listen(l, 5); + + printf("* Creating connections table\n"); + conns = (connections *) malloc( sizeof(connections) * MAX_CONNECTIONS ); + if(conns == (connections *) 0) + error("Can't allocate memory for connections table"); + int cnum; + for(cnum=MAX_CONNECTIONS; cnum--;) + conns[cnum].state = CST_FREE; + + printf("* Accepting connections\n"); + /* re-use the same vars over-and-over again + * is a little faster than defining them each time */ + int n, cn, newid, clifd; + char stop = 0; + fd_set rd, wr; + struct sockaddr_in cliaddr; + unsigned int clilen; + /* main loop */ + while(!stop) { + /* set FDs for select() */ + FD_ZERO(&rd); FD_ZERO(&wr); + n = 0; + FD_SET(l, &rd); + n = MAX(l, n); + + /* set FDs for the connections */ + for(cn=MAX_CONNECTIONS;cn--;) { + if(conns[cn].state == CST_READ) { + FD_SET(conns[cn].fd, &rd); + n = MAX(n, conns[cn].fd); + } else if(conns[cn].state == CST_WRITE) { + FD_SET(conns[cn].fd, &wr); + n = MAX(n, conns[cn].fd); + } + } + + n = select(n + 1, &rd, &wr, (fd_set *) NULL, (struct timeval *) 0); + if(n < 0) + error("select() failed..."); + if(n == 0) + continue; + + /* Something happend, handle it :) */ + if(FD_ISSET(l, &rd)) { /* new connection */ + /* get free slot, if one */ + newid = -1; + for(cn=MAX_CONNECTIONS;cn--;) + if(conns[cn].state == CST_FREE) { + newid = cn; break; + } + if(newid < 0) + printf(" *WARNING: Too many connections\n"); + else { + /* accept the connection */ + clilen = sizeof(cliaddr); + memset(&cliaddr, 0, clilen); + clifd = accept(l, (struct sockaddr *) &cliaddr, &clilen); + if(clifd < 0) + error("Can't accept connection"); + printf(" [%d] We have a connection!!\n", newid); + conns[newid].state = CST_WRITE; + if((conns[newid].buf = malloc(READ_BUFFER_SIZE)) < 0) + error("Can't allocate memory"); + sprintf(conns[newid].buf, "Hello world!\n"); + conns[newid].fd = clifd; + } + } + + /* checking active sockets */ + for(cn=MAX_CONNECTIONS;cn--;) { + /* we can write */ + if(conns[cn].state == CST_WRITE && FD_ISSET(conns[cn].fd, &wr)) { + if(write(conns[cn].fd, conns[cn].buf, strlen(conns[cn].buf)) <= 0) + close_and_free(cn); + printf(" [%d] Sent: %s", cn, conns[cn].buf); + conns[cn].state = CST_READ; + } + /* we can read */ + if(conns[cn].state == CST_READ && FD_ISSET(conns[cn].fd, &rd)) { + memset((void *) conns[cn].buf, 0, READ_BUFFER_SIZE); + if(read(conns[cn].fd, conns[cn].buf, READ_BUFFER_SIZE) <= 0) + close_and_free(cn); + printf(" [%d] G0t: %s", cn, conns[cn].buf); + conns[cn].state = CST_WRITE; + if(strstr(conns[cn].buf, "exit") == conns[cn].buf) { + printf(" [%d] Closing connection\n", cn); + close_and_free(cn); + } else if(strstr(conns[cn].buf, "die()") == conns[cn].buf) { + printf("Got die() from connection #%d, dying!\n", cn); + stop = 1; + } + } + } + } + /* close all connections before dying */ + for(cnum=MAX_CONNECTIONS;cnum--;) + if(conns[cnum].state != CST_FREE) + close_and_free(cnum); + close(l); + + + return 0; +} +void close_and_free(int cn) { + close(conns[cn].fd); + conns[cn].state = CST_FREE; + free(conns[cn].buf); +} + + +void error(const char *msg) { + perror(msg); + exit(1); +} + diff --git a/download/code/grenamr-0.1.pl b/download/code/grenamr-0.1.pl new file mode 100644 index 0000000..17aa506 --- /dev/null +++ b/download/code/grenamr-0.1.pl @@ -0,0 +1,248 @@ +#!/usr/bin/perl + +# grenamr v0.1 +# 2008-08-01 +# Yoran Heling + +# License: MIT + + +use warnings; +use strict; +use Gtk2 -init; + +our $VERSION = '0.1'; + +my %w; +my $m; +use constant { + C_OLD => 0, + C_NEW => 1, + C_FLG => 2, + F_REG => 0x01, + F_MAN => 0x02, # not implemented yet... + F_CON => 0x04, +}; + + +create(); +Gtk2->main; + + +sub create { + $w{win} = Gtk2::Window->new('toplevel'); + $w{win}->signal_connect(destroy => \&close); + $w{win}->resize(500, 500); + $w{win}->move(300, 300); + $w{win}->set(title => 'GRenamR v'.$VERSION); + + $w{vbGlobal} = Gtk2::VBox->new(0, 0); + $w{win}->add($w{vbGlobal}); + + $w{hbDir} = Gtk2::HBox->new(0, 0); + $w{vbGlobal}->pack_start($w{hbDir}, 0, 1, 0); + + $w{lbDir} = Gtk2::Label->new('_Directory'); + $w{hbDir}->pack_start($w{lbDir}, 0, 0, 5); + + $w{fcDir} = Gtk2::FileChooserButton->new('Select a directory', 'select-folder'); + $w{fcDir}->signal_connect('current-folder-changed', \&fetchdir); + $w{hbDir}->pack_start($w{fcDir}, 1, 1, 0); + $w{lbDir}->set(mnemonic_widget => $w{fcDir}, use_underline => 1); + + $w{swFiles} = Gtk2::ScrolledWindow->new; + $w{swFiles}->set_policy('automatic', 'automatic'); + $w{vbGlobal}->pack_start($w{swFiles}, 1, 1, 0); + + $w{tvFiles} = Gtk2::TreeView->new; + $w{swFiles}->add($w{tvFiles}); + $m = $w{lsFiles} = Gtk2::ListStore->new('Glib::String', 'Glib::String', 'Glib::Int'); + $w{tvFiles}->set_model($w{lsFiles}); + $w{tvFiles}->insert_column_with_data_func(0, '', Gtk2::CellRendererPixbuf->new, \&column_func, 0); + my $c = Gtk2::CellRendererText->new; + $w{tvFiles}->insert_column_with_data_func(1, 'Old', $c, \&column_func, 1); + $w{tvFiles}->insert_column_with_data_func(2, 'New', $c, \&column_func, 2); + $w{tvFiles}->get_column(1)->set(sizing => 'autosize'); + $w{tvFiles}->get_column(2)->set(sizing => 'autosize'); + + $w{hbPerl} = Gtk2::HBox->new(0, 0); + $w{vbGlobal}->pack_start($w{hbPerl}, 0, 1, 0); + + $w{lbPerl} = Gtk2::Label->new('_Expression'); + $w{hbPerl}->pack_start($w{lbPerl}, 0, 0, 5); + + $w{enPerl} = Gtk2::Entry->new; + $w{enPerl}->signal_connect('changed', \&applyfilter); + $w{hbPerl}->pack_start($w{enPerl}, 1, 1, 0); + $w{lbPerl}->set(mnemonic_widget => $w{enPerl}, use_underline => 1); + + $w{imPerl} = Gtk2::Image->new_from_stock('gtk-yes', 'menu'); + $w{hbPerl}->pack_start($w{imPerl}, 0, 1, 0); + + $w{hbBottom} = Gtk2::HBox->new(0, 0); + $w{vbGlobal}->pack_start($w{hbBottom}, 0, 1, 0); + + $w{alStatus} = Gtk2::Alignment->new(0,0.8,0,0); + $w{hbBottom}->pack_start($w{alStatus}, 1, 1, 5); + + $w{lbStatus} = Gtk2::Label->new(''); + $w{alStatus}->add($w{lbStatus}); + + $w{alBottom} = Gtk2::Alignment->new(1,1,0,1); + $w{hbBottom}->pack_start($w{alBottom}, 0, 1, 0); + + $w{bbBottom} = Gtk2::HButtonBox->new; + $w{bbBottom}->set(spacing => 5); + $w{alBottom}->add($w{bbBottom}); + + $w{btApply} = Gtk2::Button->new('_Rename'); + $w{btApply}->signal_connect('clicked', \&dorename); + $w{bbBottom}->pack_start($w{btApply}, 0, 0, 5); + + $w{btClose} = Gtk2::Button->new('_Close'); + $w{btClose}->signal_connect('clicked', \&close); + $w{bbBottom}->pack_start($w{btClose}, 0, 0, 5); + + $w{win}->show_all; + $w{enPerl}->grab_focus; + + if($ARGV[0] && -d $ARGV[0]) { + $w{fcDir}->set_current_folder($ARGV[0]); + } else { + fetchdir(); + } +} + + +sub column_func { + my ($column, $cell, $model, $iter, $col) = @_; + my $flags = $model->get($iter, 2); + $cell->set( + $col > 0 ? ( + text => $model->get($iter, $col-1), + ) : ( + 'stock-id' => $flags & F_CON ? 'gtk-dialog-error' + : $flags & F_REG ? 'gtk-edit' + : $flags & F_MAN ? 'gtk-apply' + : 'gtk-file', + ), + $flags & F_CON ? ( cell_background => '#ffcccc' ) : + $flags & F_REG ? ( cell_background => '#ccffcc' ) : + $flags & F_MAN ? ( cell_background => '#ffffcc' ) : + ( cell_background_set => 0 ), + ); +} + + +sub close { + Gtk2->main_quit; +} + + +sub fetchdir { + Gtk2->main_iteration_do(0); + my $d = $w{fcDir}->get_current_folder; + + $w{lbStatus}->set(label => 'Loading...'); + + my @lst; + opendir(my $D, $d) + || return $w{lbStatus}->set(label => 'Unable to open the selected directory'); + -f $d.'/'.$_ and push @lst, $_ for (readdir $D); + closedir $D; + + $m->clear; + $m->set($m->append, C_OLD, $_, C_NEW, $_, C_FLG, 0) + for (sort @lst); + $w{lbStatus}->set(label => sprintf '%d files found.', scalar @lst); + applyfilter(); +} + + +sub applyfilter { + my $p = $w{enPerl}->get_text; + + # create a list of files + my @list; + my $i = $m->get_iter_first; + do { + push @list, $m->get($i, C_OLD) + } while ($i = $m->iter_next($i)); + + # eval using a for loop + $i=-1; + eval 'no strict; no warnings; for (@list) { ++$i; '.$p.' }'; + my $e = $@; + $w{imPerl}->set(stock => $e ? 'gtk-no' : 'gtk-yes'); + + # compare and update the list + my $j=0; my $matched=0; + $i = $m->get_iter_first; + do {{ + next if $m->get($i, C_FLG) & F_MAN; + my $match = $e || $m->get($i, C_OLD) eq $list[$j] ? 0 : 1; + $m->set($i, C_NEW, $list[$j++], C_FLG, $match); + $matched += $match; + }} while ($i = $m->iter_next($i)); + + # update status + $w{lbStatus}->set(label => $e + ? 'Invalid expression' + : sprintf 'Matched %d/%d files.', $matched, scalar @list); + + findconflicts(); +} + + +sub findconflicts { + # create a list of old filenames + my @old; + my $i = $m->get_iter_first; + do { + push @old, $m->get($i, C_OLD); + } while ($i = $m->iter_next($i)); + + # search for modified items having a new filename in that list + my $e=0; + $i = $m->get_iter_first; + do {{ + next if !$m->get($i, C_FLG); + my $new = $m->get($i, C_NEW); + my $match = $new eq '' || $new =~ /\// || grep $_ eq $new, @old; + $m->set($i, C_FLG, $m->get($i, C_FLG) | F_CON) + if $match; + $e++ if $match; + }} while ($i = $m->iter_next($i)); + + $w{lbStatus}->set(label => 'Errors found!') if $e; +} + + +sub dorename { + my $d = $w{fcDir}->get_current_folder; + + # count number of renamable files + my $i = $m->get_iter_first; + my $count=0; + do { + $count++ if $m->get($i, C_FLG) && !($m->get($i, C_FLG) & F_CON); + } while ($i = $m->iter_next($i)); + + return $w{lbStatus}->set(label => 'Nothing to do...') if !$count; + + $w{lbStatus}->set(label => 'Renaming...'); + my $j=0; + $i = $m->get_iter_first; + do {{ + next if !$m->get($i, C_FLG) || $m->get($i, C_FLG) & F_CON; + rename $d.'/'.$m->get($i, C_OLD), $d.'/'.$m->get($i, C_NEW); + $m->set($i, C_OLD, $m->get($i, C_NEW), C_FLG, 0); + $w{lbStatus}->set(label => sprintf 'Renaming file %d/%d...', ++$j, $count); + Gtk2->main_iteration_do(0); + }} while ($i = $m->iter_next($i)); + + $w{lbStatus}->set(label => sprintf 'Renamed %d files.', $j); +} + + + diff --git a/download/code/mdc2-parse.pl b/download/code/mdc2-parse.pl new file mode 100644 index 0000000..eb45c67 --- /dev/null +++ b/download/code/mdc2-parse.pl @@ -0,0 +1,150 @@ +#!/usr/bin/perl + + +# mdc3-parse.pl +# June 2007 +# Yoran Heling + +# License: MIT + + +use strict; +use warnings; +use Storable 'store', 'retrieve'; +use POSIX; +use POSIX::strptime; + +my $log = 'log'; # the microdc2 log file +my $result = 'transferred.html'; # the resulting html file +my $cache = 'logparse.pl_cache'; # file for the Storable cache + + +my %ts = -s $cache ? ( %{retrieve($cache)} ) : (); +my $totalsent = 0; + +# using STDIN/OUT -> lazy and ugly :-) +open(STDIN, '<', $log) || die $!; +open(STDOUT, '>', $result) || die $!; + + +while(<>) { + s/\r?\n//; + # 28.04.2007 20:15:25 + next if !s/^([0-9]{2}\.[0-9]{2}\.[0-9]{4}\s+[0-9]{2}:[0-9]{2}:[0-9]{2})\s//; + my $date = $1; + + # plesnivec: Upload of `Ghost in the Shell - Stand Alone Complex - 25.avi' succeeded (transfer complete). 1.5MiB transferred in 53s (29KiB/s). + # [Anime]Spank: Upload of `Rozen Maiden - Traumend - 07.avi' succeeded (transfer complete). 177MiB transferred in 2h46m35s (19KiB/s). + # [izms]Inkognito: Upload of `Ultra Maniac TV - 16.avi' failed (communication error). 1.7MiB transferred in 3m4s (9KiB/s). + if(/^(.+): Upload of `(.+)' (succeeded|failed) \(([^)]+)\)\. ([0-9\.]+[GMK]?i?B) transferred in ([0-9dhms]+) \(([0-9]+)KiB\/s\)/) { + my($nick, $file, $sf, $msg, $sent, $time, $speed) = ($1, $2, $3, $4, $5, $6); + $file =~ s/\\'/'/g; + + my $epoch = POSIX::mktime(POSIX::strptime($date, '%d.%m.%Y %T')); + + $sent = calcsize($sent); + $time = calctime($time); + + $totalsent += $sent; + + my $k = $nick.$file; + next if $ts{$k} && grep { +$_ == $epoch } @{$ts{$k}{epoch}}; + if($ts{$k}) { + $ts{$k}{sent} += $sent; + $ts{$k}{time} += $time; + $ts{$k}{chunks}++; + $ts{$k}{failed}++ if $sf eq 'failed'; + $ts{$k}{succeeded}++ if $sf eq 'succeeded'; + push(@{$ts{$k}{epoch}}, $epoch); + } else { + $ts{$k} = { + file => $file, + nick => $nick, + sent => $sent, + time => $time, + date => $date, + epoch => [ $epoch ], # only used for identification and sorting +# msg => $msg, # unused + chunks => 1, + failed => $sf eq 'failed' ? 1 : 0, + succeeded => $sf eq 'succeeded' ? 1 : 0, + }; + } + } +} +store \%ts, $cache; + +printf "\nSent %d files and %s\n", scalar keys %ts, calcsize($totalsent); +print qq| + + + + + + + + + + + + + + + \n|; + +printf(qq| + + + + + + + +\n|, + $ts{$_}{date}, + calcsize($ts{$_}{sent}), + calctime($ts{$_}{time}), + $ts{$_}{sent}/($ts{$_}{time}||1), + $ts{$_}{chunks}, $ts{$_}{succeeded}, $ts{$_}{failed}, + $ts{$_}{nick}, + $ts{$_}{file}, +) + for (sort { $ts{$b}{epoch}[0] <=> $ts{$a}{epoch}[0] } keys %ts); + +print qq|
    Date/timeTransferedTimeSpeedChunksUserFilename
    %s%s%s%.2f KiB/s%d/%d/%d%s%s
    + +|; + + +sub calcsize { # in KBytes by default, to avoid a 32bit int overflow + if($_[0] =~ /^([0-9\.]+)(GiB|MiB|KiB|B)$/) { + return $2 eq 'B' ? $1/1024 : + $2 eq 'KiB' ? $1 : + $2 eq 'MiB' ? $1*1024 : + $1*1024*1024; + } else { + my $r = $_[0]; my $x = 'KiB'; + if($r > 1024) { $r/=1024; $x='MiB' } + if($r > 1024) { $r/=1024; $x='GiB' } + return sprintf "%.1f %s", $r, $x; + } +} +sub calctime { + if($_[0] =~ /[dhms]/) { + my @t = reverse split(/[dhms]/, $_[0]); + return ($t[3]||0)*86400 + ($t[2]||0)*3600 + ($t[1]||0)*60 + $t[0]; + } else { + my $r = $_[0]; my $x = ''; + if($r > 24*3600) { $x .= int($r/(24*3600)).' d '; $r%=24*3600; } + $x .= sprintf '%d:%02d:%02d', + int($r/3600), + int(($r%3600)/60), + ($r%3600) % 60; + return $x; + } +} diff --git a/download/code/nccolour.c b/download/code/nccolour.c new file mode 100644 index 0000000..2b19d17 --- /dev/null +++ b/download/code/nccolour.c @@ -0,0 +1,99 @@ +/* nccolour.c - Print out some ncurses colours. + * + * Compile using: + * gcc nccolour.c -o nccolour -lncurses + * + * Written by Yoran Heling + * + * Date: 2011-06-11 + * License: MIT + * Web: http://dev.yorhel.nl/dump/nccolour + */ + +#include +#include + + +struct colour { + int code; char *desc; +} colours[] = { + { -1, "default" }, + { COLOR_BLACK, "BLACK" }, + { COLOR_RED, "RED" }, + { COLOR_GREEN, "GREEN" }, + { COLOR_YELLOW, "YELLOW" }, + { COLOR_BLUE, "BLUE" }, + { COLOR_MAGENTA, "MAGENTA" }, + { COLOR_CYAN, "CYAN" }, + { COLOR_WHITE, "WHITE" }, +}; + + +void print_colourpart(int attr, int i) { + addstr(" "); + attron(attr | COLOR_PAIR(i*6+1)); + addstr("FD"); + addstr(" "); + attron(attr | COLOR_PAIR(i*6+2)); + addstr("FB"); + attroff(attr | COLOR_PAIR(i*6+2)); + addstr(" "); + attron(attr | COLOR_PAIR(i*6+3)); + addstr("FW"); + attroff(attr | COLOR_PAIR(i*6+3)); + addstr(" "); + attron(attr | COLOR_PAIR(i*6+4)); + addstr("BG"); + attroff(attr | COLOR_PAIR(i*6+4)); + addstr(" "); + attron(attr | COLOR_PAIR(i*6+5)); + addstr("BD"); + attroff(attr | COLOR_PAIR(i*6+5)); +} + + +int main(int argc, char **argv) { + if(!initscr()) { + printf("Error initializing screen.\n"); + exit(1); + } + if(!has_colors()) { + printf("This terminal does not support colours.\n"); + exit(1); + } + start_color(); + + // this prevents ncurses from forcing a white-on-black colour scheme, + // regardless of what scheme is used by the terminal. + use_default_colors(); + + attron(A_BOLD); + mvaddstr(0, 0, "Colour FD FB FW BG BD BFD BFB BFW BBG BBN"); + attroff(A_BOLD); + + int i; + for(i=0; i -p + + TODO: + - Giving password on the commandline is a really bad idea, + need to fix an alternative method. + - Display more info on VN info output (links/description) + - Make host/port configurable + - VN searching + - More error checking on the received JSON data + - Producers/releases? + + + Copyright (c) 2009 Yoran Heling + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +#define PROGRAM "vinfo" +#define VERSION 0.1 + +#define SERVER "81.204.242.156" /* beta, you may want to change this to whatever api.vndb.org resolves to */ +#define PORT 19534 + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#define WS "\011\012\015\040" +#define DIE(str) { perror(str); exit(1); } + + +char *user, *pass; +int sock; + + +/* sends command and returns reply */ +char *docmd(char *cmd) { + char *res, *fmt; + unsigned int start, end, read = 0, size = 1024; + int r; + json_object *json; + + if(send(sock, cmd, strlen(cmd), 0) < 0) + DIE("send"); + + /* receive data */ + res = malloc(size); + while(memchr(res, 4, read) == NULL) { + if(read > 102400) { + printf("ERROR: Too long reply.\n"); + exit(1); + } + if(size-read < 500) { + size *= 2; + res = realloc(res, size); + } + if((r = recv(sock, res+read, size-read, 0)) < 0) + DIE("recv"); + read += r; + } + + /* remove leading and trailing whitespace */ + end = ((char *)memchr(res, 4, read))-res; + res[end--] = 0; + while(strspn(res+end, WS)) + end--; + start = strspn(res, WS); + + if(start == 0) + fmt = res; + else { + fmt = malloc(end-start+1); + strcpy(fmt, res+start); + free(res); + } + + /* check for error response */ + if(!strncmp(fmt, "error", strlen("error"))) { + res = fmt+strlen("error"); + res += strspn(res, WS); + json = json_tokener_parse(res); + if(json != NULL && json_object_is_type(json, json_type_object)) { + printf("ERROR(%s): %s\n", + json_object_get_string(json_object_object_get(json, "id")), + json_object_get_string(json_object_object_get(json, "msg"))); + json_object_put(json); + } else { + printf("Received something strange...\n> %s\n", fmt); + } + free(fmt); + exit(1); + } + + return fmt; +} + + +/* opens the TCP socket and logs in */ +void login() { + struct sockaddr_in addr; + json_object *arg; + const char *json; + char *cmd, *res; + + /* connect */ + if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + DIE("socket"); + + addr.sin_family = AF_INET; + addr.sin_port = htons(PORT); + inet_aton(SERVER, &addr.sin_addr); + if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + DIE("connect"); + + /* construct login command */ + arg = json_object_new_object(); + json_object_object_add(arg, "protocol", json_object_new_int(1)); + json_object_object_add(arg, "client", json_object_new_string(PROGRAM)); + json_object_object_add(arg, "clientver", json_object_new_double(VERSION)); + json_object_object_add(arg, "username", json_object_new_string(user)); + json_object_object_add(arg, "password", json_object_new_string(pass)); + json = json_object_to_json_string(arg); + cmd = malloc(strlen(json) + 10); + sprintf(cmd, "login %s\04", json); + json_object_put(arg); + + /* login */ + res = docmd(cmd); + free(cmd); + if(strncmp("ok", res, 2)) { + printf("ERROR: Received something strange.\n> %s\n", res); + free(res); + exit(1); + } + free(res); +} + + +void vninfo(int vid) { + char cmd[50], *res, *tmp, *tmp2; + const char *str; + int i, n; + json_object *json, *vn, *itm; + + login(); + sprintf(cmd, "get vn basic,details (id=%d)\04", vid); + res = docmd(cmd); + if(strncmp("results", res, 7)) { + printf("ERROR: Received something strange.\n> %s\n", res); + exit(1); + } + tmp = res+7; + tmp += strspn(tmp, WS); + if((json = json_tokener_parse(tmp)) == NULL || !json_object_is_type(json, json_type_object)) { + printf("ERROR: Received something strange.\n> %s\n", res); + exit(1); + } + /*printf("\n%s\n\n", tmp);*/ + + /* note: may want to put in some checks on whether the data indeed confirms to what we expect */ + if(json_object_get_int(json_object_object_get(json, "num")) < 1) { + printf("No VN with that ID.\n"); + exit(1); + } + vn = json_object_array_get_idx(json_object_object_get(json, "items"), 0); + + /* header + titles */ + printf("------------------------------ v%-5d ----------------------------\n", vid); + printf(" Title : %s\n", json_object_get_string(json_object_object_get(vn, "title"))); + if((str = json_object_get_string(json_object_object_get(vn, "original"))) != NULL) + printf(" Official : %s\n", str); + + /* aliases (string processing in C, meh) */ + str = json_object_get_string(json_object_object_get(vn, "aliases")); + if(str != NULL) { + printf(" Aliases : "); + tmp = strdup(str); + tmp2 = tmp; + i = -1; + do { + i++; + if(!tmp[i] || tmp[i] == ',' || tmp[i] == '\n') { + if(tmp2 != tmp) + printf(" "); + tmp2 += strspn(tmp2, ", \n"); + n = tmp[i]; + tmp[i] = 0; + printf("%s\n", tmp2); + if(n) { + i++; + tmp2 = tmp+i; + } + } + } while(tmp[i]); + free(tmp); + } + + /* release date */ + str = json_object_get_string(json_object_object_get(vn, "released")); + printf(" First release : %-10s\n", str != NULL ? str : "-"); + + /* length */ + itm = json_object_object_get(vn, "length"); + if(json_object_is_type(itm, json_type_int)) { + printf(" Length : "); + switch(json_object_get_int(itm)) { + case 1: printf("Very short\n"); break; + case 2: printf("Short\n"); break; + case 3: printf("Medium\n"); break; + case 4: printf("Long\n"); break; + case 5: printf("Very long\n"); break; + } + } + + /* languages */ + itm = json_object_object_get(vn, "languages"); + if(json_object_array_length(itm) > 0) { + printf(" Available in : "); + for(i=0; i 0) { + printf(" ...for : "); + for(i=0; i= 0) { + switch(r) { + case 'u': + user = optarg; + break; + case 'p': + pass = optarg; + break; + case '\1': + query = optarg; + break; + default: + usage(); + } + } + if(!pass || !user || !query) + usage(); + + if(sscanf(query, "%d", &r) == 1 && r > 0) { + vninfo(r); + } else { + printf("Sorry, searching is not supported yet\n"); + exit(1); + } + + return 0; +} + diff --git a/download/code/yapong-0.01.c b/download/code/yapong-0.01.c new file mode 100644 index 0000000..2ff75a3 --- /dev/null +++ b/download/code/yapong-0.01.c @@ -0,0 +1,342 @@ +/* + * YAPong.c 0.01 - Yet Another pong clone, made by //YorHel + * + * Copyright 2006 Y.Heling. + * 2006-02-22 + * License: MIT + */ + +#include +#include + +#include +#include +#include + +#define DI_UP 1 +#define DI_DOWN 2 + +#define DI_RIGHT 3 +#define DI_LEFT 4 + +void movepadel(char, char); +void startgame(); +void drawpadels(); +void updatescore(); +void drawframe(); +void updatedot(); +void movedot(int); +int print_help(char *); + +int winrows, wincols, padsize, padposL, padposR, scoreL, + scoreR, dotX, dotY, delay, padstep, dotstep; +char direX, direY, started, paused, scored, autosize; +WINDOW *win; + +int main(int argc, char *argv[]) { + /* defaults */ + autosize = 0; + padstep = 1; + dotstep = 1; + winrows = 25; wincols = 80; + padsize = ((winrows-3)/10); + delay = 50 * 1000; + /* args */ + { + char *name = *argv++; + char *ch; + while(ch = *argv++) { + if(!strcmp(ch, "-h")) + return print_help(name); + else if(!strcmp(ch, "-l")) { + int level = atoi(*argv++); + switch(level) { + case 1 : delay = 100*1000; padsize = 6; padstep = 2; dotstep = 1; break; + case 2 : delay = 80*1000; padsize = 6; padstep = 2; dotstep = 1; break; + case 3 : delay = 65*1000; padsize = 5; padstep = 1; dotstep = 1; break; + case 4 : delay = 50*1000; padsize = 3; padstep = 1; dotstep = 1; break; + case 5 : delay = 80*1000; padsize = 3; padstep = 1; dotstep = 2; break; + default : + printf("ERROR: unknown level %d\n", level); + return 0; break; + } + } + else if(!strcmp(ch, "-d")) { + delay = atoi(*argv++) * 1000; + if(delay >= 1000*1000 || delay == 0) { + printf("ERROR: delay should be an integer between 0 and 1000\n"); + return 1; + } + } + else if(!strcmp(ch, "-p")) { + padsize = atoi(*argv++); + if(padsize > wincols-3 || padsize == 0) { + printf("ERROR: padel size should at least be 1 and should not be too high\n"); + return 1; + } + } + else if(!strcmp(ch, "-s")) { + if(!strcmp(*argv, "auto")) { + autosize = 1; *argv++; + } else { + wincols = atoi(*argv++); + winrows = atoi(*argv++); + autosize = 0; + if(wincols < 20 || winrows < 5) { + printf("ERROR: Window size should at least be 20x5\n"); + return 1; + } + } + } + else if(!strcmp(ch, "-ps")) { + padstep = atoi(*argv++); + if(padstep > padsize || padstep <= 0) { + printf("ERROR: padstep should at least be 0 and should not be larger than padsize\n"); + return 1; + } + } + else if(!strcmp(ch, "-ds")) { + dotstep = atoi(*argv++); + if(dotstep <= 0) { + printf("ERROR: dotstep should be a positive integer\n"); + return 1; + } + } + else { + printf("ERROR: no such option: %s\n", ch); + return print_help(name); + } + } + } + + /* initialize */ + if( (win = initscr()) == NULL) { + fprintf(stderr, "ERROR: Can't initialize ncurses\n"); + return(1); + } + cbreak(); /* imidiatly get input chars */ + noecho(); /* don't print input chars */ + keypad(stdscr, TRUE); /* also get other keys */ + curs_set(0); /* hide cursor */ + + if(autosize) + getmaxyx(stdscr, winrows, wincols); + + /* non-changable stuff */ + padposL = padposR = ((winrows/2)-(padsize/2)); + scoreL = scoreR = 0; + dotX = (wincols/2); + dotY = (winrows/2)-1; + direX = DI_RIGHT; + direY = DI_DOWN; + started = paused = 0; + + + mvaddstr(0, 0, "Initializing, please wait..."); + refresh(); + clear(); + + /* draw stuff */ + drawframe(); + drawpadels(); + mvaddch(dotY, dotX, '0'); + refresh(); + + + /* get keyboard input */ + int ch; + while(1) { + ch = getch(); + switch(ch) { + case KEY_UP : + movepadel('r', 'u'); break; + case KEY_DOWN : + movepadel('r', 'd'); break; + case 'a' : + movepadel('l', 'u'); break; + case 'z' : + movepadel('l', 'd'); break; + case ' ' : + if(!started) + startgame(); + else if(scored) { + scored = 0; + mvaddch(dotY, dotX, ' '); + dotX = (wincols/2); + dotY = (winrows/2)-1; + refresh(); + } else if(!paused) + paused = 1; + else if(paused) + paused = 0; + break; + case 'q' : + goto end; + break; + } + } + + /* cleanup */ + end: + erase(); + mvaddstr(0, 0, "Thank you for playing Yet Another pong game. :)\nPlease visit http://yorhel.nl/ when your bored...\n"); + refresh(); + delwin(win); + endwin(); + refresh(); + + return 0; +} + +void movepadel(char which, char direct) { + if(paused || scored || !started) + return; + int *pos = which == 'r' ? &padposR : &padposL; + *pos += direct == 'u' ? -1*padstep : padstep; + if(*pos < 2) + *pos = 2; + if(*pos > winrows-padsize-2) + *pos = winrows-padsize-2; + drawpadels(); + move(wincols-1, 0); + refresh(); +} + +void startgame() { + struct itimerval t; + t.it_interval.tv_sec = t.it_value.tv_sec = 0; + t.it_interval.tv_usec = t.it_value.tv_usec = delay; + setitimer(ITIMER_REAL, &t, NULL); + + struct sigaction s; + s.sa_handler = movedot; + s.sa_flags = 0; + sigemptyset(&s.sa_mask); + sigaction(SIGALRM, &s, NULL); + + started = 1; +} + +void drawframe() { + mvaddstr(0, 3, "left"); + mvaddstr(0, wincols-8, "right"); + mvaddstr(0, ((wincols/2)-7), "YAPong by //YorHel"); + move(1, 0); + hline(ACS_HLINE, wincols); + move(winrows-1, 0); + hline(ACS_HLINE, wincols); + updatescore(); +} + +void updatescore() { + char scl[3], scr[3]; + sprintf(scl, "%02d", scoreL); + sprintf(scr, "%02d", scoreR); + mvaddstr(0, 0, scl); + mvaddstr(0, wincols-2, scr); +} + +void drawpadels() { + int c; + for(c=winrows; c--; ) { + if(c < 2 || c >= winrows-1) + continue; + /* left paddel */ + if(c >= padposL && c <= padposL+padsize) + mvaddch(c, 0, ' ' | A_REVERSE); + else + mvaddch(c, 0, ' '); + /* right paddel */ + if(c >= padposR && c <= padposR+padsize) + mvaddch(c, wincols-1, ' ' | A_REVERSE); + else + mvaddch(c, wincols-1, ' '); + } +} + +/* called from signal */ +void movedot(int signal) { + if(signal != SIGALRM || !started || paused || scored) + return; + + mvaddch(dotY, dotX, ' '); + dotX += direX == DI_LEFT ? -1*dotstep : dotstep; + dotY += direY == DI_UP ? -1*dotstep : dotstep; + + if(direY == DI_UP && dotY <= 2) { + direY = DI_DOWN; + dotY = 2; + } + if(direY == DI_DOWN && dotY >= winrows-2) { + direY = DI_UP; + dotY = winrows-2; + } + + if(direX == DI_RIGHT && dotX >= wincols-2) { + direX = DI_LEFT; + dotX = wincols-2; + if(dotY < padposR || dotY > padposR + padsize) { + scored = 1; + scoreL++; + direX = DI_LEFT; + updatescore(); + } + } + if(direX == DI_LEFT && dotX <= 1) { + direX = DI_RIGHT; + dotX = 1; + if(dotY < padposL || dotY > padposL + padsize) { + scored = 1; + scoreR++; + direX = DI_RIGHT; + updatescore(); + } + } + + mvaddch(dotY, dotX, '0'); + move(wincols-1, 0); + refresh(); +} + +int print_help(char *name) { + printf("Usage: %s [options]\n\n", name); + printf("Options:\n"); + printf(" -h This help message.\n"); + printf(" -d int Specifies the interval between every move\n"); + printf(" of the dot. You can speed up the game by\n"); + printf(" setting this to a lower value.\n"); + printf(" -p int Specifies the size of each padel in pixels\n"); + printf(" -s x y Specifies the size of the window, or set\n"); + printf(" to 'auto' to use the size of your current\n"); + printf(" terminal. Recommended and default size is\n"); + printf(" 80x25.\n"); + printf(" -ps int Specifies the amount of pixels the padels\n"); + printf(" move each time\n"); + printf(" -ds int The amount of pixels the dot moves each\n"); + printf(" time, setting this to a larger value\n"); + printf(" increases game speed a lot.\n"); + printf(" -l level The game-level, higher levels are more\n"); + printf(" difficult. See below for more information\n\n"); + + printf("Levels:\n"); + printf(" option equals to\n"); + printf(" -l 1 -d 100 -p 6 -ps 2 -ds 1\n"); + printf(" -l 2 -d 80 -p 6 -ps 2 -ds 1\n"); + printf(" -l 3 -d 65 -p 5 -ps 1 -ds 1\n"); + printf(" -l 4 -d 50 -p 3 -ps 1 -ds 1\n"); + printf(" -l 5 -d 80 -p 3 -ps 1 -ds 2\n"); + printf(" Please note that all the levels are meant for a 80x25\n"); + printf(" window size, level 5 might be very easy with a higher\n"); + printf(" window size. In that case you should change the\n"); + printf(" the options yourself.\n\n"); + + printf("Ingame keys:\n"); + printf(" space Start/pause/resume game\n"); + printf(" key_up Move right padel up\n"); + printf(" key_down Move right padel down\n"); + printf(" a Move left padel up\n"); + printf(" z Move left padel down\n"); + printf(" q Quit game\n"); + return 0; +} + diff --git a/download/code/yapong.c b/download/code/yapong.c new file mode 100644 index 0000000..31bfd55 --- /dev/null +++ b/download/code/yapong.c @@ -0,0 +1,335 @@ +/* + * YAPong.c 0.02 - Yet Another pong clone, made by //YorHel + * + * Copyright 2006 Y.Heling. + * 2006-02-23 + * License: MIT + */ + +#include +#include + +#include + +#define DI_UP 1 +#define DI_DOWN 2 + +#define DI_RIGHT 3 +#define DI_LEFT 4 + +void movepadel(char, char); +void drawpadels(); +void updatescore(); +void drawframe(); +void updatedot(); +void movedot(); +int print_help(char *); + +int winrows, wincols, padsize, padposL, padposR, scoreL, + scoreR, dotX, dotY, delay, padstep, dotstep; +char direX, direY, started, paused, scored, autosize, autopsize; +WINDOW *win; + +int main(int argc, char *argv[]) { + /* defaults */ + autosize = 1; + autopsize = 1; + padstep = 1; + dotstep = 1; + winrows = 25; wincols = 80; + padsize = 0; + delay = 50; + /* args */ + { + char *name = *argv++; + char *ch; + while(ch = *argv++) { + if(!strcmp(ch, "-h")) + return print_help(name); + else if(!strcmp(ch, "-l")) { + int level = atoi(*argv++); + switch(level) { + case 1 : delay = 100; padsize = 6; padstep = 2; dotstep = 1; break; + case 2 : delay = 80; padsize = 6; padstep = 2; dotstep = 1; break; + case 3 : delay = 65; padsize = 5; padstep = 1; dotstep = 1; break; + case 4 : delay = 50; padsize = 3; padstep = 1; dotstep = 1; break; + case 5 : delay = 80; padsize = 3; padstep = 1; dotstep = 2; break; + default : + printf("ERROR: unknown level %d\n", level); + return 0; break; + } + } + else if(!strcmp(ch, "-d")) { + delay = atoi(*argv++); + if(delay >= 1000 || delay == 0) { + printf("ERROR: delay should be an integer between 0 and 1000\n"); + return 1; + } + } + else if(!strcmp(ch, "-p")) { + if(!strcmp(*argv, "auto")) { + autopsize = 1; *argv++; + } else { + autopsize = 0; + padsize = atoi(*argv++); + if(padsize > wincols-3 || padsize == 0) { + printf("ERROR: padel size should at least be 1 and should not be too high\n"); + return 1; + } + } + } + else if(!strcmp(ch, "-s")) { + if(!strcmp(*argv, "auto")) { + autosize = 1; *argv++; + } else { + wincols = atoi(*argv++); + winrows = atoi(*argv++); + autosize = 0; + if(wincols < 20 || winrows < 5) { + printf("ERROR: Window size should at least be 20x5\n"); + return 1; + } + } + } + else if(!strcmp(ch, "-ps")) { + padstep = atoi(*argv++); + if(padstep <= 0) { + printf("ERROR: padstep should at least be 1\n"); + return 1; + } + } + else if(!strcmp(ch, "-ds")) { + dotstep = atoi(*argv++); + if(dotstep <= 0) { + printf("ERROR: dotstep should be a positive integer\n"); + return 1; + } + } + else { + printf("ERROR: no such option: %s\n", ch); + return print_help(name); + } + } + } + + /* initialize */ + if( (win = initscr()) == NULL) { + fprintf(stderr, "ERROR: Can't initialize ncurses\n"); + return(1); + } + cbreak(); /* imidiatly get input chars */ + noecho(); /* don't print input chars */ + keypad(stdscr, TRUE); /* also get other keys */ + curs_set(0); /* hide cursor */ + nodelay(stdscr, TRUE); + + if(autosize) + getmaxyx(stdscr, winrows, wincols); + if(autopsize) + padsize = ((winrows-3)/10)*2; + + /* non-changable stuff */ + padposL = padposR = ((winrows/2)-(padsize/2)); + scoreL = scoreR = 0; + dotX = (wincols/2); + dotY = (winrows/2)-1; + direX = DI_RIGHT; + direY = DI_DOWN; + started = paused = 0; + + /* draw stuff */ + drawframe(); + drawpadels(); + mvaddch(dotY, dotX, '0'); + refresh(); + + /* main loop */ + delay = delay/15; /* assume napms() takes 50% more time */ + int ch; int d = 0; + while(1) { + ch = getch(); + switch(ch) { + case ERR : break; + case KEY_UP : + movepadel('r', 'u'); break; + case KEY_DOWN : + movepadel('r', 'd'); break; + case 'a' : + movepadel('l', 'u'); break; + case 'z' : + movepadel('l', 'd'); break; + case ' ' : + if(!started) + started = 1; + else if(scored) { + scored = 0; + mvaddch(dotY, dotX, ' '); + dotX = (wincols/2); + dotY = (winrows/2)-1; + refresh(); + } else if(!paused) + paused = 1; + else if(paused) + paused = 0; + break; + case 'q' : + goto end; + break; + } + if(++d == delay) { + d = 0; + movedot(); + } + napms(10); + } + + /* cleanup */ + end: + erase(); + mvaddstr(0, 0, "Thank you for playing Yet Another pong game. :)\nPlease visit http://yorhel.nl/ when your even more bored...\n"); + refresh(); + delwin(win); + endwin(); + refresh(); + + return 0; +} + +void movepadel(char which, char direct) { + if(paused || scored || !started) + return; + int *pos = which == 'r' ? &padposR : &padposL; + *pos += direct == 'u' ? -1*padstep : padstep; + if(*pos < 2) + *pos = 2; + if(*pos > winrows-padsize-2) + *pos = winrows-padsize-2; + drawpadels(); + move(wincols-1, 0); + refresh(); +} + +void drawframe() { + mvaddstr(0, 3, "left"); + mvaddstr(0, wincols-8, "right"); + mvaddstr(0, ((wincols/2)-7), "YAPong by //YorHel"); + move(1, 0); + hline(ACS_HLINE, wincols); + move(winrows-1, 0); + hline(ACS_HLINE, wincols); + updatescore(); +} + +void updatescore() { + char scl[3], scr[3]; + sprintf(scl, "%02d", scoreL); + sprintf(scr, "%02d", scoreR); + mvaddstr(0, 0, scl); + mvaddstr(0, wincols-2, scr); +} + +void drawpadels() { + int c; + for(c=winrows; c--; ) { + if(c < 2 || c >= winrows-1) + continue; + /* left paddel */ + if(c >= padposL && c <= padposL+padsize) + mvaddch(c, 0, ' ' | A_REVERSE); + else + mvaddch(c, 0, ' '); + /* right paddel */ + if(c >= padposR && c <= padposR+padsize) + mvaddch(c, wincols-1, ' ' | A_REVERSE); + else + mvaddch(c, wincols-1, ' '); + } +} + +void movedot() { + if(!started || paused || scored) + return; + + mvaddch(dotY, dotX, ' '); + dotX += direX == DI_LEFT ? -1*dotstep : dotstep; + dotY += direY == DI_UP ? -1*dotstep : dotstep; + + if(direY == DI_UP && dotY <= 2) { + direY = DI_DOWN; + dotY = 2; + } + if(direY == DI_DOWN && dotY >= winrows-2) { + direY = DI_UP; + dotY = winrows-2; + } + + if(direX == DI_RIGHT && dotX >= wincols-2) { + direX = DI_LEFT; + dotX = wincols-2; + if(dotY < padposR || dotY > padposR + padsize) { + scored = 1; + scoreL++; + direX = DI_LEFT; + updatescore(); + } + } + if(direX == DI_LEFT && dotX <= 1) { + direX = DI_RIGHT; + dotX = 1; + if(dotY < padposL || dotY > padposL + padsize) { + scored = 1; + scoreR++; + direX = DI_RIGHT; + updatescore(); + } + } + + mvaddch(dotY, dotX, '0'); + move(wincols-1, 0); + refresh(); +} + +int print_help(char *name) { + printf("Usage: %s [options]\n\n", name); + printf("Options:\n"); + printf(" -h This help message.\n"); + printf(" -d int Specifies the interval between every move\n"); + printf(" of the dot. You can speed up the game by\n"); + printf(" setting this to a lower value.\n"); + printf(" -p int Specifies the size of each padel in pixels,\n"); + printf(" set to auto to automatically calculate the\n"); + printf(" size using the window size.\n"); + printf(" -s x y Specifies the size of the window, or set\n"); + printf(" to 'auto' to use the size of your current\n"); + printf(" terminal. Recommended size: 80x25, default:\n"); + printf(" auto.\n"); + printf(" -ps int Specifies the amount of pixels the padels\n"); + printf(" move each time\n"); + printf(" -ds int The amount of pixels the dot moves each\n"); + printf(" time, setting this to a larger value\n"); + printf(" increases game speed a lot.\n"); + printf(" -l level The game-level, higher levels are more\n"); + printf(" difficult. See below for more information\n\n"); + + printf("Levels:\n"); + printf(" option equals to\n"); + printf(" -l 1 -d 100 -p 6 -ps 2 -ds 1\n"); + printf(" -l 2 -d 80 -p 6 -ps 2 -ds 1\n"); + printf(" -l 3 -d 65 -p 5 -ps 1 -ds 1\n"); + printf(" -l 4 -d 50 -p 3 -ps 1 -ds 1\n"); + printf(" -l 5 -d 80 -p 3 -ps 1 -ds 2\n"); + printf(" Please note that all the levels are meant for a 80x25\n"); + printf(" window size, level 5 might be very easy with a higher\n"); + printf(" window size. In that case you should change the\n"); + printf(" the options yourself.\n\n"); + + printf("Ingame keys:\n"); + printf(" space Start/pause/resume game\n"); + printf(" key_up Move right padel up\n"); + printf(" key_down Move right padel down\n"); + printf(" a Move left padel up\n"); + printf(" z Move left padel down\n"); + printf(" q Quit game\n"); + return 0; +} + diff --git a/download/ncdu-1.13.tar.gz.asc b/download/ncdu-1.13.tar.gz.asc new file mode 100644 index 0000000..2af4dee --- /dev/null +++ b/download/ncdu-1.13.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEdEYNMrgIEOupr6LpYjlMaYwnOfoFAlpu/qsACgkQYjlMaYwn +OfqxAA//QtGz3x1IdBJo1VFblt9MNiaI5C/YOP7u40u72147+DX7wqsXBG/LgSBM +3CY9+GPg4gRZTN/ylaAEF7lqb3epsP76BBiIkqErs70DkR27svdMCmv5I7II8X38 +w2HmT0A5dD0ktn5wih4YOepjhMGzw9LQG5/yQjrTHzWoZHVkYhXB5zamNdMmnvPC +yI4/zcwMxLrFYvc0aUNDDauwaCHbDmyuxcbKRm+SShSE53QLz/whl4wrBDGE1Oxo +7JAIgwWyu6D2NRYET4x3oipeFmeaBK8IbJLA/oO8mY76iutu5Nu9+xo3xYftJhKw +WB4HxxNvfMqX1d2kO1TJAiDYu4eCl6ND3nZZyPjxH07vLYC3g8ddGsCvVEgDKyrs +JD6NFMvDVEiL/RG01gnvwkVi704maT0LHC4l6GsAXb4mpNHwKT0HNHHCAFnBDwAf +hqMHhBZYIvj90RrSP9vRx/rrhg55s+MPddb/o149z+L/hapF7IHpJnrNsBf5MGrW +2Q64d7mc2sYsm03KcXI5bfVATMALRfbJK9XQHFjIxggdVd6j+F+vOsQz0T93Wwx7 +uHIqtB0NQD4CxHl5119m7KU0BFV0Qpe1rtI4ZGlGmGAhpUVx2cGpdH8GA1p1FA/2 +dAqQQbOjEpMsFZ5PZ2uE8aOSz+lMqSLPzEuV+VJK/Y3sLNFzmrs= +=ze3z +-----END PGP SIGNATURE----- diff --git a/download/ncdu-1.13.tar.gz.md5 b/download/ncdu-1.13.tar.gz.md5 new file mode 100644 index 0000000..c8c78bc --- /dev/null +++ b/download/ncdu-1.13.tar.gz.md5 @@ -0,0 +1 @@ +67239592ac41f42290f52ab89ff198be ncdu-1.13.tar.gz diff --git a/download/ncdu-1.13.tar.gz.sha1 b/download/ncdu-1.13.tar.gz.sha1 new file mode 100644 index 0000000..736b770 --- /dev/null +++ b/download/ncdu-1.13.tar.gz.sha1 @@ -0,0 +1 @@ +3233c4185208d9989ac528a94817ed92dd59c773 ncdu-1.13.tar.gz diff --git a/img/ncduconfirm-2.png b/img/ncduconfirm-2.png new file mode 100644 index 0000000000000000000000000000000000000000..f10cf1b4ae5f8d25876237910763464fa31a697f GIT binary patch literal 42545 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⁡vE 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 literal 0 HcmV?d00001 diff --git a/img/ncdudone-2.png b/img/ncdudone-2.png new file mode 100644 index 0000000000000000000000000000000000000000..0758369acdc66952dbf6642f252a0767d654921d GIT binary patch literal 24131 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 z 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 bxn_c{)rHbE#pHu$(A-f|(pIdLw+;Cp6fo1p literal 0 HcmV?d00001 diff --git a/img/ncduinfo-2.png b/img/ncduinfo-2.png new file mode 100644 index 0000000000000000000000000000000000000000..2076d5faa73db38d48aa59ccdbcba68920ed9d81 GIT binary patch literal 36225 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 a_+u|NsZ9Qwrx+Il5O})!xvXv)0 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 literal 0 HcmV?d00001 diff --git a/index.cgi b/index.cgi index eafc80a..6e3bef5 100755 --- a/index.cgi +++ b/index.cgi @@ -3,7 +3,7 @@ use strict; use warnings; use utf8; -use TUWF ':html', ':xml'; +use TUWF ':html'; use POSIX 'strftime'; use Cwd 'abs_path'; @@ -12,6 +12,10 @@ BEGIN { ($ROOT = abs_path $0) =~ s{index\.cgi$}{}; } my @changes = ( + [ '2018-01-29', '/ncdu', 'ncdu 1.13 released' ], + [ '2018-01-24', '/nginx-confgen', 'nginx-confgen 1.1 released' ], + [ '2018-01-19', '/nginx-confgen', 'New project: nginx-confgen' ], + [ '2017-05-28', '/doc/funcweb', 'New article: An Opinionated Survey of Functional Web Development' ], [ '2016-12-30', '/ncdc', 'ncdc 1.20 released' ], [ '2016-08-24', '/ncdu', 'ncdu 1.12 released' ], [ '2016-08-16', '/dump/btrfssize', 'Uploaded btrfs-size.pl' ], @@ -109,6 +113,9 @@ TUWF::register( qr{globster/daemon} => sub { podpage(shift, 'globster-daemon', 'globster', 'daemon', 'The globster(1) Man Page', 1) }, qr{globster/launch} => sub { podpage(shift, 'globster-launch', 'globster', 'launch', 'The globster-launch(1) Man Page', 1) }, qr{globster/ctl} => sub { podpage(shift, 'globster-ctl', 'globster', 'ctl', 'The globsterctl(1) Man Page', 1) }, + qr{nginx-confgen} => sub { podpage(shift, 'nginx-confgen', 'nginx-confgen', '', 'Nginx Configuration Generator') }, + qr{nginx-confgen/man} => sub { podpage(shift, 'nginx-confgen-man', 'nginx-confgen', 'man', 'The nginx-confgen(1) Man Page', 1) }, + qr{nginx-confgen/changes} => sub { changelog(shift, 'nginx-confgen-changelog', undef, 'nginx-confgen', 'changes', 'nginx-confgen Changelog', 1) }, qr{tuwf} => sub { podpage(shift, 'tuwf', 'tuwf', '', 'The Ultimate Website Framework') }, qr{tuwf/man(?:/(db|misc|request|response|xml))?} => \&tuwfmanual, qr{tuwf/changes} => sub { changelog(shift, 'tuwf-changelog', 'TUWF', 'tuwf', 'changes', 'TUWF Changelog') }, @@ -120,6 +127,7 @@ TUWF::register( qr{doc/commvis} => sub { podpage(shift, 'doc-commvis', 'doc', '', 'A Distributed Communication System for Modular Applications', 1) }, qr{doc/dcstats} => sub { podpage(shift, 'doc-dcstats', 'doc', '', 'Some Measurements on Direct Connect File Lists', 1) }, qr{doc/easyipc} => sub { podpage(shift, 'doc-easyipc', 'doc', '', 'The Sorry State of Convenient IPC', 1) }, + qr{doc/funcweb} => sub { podpage(shift, 'doc-funcweb', 'doc', '', 'An Opinionated Survey of Functional Web Development') }, qr{dump} => sub { podpage(shift, 'dump', 'dump', '', 'Code dump') }, qr{demo} => sub { podpage(shift, 'dump-demo', 'dump', 'demo', 'Demos') }, qr{dump/awshrink} => sub { podpage(shift, 'dump-awshrink', 'dump', 'awshrink', 'AWStats Data File Shrinker') }, @@ -165,8 +173,11 @@ sub changelog { $v =~ s/^([0-9]+\.[0-9]+(?:\.[0-9]+)?)\s+-\s+([0-9]{4}-[0-9]{2}-[0-9]{2})//; li style => 'list-style-type: none; margin: 0'; b $1; - txt " - $2 - "; - lit $s->genDLLink("$pr-$1.tar.gz"); + txt " - $2"; + if($pr) { + txt ' - '; + lit $s->genDLLink("$pr-$1.tar.gz"); + } br; ul; for (split(/\r?\n\s+-\s+/, $v)) { @@ -203,7 +214,7 @@ sub atom { my $t = (stat("$ROOT/index.cgi"))[9]; $s->resHeader('Last-Modified' => strftime '%a, %d %b %Y %H:%M:%S GMT', gmtime $t); $s->resHeader('Content-Type' => 'application/atom+xml'); - xml; + TUWF::XML::xml; tag feed => xmlns => 'http://www.w3.org/2005/Atom', 'xml:lang' => 'en', 'xml:base' => 'https://dev.yorhel.nl/'; tag title => $sub ? "\u$sub Project Announcements" : "Yorhel's Projects"; tag updated => strftime('%Y-%m-%dT%H:%M:%SZ', gmtime $t); @@ -387,6 +398,7 @@ sub htmlPOD { globster-launch(1) /globster/launch globster(1) /globster/daemon globster-api(7) /globster/api + ncdu(1) /ncdu/man |; return $l{$l} || ($l =~ /(.+)\((.)\)/ and "http://manned.org/$1.$2"); }; @@ -444,7 +456,7 @@ sub genChanges { sub htmlHeader { my $s = shift; my %o = ( - spec => { map +($_,1), qw|ncdu ncdc globster tuwf yxml| }, + spec => { map +($_,1), qw|ncdu ncdc globster tuwf yxml nginx-confgen| }, page => '', sec => '', sec2 => '', @@ -548,12 +560,17 @@ sub htmlMenu { $m->('/yxml', 'Info', !$o{sec}); $m->('/yxml/man', 'Manual', $o{sec} eq 'man'); $m->('/yxml/bug', 'Bug tracker', $o{sec} eq 'bug'); + } elsif($o{page} eq 'nginx-confgen') { + $m->('/nginx-confgen', 'Info', !$o{sec}); + $m->('/nginx-confgen/man', 'Manual', $o{sec} eq 'man'); + $m->('/nginx-confgen/changes', 'Changelog', $o{sec} eq 'changes'); } else { $m->('/', 'Home', !$o{page}); $m->('/ncdu', 'Ncdu '); $m->('/ncdc', 'Ncdc '); $m->('/tuwf', 'Tuwf '); $m->('/yxml', 'Yxml '); + $m->('/nginx-confgen', 'Nginx-cfg '); $m->('/ylib', 'Ylib', $o{page} eq 'ylib'); $m->('/doc', 'Writing', $o{page} eq 'doc'); $m->('/dump', 'Code dump', $o{page} eq 'dump', sub {