Planeta Blogów WMI UAM

December 09, 2024

Borkowski Marcin

2024-12-09 The expect command line tool

Some time ago I wrote about the ways you can provide psql with a password to the database. I didn’t mention one of the simplest ideas I had, partly because it didn’t work, and partly because a variant of it did work, but was quite involved. So, here is my initial idea and its working version.

At first, I figured that I could make psql ask for password using the --password option, and just provide the password on the standard input, using redirection. This was a bad idea for two reasons. First and foremost, psql just doesn’t work like that – when you give it something on stdin, it just treats it as an SQL script to run and reads the password directly from your terminal. And even if that worked, what I really wanted then was to start an interactive psql session (just without having to type the password), so piping anything but the terminal to stdin would make it impossible anyway.

When I shared my initial idea with a colleague, he told me about the expect utility (warning: the latter link points to expect​’s homepage on SourceForge). I have to admit that despite using GNU/Linux command line for over two decades, I have never heard about it earlier! It is a wonderful gem, probably easiest to describe as “AutoHotkey for the command line”.

The main drawback of expect is that it is written in Tcl, and instead of defining its own DSL, it just extends Tcl. This is of course a good idea – why write something from scratch when you can extend an existing language – but Tcl is, well, Tcl, an old, rather non-Lispy programming langauge I know basically nothing about. Still, there are both examples on the web and ChatGPT, which seems to be able to write at least very basic expect scripts.

For example, assume that I have a password to the database stored in pass. I want to get the password from the store (which, depending on my gpg-agent configuration, may or may not require typing some passkey interactively) and run psql, providing the read password to psql​’s prompt. Here is what ChatGPT produced, which seems to work well enough for me.

# Retrieve the password from pass
set password [exec pass show database/password]

# Launch psql and provide the password at the password prompt
spawn psql -h localhost -U mbork -d db
expect "Password: "
send "$password\r"
interact

I read portions of Tcl’s manpage (and also Wikipedia page) to actually understand what is happening here. set and exec are commands from Tcl, not expect, and the first line sets the password variable to the output of pass. spawn, as you may have guessed, spawns a new process, which becomes the “current process”. The expect command waits until the output matches the given pattern. As you may guess from the fact that its name is the name of the tool, it is one of the central features of expect, and can be pretty complicated – here it just waits until psql prints the string Password:_ (where the underscore denotes a space). In a sense, send is its opposite – while expect pretends to be the eyes of the user who looks at the output of an interactive command, send pretends to be their fingers typing on the keyboard. The sequence \r means the “enter” key. Finally, interact sort of “gives back” the control to the user, although it is far from that simple in general.

And that’s it! I just wrote my first expect script (well, I had it written for me…), and here it is. Funnily enough, the manpage for expect (which is pretty long at over 1700 lines) gives an alphabetical list of expect commands, but says first
Commands are listed alphabetically so that they can be quickly located. However, new users may find it easier to start by reading the descriptions of spawn, send, expect, and interact, in that order.
and these are exactly the commands we needed, and almost in that order (not that it is a surprise).

I can only suggest that you read the expect manpage for more details, especially the hints near the end. I had some doubts whether using an obscure (well, at least one I didn’t know earlier) utility like this for something as delicate as passwords, but it seems that (a) expect was explicitly created with typing passwords like in our example as one of the uses, and (b) it was written by hackers infinitely better than me over the course of more than 30 years, so I am pretty confident that it is stable, mature and safe enough to be handling my passwords.

CategoryEnglish, CategoryBlog

December 09, 2024 06:00 PM

December 02, 2024

Borkowski Marcin

2024-12-01 Automatically inserting Ledger transactions

I wrote a few times that I use and like Ledger a lot. As some of you might know, I even wrote a booklet about personal accounting, using Ledger in examples. One of the nice things about Ledger is that it comes with an Emacs mode to edit its files (which is not a surprise, given that it is written by John Wiegley himself). That is not to say, though, that it suits my needs perfectly.

Most of the transactions I enter in my Ledger file are purchases. They almost always have the same structure – one or more categories of expenses followed by the source, which is almost always some cash account (like Assets:Cash:Wallet:Me) or a payment card (like Assets:Bank:Wife). Ledger mode provides rudimentary support for inserting a transaction based on history (try C-c C-a and C-c <tab>, that is, ledger-add-transaction and ledger-fully-complete-xact, respectively), but I wanted something even more automatic. Of course, this is Emacs, so coding something like this should be a breeze.

I started with skimming the Ledger mode manual and sources to make sure I don’t reinvent a wheel. A bit surprisingly, I didn’t find a ready-made command to insert a transaction, so I decided that I’ll just need a bunch of insert​s and a call to ledger-post-align-xact.

I strive to enter my Ledger transactions on the day they were made, but I don’t always succeed, so my inserting command should first ask the user the date (defaulting to today). The next thing is the description, which should obviously have history and completions based on previously entered descriptions. I’m going to use persist-defvar from the persist package for that so that the history is remembered across Emacs sessions. (Note that I specifically do not want to use all the description from my Ledger file as autocompletion candidates – the file is over 8 years old, and I often don’t want to mimic transactions from many years ago.) Next comes the source – I could also use a persisted history for that, but since the possible source accounts are usually very limited (in my case, there are basically three of them possible – my wallet, my wife’s wallet, and my wife’s bank card, since I don’t use any), I decided to go with read-char-choice. This approach requires configuring the source accounts in the init file, but this is something done once, so it’s not a big problem. Finally, the user needs to provide the amount. Here I implemented a simple trick so that I won’t have to type the decimal point – if the amount is an integer greater than 100, it is treated as the number of cents (or grosze in my case) and divided by 100. This lets me save one keystroke.

The code is pretty simple. I thought about making this command a bit more versatile and allowing for non-interactive use (via the trick I wrote about almost a decade ago), but ultimately decided against it – the only purpose of my command is to allow entering transations quickly and interactively, so I figured that the added complexity is not worth it.

(require 'persist)

(persist-defvar mbork-ledger-descriptions ()
 "Alist of transaction descriptions for `mbork-ledger-insert-transaction'.
Each element is a cons where the car is the transaction description and
the cdr is the default target account.")

(defcustom mbork-ledger-source-accounts
  '((?c . "Assets:Cash")
    (?b . "Assets:Bank")
    (?d . "Liabilities:Card"))
  "Alist of source accounts for `mbork-ledger-insert-transaction'.
Each element is a cons where the car is the character used to select the
account and the cdr is the account name.")

(defcustom mbork-ledger-default-commodity "PLN"
  "The default commodity to use with `mbork-ledger-insert-transaction'.")

(defun mbork-ledger-insert-transaction ()
  "Quickly insert a Ledger transation.
Ask about the date, description, source and amount.  If the amount
entered is an integer greater than 100, divide it by 100, so that you
can enter e.g. 12.34 USD as `1234' for faster typing."
  (interactive)
  (let* ((date (ledger-read-date "Transation: "))
         (date-encoded
          (when (string-match ledger-iso-date-regexp date)
            (encode-time 0 0 0 (string-to-number (match-string 4 date))
                         (string-to-number (match-string 3 date))
                         (string-to-number (match-string 2 date)))))
         (description (completing-read "Description: "
                                       mbork-ledger-descriptions
                                       nil nil nil
                                       #'mbork-ledger-descriptions))
         (source (alist-get (read-char-choice
                             (concat (mapconcat (lambda (char)
                                                  (format "%c: %s" (car char) (cdr char)))
                                                mbork-ledger-source-accounts
                                                "\n")
                                     "\n")
                             (mapcar #'car mbork-ledger-source-accounts))
                            mbork-ledger-source-accounts))
         (amount (let ((input (read-number "Amount: ")))
                   (if (and (integerp input)
                            (> input 100))
                       (/ input 100.0)
                     input))))
    (ledger-xact-find-slot date-encoded)
    (insert (format "%s %s\n    "
                    date description))
    (save-excursion
      (insert (format "\n    * %s  -%.2f %s\n\n"
                      source amount mbork-ledger-default-commodity)))))

That’s it for today, see you next time!

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryLedger

December 02, 2024 08:00 AM

November 25, 2024

Borkowski Marcin

2024-11-25 Providing passwords to psql

Some time ago I embarked on a quest to learn how to provide psql with a password in a non-interactive way (for example, in a script).

It turns out that there are quite a few ways to do that, and some ways in which you can’t do that.

For example, psql has the --password and --no-password command line options. Neither takes any argument – they only mean to never ask the user the password or always ask the user the password. The reason you might want to use the former is when you run psql in a script and you want it to fail immediately if no password is available. The latter can be used when you already know the user will need to type the password, so there is no point in trying to connect to the database, discovering that the password is needed, asking the user for it and connecting again – psql might as well ask the password first and only try to connect to the database once.

You might think that there is no option to give psql the password on the command line for security reasons – after all, if you give a password on the command line, then every other user on the same system can see the password with ps -ef. However, in fact there is a way to do exactly that – psql can accept an URI in place of the database name, and an URI may contain a password.

Another way to tell psql the password to use is to set the PGPASSWORD environment variable. As the manual says, this is “not recommended for security reasons, as some operating systems allow non-root users to see process environment variables via ps” – although apparently my Arch Linux does not allow that.

The recommended way is to use the “password file”, which is ~/.pgpass by default. This has one significant drawback – it means that you’ll have your password unencrypted in a plain text file. That is perfectly fine on an application server (where you need to store your database password unencrypted anyway), but it’s a big “no” on e.g. a laptop, which can be lost, stolen etc. (You could encrypt your disk, of course, either the whole partition or just your home directory, but that is not something that’s always feasible.) Interestingly, psql (in fact, it’s libpq, but psql uses it, of course) has some requirements with respect to the password file. For example, it must not be readable by anyone but the owner (in other words, it’s permissions should be at most 0600). This is perfectly understandable. However, I found the hard way that it must be a “regular file”. I didn’t understand this requirement at first, and here is how I found out about it. I wanted to create a .pgpass file so that I could use psql without typing the password. However, I already had the password in the .env file. Trying to be a good programmer following the DRY principle (which is not an absolute rule, but makes sense in this context), I didn’t want to put the password in two separate files. What if the password changes and someone updates only one of these files? So, I wanted to be fancy and use a named pipe for that. One process would be a simple Bash loop using sed to extract the hostname, port, database name, user name and password from the .env file and the other would be psql, reading the pipe ~/.pgpass. That way I would even be able to change the password mid-session, \c to another - or the same - database and it would still work (because psql reads .pgpass again when you open a connection to a database). To my big disappointment, when I set this up, psql told me this:

WARNING: password file "/home/mbork/.pgpass" is not a plain file

and my carefully crafted plan fell apart. That was a pity – while this solution would be a bit contrived, it would still be a nice way to create a “dynamic file” whose contents depend on the contents of another file. (Now that I think of it, I guess I know the reason this didn’t work. Here is my conjecture. libpq probably has to read the whole .pgpass before connecting – or at least read enough of it to find the password to use for the given connection data. The named pipe approach, however, would give it the same line over and over again, without any termination condition. If that line was the one libpq needed, everything would be fine – but if not, the process would hang indefinitely. On the other hand, creating a one-line regular file and removing it after connecting would not work, either, since psql may need .pgpass again if the user wants to establish another connection using \c, for example to connect to another database.)

There is probably another way to achieve a very similar result, namely create a custom fuse filesystem which would generate the .pgpass file dynamically from the .env file, much like the named pipe approach, but more sophisticated. While this could actually work – and in fact, I’m tempted to try and do this some day – this would be more of an interesting hack than a production-grade solution. It seems to me that fuse is much, much too complex to be a good fit here. (In fact, I finally went for the simplest solution of all – wrapping psql in a simple psql.sh script which first parses .env, then creates and populates .pgpass, and then runs psql. Simple but effective.)

The last way to provide passwords to psql I know about is complex enough (and interesting enough) to deserve its own article, which I am going to post quite soon. (And this time I mean really soon, not in a few years!)

That’s it for today, see you next time!

CategoryEnglish, CategoryBlog, CategoryPostgreSQL

November 25, 2024 05:00 PM

November 18, 2024

Borkowski Marcin

2024-11-18 Discovering functions and variables in Elisp files

Sometimes I have an Elisp file which I suspect contains some useful functions. Even if the file is well-documented (for example, it belongs to Emacs itself), that does not mean that every function in it is described in the manual. What I need in such a case is a list of functions and variables (possibly also macros) defined in this file.

My usual solution was to isearch for defun (or (defun, or (def, etc.) and just skim the file, pressing C-s repeatedly. (Sometimes I look for the string (interactive, too, for obvious reasons.) It occurred to me recently (pun intended;-)) that I could use Occur for that. Typing M-s o, then (def and RET gives me a list of all defun​s, defvar​s, defcustom​s, defmacro​s etc. What’s even better, pressing n and p in the Occur buffer immediately moves point to the corresponding place in the searched buffer, so that I can easily see the docstrings of the things I found!

I can do better, though. This simplistic approach does not take into account the fact that some functions and variables are “internal” or “private” and are explicitly not the part of the “official” API of the package in question. These “private” entities are easily recognized, since the convention is to use a double dash in their names.

At first, I wanted to write some custom Elisp to generate the occur buffer first, then remove the double-dashed lines from it, or maybe don’t put them there at all, although that would probably require me to construct that buffer completely by hand, not relying on the occur command. (Of course, you can’t construct a regular expression matching “every line that starts with (def, but excluding lines containing --”, so it seemed that a bit of Elisp is necessary here.) Don’t get me wrong – I have nothing against writing Elisp;-) – but why work if you don’t have to? I had a bright idea and wrote this regex instead:

^(def[^ ]+ -?\(?:[^ -]+-?\)+\_>

Let’s analyze it. It matches first the string (def at the beginning of line, followed by one on more non-space characters and then a space – this is just any (defun, (defvar etc. Then the magic happens. The regex in the shy group matches one or more occurrences of one or more characters other than a space or a dash, followed by an optional dash. This means that any valid Elisp symbol except ones that contain double dashes should match it. (Well, a valid symbol could also begin with a dash – that’s why there is -? before the group. Also, there are things which are not valid symbols matching this regex, too, for example some strings containing parentheses – but they should not appear right after a def-something in a syntactically correct Elisp buffer, and even if they did, I don’t care about extremely rare false positives.) I ended the regex with \_> to make sure that the repeated shy group captures the whole symbol. Otherwise, when there is a double dash in it, the regex would just match its part until that double dash.

I have to admit that I am pretty proud of this – I think it is a pretty clever hack. It doesn’t mean that I won’t write any Elisp at all – I decided to wrap in in the following command:

(defun discover-public-api ()
  "Show all public functions, variables etc. in the `*Occur*' buffer."
  (interactive "" emacs-lisp-mode)
  (list-matching-lines "^(\\(?:cl-\\)?def[^ ]+ -?\\(?:[^ -]+-?\\)+\\_>")
  (select-window (get-buffer-window "*Occur*"))
  (message (substitute-command-keys "\\<occur-mode-map>Press \\[next-error-no-select] and \\[previous-error-no-select] to move around.")))

(I added one thing to the regex – an optional cl- prefix, for things like cl-defun and friends. Also, I used the mode indication for interactive.)

Note that the \<occur-mode-map> part is needed, because at the point when message is evaluated, the *Occur* buffer is not the current buffer – it will be made so by the command loop after the function finishes. Therefore I need to tell substitute-command-keys to use occur-mode-map explicitly. My approach here – to use select-window and count on the command loop to switch to the *Occur* buffer – is definitely not a good practice, but at least allows me to show the \[...] construct;-). Also, this will be changed in a few minutes anyway.

Now, this is enough for my use, but definitely not something production-grade and nice – for example, the lines in the occur buffer have the part matching the regex highlighted. For this regex, this includes everything from the opening parenthesis up to the end of the symbol, which looks a bit weird. (This could be remedied by adding .*$ to the regex, but it would mean that the highlighting face – which by default has a bright yellow background – would be used all over the place. While arguably more “consistent”, it would look even worse.) This can be fixed, too, of course – this is Emacs, after all – but it is slightly more work than one could expect.

The highlighting is done by adding the match face to the face property. This means that the value of that property is either just match or a list of faces beginning with match. This way, all the fontification is carried over from the Elisp buffer to the Occur buffer, which is a desirable behavior. For example, faces like font-lock-keyword-face, used in Elisp buffers, are still used in the *Occur* buffer. It is fairly easy to remove all faces from text properties:

(let ((inhibit-read-only t))
  (remove-text-properties (point-min)
                          (point-max)
                          '(face nil)))

(the *Occur* buffer is normally read-only, hence the inhibit-read-only), but this is not what I would like to do, since it also removes the faces installed there by font locking. It turns out that removing only the match face from the whole buffer is a surprising amount of work. Elisp has the add-face-text-property function which can add a face to a text (possibly resulting in combining more than one face), but no remove-face-text-property one. Of course, it’s not impossible to write it, but it is a bit tricky. One of the reasons is that the face text property can be either a symbol (denoting a face) or a list of such symbols. This is nothing difficult to deal with, but it adds complexity, and it helps to have some functions dealing with it:

(defun mbork/contains-or-equals (needle haystack)
  "Return non-nil if NEEDLE is `eq' to HAYSTACK or HAYSTACK cotains NEEDLE."
  (or (eq needle haystack)
      (and (listp haystack)
           (memq needle haystack))))

(defun mbork/remove-face (face face-prop)
  "Remove FACE from FACE-PROP and return the result.
If FACE-PROP is `eq' to FACE, return nil.  If FACE-PROP is a list,
return the result of `(remq face face-prop)'.  Otherwise, return
FACE-PROP."
  (cond ((eq face face-prop)
         nil)
        ((listp face-prop)
         (remq face face-prop))
        (t face-prop)))

If the face property were always a list (possibly containing just one element), it would suffice to use memq and remq in place of those functions. (Note that mbork/remove-face can output a list consisting of just one element, which could then be turned into just that element in the context of the face property – but I don’t think the added complexity would be worth it.)

Now, the code below employs even more trickery. First of all, keep in mind that while-let is more akin to let* in the sense that the bindings are evaluated one after another, so you can use the variable bound in the first one when creating the second one. Next, the very handy function text-property-search-forward called this way searches for a region where the face text property is the same across that region and not nil. (See its docstring for more details.) This means that if prop-match is nil, the while-let will end, but if it is not nil, neither is prop-match-value and the put-text-property will be evaluated, removing the match face whenever it finds one.

(defun mbork/remove-face-text-property (start end face)
  "Remove FACE from properties in the current buffer between START and END."
  (save-excursion
    (save-restriction
      (narrow-to-region start end)
      (goto-char (point-min))
      (while-let
          ((prop-match (text-property-search-forward 'face))
           (prop-match-value (prop-match-value prop-match)))
        (when (mbork/contains-or-equals face prop-match-value)
          (put-text-property (prop-match-beginning prop-match)
                             (prop-match-end prop-match)
                             'face
                             (mbork/remove-face face prop-match-value)))))))

So, to wrap it up, here is the “nicer” version of discover-public-api. Notice that we no longer need the \<occur-mode-map> part – as mbork/remove-face-text-property operates on the current buffer, we needed to switch to it using set-buffer, so occur-mode-map became the current map anyway.

(defun discover-public-api ()
  "Show all public functions, variables etc. in the `*Occur*' buffer."
  (interactive "" emacs-lisp-mode)
  (list-matching-lines "^(\\(?:cl-\\)?def[^ ]+ -?\\([^ -]+-?\\)+\\_>")
  (select-window (get-buffer-window "*Occur*"))
  (set-buffer "*Occur*")
  (let ((inhibit-read-only t))
    (mbork/remove-face-text-property (point-min) (point-max) 'match))
  (message (substitute-command-keys "Press \\[next-error-no-select] and \\[previous-error-no-select] to move around.")))

This is still not ideal – there are lots of ways this code could be improved (as is usually the case). For example, it shows all the opening parens but not the closing ones (unless the (def...) fits in one line, which it almost never does). Also, the pretty complicated regex is still visible at the top of the *Occur* buffer, and that is in fact an implementation detail the user should not be concerned with. In fact, the *Occur* buffer name itself is hardcoded, which is not very good, either (this could be fixed by using occur-1 instead of occur or its alias list-matching-lines, but that function is a bit weird as it does not have a docstring (!), which might mean that it should be considered an “internal” or “private” function). But right now the code is definitely very useful (at least to me) and nice enough to use without the garish yellow, and this post is already long enough, so let’s just stop here. The takeaway here is not that the code is 100% polished, but rather that Emacs has so many useful (and usually pretty general) features that even if you have a need which is somewhat atypical, you don’t always have to code it from scratch.

CategoryEnglish, CategoryBlog, CategoryEmacs

November 18, 2024 06:00 AM

November 11, 2024

Borkowski Marcin

2024-11-11 A situated approach to passwords

It is a well-known mantra that when writing a web application or a similar thing, you should never store your users’ passwords unencrypted.

Well, I’m now going to challenge this idea (a bit). Note: I’m definitely not a security expert by any means, and it’s quite possible that I’m completely wrong. But I think I encountered two cases when storing passwords in plain text is actually pretty fine.

I guess what I’m really trying to say here is that security is just a bunch of trade-offs. If your program is somehow exposed on the network (for example, you can access the database from another machine), it is never “absolutely secure”. And even if you only allow access to your data from the machine the data is one, and that machine is air gapped, and all data reside on an encrypted partition with a very strong password, it is still not “absolutely secure”.

That said, an obligatory disclaimer. Let me repeat, it’s quite possible that I am wrong, and if you do not know a lot about security and you use this very article as a justification for storing passwords in plain text, you are doing it wrong. This is just some rambling, food for thought, written by someone who doesn’t like people telling what they think are absolute rules without any justification. And in fact, encrypting, or hashing, or better, key-stretching passwords is so cheap that there is almost no reason not to use it anyway, so even my use-cases I write about below are rather contrived.

So, when I personally consider storing passwords in plain text an acceptable trade-off? Well, some time ago I read an absolutely fascinating article about a software equivalent of a home cooked meal, also known as situated software. That resonated with me a lot, and I will write about it more in the following weeks. The idea is that some software isn’t meant for the general public (which almost inevitably will include some malicious actors), but for small groups of people instead. (In a special case, this small group is actuall a group of one.) The cases I used the simplistic, naive approach of not encrypting passwords fall into exactly this category.

Here is the first case. I once built a very simple app to render a visual representation of my home budget. I use ledger, and while I like it a lot, I wanted something visual to show me whether I am keeping within my budget or not. Also, I wanted it on the web so that I could open it on my phone while shopping and decide – in a rational way – whether I can afford that fancy thing or not. On the other hand, I wanted some kind of authorization so that only me and my family could access it. This is what I did. First and foremost, the app is 100% read-only, the only thing it does with the ledger file is read it (actually, transform it using ledger itself). And secondly, even if this app had a bug which allows to somehow modify the ledger file, it wouldn’t really matter, since it only has access to a copy of it. (This works in a very simple way: after I update my ledger file, I commit it to Git, and I have a post-commit hook copying it with scp to the server where the app resides.) Now, what could happen if someone somehow got my password? Nothing could be modified, or even if it could, I wouldn’t bother – the worst case would be that my fancy budget chart would be wrong. Equally importantly, I used a unique password I don’t use anywhere else (this is actually the most important thing!), so even if someone gained access to that password, they would only be able to see my monthly budget (and the current state of my monthly expenses). None of it is secret enough that it would be a problem for me (in fact, I probably could make this app totally open to everyone with the right URL and still nothing bad would happen). The method I settled on is trivially simple – the password is a part of a config file, stored in JSON alongside the app. (Interestingly, there are no usernames at all – just a list of passwords, and any of them can be used to log in. It turned out that this created an unexpected problem – I used Passport to implement authorization, and Passport requires a username to operate. I decided to inject a one-line middleware to the POST /login endpoint which just inserts the key username with the value username to the body of the request.) By the way, this approach is very similar to what Oddmuse does. In Oddmuse’s case, the rationale for being apparently lax with even admin passwords is that even an admin usually cannot permanently damage an Oddmuse site.

Another case is similar. Almost a decade ago, I built another app, this time not for myself, but for someone I know who needed such a thing. This app also needed some kind of authorization, but it didn’t contain anything crucial like financial or medical data. Again, the set of users would be very limited (this time it would be a bit higher than single digits number, but still not greater than about a dozene). One argument I had against encrypting passwords was that if I did that, I would have to provide the whole infrastructure for dealing with forgotten passwords. That means that I would have to store email addresses and provide “password reset” links via email. This in turn means that I would have to support sending emails, which is simple, but still needs work and perhaps some maintenance. All of that means work and time I didn’t necessarily want to spend on this. (After I wrote this, I discussed this idea with a friend, who suggested a more secure approach without the overhead – I’ll explain it in a minute.)

Instead, I settled down for another approach. First of all, I decided to store my passwords unencrypted. (In fact, encrypting passwords is in fact very little work, so I could actually change that.) More importantly, even if I decided to encrypt passwords, I would not hash them. Why? Because I decided to use usernames which are explicitly not email addresses, and even more importantly, I didn’t let the user choose their usernames and passwords at all. Yes, you heard that right. The username (aka the login) for every user was set by the admin. The password for every user was just set to a random string of characters. There was an option to reset the password to another random string, and that’s it. Here, the idea is that the administrator (for example me) can physically contact all users and give them their passwords via some other channel. Hence one of the main reasons for encrypting (or hashing passwords) – that any breach might expose the users’ data on other systems where they reuse the password – was gone. And even if someone gained access to this system, again – it didn’t contain any crucial (or personal) data.

After I wrote most of this, I consulted a friend who – unlike me – is a security expert, and he tried very hard to convince me that my approach is wrong. He partially succeeded – I admit that in the latter case I could do better with very little effort. There are two things I could have done to increase security (though let me stress that I still think these gains would be marginal). Firstly, I could avoid storing plain-text passwords and key stretch them instead (which is obviously better than just hashing). Of course, that would mean that the password reset procedure would have to be a bit more involved. The admin would initiate it, the system would show them the new password (just this one time), but then it would completely “forget” the password and only store the “enhanced key” (the result of key stretching) from now on. This way the time the system even has the plain-text password would be reduced to a minimum. (I would still disallow setting the passwords by the users.) Secondly, it is much better to concatenate a few words instead of selecting characters at random, since the resulting passphrase can have very high entropy while being easier to remember. (Predictably, a quick search turned out a lot of tools – from web-based, to command-line, to libraries – to generate diceware-like passwords. Also predictably, the quality of these tools seems to have, so to speak, extreme variability.)

So, this is it for today. I hope no security expert died of heart attack while reading this, and I’m curious if someone can prove me wrong (which, as I said, is quite possible, although I really did think my approach through, so I still would be a bit surprised). Generally, I think the main argument for not storing passwords in plain text is “but it is so little work to do it «correctly»”, and while I agree with that, I am aware that it’s still work. (For the record, I decided to no longer store passwords in plain text in my future projects, just in case and to promote better security practices.)

CategoryEnglish, CategoryBlog

November 11, 2024 12:00 PM

November 04, 2024

Borkowski Marcin

2024-11-04 Persisting variables across Emacs sessions

Today, I have a short tip to all people who write Elisp and want to preserve some variable other than user customizations between Emacs sessions. (For user settings, configuring them manually in init.el is the standard way to go.) A classic example would be histories of the user’s entries.

In fact, I already mentioned the persist package a long time ago. It is a fairly small but extremely useful tool. What it does is, well, persist a variable across Emacs sessions. As I said above, I find it especially useful for variables keeping various completion histories. If you write any Emacs tool which could benefit from being able to remember things even after quitting Emacs and starting it again, persist is definitely your friend!

CategoryEnglish, CategoryBlog, CategoryEmacs

November 04, 2024 08:00 AM

October 28, 2024

Borkowski Marcin

2024-10-28 Command alternatives

Today I’d like to write about an Emacs feature I didn’t know about, even though it’s part of Emacs since quite some time – it appeared in version 24.4, which means it is over 10 years old! It seems I’m not the only one who didn’t know this exists – I’ve just searched my ~/.emacs.d/elpa directory (which contains almost a hundred packages now!), and none of the packages I have installed there uses it, either.

Assume you want to define a user command dired-play which plays a media file the point is on in Dired. There are several ways to play a file, though – you could use mplayer, vlc, or mpv (the latter being probably the best choice, but that’s another topic). You can define three commands – dired-play-mplayer, dired-play-vlc and dired-play-mpv – and allow the user some way to choose one (most probably via an option declared using defcustom). There is, however, an alternative (pun totally intended!) to a defcustom! Let’s define the three commands (for simplicity, they will be just dummies, and I won’t include docstrings for the sake of brevity) and use define-alternatives to allow the user to choose one of them.

(defun dired-play-mplayer ()
  (interactive)
  (message "playing the sound using mplayer"))

(defun dired-play-vlc ()
  (interactive)
  (message "playing the sound using vlc"))

(defun dired-play-mpv ()
  (interactive)
  (message "playing the sound using mpv"))

(defvar dired-play-alternatives '(("MPlayer" . dired-play-mplayer)
                                    ("VLC" . dired-play-vlc)
                                    ("mpv" . dired-play-mpv)))

(define-alternatives dired-play)

Now the user can say M-x dired-play (of course, in practice this would be bound to some key in dired-mode-map, and Emacs will ask them to choose one of the players. From now on, every invocation of dired-play will use the selected player. Should the user want to change their choice, they can just invoke dired-play with a prefix argument. How cool is that?

One thing I don’t like about this feature is that it silently uses customize-save-variable to persist the customization. This means that it modifies and saves my init.el behind the scenes. I’m not a fan of Emacs modifying my init file, but here it is. (Admittedly, it does make sense in this particular case.)

So, that’s basically it for today. Command alternatives seems a nice (and heavily underused) feature of Emacs – not a single one file in Emac core repository uses it, and not a single one of almost 90 packages I have installed in my Emacs uses it, either. Still, it’s there in case you need it.

CategoryEnglish, CategoryBlog, CategoryEmacs

October 28, 2024 09:00 PM

October 19, 2024

Borkowski Marcin

2024-10-19 substitute-command-keys

Today I have a short tip for everyone that codes Elisp (for other people or even only for themselves), inspired by something I wrote recently (and will blog about soon, too). If you want to tell the user things like “press C-c C-c to finish what you are doing”, don’t hardcode the keybindings in the message string. You may bind the command to finish whatever the user is doing to C-c C-c, true, but the user could rebind it to <f10> or even M-s s-a or whatever key they like, or even unbind it completely. Instead, use the following syntax: \[command-name] (of course, you need to double the slash if you put it in an Elisp string), and process the string with substitute-command-keys. This way, Emacs will convert your command-name to the textual representation of the actual binding of your command. If the command has more than one binding, you can set the “preferred one” by setting the :advertised-binding property of the function name using put (or preferably function-put). If that property is not set, the binding used is selected according to where-is-preferred-modifier, which see; note that the docstring of that variable is apparently wrong, since it should say where-is-internal, not where-is. Even better, the resulting string will be fontified so that the binding is in the help-key-binding face.

For example, in emacs -Q, (substitute-command-keys "\\[undo]") yields C-x u, and (substitute-command-keys "\\[describe-face]") yields M-x describe-face (since this one is not bound to any key by default).

In fact, substitute-command-keys can do a lot more – see the relevant section of the documentation in the Elisp reference.

As usual, the self-documenting nature of Emacs shows itself – the support for something as trivial as displaying the binding of a command is superb, and if you want your code to be as user-friendly as possible when showing those bindings, you only need to make use of what Emacs already gives you.

CategoryEnglish, CategoryBlog, CategoryEmacs

October 19, 2024 05:00 PM

October 14, 2024

Borkowski Marcin

2024-10-14 mrr-replace-mode

I have to admit that this is a bit embarrassing. A long time ago I announced a future post (and promised to release my code) for performing multiple regex replacements in a buffer, possibly in an interactive way. A few months later I started my first programming job (yay!) and promptly forgot about it…

Good thing is, I was reminded about this recently, so I have a chance to revisit the topic. Without further ado, let’s go!

As I said in that previous post, I also wrote a minor mode for selectively (and interactively) performing replacements of some regexen. It proved immensely useful when I worked for Wiadomości Matematyczne as a copyeditor and proofreader. In order to use it, you need to configure it first. There is just one option to do that: mrr-interactive-substitutions. It is a list of lists of strings. Every sublist starts with a regex to replace, followed by an optional list of key-value pairs, followed by a list of possible replacements.

As of now, there are two options: :hint (a string, displayed in the echo area when a string matching the regex is found) and :test (a symbol, which should be a predicate function accepting no arguments; the replacement is skipped if that function returns nil).

The default value for mrr-interactive-substitutions – which serves as an example – looks like this:

'(("\\(\\b\\| +\\)-\\{1,3\\}\\(\\b\\| +\\)" :hint "TeX dashes" "-" "--" "~-- ")
  ("d\\([xts]\\)" :hint "Differential operator" :test texmathp "\\\\mathrm{d}\\1"))

Let’s analyze this. The first entry matches a string of one to three hyphens, preceeded (and followed) either by at least one space or a word boundary. The suggested replacements are a hyphen, double hyphen and a double hyphen surrounded by spaces (an unbreakable one on the left and a normal one on the right). The rationale is that many authors do not care about hyphens, en-dashes and em-dashes, so we checked every occurrence of such things and possibly fixed them. (It is disputable whether you really should use an em-dash or just an en-dash surrounded by spaces; we followed Polish typographical customs here, and apparently Robert Bringhurst agrees.)

The second entry is the letter d followed by one of the letters x, t or s, which are the most common differentials (in integrals, for example). Those are potentially replaced by the same thing, but with an upright d. Note the use of a capturing group in the regex and \1 in the replacement. Also, I used the :test keyword here – these strings can appear in words (take “redshift”, for example). Old-time readers of my blog might remember that the function texmathp returns true if the point is in TeX math mode.

Now, if I say M-x mrr-replace-mode, Emacs searches for the first match for any of the given regexen, highlights it with an overlay (using the same face as isearch does) and shows the “hint” in the echo area. You have three options then. You can press C-g to quit mrr-replace-mode, RET to move to the next match (or quit if there are no matches), and TAB to cycle between possible replacements (including the original text – after all, you might decide you want to leave it as it is).

A cool (and rather Emacs’y) thing is that it is a minor mode. This means that you can normally edit the surrounding text while doing the replacements, or do something in a different buffer and come back later. You might even notice that some useful pattern is missing from mrr-interactive-substitutions, move to your init.el, add it, evaluate the setq, get back to the original buffer, move point to the right place and press RET to look for the new list of patterns – all without even leaving the minor mode! You can also manually edit the text under replacement, but be warned that pressing TAB then will remove your edits.

I wrote this code almost a decade ago, and it shows. There is at least one stupid bug left (the “hint” is suggested as one of the replacements (how could I have not noticed that?), and the format of the mrr-interactive-substitutions option is very terse which makes it almost impossible to describe properly in defcustom. I intend to review the code and fix both issues, but it might take a while. Still, the code is usable as-is (assuming you don’t use the :hint option), and I can assure you that it helps tremendously with copyediting. (When I worked for “Wiadomości Matematyczne”, I had almost 50 entries in mrr-interactive-substitutions!) It is not on any Emacs package repository (I am going to finally learn how to add a package to Melpa, and this is going to be one of the packages I am going to put there), but you can find it on Gitlab.

CategoryEnglish, CategoryBlog, CategoryEmacs

October 14, 2024 12:00 PM

October 07, 2024

Borkowski Marcin

2024-10-07 Autoloads

I’ve known about the Emacs autoload feature for a long time, but I never bothered to read about it. I decided to fix that and finally read the relevant part of the Emacs Lisp manual.

It turns out that autoloads are a pretty simple concept. They basically serve as a way of deferring loading a package until it is really needed. If you have a lot of packages, loading them on Emacs startup may take considerable time and memory. (Of course, nowadays we usually don’t care too much for the latter, since computers now have insane amounts of RAM. My first computer had 64 kilobytes of RAM, and my first PC had 4 megabytes, and GNU Emacs was written in times when 4 megabytes was a lot!) Autoloads are a way to tell Emacs when the package should be loaded by defining some functions as “entry points” to the package. (Actually, it is a bit more sophisticated than that, but that’s the main idea.)

If you write a package, you should mark the entry point(s) with the “autoload comment”. That means putting the string ;;;###autoload on the line before the relevant defun (or perhaps other form defining something, like defvar or cl-defun). When the package is installed, Emacs scans it for these comments and generates a special file containing information about these functions, variables etc. During startup, Emacs loads that special file (which is much, much smaller than the main package file or files, and hence faster to load). This means that all autoloaded functions become actually callable – but calling any of them causes Emacs to load the package in question first. This means that autoloaded functions are loaded “on demand” – when they are first called.

That is (of course!) not the whole story. For example, you can make Emacs put basically arbitrary code into the autoloads file by putting it after the autoload comment but on the same line. This way, that piece of code is not evaluated when loading the package (since it is commented out), but on Emacs startup (because it gets copied to the autoloads file). This may be useful if the package uses non-standard ways to define things.

I intend to put this knowledge into practice soon – I’d like to take some of my Elisp code and submit it as a package to Melpa, both to make it more discoverable and hence useful to other people and also to learn the process. Of course, when I do it, I will write about it here!

CategoryEnglish, CategoryBlog, CategoryEmacs

October 07, 2024 07:00 PM

January 08, 2015

Hromada Mateusz

Warka 9 – American India Pale Ale

Zasyp:

  • pale ale 4kg
  • pszeniczny 0,8kg
  • carapils 0,5kg

Zacieranie w 18l wody, słód dodany w 55°C:

  • 68°C – 65 minut przerwy (po 30 minutach podgrzanie z 65°C do 68°C)

Po filtracji i wysładzaniu wyszło 21,5 litra brzeczki o BLG 11,1.

Chmielenie:

  • 60 minut – 40g Simcoe
  • 20 minut – 30g Simcoe
  • 5 minut – 30g Simcoe
  • 0 minut – 30g Amarillo
  • dry hopping – 30g Simcoe (6 dni), 30g Simcoe (3 dni)

Po schłodzeniu i filtracji wyszło 19 litrów o BLG 16.

Fermentacja (drożdże US-05):

  • 11 dni burzliwej
  • 23 dni cichej

Do refermentacji użyłem 140g cukru i 735g wody.

ABV: ok. 6.2%

by ruanda at January 08, 2015 09:38 PM

Warka 8 – Cydr

Składniki:

  • sok jabłkowy Riviva 22l

Sok ma BLG 12.

Fermentacja (drożdże US-05):

  • 7 dni burzliwej
  • 38 dni cichej

Do refermentacji użyłem 155g cukru i 1135g wody.

ABV: ok. 6.3%

by ruanda at January 08, 2015 09:34 PM

Warka 7 – American Wheat

Zasyp:

  • pszeniczny 2kg
  • pilzneński 2kg

Zacieranie w 16l wody, słód dodany w 45°C:

  • 45°C – 15 minut przerwy
  • 53°C – 15 minut przerwy
  • 68°C – 75 minut przerwy (po 30 minutach podgrzanie z 64°C do 70°C)

Po filtracji i wysładzaniu wyszło 21 litry brzeczki o BLG 7.

Chmielenie:

  • 60 minut – 10g Chinook
  • 20 minut – 20g Palisade
  • 5 minut – 20g Cascade
  • 0 minut – 20g Amarillo
  • dry hopping – 30g Amarillo, 10g Cascade, 10g Palisade

Po schłodzeniu i filtracji wyszło 18 litrów o BLG 12.

Fermentacja (drożdże US-05):

  • 8 dni burzliwej
  • 35 dni cichej

Do refermentacji użyłem 120g cukru i 880g wody.

ABV: ok. 5.5%

by ruanda at January 08, 2015 09:28 PM

November 11, 2014

Girl, lost in IT

Nowy wpis, nowe miejsce

W poprzednim wpisie uprzedzałam, że muszę wprowadzić duże zmiany. Nie jestem już w stanie pisać każdego tekstu w dwóch językach. Dodatkowo czuję, że zmieniłam się przez ostatnie kilka lat – czuję, że „wyrosłam” trochę z tego bloga. Właśnie napisałam pierwszy tekst w nowym miejscu. Blog nazywa się Na miękko - serdecznie zapraszam.

by ynka at November 11, 2014 09:02 PM

October 13, 2014

Krzysztof Szarzyński

Zawieszenie publikacji

Jeśli dobrze liczę, to od 402 dni nic tu nie napisałem. Ponieważ zazwyczaj nie mam niczego interesującego do powiedzenie/napisania, dlatego przerzuciłem się na inne platformy, które lepiej pasują do “beztekstowej” formuły. Nadal robię zdjęcia – więcej niż kiedyś, ale publikuje je w mniejszych porcjach. Zapraszam na mój profil 500px, gdzie wrzucam rożne zdjęcia z całego […]

by Quati at October 13, 2014 06:41 PM

June 12, 2014

Hromada Mateusz

Warka 6 – Żytni Stout

Zasyp:

  • pale ale 2kg
  • żytni 2kg
  • żytni czekoladowy 0,25kg
  • Carafa typ III special 0,25kg

Zacieranie w 16l wody, słód dodany w 55°C:

  • 55°C – 10 minut przerwy
  • 70°C – 60 minut przerwy (po 60 minutach podgrzanie z 62°C do 68°C)
  • 68°C – dodanie ciemnych słodów, 40 minut przerwy

Po filtracji i wysładzaniu wyszło 20,5 litra brzeczki.

Chmielenie:

  • 60 minut – 10g Tomahawk
  • 15 minut – 30g Tomahawk
  • 5 minut – 30g Tomahawk
  • dry hopping – 30g Tomahawk

Po schłodzeniu i filtracji wyszło 18 litrów o BLG 13.

Fermentacja (drożdże S-04):

  • 22 dni burzliwej

Do refermentacji użyłem 125g cukru i 835g wody.

ABV: ok. 4,4%

by ruanda at June 12, 2014 08:38 PM

April 27, 2014

Girl, lost in IT

W planie zmiany + jak tu trafiłam (w obrazkach)

Kolega wyraził ostatnio zaniepokojenie działaniem swojego czytnika RSS. To przecież niemożliwe, żebym tak długo nie napisała nic na swoim blogu! Niestety, możliwe. Do tego powód jest dość absurdalny: piszę mniej, ponieważ piszę więcej. Naprawdę. Pamiętacie, jak przeżywałam swoje 10000. urodziny? Postanowiłam wtedy na poważnie wziąć się za rzeczy, o których zawsze myślałam, że zrobię je […]

by ynka at April 27, 2014 06:28 AM

March 22, 2014

Hromada Mateusz

Warka 5 – Imperial India Pale Ale

Zasyp:

  • pale ale 5kg
  • wiedeński 1kg
  • carapils 0,5kg
  • pszeniczny 0,2kg

Zacieranie w 21l wody, słód dodany w 55°C:

  • 55°C – 10 minut przerwy
  • 65°C – 90 minut przerwy (po 60 minutach podgrzanie z 61°C do 65°C)

Po filtracji i wysładzaniu wyszło 23 litry brzeczki o BLG 14.

Chmielenie:

  • 60 minut – 40g Chinook
  • 10 minut – 20g Citra, 20g Simcoe
  • 5 minut – 30g Citra, 30g Simcoe
  • 0 minut – 15g Cascade, 15g Palisade
  • dry hopping – 15g Cascade, 15g Palisade

Po schłodzeniu i filtracji wyszło 21 litrów o BLG 17.

Fermentacja (drożdże US-05):

  • 9 dni burzliwej
  • 10 dni cichej

Do refermentacji użyłem 130g cukru i 630g wody.

ABV: ok. 7,6%

by ruanda at March 22, 2014 07:44 PM

March 12, 2014

Hromada Mateusz

Warka 4 – American Wheat

Zasyp:

  • pszeniczny 2kg
  • pilzneński 2kg

Zacieranie w 15l wody, słód dodany w 55°C:

  • 55°C – 10 minut przerwy
  • 68°C – 70 minut przerwy (po 50 minutach podgrzanie z 62°C do 67°C)

Po filtracji i wysładzaniu wyszło 21 litry brzeczki o BLG 9,5.

Chmielenie:

  • 60 minut – 10g Chinook
  • 20 minut – 20g Palisade
  • 5 minut – 20g Cascade
  • 0 minut – 20g Amarillo
  • dry hopping – 30g Amarillo

Po schłodzeniu i filtracji wyszło 18 litrów o BLG 13.

Fermentacja (drożdże US-05):

  • 8 dni burzliwej
  • 11 dni cichej

Do refermentacji użyłem 120g cukru i 800g wody.

ABV: ok. 5.3%

by ruanda at March 12, 2014 06:14 PM

February 23, 2014

Girl, lost in IT

Oddam za darmo!

Raz na jakiś czas znajduję w domu coś, co dawno już przestało mi być potrzebne, ale co mogłoby jeszcze przydać się komuś innemu. Niektóre takie rzeczy wystawiam na Allegro (zwłaszcza, jeśli są warte więcej niż kilkadziesiąt złotych), jednak do Allegro często zniechęca mnie konieczność oszacowania kosztów przesyłki. Jeśli chcę pozbyć się czegoś szybko, tanio i […]

by ynka at February 23, 2014 05:23 PM

February 15, 2014

Hromada Mateusz

Instalacja Raspbian przez debootstrap

IMG_20140214_203617

Wymagania

Potrzebny jest Linux, w miarę świeży debootstrap i qemu-arm-static. Oczywiście potrzebny też jest dostęp do użytkownika root.

Partycjonowanie i formatowanie karty SD

Kartę należy podzielić na dwie partycje. Pierwsza, sformatowana w FAT będzie zamontowana jako /boot. Druga partycja będzie zamontowana jako /, można ją sformatować np. w ext4:

root@lol:/mnt# fdisk /dev/sdh
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c') and change display units to
sectors (command 'u').

Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1021, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-1021, default 1021): +64M

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): c
Changed system type of partition 1 to c (W95 FAT32 (LBA))

Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (10-1021, default 10):
Using default value 10
Last cylinder, +cylinders or +size{K,M,G} (10-1021, default 1021):
Using default value 1021

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.
root@lol:/mnt# mkfs.vfat /dev/sdh1
[...]
root@lol:/mnt# mkfs.ext4 /dev/sdh2
[...]
root@lol:/mnt# mkdir rpi
root@lol:/mnt# mount /dev/sdh2 rpi/
root@lol:/mnt# mkdir rpi/boot
root@lol:/mnt# mount /dev/sdh1 rpi/boot/

Instalacja i konfiguracja

Debootstrap należy przeprowadzić w dwóch etapach, gdyż binarki przeznaczone są na inną architekturę.

root@lol:/mnt# debootstrap --foreign --arch armhf wheezy rpi/ http://archive.raspbian.org/raspbian
[...]
root@lol:/mnt# cp /usr/bin/qemu-arm-static rpi/usr/bin/
root@lol:/mnt# LANG=C chroot rpi/ /debootstrap/debootstrap --second-stage

Następnie można chrootować się na budowany system:

root@lol:/mnt# LANG=C chroot rpi/ /bin/bash

Potrzebne są repozytoria w sources.list:

deb http://archive.raspbian.org/raspbian wheezy main contrib non-free
deb-src http://archive.raspbian.org/raspbian wheezy main contrib non-free

W pliku /boot/cmdline.txt należy dodać parametry do kernela:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

/etc/fstab:

proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 0

Różne sieciowe ustawienia są w plikach /etc/hostname, /etc/resolv.conf i /etc/network/interfaces.

W chroocie należy doinstalować paczki git, binutils i ca-certificates.

Potrzebne jest narzędzie rpi-update:

root@lol:/# wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update
root@lol:/# chmod +x /usr/bin/rpi-update
root@lol:/# mkdir /lib/modules
root@lol:/# rpi-update
[...]

Aby dostać się do RPi po restarcie potrzebne jest ssh i hasło na roota:

root@lol:/# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@lol:/# apt-get install ssh
[...]

Po wyjściu z chroota, odmontowaniu obu filesystemów i przełożeniu karty do RPi powinien zabootwać się Raspbian dostępny przez ssh:

root@trololo:~# uname -a
Linux trololo 3.10.30+ #640 PREEMPT Fri Feb 14 19:09:14 GMT 2014 armv6l GNU/Linux

Linki

by ruanda at February 15, 2014 01:20 PM

February 02, 2014

Hromada Mateusz

Warka 3 – American Stout

Zasyp:

  • pilzneński 3kg
  • monachijski 1kg
  • jęczmień palony 0,3kg
  • barwiący 0,2kg

Zacieranie w 15l wody, słód dodany w 55°C:

  • 55°C – 10 minut przerwy
  • 68°C – 70 minut przerwy (po 35 minutach podgrzanie z 64°C do 66°C)
  • 66°C – dodanie ciemnych słodów i 15 minut przerwy

Po filtracji i wysładzaniu wyszło 22 litry brzeczki o BLG 11.

Chmielenie:

  • 60 minut – 15g Centennial
  • 15 minut – 15g Centennial
  • 5 minut – 15g Centennial
  • 0 minut – 25g Centennial
  • dry hopping – 30g Centennial

Po schłodzeniu i filtracji wyszło 19,5 litra o BLG 15. Dodałem 1,5l wody.

Fermentacja (drożdże S-04):

  • 8 dni burzliwej
  • 12 dni cichej

Do refermentacji użyłem 140g cukru i 860g wody.

by ruanda at February 02, 2014 09:54 PM

Girl, lost in IT

10000* lat

Parę (naście) dni temu skończyłam 32 lata. Ta magiczna liczba nie doskwiera mi za bardzo i nie ona jest bezpośrednią przyczyną powstania tego tekstu. Do rozmyślań skłoniły mnie życzenia, które składano mi z tej okazji. Kilkoro (młodszych) znajomych, niezależnie od siebie, obdarowało mnie życzeniami brzmiącymi mniej więcej tak: „Wszystkiego najlepszego. Żebyś miała wspaniały rok. I […]

by ynka at February 02, 2014 06:17 PM

January 27, 2014

Hromada Mateusz

Warka 2 – American Pale Ale

Zasyp:

  • pilzneński 2,5kg
  • monachijski 1,3kg
  • karmelowy jasny 0,2kg

Zacieranie w 12l wody, słód dodany w 55°C:

  • 55°C – 10 minut przerwy
  • 69°C – 60 minut przerwy (z podgrzaniem w 40 minucie)

Po filtracji i wysładzaniu BLG 10.

Chmielenie:

  • 60 minut – 15g Simcoe
  • 15 minut – 15g Simcoe
  • 5 minut – 15g Simcoe
  • 0 minut – 25g Simcoe
  • dry hopping – 30g Simcoe

Po schłodzeniu i filtracji wyszło 16,5 litra o BLG 13.

Fermentacja (drożdże US-05):

  • 8 dni burzliwej
  • 10 dni cichej

Do refermentacji użyłem 110g cukru i 740g wody.

ABV: ok. 5%

by ruanda at January 27, 2014 06:25 PM

January 26, 2014

Hromada Mateusz

Warka 1 – American India Pale Ale

Pierwszą warkę uwarzyłem z przygotowanego zestawu surowców.

Zasyp:

  • pale ale 5,5kg
  • Cara Gold 0,5kg
  • pszeniczny 0,2kg

Zacieranie w 18l wody, słód dodany w 55°C:

  • 55°C – 10 minut
  • 69°C – 60 minut (bez podgrzewania, końcowa 62°C)
  • 76°C – mashout

Po filtracji i wysładzaniu wyszło 23 litry brzeczki o BLG 15.

Chmielenie:

  • 60 minut – 25g Warrior
  • 20 minut – 20g Simcoe
  • 10 minut – 10g Amarillo
  • 5 minut – 10g Amarillo
  • dry hopping – 30g Amarillo

Po schłodzeniu i filtracji wyszło 20,5 litra o BLG 17.

Fermentacja (drożdże US-05):

  • 10 dni burzliwej
  • 11 dni fermentacji cichej

Do refermentacji użyłem 135g cukru i 660g wody.

ABV: ok. 7%.

by ruanda at January 26, 2014 07:03 PM

December 15, 2013

Girl, lost in IT

O zmianie (pracy)

Kilka dni temu kolega z poprzedniej pracy spytał, czy przeniosłam blog w nowe miejsce – nie napisałam prawie nic od czasu, gdy zmieniłam pracę. Babcia przy każdym spotkaniu pyta, czy „korporacja” zdążyła już przeżuć mnie i wypluć. Odpowiem krótko: nie i nie! To prawda, że w ciągu ostatnich kilku miesięcy nie napisałam zbyt wiele. Miało […]

by ynka at December 15, 2013 07:46 PM

September 08, 2013

Krzysztof Szarzyński

Warszawa 2013 – Quati w stolicy.

Zanim zaproszę na ostatnią odsłonę zdjęć z mojego krótkiego pobytu w Warszawie, chwila luźnych wywodów. Nocowałem w hotelu przy placu Konstytucji, który oferował dwa rodzaje pokoi: ciche i z widokiem na miasto. Mi się trafiło oglądanie miasta, ale ponieważ ze mną na szkolenie przyjechało kilka innych osób z Poznania, to zdecydowaliśmy się z Adamem iść […]

by Quati at September 08, 2013 06:19 PM

September 04, 2013

Krzysztof Szarzyński

Warszawa 2013 – część druga

Dziś druga porcja obrazków z Warszawy. Hasłem przewodnim miało być “ludzie w Warszawie”, ale chyba troszkę bardziej pasuje “życie w Warszawie”. Chyba nigdy nie byłem dobry w nadawaniu tytułów i nazw. 🙂 Część trzecia zostanie opatrzona moimi przemyśleniami i komentarzem co do samego miasta. Zdjęcia również będą bardziej dotyczyć tego co widziałem i przeżyłem 🙂

by Quati at September 04, 2013 05:27 PM

September 01, 2013

Krzysztof Szarzyński

Warszawa 2013 – część pierwsza

W tym roku wakacje były podzielone na dwie cześći. Najpierw pojechaliśmy z Olą do Zwierzyńca, gdzie odpoczywaliśmy aktywnie zwiedzając Zamojszczyznę i korzystając z dobrodziejstwa krętych rzek i kajaków turystycznych. Ciągle czekam na chwilę weny żeby wybrać kilka zdjęć i je opublikować 🙂  Drugim etapem moich wakacji było… skończenie życia jako student i rozpoczęcie “dorosłości” w […]

by Quati at September 01, 2013 08:07 PM

Girl, lost in IT

Cicho sza!

Wcale nie zarzuciłam pisania tego bloga. Krótko o tym, co ostatnio dzieje się u mnie: Kupiliśmy dom. Trwa remont. Kompletnie nie doszacowałam nakładów czasowych (o finansowych nie będziemy tu rozmawiać) niezbędnych do realizacji takiego przedsięwzięcia. Tłumaczę książkę o C++ i Qt (Dlaczego? Patrz wyżej). Jest gruba. Zamiast tłumaczyć, spędzam godziny na rozmowach z fachowcami. Pół […]

by ynka at September 01, 2013 07:36 PM

July 13, 2013

Girl, lost in IT

Open’er, czyli wieczne poszukiwania

Heineken Open’er to co roku ta sama historia. Wiele tygodni przed festiwalem niecierpliwie zaczynam śledzić lineup i planować, co będę chciała zobaczyć. Bliżej terminu okazuje się, że z pięciu wymarzonych koncertów dwa odbywają się naraz, a trzy inne jeden po drugim – na scenach oddalonych od siebie o kilometr. Planuję także, z kim pojadę i […]

by ynka at July 13, 2013 08:00 AM

June 26, 2013

Krzysztof Szarzyński

Nowe zabawki i noc kupały

Obiecanki – cacanki. Czyli tradycyjnie, jak Quati mówi, że coś napisze, to znaczy, że mówi. 🙂 Dziś mam kilka zdjęć zrobionych za pomocą nowej zabawki, która oprócz tego, że jest świetnym gadżetem, to spełnia też czasami funkcję obiektywu. Otóż moim nabytkiem jest Sigma 50 mm F1.4 DG EX HSM, czyli typowa portretowa “stałka” z dość jasnym […]

by Quati at June 26, 2013 09:43 PM

May 30, 2013

Girl, lost in IT

Feminiści kontra statystyka

Uczestniczyłam ostatnio w konferencji, w której programie znalazł się panel dyskusyjny poświęcony mniejszościom w środowisku informatyków. Podczas panelu miałam okazję porozmawiać z inspirującymi i pełnymi dobrej woli ludźmi, jednak doszło tam również do pewnego zderzenia opinii, które wspominam do tej pory. Był sobie facet. Doświadczony lider, blogger, walczący o zwiększenie liczby kobiet w IT. Osoba, […]

by ynka at May 30, 2013 04:54 PM

April 20, 2013

Girl, lost in IT

Kup swojemu dziecku sobie robota Lego Mindstorms

Pierwszy raz klocki Lego widziałam, będąc małym dzieckiem, nie pamiętam nawet, czy było to Peweksie, „u prywaciarza”, czy może u kolegi, którego tata był kapitanem na statku handlowym, przez co w ich domu zawsze można było trafić na skarby niedostępne w normalnych sklepach (począwszy od mandarynek). Pamiętam, że zachwyciły mnie czyste kolory, przemyślane projekty oraz możliwości, jakie […]

by ynka at April 20, 2013 04:05 PM

March 16, 2013

Girl, lost in IT

Na słodko-gorzko o skutkach asertywności

Minęło już półtora miesiąca od kiedy zmieniłam pracę. Czas… biegnie szybko. Decyzja ciągle wydaje się dobra. Uczę się bardzo dużo. W trakcie ostatnich tygodni dwa razy odwiedziłam Warszawę, po raz pierwszy spróbowałam koreańskiej kuchni (z wyjątkiem zupy kimchi w Art Sushi, którą polecam, ale tylko ludziom o żołądkach ze stali), a także zapisałam się na […]

by ynka at March 16, 2013 12:37 PM

February 24, 2012

Dopierała Andrzej

2011-05-27 Darmowe fotoradary dla nissan connect

Może kogoś zainteresuje - nie znalazłem nigdzie opisu jak to łatwo zrobić “za friko”.

1. Ściągamy listę fotoradarów z http://ump.waw.pl/ plik z mapą fotoradarów (http://ump.waw.pl/update/Jacek.zip).
2. Rozkompresowujemy go
3. Łączymy to co nas interesuje do jednego pliku csv:

undefine@uml:~/tmp$ cat Kontrole\ Drogowe/*.csv Niebezpieczne\ Miejsca/*.csv Przejazdy\ Kolejowe/*.csv >x.csv
undefine@uml:~/tmp$ 

4. Usuwamy polskie znaczki (zapewne można jakoś przekodować, ale nie chciało mi się metodą prób i błędów szukać kodowania):

iconv -f cp1250 -t ascii//TRANSLIT  < x.csv > jacek.csv

5. Plik jacek.csv umieszczamy w katalogu myPOIs/myPOIWarnings na pendrive
6. Pendrive wkładamy do nissan connect i ładujemy POI użytkownika z menu(Setup → Navigation → Download my POIs)
7. Przestrzegamy ograniczeń ;)

February 24, 2012 08:24 AM

December 23, 2011

Dopierała Andrzej

2011-12-23 Ankieta Polskiego Badania Czytelnictwa: Przyszła do mnie prośba o wypełnienie ankiety. Z Polskiego Badania Czytelnictwa, sp. z o.o. Niby nic dziwnego, ale.. przyszła "smailem". A sama ankieta, po podaniu "pinu" z listu do wypełnienia na stronie http://www.ankieta.pbc.pl/ W zamian za wypełnienie ankiety oferują m.in. kupony sodexo na kwotę 20zł. I w sumie... Podszedłem do tematu trochę z mieszanymi uczuciami. Jak? Skąd? Po co? Z tego co znalazłem dane osobowe otrzymali z bazy PESEL na podstawie Dz.U. 2006 nr 139 poz. 993, 44h ust 2 par 2. List - był zaadresowany do mnie (imię, nazwisko, adres). Natomiast w samej ankiecie na stronie zwrot był przez "Pani". Pomyłka? Koniec końców zmarnowałem kwadrans i wypełniłem. Co prawda niezbyt wartościowo, bo z proponowanych czasopism to tylko sporadycznie Metro przeglądam jak akurat mi w korku wcisną, natomiast Fantastyki w ankiecie nie było, ale - jak to badanie statystyczne, to.. czemu nie.

Przyszła do mnie prośba o wypełnienie ankiety.
Z Polskiego Badania Czytelnictwa, sp. z o.o.

Niby nic dziwnego, ale.. przyszła “smailem”. A sama ankieta, po podaniu “pinu” z listu do wypełnienia na stronie http://www.ankieta.pbc.pl/

W zamian za wypełnienie ankiety oferują m.in. kupony sodexo na kwotę 20zł.

I w sumie… Podszedłem do tematu trochę z mieszanymi uczuciami. Jak? Skąd? Po co? Z tego co znalazłem dane osobowe otrzymali z bazy PESEL na podstawie Dz.U. 2006 nr 139 poz. 993, 44h ust 2 par 2.

List - był zaadresowany do mnie (imię, nazwisko, adres). Natomiast w samej ankiecie na stronie zwrot był przez “Pani”. Pomyłka?

Koniec końców zmarnowałem kwadrans i wypełniłem. Co prawda niezbyt wartościowo, bo z proponowanych czasopism to tylko sporadycznie Metro przeglądam jak akurat mi w korku wcisną, natomiast Fantastyki w ankiecie nie było, ale - jak to badanie statystyczne, to.. czemu nie.

December 23, 2011 09:04 PM

November 07, 2011

Dopierała Andrzej

2011-11-07 brother mfc5490CN: drukarka brother mfc 5490cn pod linuksem i.. ipv6.

Stara drukareczka HP 6540 się popsuła (uchwyt od czarnego tuszu przestał kontaktować), naprawa oczywiście nieopłacalna, a mi by się w domu przydał skaner, wiec… Nabyłem nową drukareczkę. Po przejrzeniu dostępnych opcji wybór padł na Brother MFC 5490CN
I - jak na razie nie mam co narzekać.
Drukowanie spod linuksa - ruszyło praktycznie od razu.
Skanowanie spod linuksa - również. Mimo iż po raz pierwszy w życiu konfigurowałem skaner pod linuksem.

A na dokładkę - drukarka działa również po ipv6…

Local> show ip v6

IPv6 is Enabled
IPv6 Static Address is Enabled
IPv6 Addresses are 2A02:848:A::XXXX:XXXX:XXXX:XXXX/64 (via Router)
                   FE80::XXXX:XXXX:XXXX:XXXX/64 (link-local)

The priority IP version of name resolving is IPv4

Będę musiał chyba firewalla wyklikać dla ipv6 :/

November 07, 2011 10:56 PM

September 09, 2011

Ogrodowczyk Wojciech

Koniec tej zabawy

Jak co bystrzejsi czytelnicy mogli zauważyć, nie pisuję już tu praktycznie nic, a zdjęcia tu umieszczane to jedynie opóźnione „przedruki” względem mojego konta na flickr. Kierując się więc brzytwą Okhama i zwykłym lenistwem...

September 09, 2011 08:12 AM

August 22, 2011

Dopierała Andrzej

2011-08-22 Lekko przerobiony multi router looking glass w php: Skrypt do przedstawiania na routerach.

Już kilka osób się mnie pytało jak zrobiłem http://lg.maverick.com.pl/.

Bazuję na lekko zmodyfikowanej wersji MRLG (Multi Router Looking Glass for PHP). Obecnie jego strona niestety nie działa - i oryginału nie mam do pobrania.

Moją zmodyfikowaną wersję umieściłem na mrlg-20091215.tgz, natomiast plik konfiguracyjny do niej na mrlg-config.php. Na pytania nie odpowiadam, w konfiguracji nie pomagam (bo nie mam czasu) - ale może komuś się przyda :).
Licencja - zgodnie z licencja oryginału - GPL.

Ale jak masz jakieś poprawki - podsyłaj :)

Wiem że brzydko zrobione, ale - było potrzebne na szybko i w parę godzin tylko na tyle mnie było stać.

Jak dodasz w swojej sieci kopię - zgłoś na traceroute.org - widoczność swojego miejsca w sieci się często przydaje :).

August 22, 2011 07:55 PM

August 21, 2011

Ogrodowczyk Wojciech

August 11, 2011

Ogrodowczyk Wojciech

August 05, 2011

Dopierała Andrzej

2011-08-05 Problematyczne ipv6 - dziwny resolver: problem z domenami z dodanym rekordem AAAA.

undefine@uml:~$ host aramin.net
aramin.net has address 42.1.94.0
;; Warning: Message parser reports malformed message packet.
;; connection timed out; no servers could be reached

i tak dla sporej części, o ile nie wszystkich adresów z dualstackiem - taki dziwny feature AP DSL-G604T w hotelu.

Do tej pory myślałem że dodanie rekordu AAAA nic nie psuje, teraz - sam się przekonałem że nie jest tak różowo, jak sie okazało że nie mogę się dostać na strony/serwery z dodanym AAAA. Na szczęście - można skorzystać z własnych albo googlowych dnsów.

Oczywiście prawidłowa odpowiedź to

undefine@uml:~$ host aramin.net
aramin.net has address 195.110.48.48
aramin.net has IPv6 address 2a01:5e00:2:52::30
aramin.net mail is handled by 0 mx.aramin.net.

August 05, 2011 04:55 PM

July 29, 2011

Ogrodowczyk Wojciech

July 27, 2011

Ogrodowczyk Wojciech

July 21, 2011

Ogrodowczyk Wojciech

July 14, 2011

Ogrodowczyk Wojciech

June 26, 2011

Dopierała Andrzej

2011-06-26 IPv6 na stronie: ipv6 na stronie

Co prawda po IPv6 day, ale.. wreszcie dołożyłem AAAA do mojej strony(i stron firmowych). Ciekawe co wybuchnie ;)

June 26, 2011 07:24 PM

June 17, 2011

Ogrodowczyk Wojciech

May 31, 2011

Ogrodowczyk Wojciech

Planet shot

Bcn planet shot

Eksperymentale ujęcie wychodka na szczycie świata, krok po...

May 31, 2011 11:44 AM

May 29, 2011

Ogrodowczyk Wojciech

March 12, 2011

Dopierała Andrzej

2011-03-12 IPv6-garsc-statystyk: kilka słów podsumowania o ruchu ipv6

Kilka statystyk z pewnego routerka. Zbierane ip6tables, w dłuższym okresie czasu. Wykresów nie daję, bo za mała próbka by ładnie wyglądało ;)

Dane z pewnej sieci osiedlowej w Poznaniu. IPv6 udostępnione klientom przez radvd. Głównie klienci “prywatni”.

Wejście:
2% - 6to4
pomijalne - PIX
24% - PLIX
3% - natywne IPv6 od Crowleya
69% - tunel z HE

Wyjście:
51% - 6to4(!)
6% - PIX
36% - PLIX
1% - Crowley
6% - tunel z HE.

Wnioski:
- podobnie jak w przypadku ipv4 duża część ruchu przypada na PLIX
- upload to głównie ruch kierowany do 6to4 - jak sądzę ruch p2p.
- bardzo duży download na tunelu z HE. Co prawda miałem trochę wątpliwości czy należy się w to bawić - to jednak obserwując ruch przy włączonym i przy wyłączonym tunelu widać że opóźnienia przez HE są często niższe. Pozatym - alternatywa to pchanie ruchu przez Crowleya, który.. również sporą część ruchu ma przez HE. HAWE jak na razie ipv6 nie dostarcza.

March 12, 2011 11:49 PM

February 22, 2011

Dopierała Andrzej

2011-02-22 IPv6 a 6to4: ipv6 6to4 sit0 routing ruch siec

Powolutku bawię się w wdrożenie IPv6 u pewnego ISP.

Na peeringach (w PIX i PLIX) ipv6 śmiga “natywnie”. Świata niestety jak na razie nikt nie dostarczył, więc leci tunelem z HE.

Do tego rozgłoszenie prefiksów do kilku testowych sieci - i troszkę ruchu widać.

W którymś momencie zauważyłem, że trochę ruchu leci do 6to4. Postawiłem więc bezpośredniego relaya(opis z http://wiki.debian.org/DebianIPv6) i…

mav-ipv6

Wniosek? Wbrew pozorom bardzo dużo (tak na oko 1/3) ruchu to ruch z relayami 6to4. Stąd zapewnienie dobrej komunikacji z nimi powinno być dosyć istotne przy udostępnianiu ipv6. Do testowego ip z którym obserwowałem ruch po ustawieniu bezpośredniego tunelowania 6to4 na moim routerze opóźnienia spadły z ok 80 do 50ms - a ruch wzrósł o kilkanaście procent.

(na wykresie jest widoczny wyłącznie ruch na tunelach - peeringi/polska leci natywnie, stąd nie mam prostej możliwości wyróżnienia go od ipv4)

February 22, 2011 11:06 PM

February 17, 2011

Dopierała Andrzej

2011-02-17 Rozkład ruchu na łączach: rozkład ruchu plix hawe tp pix

Taka mała ciekawostka.

Jest sobie mały operator. Świadczący głównie usługę dostępu do internetu dla “ludzi”. Pakiety - dosyć duże, po kilka/kilkadziesiąt megabitów, upload ciut mniejszy - po 2-3 megabity.
Ogólnie - zazwyczaj mało kto dociera do limitu w którąkolwiek ze stron.

Do tego jest troszkę hostingu i łącz biznesowych… Ale większośc to klienci indywidualni.

Łącza:
- peering w PIX-ie (http://www.pix.net.pl)
- peering w PLIX-ie (http://www.plix.pl)
- PBT HAWE (http://www.pbthawe.eu)
- Transmisję CDP Global od crowleya (http://www.crowley.pl)

i w którymś momencie na parę chwil pojawiła się testowa transmisja do TPSA - normalnie leci przez HAWE (i dalej styk z crowleyem).

Ruch - puszczony przez bgp prawie “samopas”. Lekkie preferencje by sterować ruchem na łączach zagranicznych (hawe/cdp), gdzieniegdzie unikanie problematycznych ścieżek - ale - można powiedzieć że rozkład jest prawie naturalny.

I teraz - procentowy wykres ruchu:
rozklad-lacz

Interesuje nas głównie download - uploadu jest niewiele - ok połowy downloadu, więc zazwyczaj mieści się w ramach kontraktu.

Co jest ciekawe… ok 30% ruchu zamyka się w plixie. Nawet trochę więcej.

PIX - jest malutki. poniżej 3% ruchu. Gdyby nie skala oraz fakt że jest prawie za darmo - nie było by go sensu trzymać.

HAWE i crowley - utrzymują się mniej więcej na zbliżonym poziomie - przerzucanie to głównie zmiany na ich upstreamach oraz “rzucanie” nimi (prepend przez community) by przerzucić na łącze gdzie dalej od kontraktu.

Przez jakiś czas była testowana tpsa. I tutaj niespodzianka - download był ledwo w okolicach 5% sumarycznego ruchu. Czyli - biorąc pod uwagę cenę - malutko. Z koleji upload to ok 20% ruchu - co w tej sytuacji oznaczało że było to jedyne łącze gdzie upload przekraczał download! I przypominam że to nie hosting, tylko głównie klienci indywidualni. Cóż - P2P rządzi.

February 17, 2011 11:59 AM

January 06, 2011

Dopierała Andrzej

2011-01-06 Konto w aliorbank: zakładanie konta w aliorbanku cz.1

Stwierdziłem że w mojej małej firemce przyda się kolejne konto. Obecne mam w mBanku, bo.. wiadomo - za darmo. No - prawie. 1zł za każdy przelew “na zewnątrz” - to już trochę w miesiącu wychodzi.

A Aliorbank ciągle kusi darmowym kontem, 5-cioma darmowymi przelewami w miesiącu i “premią” 50zł przy stanie konta 9k. Czyli więcej niż na lokacie w mbanku.

Z nowym rokiem - próbuję więc założyć konto.
Pierwsze wrażenia po przebrnięciu przez formularz?

  • Nie pozwala mi na wpisywanie polskich znaczków. Przeglądarka chrome. Po wklejeniu tekstu z polskimi znaczkami - ogonki znikają.
  • Do wybrania klasyfikacja usług… Ja w GUS-ie mam zgłoszoną 6202Z(działalność związana z doradztwem w zakresie informatyki - wg klasyfikacji z 2007 roku). A na stronie pozwalają na wybór pomiędzy.. 6201 a 6203.

Ale przebrnąłem - polskie znaczki jak sądzę poprawią mi w oddziale. O efektach pewnie poinformuję…

January 06, 2011 08:40 PM

October 16, 2010

Nawrot Andrzej

Rozmowy ze specjalistą ds. wdrożeń

Taki kwiatek.
Pytanie dotyczące odpowiedzialności za wykonywanie backupów pewnego systemu i odpowiedź konsultanta.

IT: Kto wykonuje backupy?

Specjalista:Backupy wykonuje MS SQL z automatu codziennie, raz na okres np. miesiąc kwartał baza powinna być nagrywana na trwały nośnik i to w zależności od firmy albo my albo dział IT
Danych nie powinniśmy stracić żadnych tylko w przypadku kataklizmu kiedy to stracimy serwer oraz kopie dyskowe – pozostaną nam tylko kopie na trwałych nośnikach, ale to sytuacje bardzo sporadyczna
Kopie na serwerze służą przede wszystkim do ewentualnych porównań w przypadku uszkodzenia – stąd codzienne kopie .

by jendras (noreply@blogger.com) at October 16, 2010 08:34 PM

June 08, 2010

Nawrot Andrzej

PowerShell via GPO

Aby zmienić ustawienia wykonywania skryptów potrzebujemy tego template'a.

http://www.microsoft.com/downloads/details.aspx?familyid=2917a564-dbbc-4da7-82c8-fe08b3ef4e6d&displaylang=en

by jendras (noreply@blogger.com) at June 08, 2010 08:29 AM

March 04, 2010

Nawrot Andrzej

Limit połączeń RDP

Ku pamięci

query session /server:servername


reset session [ID] /server:servername

by jendras (noreply@blogger.com) at March 04, 2010 02:17 PM

October 28, 2009

Nawrot Andrzej

Rodzinka w komplecie

 

Rodzinka w komplecie, brakuje tylko zniewiescialego SL :)
Posted by Picasa

by jendras (noreply@blogger.com) at October 28, 2009 10:08 PM

October 07, 2009

Najtkowski Marcin Jan

Dua Tonight

W trakcie nieustających muzycznych wojaży trafiłem znów na kawałek, którego słucham po kilkanaście-kilkadziesiąt razy dziennie. Kobiecy wokal – oczywiście, fajny, “chwytliwy” rytm oraz ogólna “sympatyczość” sprawiły, że Tonight zespołu Dua stał się moim numerem jeden ostatniego tygodnia.

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" height="265" width="320"><param name="allowFullScreen" value="true"/><param name="allowscriptaccess" value="always"/><param name="src" value="http://www.youtube-nocookie.com/v/YIfJvPm9-rg&amp;hl=pl&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999"/><param name="allowfullscreen" value="true"/><embed allowfullscreen="true" allowscriptaccess="always" height="265" src="http://www.youtube-nocookie.com/v/YIfJvPm9-rg&amp;hl=pl&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" width="320"></embed></object>

Utwór można znaleźć na A Lounge Supreme vol. 5.

by naytec at October 07, 2009 11:40 AM