[GiM logo]gim.org.pl is down || odświeżony jogger (v.0.4) GiMa

gim photo
Michał 'GiM' Spadliński
programowanie, google, *nix, av, re
last buzz

mini:
  • The Cambist and Lord Iron

    by Daniel Abraham for free @issuu or @POD Castle.

  • Dark Side of C++

    [link]

  • Lost

    No i koniec.

  • Vista vs Open / Save As Dialog Box

    Zdaje się, że od XP 'Save As' i 'Open' pamiętają folder, gdzie ostatnio się pracowało. Jest to dość irytujące w z zachowaniem, do którego większość się chyba przyzwyczaiła, gdzie dialogi te startują w aktualnym katalogu.

    Żeby to zmienić w Viście, wystarczy odebrać sobie prawa do odczytu klucza: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\comDlg32\LastVisitedPidlMRU. To pewnie nie jest najlepszy sposób, ale dla aplikacji z których korzystam DZIAŁA :P

  • Holy fsckin cow

    Zastanawiam się, dlaczego nie wygooglałem tego wcześniej: Speed up powershell startup

  • numery tygodni w Google Calendar

    Nie wiem czy da się to zrobić, jakoś prościej, w każdym razie znalazłem takie fajne coś: google calendar week numbers

  • xps przykłady dokumentów
    Może komuś się przyda: klik
  • D tutorials
    Kilka video tutoriali o podstawach D, różnych edytorach instalacji dmd, tango.
  • niech mi z oczu zejdą

    Każdy problem ma rozwiązanie,
    jeśli nie ma rozwiązania, to nie ma problemu, nie ma problemu

    Ej, człowieku to jest przecież jakiś horror,
    to nie tędy dróżka, jeśli chcesz żeby jakaś fróźka
    poszła z tobą do ee kina

  • powershell - path

    Do zapamiętania:
    PS> $env:path
    PS> $env:path = $env:path + ";c:\blah"

  • Jakiś czas temu...
    ...napisałem, że Programowanie Uogólnione (generic programming), brzmi syfnie, wycofuję się z tego zarzutu, po pierwsze sam zaczynam stosować to sformułowanie, poza tym po dłuższym namyśle brzmi całkiem nieźle, na pewno lepiej niż 'programowanie generyczne', także trochej, zwracam honor : )
  • Kimya Dawson - Loosy Lips
    we won't stop until somebody calls the cops
    and even then we'll start again and just pretend that
    nothing ever happened

Szorty gima (obsolete):
loading...
05
lipiec-2011
001111

(Long time, no see…)
Recently, there was a bit loud about Immunity's ASLR+DEP bypass. Just out of curiosity I've made step-by-step (well, gadget-by-gadget) dissection. It's pretty neat.

Pokaż więcej...

catz: [kom.puterowe] [Techblog]
tagz: [aslr] [bypass] [dep] [dissection] [sayonara]
Dodaj swoją opinię
23
styczeń-2011
182350

Jakiś czas temu potrzebowałem napisać małą aplikację, która pozwoliłaby mi na wysyłanie maili poprzez MS Exchange 2007. Udostępnie on po SOAPie api które się zwie EWS (Exchange Web Services)

Głównym celem było zrobienie tego możliwie szybko.
Najpierw próbowałem biblioteki do obsługi SOAPa w pythonie python-suds.
Po kilku problemach na wstępie (których już dokładnie nie pamiętam) i chwili googlania, znalazłem coś co się zwie suds-ews, czyli teoretycznie suds ze wsparciem dla EWS.

Z tego co pamiętam dorzucając python-ntlm i korzystając potem z suds.transport.windows udało się nawet połączyć z serwerem exchange'a, ale wyglądało na to, że ten suds-ews, niezbyt obsługuje typy tablicowe, które EWS sobie definiuje, a przynajmniej ja nie miałem pojęcia jak z nich skorzystać.

Skończyło się na tym, że odpaliłem Visuala i napisałem krótki program, który robi to co trzeba.
Najpierw trzeba wygenerować Proxy, można to zrobić przy użyciu narzędzia wsdl, ja to robiłem z poziomu Visuala, opis jest tutaj.
Istotna informacja, która dla SOAPowców pewnie jest dość oczywista, dla mnie nie była :> : przy tworzeniu Proxy w Visualu należy podawać ścieżkę do /EWS/Services.wsdl, a w kodzie ściężkę do /ews/Exchange.asmx

Nie ukrywam, że nie znam C#, ale mając przykłady napisanie aplikacji nie było zbyt problematyczne.
Celowo wykomentowałem własny callback do sprawdzania certyfikatu, głównie po to, by móc odpalić to pod mono (o tym za chwilę) bez konieczności weryfikacji CRL.
Aplikacja jako argument bierze nazwę pliku który będzie wysłany, pierwsza linijka jest traktowana jako temat wiadomości, dodatkwo potrzebuje pliku config.txt o skomplikowanej postaci:

  • recipients = one@foobar.com, two@foobar.com

Kod jest tu: Ews.cs.
Należy sobie zmodyfikować usera, hasło, domenę i hostname w CreateBinding() (Wszystkie metody są statyczne, bo jak już wspomniałem, jestem leniwy ;p).

Próbowałem wygenerować Proxy, używając narzędzia wsdl, które przychodzi z mono, ale aktualnie nie działa, bug odnośnie tego wisi półtora roku.
Jeżeli jednak mamy Proxy wygenerowane w Visualu, to można powyższą aplikację skompilować i odpalić w mono

  • mono-csc -r:System.Web.Services.dll Ews.cs Web\ References/ExchangeWebServices/Reference.cs

Certyfikat który przychodzi z serwera, nie musi zawierać certyfikatu root'a, więc najlepiej jest dodać ręcznie certyfikat dla CA, którym podpisany jest certyfikat serwera Exchange. W moim przypadku Thawte Premium Server CA

  • wget https://www.thawte.com/roots/thawte_Premium_Server_CA.pem -O root.cer
  • certmgr -add -c Trust root.cer
  • mono Ews.exe listaOdbiorcow.txt

Rozszerzenie certyfikatu ma znaczenie, certmgr, nie łyknie rozszerzenia .pem

catz: [kom.puterowe] [micr.osoft] [pro.gramowanie] [Techblog]
tagz: [C#] [EWS] [Exchange 2007] [Exchange Web Services] [certmgr] [mono] [python-suds] [send e-mail] [suds-ews]
Dodaj swoją opinię
02
listopad-2010
090124

...that you might need to know or maybe just forgot

This will be a bit long, longer then I initially expected.
First let's have a look at typical table-based CRC-32 implementation:

  1. uint32_t calcCrc32(const uint8_t *buf, size_t len) {
  2.     uint32_t rCrc = 0xffffffff;
  3.     size_t n;
  4.     for (n = 0; n < len; ++n) {
  5.         rCrc = crc_table[(rCrc ^ buf[n]) & 0xff] ^ (rCrc >> 8);
  6.     }
  7.     return rCrc ^ 0xffffffff;
  8. }

This is similar to the implementation that can be found in PNG Specification
But for a few experiments the following implementation will be more suitable. The only difference, is that instead of using constant values of 0xffffffff, we'll pass them as function arguments.

  1. uint32_t crc32(const void* buf, size_t bufLen, uint32_t initial, uint32_t final) {
  2.     const uint8_t* data = (const uint8_t*)buf;
  3.     uint32_t rCrc = initial;
  4.     for (size_t i = 0; i < bufLen; ++i) {
  5.         uint32_t bytesCrc = crcTable[(rCrc ^ data[i]) & 0xff];
  6.         rCrc = (rCrc >> 8) ^ bytesCrc;
  7.     }
  8.     return rCrc ^ final;
  9. }

As you probably know CRC is the remainder polynomial resulting from 'dividing' shifted message's polynomial by some chosen generetor polynomial.
(I'll be talking about 32-bit CRC and I was using the same polynomial that png uses 0xedb88320, but the polynomial itself doesn't change anything that's discussed below.)

The need of preset

Normally to get the remainder crc would be called like: crc32(buffer, buLen, 0, 0). But this causes two problems.
First problem is that if you prepend the message with any number of zeroes it won't change the resulting reminder, because this will prepend message polynomial with some 0 coefficients, and that obviously won't change the reminder itself.
Below is an example. It creates such messages, calculates crcs and prints them.

  1. uint8_t mesg[12] = { 0 };
  2. size_t len;
  3. for (len = 0; len < 10; ++len) {
  4.     if (len) mesg[len-1] = 0;
  5.     mesg[len] = 0xa5;
  6.     c1 = crc32 (mesg, len+1, 0, 0);
  7.     printf ("%2d %#08x\n", len+1, c1);
  8. }

And the results:

  1. 1 0xa6bc5767
  2. 2 0xa6bc5767
  3. 3 0xa6bc5767
  4. 4 0xa6bc5767
  5. 5 0xa6bc5767
  6. 6 0xa6bc5767
  7. 7 0xa6bc5767
  8. 8 0xa6bc5767
  9. 9 0xa6bc5767
  10. 10 0xa6bc5767

This is solved by preseting the CRC, but before we'll get to that, let's discuss the second problem.

The need of post-invert

Instead of calculating the CRC on some buffer and then verifying it, it's easier to append CRC after the message, calculate CRC of this new message, the result should be 0.
(It's quite easy to understand why it's so, but guys at this wiki page already did that, so I'm not going to duplicate it :))
Here's an example:

  1. uint8_t mesg[12] = { 0 };
  2. size_t len;
  3. /* fill the buffer with some dummy data */
  4. for (len = 0; len < 6; ++len)
  5.     mesg[len] = len;
  6.  
  7. /* appending crc */
  8. c1 = crc32 (mesg, 6, 0, 0);
  9. *(uint32_t*)(mesg+6) = c1;
  10.  
  11. printf ("10 %#08x\n", crc32(mesg, 10, 0, 0));

This brings us to the second problem, if we append any zeroes to message constructed as above, the reminder will still be 0.
And because mesg above has size of 12, and it's initially filled with zeroes, the following two lines, will also print 0x00000000 as a resulting CRC

  1. printf ("11 %#08x\n", crc32(poly, 11, 0, 0));
  2. printf ("12 %#08x\n", crc32(poly, 12, 0, 0));

That's also quite easy to understand. If the resulting reminder is 0 it means that the message polynomial was multiple of our generator, so appending any number of zero coefficients will give a new message that is still mutiple of a generator

Post-invert

The second problem is usually 'fixed' by negating CRC result. In this case that will be calling: crc32(buffer, buLen, 0, 0xffffffff)
So let's fix last example by appending negated CRC:

  1. c1 = crc32 (mesg, 6, 0, 0xffffffff);
  2. *(uint32_t*)(mesg+6) = c1;
  3. printf ("inverted crc: %08x\n", c1);

Of course now the calculation of CRC for that new message won't return 0, so we should calculate the CRC for the first 6 bytes and compare it with appended CRC or... we could calculate so called reciprocal polynomial and as before calculate the CRC for whole the message and compare it with our reciprocal

  1. /* calculate reciprocal polynomial */
  2. uint32_t test = 0xffffffff;
  3. c1 = crc32 (&test, sizeof(test), 0, 0xffffffff);
  4. printf ("reciprocal: %08x\n", c1);
  5.  
  6. printf ("10 %#08x\n", crc32(poly, 10, 0, 0xffffffff));
  7. printf ("11 %#08x\n", crc32(poly, 11, 0, 0xffffffff));
  8. printf ("12 %#08x\n", crc32(poly, 12, 0, 0xffffffff));

And here are the results, as you can see the calculated CRCs are no longer the same.

  1. reciprocal: 0x2144df1c
  2. 10 0x2144df1c
  3. 11 0xc622f71d
  4. 12 0xb1c2a1a3

Preset to -1

Now back to the first problem which is usually 'fixed' by preseting CRC to -1 (0xffffffff) instead of 0.
This is equivalent to the calling: crc32(buffer, bufLen, 0xffffffff, 0). The following code is almost identical to the first one presented, the only difference is using the preset value in call to crc32.

  1. uint8_t mesg[12] = { 0 };
  2. size_t len;
  3. for (len = 0; len < 10; ++len) {
  4.     if (len) mesg[len-1] = 0;
  5.     mesg[len] = 0xa5;
  6.     c1 = crc32 (mesg, len+1, 0xffffffff, 0);
  7.     printf ("%2d %#08x\n", len+1, c1);
  8. }

And coresponding results:

  1. 1 0x8b414715
  2. 2 0x189aba67
  3. 3 0xa602718a
  4. 4 0x78077784
  5. 5 0x9f615f85
  6. 6 0xe881093b
  7. 7 0xc42f77e6
  8. 8 0x3c6177f1
  9. 9 0xbf4abc36
  10. 10 0xbac9c0ee

Preset and post-invert

Preset and post-invert are usually used together. First important observation is that 0xffffffff becomes fixed point of a crc32

  1. test = 0xffffffff;
  2. c1 = crc32(&test, sizeof(test), 0xffffffff, 0xffffffff);
  3. printf ("fp : %#08x\n", c1);

0xffffffff is printed to the screen. As you've probably noted this is also reciprocal.
Now take a look at crc32 function, now back here, now back at crc32 function, now back here. Just before returning the value it's xored with 0xffffffff value (or you can say inverted).
That tells us, that after finishing the loop, the value of rCrc variable had to be 0.
That isn't too good, because it basically means, that we can again append any numbers of zeroes, after that value and the result won't change

  1. uint8_t mesg[12] = { 0 };
  2. size_t len;
  3.  
  4. *(uint32_t*)(mesg) = 0xffffffff;
  5. for (len = 4; len < 10; ++len) {
  6.     if (len > 4) mesg[len-1] = 0;
  7.     mesg[len] = 0xa5;
  8.     c1 = crc32 (mesg, len+1, 0xffffffff, 0xffffffff);
  9.     printf ("%2d %08x\n", len+1, c1);
  10. }

Final stuff

...or because we know that reciprocal has the same value, we can append calculated CRC after the message. We need to negate the calculated CRC first. Here's the thing:

  1. memset(poly, 0, sizeof(poly));
  2.  
  3. /* prepare dummy buffer */
  4. for (len = 0; len < 5; ++len)
  5.     poly[len] = len+66;
  6.  
  7. /* add NEGATED crc */
  8. c1 = crc32 (poly, 5, 0xffffffff, 0xffffffff);
  9. *(uint32_t*)(poly+5) = ~c1;
  10.  
  11. printf ("09 %#08x\n", crc32(poly, 9, 0xffffffff, 0xffffffff));
  12. printf ("10 %#08x\n", crc32(poly, 10, 0xffffffff, 0xffffffff));
  13. printf ("11 %#08x\n", crc32(poly, 11, 0xffffffff, 0xffffffff));
  14. printf ("12 %#08x\n", crc32(poly, 12, 0xffffffff, 0xffffffff));
  15. printf ("\n");
  16.  
  17. for (len = 9; len < 12; ++len) {
  18.     if (len > 9) poly[len-1] = 0;
  19.     poly[len] = 0xa5;
  20.     c1 = crc32 (poly, len+1, 0xffffffff, 0xffffffff);
  21.     printf ("%2d %08x\n", len+1, c1);
  22. }

...and the results:

  1. 09 0xffffffff
  2. 10 0xffffffff
  3. 11 0xffffffff
  4. 12 0xffffffff
  5.  
  6. 10 0x5943a898
  7. 11 0x5943a898
  8. 12 0x5943a898
catz: [kom.puterowe] [pro.gramowanie] [Techblog]
tagz: [crc] [crc32] [crc32 computation] [reciprocal] [same results]
Dodaj swoją opinię
07
październik-2010
204302

A friend of mine, had a problem today (with Python) which voils down to the following piece of code:

  • f = open('input.txt')
  • c = f.readlines()
  • # here were different operations
  • # on c, but that's not really important
  • print len(c)

Don't ask why there is readlines() in the first place, that's not the problem.
The problem was, that c had wrong number of lines. However answer to that lies in python's documentation:

Read until EOF using readline() and return a list containing the lines thus read. If the optional sizehint argument…

Unfortunatelly the file contained some random bytes, among different bytes there was also character with hex value of 0x1A. Now let me quote everyone's favourite source of information - wikipedia:

In the MS-DOS operating system, this character is used to indicate the end of a file or the end of user input in an interactive command line window. This behavior was borrowed from the earlier CP/M operating system.

Some operating systems such as the pre-VMS DEC operating systems, along with CP/M, tracked file length only in units of disk blocks and used Control-Z (SUB) to mark the end of the actual text in the file. For this reason, EOF, or end-of-file, was used colloquially and conventionally as a TLA for Control-Z instead of SUBstitute.

There is simple "solution" to this problem:

  • f = open('input.txt', 'rb')

Since CP/M was mentioned twice here, I can't resist to quote famous words of a man I've always regarded as a brilliant visionary - Gary Kildall (but unfortunately rather poor businessman for that matter) (the quote relates to int 21h/AH=09h):

"Ask Bill [Gates] why the string in function 9 is terminated by a dollar sign. Ask him, because he can't answer, only I know that."

catz: [eng.lish] [kom.puterowe] [micr.osoft] [pro.gramowanie]
tagz: [0x1A] [EOF] [python] [readline] [readlines] [windows]
Dodaj swoją opinię
03
sierpień-2010
130411
catz: [kom.puterowe] [Miniblog] [pro.gramowanie]
tagz: [c++] [ramblings]
Dodaj swoją opinię
11
lipiec-2010
172359

Niedawno, przez kilka dni z rzędu właściwie grałem w Lugaru. Kupiłem ją w Humble Indie Bumble.

Pomimo tragicznej grafiki gra jest przyjemna, dość wciągająca i nawet ma zabawną fabułę :). Oprócz trybu kampanii (tylko jednej) jest jeszcze tryb challanges.
Postaram się nie spoilować (za bardzo).

Na początku zdziwiło mnie, że gra się królikiem (właściwie to chyba raczej zającem, ale niech będzie królik). Do królika człowiek się jednak dość szybko przyzwyczaja, a po kilku nieudanych potyczkach bluzga się pod nosem na pozostałe króliki a później inne stworzenia.
Jest tutorial i jest on wysoce wskazany. Nie ma sejwowania (prawda, że piękne słowo), stan gry jest automatycznie zapisywany po przejściu kolejnego levelu.
W tutorialu brakło kilku rzeczy, z którymi pewnie grałoby się prościej:

  • noże można wyciągać z leżącego ciała przeciwnika (martwego lub nie),
  • nóż dobrze jest wyczyścić z krwi (atak kucając),
  • mieczem (nożem zdaje się też) można próbować zabić leżącego przeciwnika (nie pamiętam jaka kombinacja to robiła :>),
  • to akurat było w tutorialu, nożem można rzucać (q), tyle, że w tutorialu twierdzili, że jest to mało skuteczna metoda, co nie do końca jest prawdą

Byłbym zapomniał, są 3 poziomy trudności: Easier, Difficult i Insane, zdecydowanie warto spróbować Difficult, Insane, jak ktoś ma silną wolę ;)
(Co do rzucania nożem jeszcze, to zdaża się że przeciwnik złapie ów nóż ;), wygląda na to, że jest to zależne od poziomu trudności i od tego czy przeciwnik stoi do nas przodem)

Have fun!

catz: [kom.puterowe]
tagz: [gry] [humble indie bumble] [lugaru]
4 komentarze
25
maj-2010
003819

No i koniec.

21
marzec-2010
190232

Moja zabawka: PixelToastereD i coś co ma robić za doki: Release Notes 0x1

catz: [kom.puterowe] [programowanie w D]
tagz: [D bindings] [D programming language] [framebuffer] [język programowania D] [pixeltoaster]
Dodaj swoją opinię
19
luty-2010
104133

As I've mentioned a while ago, I try to use powershell (1.0) on daily basis.

Recently I had strange problem regarding Execution Policy.

I've started powershell as admin, executed Set-ExecutionPolicy RemoteSigned. Then I've started powershell under console2 as a normal user.
To my suprise running Get-ExecutionPolicy returned Restricted

First explanation, solution below: I'm running 32bit version of Console2 on x64 version of vista. Since console2 starts powershell, it's also treated* as a 32bit application, so requests to HKLM\Software\ because of WOW64 goes to HKLM\Software\Wow6432Node.
These are totally independent registry keys, so when I've started powershell as Admin, changing execution-policy, changed only the first key (since powershell.exe is a 64bit application).
*Edit: Of course under console2, 32bit version of powershell is also started due to WOW64.

Solution is pretty simple, start Console2 as Admin, and then change execution policy.
Hope that helps anybody ;)

31
grudzień-2009
163610

Chciałem się koniecznie podzielić tym znaleziskiem. Dzisiaj trafiłem na plugin Vrapperdo eclipsa. Umożliwia on (podstawową) edycję vim-like w eclipsie. Wcześniej testowałem też vimplugin i eclima chyba również. Jest też płatny viPlugin, tego nie widziałem.
Vrapper ma inne podejście niż dwa wyżej wymienione pluginy. Zamiast osadzać vim'a w eclipsie, imituje on edycję w stylu vim-a w eclipse'owych edytorach.

Lista komend trybu normal jest aktualnie niewielka, ale są najczęściej (przynajmniej przeze mnie) używane :). Nie rozminę się z prawdą, jeśli powiem, że komend vim-owego command-line'a praktycznie nie ma.
Dość specyficzne jest też 'aktywowanie' plugina, trzeba włączyć przełącznik na toolbarze (albo w menu edit) i dopiero NOWO otwarte okna edytora będą miały włączony vim-mode.

Chciałem się podzielić, bo na pierwszy rzut oka Vrapper przypadł mi bardziej do gustu niż vimplugin, a na joggerze, chyba nie było o nim wzmianki.

catz: [kom.puterowe] [pro.gramowanie] [Techblog]
tagz: [eclipse vim plugin] [vrapper]
Dodaj swoją opinię
07
październik-2009
121117

Ten kod paskowy, który widać dziś na google, to Code128.

Na zakodowanie pojedyńczego symbolu składają się szerokości sześciu pasków (3 czarne, 3 białe).
Na kodzie (czego nie można się w żadne sposób domyślić) jest zakodowane Google :]

Notacja poniżej oznacza grubośći kolejnych pasków.
pierwsze 3+3 paski to kod startowy, kolejno są litery:

  • 211214 - Start Code B
  • 211313 - G
  • 134111 - o
  • 134111 - o
  • 122114 - g
  • 221114 - l
  • 112214 - e

Ostatni symbol to suma kontrolna którą można policzyć jakoś tak:

  • def foo(a): ord(a)-32
  • str='Google'
  • (104 + reduce (lambda a,b: a+b, map(lambda a: (a[0]+1)*foo(a[1]), enumerate(str)))) % 103

[104 to wartość kodu startowego B] U mnie wychodzi 71, w tabelce z wikipedii 71 to 122114 i tak też jest na obrazku.
Ostatnie 4 paski to kod końcowy.

catz: [go.ogle] [kom.puterowe] [Techblog]
tagz: [code bar] [code-128] [doodle] [google logo]
5 komentarzy
03
październik-2009
104040

Truly saying I'm not much interested in C++0x (or rather C++1x :P).
Today I've stumbled upon few examples of delegates:

  1. [](int x, int y) -> int { int z = x + y; return z + x; }
  2. [&, foo](int x) { sum += x; prod *= foo; }

In the second code & refers to 'full closure' (so sum and prod are variables from that closure, accessed by reference), and foo is copied from the closure by value (i.e. any changes to foo inside the delegate won't be seen outside the delegate).

Truly saying, I don't mind it, but ...
C++ already has awful syntax (you can argue, but that's a fact :P)
Am I wrong or is the proposal (?) of delegates' syntax are is just über-crappish?

If you look at above samples and your answer is nope, here's one more for you:

  1. [&](int* foo, int i){i[foo] += (bar->*baz)(i); }

P.S. Your comments will be appreciated

catz: [eng.lish] [kom.puterowe] [pro.gramowanie] [Techblog]
tagz: [] [c++0x] [c++1x] [syntax-horror]
65 komentarzy
13
sierpień-2009
102931

Zdaje się, że od XP 'Save As' i 'Open' pamiętają folder, gdzie ostatnio się pracowało. Jest to dość irytujące w z zachowaniem, do którego większość się chyba przyzwyczaiła, gdzie dialogi te startują w aktualnym katalogu.

Żeby to zmienić w Viście, wystarczy odebrać sobie prawa do odczytu klucza: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\comDlg32\LastVisitedPidlMRU. To pewnie nie jest najlepszy sposób, ale dla aplikacji z których korzystam DZIAŁA :P

catz: [kom.puterowe] [micr.osoft] [Miniblog]
tagz: [dialog box] [microsoft] [open] [save as]
Dodaj swoją opinię
07
lipiec-2009
165209

Zastanawiam się, dlaczego nie wygooglałem tego wcześniej: Speed up powershell startup

catz: [kom.puterowe] [micr.osoft] [Miniblog] [Techblog]
tagz: [powershell] [speed-up startup]
1 komentarz
05
czerwiec-2009
113618

Wpis u zdzicha zachęcił mnie, żeby się podzilić, może komuś się przyda.
Od grudnia ubiegłego roku, korzystam z iplusa na modemie e169 (z różnych przyczyn musiałem wybrać modem na usb).
E169 to je flip flop device, który równocześńie robi za memory sticka (z kartą 2G micro sd w środku) i modem.
Korzystam z dwóch genialnych i prostych narzędzi:

  • usb_modeswitch
  • huh, nie trudno zgadnąć do czego służy.
  • umtsmon - maksymalnie prosty (w obsłudze) program w qt do łączenia się
  • $ lsusb
  • ..
  • Bus 002 Device 019: ID 12d1:1001 Huawei Technologies Co., Ltd. E620 USB Modem
  • ...
  • # usb_modeswitch --help
  • # usb_modeswitch -v 0x12d1 -p 0x1001 -d 1
  • # usb_modeswitch -v 0x12d1 -p 0x1001 -H 1
  • $ umtsmon

GUI umtsmona jest na tyle intuicyjne, że chyba nie trzeba niczego tłumaczyć. Ja sobie wywołanie usb_modeswitcha dodałem do udeva.

catz: [kom.puterowe] [Techblog]
tagz: [huawei e169] [linux] [umtsmon] [usb_modeswitch]
6 komentarzy
23
maj-2009
180839

At work I try to use powershell just to learn at least a few things about it. Of course I could use zsh, bash or any other unix shell, but that would be no fun, would it?

Pokaż więcej...

catz: [kom.puterowe] [micr.osoft] [Techblog]
tagz: [head] [hexdump] [powershell] [tail]
4 komentarze
20
maj-2009
100344

Nie wiem czy da się to zrobić, jakoś prościej, w każdym razie znalazłem takie fajne coś: google calendar week numbers

catz: [go.ogle] [kom.puterowe] [Miniblog]
tagz: [google] [google calendar] [week numbers]
Dodaj swoją opinię
01
maj-2009
214749

This is first of promissed posts about DDL under Linux.

If you haven't read previous post, please do so now, so I won't have to repeat myself.

If you have copy of team0xf ext repo, run hg pull; hg up; if you don't have it yet, grab it:

  • hg clone http://team0xf.com:8080/ext

I've added some new examples in ext/ddl/ddl/Sample subdir.

I've already described how to compile host application in previous post.
Compilation of testPlug01.d and testPlug02_c.c plugins is easy as a pie :]:

  • dmd -c testPlug01.d
  • gcc -c testPlug02_c.c

testHost01.d is a sample host application. It loads plugin calls a function from the plugin, creates an object of class conforming to specified interface, and call some method of that object.

testHost02.d host application declares a variable that will be accessible by a plugin written in C. It loads plugin finds a symbol of a function (declared in that plugin) and executes that function.
Function in plugin changes the variable that is provided by host application

Sorry for short post, but I don't have much time :}.
Currently there is only basic support for object files, some more things are waiting for being comitted, so again, stay tuned :)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [DDL] [DDL in Linux] [d] [d programming language] [język programowania D] [plugins in D]
1 komentarz
30
kwiecień-2009
201009

Od czasu do czasu, zdarza mi się ściągać pliki z wrzuty (bo to najprostszy sposób na znalezienie niektórych rzeczy, szczególnie jak się szuka jednego kawałka).

Od jakiegoś czasu metoda aud/file, vid/file, średnio działa, na kilku forach widziałem nawet teorie spiskowe, jakoby miałoby to być nowe zabezpieczenie.

Nie proszę państwa (chcę być tak 1337 jak g. dlatego się do was tak grzecznie zwracam :>), to nie jest żadne zabezpieczenie. Wygląda na to, jakby panowie od wrzuty wprowadzali sobie swoisty (albo mają zamiar) load-balancing (zobaczcie sobie po wygenerowanych linkach), może miejsca zaczyna brakować i jakaś reorganizacja dunno :P

Mniejsza z tym, napisałem mały skrypcik, który daje nowe linki (stare też), skrypcik leży sobie tutaj: wrzuta.

Sorry za ascetyczny wygląd :P
Gdyby coś nie działało, można drzeć^Wzgłaszać uwagi

P.S. Jakoś dużo nawiasów powychodziło :P

catz: [kom.puterowe] [Techblog]
tagz: [format nowych linków] [nowe linki] [wrzuta] [wrzuta.pl]
13 komentarzy
25
kwiecień-2009
153046

I hear voices, wait a minute, that's not what I've meant.
I've heard there are more and more people interested in DDL (D Dynamic Libraries) under Linux. This is first of short series of posts that will describe some changes I've made in h3r3tic's team0xF's repo.

Pokaż więcej...

catz: [eng.lish] [kom.puterowe] [programowanie w D]
tagz: [d] [d programming language] [ddl] [język programowania D] [linux]
1 komentarz
21
styczeń-2009
125602
Może komuś się przyda: klik
catz: [kom.puterowe] [micr.osoft] [Miniblog]
tagz: [documents] [microsoft] [xps format] [xps samples]
Dodaj swoją opinię
16
styczeń-2009
000055
Kilka video tutoriali o podstawach D, różnych edytorach instalacji dmd, tango.
catz: [kom.puterowe] [mini.] [Miniblog] [programowanie w D]
tagz: [D] [D programming language] [język D] [programowanie D] [tutoriale] [video]
2 komentarze
14
styczeń-2009
044409

Nice title, huh?
Descent plugin is being cooler and cooler, but you've probably seen it on videos.
One of the things that was driving me mad and kept me away from descent was compilation process.

Java guys probably know apache ant build system (and if they don't they definitely should). I'm going to describe here, how to force eclipse to use descent plugin's ant tasks to build D projects. I'm using this at least for a few months now and I prefer it much more over rebuild method described on Descent page, I was wondering why this method is not described there.

First there are some basic informations, how to install descent with eclipse 3.4, how to set-up a project, the rest is about ant usage.

Eclipse/Descent basic stuff

I'm using Eclipse ganymede since it's better than its predecessors. First quick installation for all the lazy bastards out there:

  1. Go and grab eclipse, I've downloaded IDE for Java Developers since it has ant plugins ready to use.
    (If you have eclipse installed already, you probably could just install apache ant stuff in software updates).
  2. Unpack and start eclipse, choose workspace, go to Help -> Software updates, Available software
    choose Add site and enter descent's site: http://downloads.dsource.org/projects/descent/update-site and OK, it should appear in the middle table, select it and Install,
  3. After few clicks and minutes Descent should be installed and Eclipse will ask you for the start, do so
  4. When it'll start again close the welcome screen, and first of all, turn on D-perspective (Window->Open perspective->Other->D), if it's not there it means you haven't installed descent plugin properly
  5. Next we'll add tango to user libraries to make project configuration simpler. Go to Window->Preferences, choose D->Build path->User libraries, choose New and enter meaningful name (tango? :>), choose Add directory and select directory with your tango lib (I got it under /opt/dmd/include/d),
  6. Go to General->Editors->Text editor->Spelling, and disable spelling engine, otherwise you'll get most of the code red-underlined :]

Now time for some fun stuff.
eclipse descent

  • Choose File->New->Project, select D project, enter name (I've used DSample) and you can click Finish,
  • Right click on your project, choose New->module, enter module name (I've used sample.d) (for simplicity everything will be in default package,
  • Now in editor window type 'main' and press Ctrl+Space (you'll love this shortcut ;)), editor should show suggestions, after hiting Enter you'll have basic main function,
  • If you try typing 'Std' [Ctrl+Space], you'll see there are no fancy proposals, right-mouse-click on your project, choose Build Path->Add Libraries, choose User Libraries, select tango (added in step 5) and click finish,
  • Now after typing 'Std' [Ctrl+Space] you should see some proposals

eclipse descent
Now let's play with ant..

Descent + ant, honey

One night I was playing with descent jar files and I've noticed interesting jar inside descent.core.
Open up your favourite terminal and extract needed jar.

  1. mkdir -p ~/.ant/lib
  2. cd ~/.ant/lib
  3. unzip ECLISPE_DIR/plugins/descent.core_0.5.3.20081231.jar ant_tasks/descent-ant.jar

ECLIPSE_DIR above is of course your eclipse installation dir (~/eclipse in my case :])
Now go back to eclipse, Window->Preferences, Ant->Runtime (Classpath), click Add External JARs and add your ~/.ant/lib/descent-ant.jar archive.
Next go to Tasks menu we'll add two tasks:
I've entered name "descent.D", choose descent-ant.jar from drop-down list, and click on: "/descent/ant/tasks" and choose "D.class"
Now do the same using "descent.DBldNum" and choose "DModuleBuildNumber.class" file.

We're going to create ant build file, but before that let's create build.properites file that will held some basic data in easily editable format.
Press Ctrl+N, choose General->File, and enter build.properties as it's name.
Here is content of my properties file:

  1. compiler.dir = /opt
  2. compiler.type = dmd-linux
  3. src.dir = .
  4. dest.dir = bin

compiler.dir is a path to compiler (without dmd/bin/dmd, descent appends it)
Press Ctrl+N and in filter box type xml, and chose XML, click next, and enter build.xml as a filename, Using bottom tabs choose Source instead of Design
I've created following build.xml (I'm not pasting it here, since this would be quite senseless, but you can take a look at it at codepad.org.
Build file is specific for linux, if I remember correctly my build.xml under windows was simpler than that one.
As you see most of the file is definition of compile macro which takes one parameter (bldtrg). (EDIT: you can find list of all possible parameters for descent.D task here)
Let's forget about that macro for a moment and take a look down at possible targets:

  1. <target name="build-number">
  2.   <descent.DBldNum file="${src.dir}/sample_bn.d" fqn="sample_bn" />
  3. </target>
  4. <target name="compile" depends="build-number" description="Compiles sample">
  5.   <compile bldtrg="sample"/>
  6. </target>

This looks quite clean don't you think?
Now you could right-mouse-click on the build.xml file, choose Run-as ->Ant build file but this is uber-lame.
Instead go to Window->Show View->Other and select Ant. I like to keep this window in lower-wight corner. Double click on any listed target will execute it (along with dependencies).
I have binded Ctrl+Shift+Q A to Show View (View: Ant), this way I can fast switch to ant window :).
eclipse descent

What's cool about it is that you can have multiple build targets (one can build few executables) and have all of them visible and easily accessible.
I'm not going to encourage anybody to use ant, but it's really cool tool, take a while to peek into ant's documentation, especially ant tasks.

catz: [eng.lish] [kom.puterowe] [programowanie w D] [Techblog]
tagz: [d] [d programming language] [descent] [eclipse]
6 komentarzy
24
lipiec-2008
183307

Ever since I started using Opera I've always had ctrl+d binded with "Paste and Go". However after upgrade from 9.5 beta to 9.51 behaviour has changed and it seems opera stopped using Xorg clipboard.
I've shed many tears ;) but didn't break down and finally found something that works the way I like it:
In keyboard setup in Application item add combo you like (I'm using "d ctrl" as I've said) and give the following string "Paste mouse selection & Go".
Remember to use '&' and not 'and'. & is used to separate actions

catz: [bro.wsers] [kom.puterowe]
tagz: [linux] [opera 9.51] [paste] [xorg] [xorg clipboard]
Dodaj swoją opinię
04
czerwiec-2008
145754

Znajomi z IRCNetu zarazili mnie tresurehuntem.

Question name Correct entry time
robot 2008-05-20 17:40:44.151252
zip 2008-05-20 17:10:56.126710
network 2008-05-27 22:47:40.954321
primes 2008-06-03 00:19:45.691278

Widać, że pierwsze zadanie rozwiązałem tego samego dnia co drugie. Drugie zadanie rozwiązałem w shellu: find + sed + awk, pierwsze zadanie z użyciem bc -lq i definicją funkcji factorial, network z ręki, bo wpisów nie było jakoś specjalnie dużo, do primes napisałem programik w D który znalazł się na tango wiki

catz: [go.ogle] [kom.puterowe] [programowanie w D]
tagz: [język D] [programowanie] [treasurehunt]
4 komentarze
30
maj-2008
130324

Do zapamiętania:
PS> $env:path
PS> $env:path = $env:path + ";c:\blah"

catz: [kom.puterowe] [micr.osoft] [mini.] [Miniblog]
tagz: [environment] [path] [powershell]
Dodaj swoją opinię
23
maj-2008
222300

D singleton Dlaczego taki tytuł? Bo singleton, jest powszechnie krytykowanym wzorcem projektowym. Dzieje się tak głównie z powodu początkująch, którzy za wszelką cenę starają się by ich programy były 'obiektowe', a przecież wiadomo, że w programowaniu obiektowym zmienne globalne są ZŁE. Niewiele mysląc młodzi adepci sztuki, opakowują zmienne globalne w singleton i są z siebie zadowoleni ;).
"Singleton nie jest odpowiedzią na zmienne globalne, odpowiedzią jest 'Na jaką cholerę Ci zmienne globalne?'"
Na początek pokażę więc, co można zrobić ze zmiennymi globalnymi w D, a dalej dla tych którzy wiedzą do czego MOŻNA i NALEŻY używać singletona, różne sposoby implementacji w D.

Pokaż więcej...

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [dziedziczenie singletonów] [język D] [programowanie D] [singleton] [singleton in d] [singletony] [singletony i wątki] [wątki]
3 komentarze
09
maj-2008
143006

Tak, pozycjonerzy z firmy http://www.technetium.pl zaatakowali mnie wczoraj.
Przy wpisach dopisują komentarze z linkami do stron (chyba nie z automatu, bo komentarze sprawiają na powiązane pi/drzwi z treścią wpisów).
Firma ma siedziebę w Rzeszowie i stamtąd też pochodziły IPki osób komentujących: jeden z proxy zdaje się w3cache.res.pl, jeden z czegoś co wygląda na AP do sieci bezprzewodowej: hansiewicza.res.pl (czy muszę dodawać, że siedziba spamerów mieści się na ulicy Hanasiewicza?) i ostatni: 91.196.9.214.
Dajcie znać jeśli u was również pojawiły się jakieś kryptoreklamy
P.S. Wpis trafia na techblog, bo myślę, że wzbudzi niejakie zainteresowanie

catz: [kom.puterowe] [Techblog]
tagz: [pozycjonerzy atakują] [pozycjonowanie IS BAAAD] [spam]
11 komentarzy
25
kwiecień-2008
150301
...napisałem, że Programowanie Uogólnione (generic programming), brzmi syfnie, wycofuję się z tego zarzutu, po pierwsze sam zaczynam stosować to sformułowanie, poza tym po dłuższym namyśle brzmi całkiem nieźle, na pewno lepiej niż 'programowanie generyczne', także trochej, zwracam honor : )
catz: [kom.puterowe] [Miniblog] [pro.gramowanie]
tagz: [językoznastwo] [metaprogramowanie] [programowanie] [programowanie uogólnione]
Dodaj swoją opinię
25
kwiecień-2008
140108

D
Dawno nic się tu nie działo, głównie dlatego, że nie bardzo mam czas cokolwiek pisać.
Deely pisał jakiś czas temu o wyrażeniach lambda w C#. Dzisiaj trochę o różnych bajerach jakie można robić w D.
Na początek zrobimy sobie małe opakowanie na foreach. Jak zwykle najpierw kawałek kodu, potem jak zwykle pseudo wyjaśnienia.

Pokaż więcej...

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [język D] [programowanie D]
5 komentarzy
09
luty-2008
131827

Learn to Tango with D
Wreszcie przyszła.

catz: [kom.puterowe] [programowanie w D]
tagz: [book] [d language] [d programming]
3 komentarze
28
listopad-2007
015223

Dziś będzie krótko, jak zacząć programowanie w OpenGLu w D.

Najpierw małe streszczenie z tego co było na warsztatach.
Na trzecich warsztatach D było więcej o klasach, dziedziczeniu, de/kon-struktorach, statycznych de/kon-struktorach, przeciążaniu metod, properties (nie, podobnie jak python nie lubimy setterów i getterów :P, atrybuty/własności w D są banalne do implementacji o czym wspomniałem w pierwszym wpisie). Dalej, o klasach zagnieżdżonych, interfejsach, invariantach (niezmiennikach) obiektów klas, atrybucie scope dla klas, przeciążaniu operatorów, rzutowaniu. uff sporo prawda? :)
Na czwartych warsztatach było natomiast o róznych rodzajach tablic w D o wycinkach tablic i o operatorze konkatenacji, następnie początek zabawy, czyli pierwszy program w OpenGLu.

Zanim jednak stworzymy nasz super ekstra pierwszy projekt, musimy przygotować sobie środowisko pracy :). Zakładam, że tak jak w drugim wpisie o D, masz już zainstalowany kompilator DMD z tango, do tego zainstalowany rebuild.
Potrzebny nam będzie Derelict, czyli zestaw bindingów dla D do różnych (głównie 'multimedialnych' (nie cierpię tego słowa ;)) bibliotek C. Do jego instalacji użyjemy dsssa (można odpalić go z konta użytkownika, wówczas derelict zostanie zainstalowany w podkatalogu w $HOME, jednak instalując jako administrator, zainstalujemy go 'globalnie'):

  • # dsss net install derelict
  • # dsss net install derelictsdl
  • # dsss net install derelictgl

Dsss oidp zapyta najpierw o wybór mirrora, następnie ściągnie za nas, skompiluje i stworzy potrzebne biblioteki, oraz zainstaluje wybrane projekty.
Jeżeli wszystko się powiodło i mamy już dsss'a możemy przystąpić do napisania pierwszego programu. Oto example.d:

  1.  import derelict.opengl.gl;
  2.  import tango.io.Stdout;
  3.  
  4.  void main()
  5.  {
  6.     try {
  7.       DerelictGL.load();
  8.       Stdout ("Successfully loaded the OpenGL shared library.").newline;
  9.     } catch (Exception e) {
  10.       Stdout ("Could not load the OpenGL shared library.").newline;
  11.     }
  12.  }

Plik wrzucamy do jakiegoś katalogu, w tym samym katalogu tworzymy prosty plik dla dsssa, mianowice dsss.conf:

  • [example.d]
  • target=example
  • buildflags=-lldl

-ll jest to flaga dla dsss'a, która sprawi, że przekaże on podaną bibliotekę do linkera, w tym przypadku libdl, potrzebną do dynamicznego ładowania bibliotek.
Teraz wystarczy jedynie:

  • dsss build

I jeżeli mamy potrzebne biblioteki, to dsss powinien skompilować naszą aplikację. Kod jest wzięty z pierwszego tutoriala ze strony dmedia i przerobiony, żeby działał z tango zamiast z phobosem (czyt: zamiana writefln na Stdout ;)).
Polecam zapoznanie się z pozostałymi Tutorialami ze strony dmedia.
Dostosowanie ich do tango nie powinno nastarczyć większych trudności. Wywołanie toStringz można usunąć i dodać na końcu ciągu "\0", lub napisać własną krótką funkcje np taką:

  1.   char[] toStringz(ref char[] str) { return str ~= "\0"; }

Nie testowane, ale chyba ok ;).
Przykłady znajdują również na slajdach z czwartych warsztatów team0xf.

P.S. Blog najprawdopodobniej w najbliższym czasie zostanie mocno zaniedbany, a wpisy jeśli się będą pojawiać to sporadycznie, z tej prostej przyczyny, że nie mam czasu :]

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [OpenGL] [SDL] [język D] [programowanie D]
2 komentarze

Ten wpis miał być, dokończeniem na temat kontraktów (design by contract), ale ponieważ akurat o tym było na drugich warsztatach, więc odsyłam tam :).
Zacznijmy od czegoś prostego, jak w D zadeklarować i zainicjalizować tablicę? Stwórzymy sobie tablicę stringów:

  1.  module arrayofstringstest;
  2.  import tango.io.Stdout;
  3.  
  4.  char[][] pom = [ "aaa", "bbb", "ccc" ];
  5.  
  6.  void main()
  7.  {
  8.     pom ~= "hello";
  9.     pom ~= "world";
  10.     foreach (a; pom)
  11.       Stdout (a).newline;
  12.  }

Przypominam, że literały znaków są w trzymane w pamięci read-only, więc o ile możemy modyfikować sam element pom[0] (czy inne), tak próba zmodyfikowania pom[0][0] skończy się niepowodzeniem (no chyba, że pom[0] został wcześniej podmieniony, na coś innego ;)). Na ten temat wspominałem wcześniej, więc traktuję, że to jasne.

Teraz coś ciekawszego. D, o czym pisałem w pierwszym artykule z tej serii, umożliwia wykonywanie funkcji w czasie kompilacji. Stwórzmy sobie więc tablicę stringów w czasie kompilacji.

  1.  module arrayofstrings;
  2.  import tango.io.Stdout;
  3.  
  4.  char[][] genStrings(int n)
  5.  {
  6.     char[][] ret;
  7.     while(n--)
  8.       ret ~= "XXX";
  9.     return ret;
  10.  }
  11.  const char[][] arrtest = genStrings(10);
  12.  
  13.  
  14.  void main()
  15.  {
  16.     foreach (a; arrtest)
  17.       Stdout (a).newline;
  18.     Stdout.newline;
  19.  }

Operator ~ to jak już wspominałem, operator konkatenacji. W podnym przykładzie, użycie ~= powoduje doklejenie kolejnego elementu do tablicy (intuicyjne prawda? :)).
Skąd pewność, że kompilator rzeczywiście stworzy ten kod w trakcie kompilacji? Po pierwsze, celowo dołożyłem na początku typ składowania const, zmienne które są nim opatrzone muszą być znane w czasie kompilacji, gdyby więc tak nie było kompilator wyrzuciłby błąd. Po drugie, można się o tym łatwo przekonać. Wystarczy linijkę pod deklaracją zmiennej arrtest dorzucić, coś w stylu: const char[] temp=arrtest[10]. Ponieważ wynikowa tablica, ma 10 elementów, a D posiada bounds checking zarówno na poziomie kompilacji (o ile to możliwe) jak i wykonania (chyba, że podamy do kompilatora opcję -release), spowoduje to zatrzymanie kompilacji (numeracja tablic oczywiście od 0), a w komunikacie z błędem zostanie nam pokazana aktualna zawartość tablicy arrtest :).

W tym przypadku wszystkie elementy są takie same, więc nie jest to jakiś powalający efekt. Dużo ciekawszy jest jednak następny przykład, który w czasie kompilacji wygeneruje nam tablicę int'ów, następnie również w czasie kompilacji, posortuje ją i wrzuci do kolejnej zmiennej :).

  1.  module compiletime;
  2.  import tango.io.Stdout;
  3.  
  4.  uint[] genNumbers(int start, int n)
  5.  {
  6.     uint[] ret;
  7.     while(n--) {
  8.       if (start & 1) {
  9.         start >>>= 1;
  10.         start ^= 0xedb88320;
  11.       } else start >>>= 1;
  12.       ret ~= start;
  13.     }
  14.     return ret;
  15.  }
  16.  const uint[] one = genNumbers(0x4d6947, 10);
  17.  
  18.  uint[] gsort(in uint[] tbl)
  19.  {
  20.     uint[] ret = tbl.dup;
  21.     uint k,l;
  22.  
  23.     for (uint i=0; i<ret.length-1; ++i) {
  24.       k = i;
  25.       for (uint j=i+1; j<ret.length; ++j)
  26.         if (ret[j] < ret[k])
  27.           k = j;
  28.       if (k != i) {
  29.         l = ret[k]; ret[k] = ret[i]; ret[i] = l;
  30.       }
  31.     }
  32.     return ret;
  33.  }
  34.  const uint[] two = gsort(one);
  35.  
  36.  void main()
  37.  {
  38.     foreach (a; one)
  39.       Stdout.format ("{:x8}", a).newline;
  40.     Stdout.newline;
  41.     foreach (a; two)
  42.       Stdout.format ("{:x8}", a).newline;
  43.     Stdout.newline;
  44.  }

D ma wbudowane metody do sortowania tablic, wystarczy dorzucić .sort po nazwie zmiennej która jest tablicą i zostanie ona posortowana w miejscu (oczywiście, tablica może być tablicą dowolnych obiektów, wystarczy przeciążyć jedną metodę :)). Metody tej (.sort) jednak nie możemy użyć w czasie kompilacji, (o ograniczeniach dotyczących funkcji wykonywanych w czasie kompilacji można poczytać w dokumentacji) dlatego napisałem krótką i prostą funkcję.
Acha, polecam na pewno ciekawe doświadczenie i umieszczenie jakiegoś const uint x=one[1111]; za deklaracją one, oraz odpowiednio z two za deklaracją two.

Dzisiejszy wpis, miał głównie na celu pokazania tablic asocjacyjnych. W D pojawia się jeden mały problem, otóż nie można zainicjalizować zmiennej która jest AA i która jest zadeklarowana na poziomie modułu. Tak więc poniższy kod nie skompiluje się.

  1.  module aaliteral1;
  2.  import tango.io.Stdout;
  3.  
  4.  int[char[]] two = ["xxx":1, "yyy":2, "zzz":666];
  5.  
  6.  void main()
  7.  {
  8.     foreach (id,val; two)
  9.       Stdout.format ("{} => {}", id,val).newline;
  10.     Stdout.newline;
  11.  }

Bez problemu jednak, można zainicjalizować zmienną typu AA, tak zwanym AA-literałem (to wyrażenie po prawej stronie znaku równości ;)), o ile znajduje się ona wewnątrz funkcji czy metody, tak więc kod poniżej skompiluje się bez problemu.

  1.  module aaliteral2;
  2.  import tango.io.Stdout;
  3.  
  4.  void testowa()
  5.  {
  6.     int[char[]] two = [cast(char[])"xxx":1, "yyyy":2, "zzzzz":666];
  7.     foreach (id,val; two)
  8.       Stdout.format ("{} => {}", id,val).newline;
  9.  }
  10.  
  11.  void main()
  12.  {
  13.     testowa();
  14.  }

Na uwagę zasługuje tutaj jedynie cast(char[]), jest to niezbędne, gdyż kompilator domyślnie przypisuje AA-literałowi typ postaci typ_zew[typ_wew], gdzie zarówno typ_zew jak i typ_wew są typami odpowiednio wartości i klucza, przy czym są one ustalane na podstawie pierwszego elementu AA-literału. Ponieważ typem (literału) "zzz" jest char[3u], kompilator próbowałby zrzutować wszystkie pozostałe klucze do tego typu.
Z tej też przyczyny rzutujemy pierwszy klucz na cast(char[]). To jest bardzo proste, ja tylko utrudniam zrozumienie tego ;). Typ AA-literału jest ustalany na podstawie pierwszego elementu.

Zastanawiałem się, dlaczego tak jest, że nie można zainicjalizować tablicy asocjacyjnej na poziomie modułu. Moim zdaniem (nie wiem czy poprawnym), wynika to z tego jak AA są reprezentowane w pamięci, w trakcie działania (w przypadku D w postaci drzewa binarnego). Tak więc, kompilator nie jest stworzyć odpowiedniej struktury dla takiej zmiennej w czasie kompilacji (tak zgaduję), natomiast umieszczenie takiej zmiennej w jakimkolwiek bloku, powoduje najprawdopodobnie dołożenie kodu, który odpowiednią strukturę stworzy. (Sprawdziłem to i wygląda na to, że moje rozumowanie jest poprawne)
Jeśli jednak potrzebujemy zmiennych typu AA na poziomie modułu, z pomocą przychodzą nam statyczne konstruktory modułów, tak więc następujący kod jest poprawny:

  1.  module aaliteral3;
  2.  import tango.io.Stdout;
  3.  
  4.  const int[char[]] two;
  5.  static this()
  6.  {
  7.     two = ["xxx":1, "yyy":2, "zzz":666];
  8.     two ["xxx"] = 123;
  9.  }
  10.  
  11.  void main()
  12.  {
  13.     foreach (id,val; two)
  14.       Stdout.format ("{} => {}", id,val).newline;
  15.  }

Zwracam jeszcze uwagę, (celowo) poprzedziłem zmienną two słówkiem const. Otóż w D, jeżeli zmiennej (na poziomie modułu) o typie przechowywania const nie nadamy wartości w definicji, możemy modyfikować jej wartość, ale tylko w konstruktorze modułu.

Na ostatnich warsztatach (wkrótce powinny się pojawić materiały z warsztatów) było krótko na temat zagnieżdżonych funkcji i przeciążania funkcji, więcej na temat typów składowania parametrów funkcji, czyli to o czym ostatnio pisałem, kontraktów, funkcji ze zmienną ilością argumentów,lazy evaluation, czyli leniwym wartościowaniu argumentów krótko o linkowaniu z C.
Także te tematy raczej nie będą tutaj poruszane.
To tyle na dzisiaj :) Have phun programming in D :)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [compile time function execution] [język D] [programowanie D] [statyczne konstrukotry] [statyczny konstruktor] [tablica asocjacyjna] [tablice asocjacyjne] [wykonywanie kodu w czasie kompilacji]
2 komentarze
12
listopad-2007
113308

W zeszłym roku, przez semestr, uczęszczałem na takowy przedmiot. Naszym zadaniem było zaimplementowanie serwera takiej bazy.
W implementacji nie korzystaliśmy z przypominającego SQLa OQLa, lecz z pomysłu który próbuje wypromować pan Kazimierz Subieta mianowicie SBQLa (Stack Based Query Language).

W obiektowej bazie danych przechowywane są całe obiekty (super stwierdzenie, nie? ;)).
Pan Subieta a zanim i my rozważa trzy typy obiektów:

  • obiekty atomowe, czyli takie które przechowują wartości,
  • obiekty złożone, czyli takie, które są kontenerami dla jakichkolwiek innych obiektów, oraz
  • obiekty pointerowe (lub jak kto woli wskaźnikowe) które służą do tworzenia referencji do innych obiektów

Każdy obiekt ma nazwę, oraz unikatowy identyfikator. Obiekt atomowy dodatkowo ma wartość, którą przechowuje, a obiekt pointerowy identyfikator obiektu na który wskazuje.
Przykład (miałem zrobić ładny obrazek, ale jestem leń :P): mamy obiekt złożony typu osoba, który posiada podobiekty atomowe typu imie, nazwisko podobiekt złożony typu adres.
Jeśli się nie mylę, bardziej skomplikowane implementacje posiadają funkcje które można wykonywać na elementach (tak jak w tradycyjnych bazach danych) a także pozwalają na przechowywanie metod w obiektach i wywoływanie tychże metod.

SBQL pozwala na wyciąganie obiektów z bazy danych. SBQL pozwala tworzyć intuicyjne zapytania (no kompletnie nieintuicyjne również ;)), moja implementacja różni się od tego co promuje pan Subieta, także przedstawione przeze mnie zapytania niekoniecznie mogą być możliwe w implemntacji opisywanej przez niego.

  • osoba where imie
  •   - zwraca te obiekty osoba, które posiadają podobiekt imie (na dowolnej głębokości)
  • osoba where nazwisko = "Kowalski"
  •   - trzeba cokolwiek tłumaczyć?

Więcej i ciekawszych przykładów, znajdziecie w...

Live show

Nie wiem dlaczego, ale nikt nie zdecydował się udostępnić efektów swojej pracy.
Postanowiłem postawić serwer i napisałem małego pehapa, który pozwala wykonać na żywo kilka zapytań. Na chwilę obecną nie ma możliwości wykonywania dowolnych zapytań (gdyż obawiam się evil hax0rów z mr0cku ;)), raczej wątpię, czy wprowadzę w ogóle taką możliwość :>.
Chętnych do pooglądania przygotowanych przeze mnie zapytań odsyłam tutaj. Jest tam seria kilku zapytań pod rząd, które zwracają to samo, ale robią to na różne sposoby TIMTOWTDI ;).

catz: [kom.puterowe] [pro.gramowanie] [Techblog]
tagz: [implementacja obiektowej bazy danych] [obiektowe bazy danych] [sbql]
11 komentarzy
10
listopad-2007
153155

Dzisiaj o typach składowania parametrów funkcji, nazywanych również atrybutami. Sporo zastanawiałem się, czy opisy umieścić tutaj, jednak stwierdziłem, że chyba łatwiej i czytelniej będzie w postaci komentarzy w kodzie. Mam nadzieję, że taka forma będzie wam odpowiadać.
Omówimy sobie krótko na przykładach trzy typy składowania in, out, oraz ref (lub jak ktoś woli inout (h3r3tic mnie dziś uświadomił, że inout nie jest aktualnie zalecany i że prawdopodobnie zostanie usunięty, lub zmieni się jego semantyka, także lepiej nie używać). Zastanawiałem się też od którego z nich zacząć, zdecydowałem się na in. Jeżeli ktoś nie miał do czynienia z programowaniem wcześniej to jego zachowanie, może wydawać się dość dziwne, w rzeczywistości jest jednak jasne i proste :).

  1.  import tango.io.Stdout;
  2.  
  3.  // atrybut 'in' mówi, że przekazanie nastąpi przez wartość.
  4.  // zmiany na obiekcie, nie będą widoczne w metodzie wywołującej
  5.  // jednakże...
  6.  void test_int(in int x) {
  7.       x = 70;
  8.       Stdout ("int in test_int ") (x).newline;
  9.  }
  10.  
  11.  // ... z powodu 'płytkiego kopiowania', zmiany na elementach
  12.  // przekazywanego obiektu (czyli wiersz z zamianą znaku) będą
  13.  // widoczne w metodzie wywołującej
  14.  void test_func(in char[] a) {
  15.       a ~= " zonk"; // ponieważ w D ciągi znaków są obiektami
  16.           // ta zmiana powoduje zmianę rozmiaru,
  17.           // i doklejenie ciągu 'zonk' (lokalnie!)
  18.           // jednakże nie niszczy obiektu, który
  19.           // otrzymaliśmy przy wywołaniu funkcji
  20.       a[0] = 'X';
  21.       a[1] = 'X';
  22.       a = "blah!".dup; // niszczymy (lokalnie) orginalny obiekt,
  23.       a[2] = 'X'; // więc te podmiany liter, nie będą
  24.       a[3] = 'X'; // widoczne w metodzie wywołującej
  25.       Stdout ("string in func ") (a).newline;
  26.  }
  27.  
  28.  void main() {
  29.       char[] t = "zażółć gęślą jaźń".dup;
  30.       int val=15;
  31.  
  32.       test_func(t);
  33.       Stdout("string in main ") (t).newline;
  34.  
  35.       test_int(val);
  36.       Stdout ("int in main ") (val).newline;
  37.  }
  38.  

Podając do rebuilda opcję -exec spowodujem odpalenie programu zaraz po kompilacj, tak więc:

  • rebuild -clean -exec test_in.d

Krótkie wyjaśnienie do powyższego kodu. W funkcji main, zaraz za ciągiem znaków widać słówko .dup. Powoduje ono utworzenie kopii stringa. Jest tak dlatego, że w linuxie literały stringów, są w pamięci read-only (jedno zdanie można znaleźć tutaj), więc próba modyfikacji elementów takiego stringa, zaowocuje kochanym SIGSEGV. Stąd potrzebujemy wcześniej skopiować ten string :).
Czas na ref, czyli przekazywanie przez referencję.

  1.  import tango.io.Stdout;
  2.  
  3.  // atrybut 'ref' mówi,
  4.  // że przekazanie nastąpi przez referencje, tak więc
  5.  // wszystkie zmiany których dokonamy na przekazywanym
  6.  // obiekcie będą widoczne w metodzie wywołującej.
  7.  void test_int(ref int x) {
  8.       x = 70;
  9.       Stdout ("int in test_int ") (x).newline;
  10.  }
  11.  
  12.  void test_func(ref char[] a) {
  13.       a ~= " zonk";
  14.       a[0] = 'X';
  15.       Stdout ("string in func ") (a).newline;
  16.  }
  17.  
  18.  void main() {
  19.       char[] t = "zażółć gęślą jaźń".dup;
  20.       int val=15;
  21.  
  22.       test_func(t);
  23.       Stdout("string in main ") (t).newline;
  24.  
  25.       test_int(val);
  26.       Stdout ("int in main ") (val).newline;
  27.  }

Chyba nie trzeba nic tłumaczyć :)
Przejdźmy do out. Out jak się można domyślić oznacza, że parametr jest tylko parametrem wyjściowym, to znaczy że dana funkcja czy metoda ma w nosie wartość jaką tam podamy. Jest przy tym jedna ważna cecha, ale to w komentarzach.

  1.  import tango.io.Stdout;
  2.  
  3.  // najciekawszy atrybut czyli 'out', przekazywanie następuje
  4.  // przez referencje, jednakże, zanim obiekt trafi do metody
  5.  // następuje jego inicjalizacja do wartości domyślnej.
  6.  void test_int(out int x) {
  7.       // zmianna typu int jest domyślnie inicjalizowana 0
  8.       Stdout ("int in test_int ") (x).newline;
  9.  }
  10.  
  11.  void test_func(out char[] a) {
  12.       a ~= " zonk"; // ponieważ na początku zmienna a
  13.           // jest inicjalizowana na pusty ciag,
  14.           // to doklejenie spowoduje tak sklejenie
  15.       // "" razem z " zonk"
  16.       Stdout ("string in func ") (a).newline;
  17.  }
  18.  
  19.  void main() {
  20.       char[] t = "zażółć gęślą jaźń".dup;
  21.       int val=15;
  22.  
  23.       test_func(t);
  24.       Stdout("string in main ") (t).newline;
  25.  
  26.       test_int(val);
  27.       Stdout ("int in main ") (val).newline;
  28.  }
  29.  

Najpierw kawałek kodu, a poniżej opis, jakie zostawiam zadanie ;)

  1.  import tango.io.Stdout;
  2.  
  3.  void test_a() { Stdout ("To jest test_AAA").newline; }
  4.  void test_X() { Stdout ("To jest test_XXX").newline; }
  5.  
  6.  void test_change(in void function() x) {
  7.       Stdout("wywolanie pierwsze w change").newline;
  8.       x();
  9.       x = &test_X;
  10.       Stdout("wywolanie drugie w change").newline;
  11.       x();
  12.  }
  13.  
  14.  void main() {
  15.       void function() a = &test_a;
  16.  
  17.       test_change(a);
  18.       Stdout("wywolanie w main ").newline;
  19.       a();
  20.  }

Małe wyjaśnienie. W main widać deklarację zmiennej a typu void function(), czyli wskaźnik na funkcję typu void, nie przyjmującą żadnych parametrów. Stąd przed test_a pojawia się &, czyli pobranie adresu funkcji test_a.
Podobnie funkcja test_change przyjmuje parametr typu wskaźnik na funkcję (typu void, która nie przyjmuje parametrów). Zadanie jest bardzo skomplikowane, mianowicie potestować, jak ten program będzie się zachowywał, gdy podmienimy atrybut pierwszego parametru funkcji test_change na inoutref oraz out.
Po zrobieniu zadania można zerknąć na ostatni przykład.

  1.  module baker;
  2.  
  3.  import tango.io.Stdout;
  4.  
  5.  void baker(inout int b)
  6.  {
  7.       assert(b < 0x10000, " RANY! b jest większe od 65535! co my teraz zrobimy?! ");
  8.       b = 666;
  9.  }
  10.  
  11.  int main()
  12.  {
  13.       int x = 0x5ac4;
  14.  
  15.       Stdout.format ("{:x}", x).newline;
  16.  
  17.       baker(x);
  18.       Stdout.format ("{:x}", x).newline;
  19.  
  20.       x = 0x12345;
  21.       baker(x);
  22.       Stdout.format ("{:x}", x).newline;
  23.  
  24.       return 0;
  25.  }

Jedynym nowym elementem, który się tu pojawia jest assert. assert podobnie jak w C sprawdza, czy podany warunek jest prawdziwy. Jeśli nie jest, 'rzuca' on wyjątkiem (który można oczywiście przechwycić).
assert(0); można używać, do oznaczania fragmentów kodu, do których program nie powinien dotrzeć. Pierwszą myślą jest, "jak to możliwe, jak może być miejsce, gdzie program ma nie dotrzeć?", jednak chociażby w przypadku budowania bardziej skomplikowanych parserów, jest to dość przydatne. Więcej na temat Contract Programming w którymś z kolejnych odcinków

Do powyższego przykładu, proszę spróbować zmienić inout w funkcji baker, na out i sprawdzić (albo jeszcze lepiej przewidzieć) jaki będzie wynik działania.

Omówiłem tylko trzy podstawowe typy składowania, jest ich jednak więcej i mają różne ciekawe zastosowania. Zaciekawionych odsyłam do dokumentacji:
invariant, const oraz final (const w D jest typem składowania, a nie atrybutem dla typu, więcej na ten temat oraz porównanie do C++ tutaj
lazy (warto wspomnieć, że typ składowania lazy został zasugerowany przez Tomasza 'h3r3tic'a Stachowiaka z Team0xf).
Podane w linkach typy składowania, pewnie pojawią się kiedyś w przykładach ;)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [in] [inout] [język D] [out] [ref] [storage class]
2 komentarze
10
listopad-2007
144925
OpenLDAP i nowa konfiguracja cn=config

Postaram się w sposób zwięzły opisać jak przejść z OpenLDAPem na Nową i Lepszą [tm] konfigurację.
Na początku ściągamy i kompilujemy źródła OpenLDAP'a oczywiście, można też pociągnąć OpenLDAPa z paczek, jeśli jednak używasz już takiego z paczek w systemie, to nie doradzałbym na nim testować, żeby nie rozwalić systemu :>.
Ja instaluję OpenLDAP'a w /opt/openldap.

  • $ tar -xvzf openldap-stable-20070831.tgz
  • $ ./configure --prefix=/opt/openldap
  • $ make depend
  • $ make
  • $ sudo make install

Dodajemy /opt/openldap/lib do /etc/ld.so.conf i odpalamy ldconfig.
Przechodzimy do katalogu etc/openldap i na początek zmieniamy domyślny suffix (base DN) i rootdn w slapd.conf

  • suffix "dc=gim,dc=org,dc=pl"
  • rootdn "cn=michal,dc=gim,dc=org,dc=pl"

Używając bin/slappasswd generujemy nowe hasło, które ustawiamy jako rootpw w slapd.conf, za database bdb. Do tego na końcu slapd.conf dodajemy dwie linijki:

  • database config
  • rootpw {SSHA}5lqZcBJMqf6mgRFW2eU2u2UB0kmDo5vf

Hasło można ustawić takie samo jak dla bdb (Berkley DB), lub wygenerować jakieś nowe, będzie ono służyło do dostania się do konfiguracji z poziomu serwera.
W ldap.conf ustawiamy tymczasowo URI oraz BASE na base dn, który ustawiliśmy w slapd.conf, czyli:

  • BASE dc=gim,dc=org,dc=pl
  • URI ldap://:1234

URI takie, gdyż w celach testowych na tym porcie będziemy startować serwer ldapa.
Upewnij się, że na wybranym porcie, nic nie chodzi, slapd poinformuje jeśli się tak zdarzy, ale ponieważ, bedziemy odpalać z włączonym debuggiem, możesz nie dostrzec tej informacji.
Przechodzimy do /opt/openldap/etc i kopiujemy domyślne ustawienia dla backendu bdb (Berkeley DB):

  • cp etc/openldap/DB_CONFIG.example var/openldap-data/DB_CONFIG

W katalogu etc tworzymy katalog slapd.d, następnie konwertujemy konfigurację na 'nową'. Nowa konfiguracja cechuje się tym, że ma hierarchiczną strukturę, której korzeniem jest cn=config. (OpenLDAP od jakiegoś czasu do trzymania konfiguracji w pamięci używa backendu, takiego samego jak do przechowywania innych danych, różnica jest taka, że schema dla konfiguracji zdefiniowana jest na poziomie samego backendu, natomiast informacje o elementach drzewa zapisywane są w plikach w katalogu slapd.d a nie w bazie danych).
Po tym kroku możemy wyrzucić slapd.conf oraz katalog schema, gdzie trzymane są schema'y ldapowe (my jednak w celach testowych zmienimy im jedynie nazwy).
Jeżeli potrzebujesz innych schema' zainclude'uj je w slapd.conf przed zmianą na nową konfigurację. Nie omawiam tutaj praw dostępu do serwera openldap'a, jeśli potrzebujesz jakieś, również zrób to przed konwersją, będzie Ci łatwiej.

  • mkdir slapd.d
  • ../../sbin/slaptest -f slapd.conf -F slapd.d
  • mv schema nietrzeba.schema
  • mv slapd.conf nietrzeba.slapd.conf

Nadszedł właściwy moment by uruchomić serwer:

  • ./libexec/slapd -h ldap://:1234 -d 1

Zostawiamy serwer odpalony, a na konsoli obok, wydamy testowo zapytanie, by sprawdzić, czy serwer działa. Jeśli wszystko poszło gładko, na pierwsze zapytanie powinniśmy w odpowiedzi dostać, to co ustawiliśmy jako base dn. (Po opcje do ldapsearch odsyłam do manuala). Na drugie zapytanie natomiast powinnienneś otrzymać natomiast drzewo konfiguracji:

  • /opt/openldap/bin/ldapsearch -x -L -b '' -s base '(objectClass=*)' namingContexts
  • /opt/openldap/bin/ldapsearch -x -L -D "cn=config" -w super_tajne_haslo -b 'cn=config' '(objectClass=*)' configContext
  •  
  • Wynikiem pomijając puste linie i komentarze, będzie coś w stylu.
  • dn: cn=config
  • dn: cn=include{0},cn=config
  • dn: cn=schema,cn=config
  • dn: cn={0}core,cn=schema,cn=config
  • dn: olcDatabase={-1}frontend,cn=config
  • dn: olcDatabase={0}config,cn=config
  • dn: olcDatabase={1}bdb,cn=config

Możesz też obejrzeć całą konfigurację usuwając słowo configContext.
Tyle na dzisiaj, Dlaczego taka konfiguracja jest jezzi, trendi i lepsza wkrótce.

catz: [kom.puterowe] [Techblog]
tagz: [OpenLDAP] [cn=config] [nowa konfiguracja] [slapd] [slapd.d]
2 komentarze
09
listopad-2007
022143

Obiecany przykład, a potem ciut wyjaśnień.

  1.  module pierwiastki;
  2.  
  3.  private import tango.io.Stdout;
  4.  private import tango.math.Math;
  5.  private import tango.text.convert.Float;
  6.  
  7.  void main()
  8.  {
  9.       double a = 1.0, b = 1.0, c = 0.0;
  10.       double delta = b*b - 4*a*c;
  11.  
  12.       if (delta<0) {
  13.           Stdout ("PUKPUK!");
  14.       } else {
  15.           double x1 = (-b - sqrt(delta)) / 2*a;
  16.           double x2 = (-b + sqrt(delta)) / 2*a;
  17.           Stdout ("pierwiastki: "~toUtf8(x1)~", "~toUtf8(x2)).newline;
  18.           // to samo inaczej
  19.           Stdout.format ("pierwiastki {}, {}", x1, x2).newline;
  20.       }
  21.  
  22.  }

W D na projekty buduje się z cegłówek zwanych modułami. Każdy plik stanowi osobny moduł. Linijka module jest opcjonalna (w podanym wyżej przykładzie wręcz zbędna). Jeżeli w pliku ma się ona znajdować, nie może przed nią być nic innego (poza komentarzami ow coz :D). Domyślnie nazwa modułu jest tworzona z nazwy pliku po usunięciu rozszerzenia. Moduł dostarcza przestrzeń nazw dla wszystkiego co się z nim znajduje.

W pythonie jeżeli importujemy tak:

  • import math

To moduł math jest wrzucany do aktualnej przestrzeni nazw statycznie, to znaczy nazwy wszystkich wrzucanych obiektów, są poprzedzone nazwą modułu, tym samym by odwołać się do jakiegokolwiek elementu tego modułu trzeba podawać pełną nazwę (np math.log).
W D jest odwrotnie domyślnie obiekty danego modułu są wrzucane do bezpośrednio do aktualnej przestrzeni nazw, (dlatego po import tango.io.Stdout nie musimy się odwoływać do obiektu Stdout tego modułu przez: tango.io.Stdout.Stdout (tak dwa razy Stdout, bo pierwsze to nazwa modułu, a drugie nazwa obiektu), lecz przez samo Stdout.
W przypadku większych projektów może to prowadzić do kolizji nazw, chcąc więc tego uniknąć (i wymusić zachowanie takie jak w pythonie) należy poprzedzić nazwę modułu słowem static.
Domyślnie importy w D są prywatne, to znaczy jeśli moduł A imporuje moduł B, który z kolei importuje moduł C, to moduł C nie jest widoczny bezpośrednio w module A. Dla ułatwienia rozpatrzmy następujący przykład:

  1.  // pierwszy.d
  2.  module pierwszy;
  3.  private import tango.io.Stdout;
  4.  
  5.  // drugi.d
  6.  
  7.  import pierwszy;
  8.  
  9.  void main()
  10.  {
  11.       Stdout ("test"); // ŹLE !! import w pierwszym jest prywatny
  12.       tango.io.Stdout ("test"); // ŹLE !! as above
  13.       pierwszy.tango.io.Stdout ("test"); // OK
  14.  
  15.  }

Proste prawda? :)
Do tego zostają jeszcze importy przemianowane i wybiórcze, ale w tym momencie odsyłam do dokumentacji :)
Doszliśmy więc do tego, że w pierwszym przykładzie mamy niepotrzebną linijkę import i niepotrzebne kwalifikatory private.
Następnie w funkcji main mamy kilka zmiennych typu double. Po listę typów i ich rozmiary (bo jak mówiłem w D zmienne mają ustalone rozmiary) odsyłam tutaj.

WAŻNA UWAGA
W D przy deklarowaniu kilku zmiennych, muszą być one tego samego typu (zdaje się, że wcześniej kompilator przed tym nie ostrzegał, teraz traktuje to jako błąd)!
To znaczy:

  1. int[] a, b, c; // deklaruje 3 tablice typu int, a nie jedną tablicę i dwa inty!
  2. int* a, b, c; // analogicznie deklaruje 3 wskaźniki na zmienne typu typu int!
  3. int a, *b,i c; // ŹLE!

Wracając do pierwszego kodu, widzimy wiec kilka zmiennych, liczenie delty, dalej w ifie liczenie pierwiastków funkcji kwadratowej z wzorów Viète'a. sqrt() jest metodą z modułu tango.math.Math, liczącą oczywiście pierwiastek, toUtf8 jest metodą z modułu tango.text.convert.Float zamieniająca float na postać tekstową.
~ jest w D operatorem konkatenacji.
Niżej jest identyczne wypisanie ale przy użyciu formattera, podobnego do tego z .neta, szczegóły tutaj.

Team0xf

Team0xf prowadzi warsztaty języka D (w Toruniu). Na stronie Warsztatow znajdziecie opis jak zainstalować dmd z phobosem, materiały z pierwszych warsztatów: filmiki, całą prezentację oraz przykładowe programy. Warsztaty będą się odbywać prawdopodobnie co tydzień i mniej więcej co tydzień na ich stronie pojawiać się będą nowe materiały.


Ponieważ nie zamierzam w żaden sposób konkurować z tym co oni prezentują (tym bardziej, że prezentują wyższy poziom :D), gorąco zachęcam do odwiedzania ich strony.
Jeżeli coś jeszcze będzie się pojawiać na joggu na temat D, to coś, czego (jeszcze) na warsztatach nie było, albo coś czego nie było i nie bedzie ;).
To tyle na dzisiaj, miłej nocy z D :)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [język D]
5 komentarzy
09
listopad-2007
002222

Jak wspomniałem w pierwszej części istnieją dwa kompilatory: oficjalny rozwiajny przez digitalmars - dmd oraz nakładka na gcc - gdc. Do tego istnieją trzy biblioteki standardowe phobos, rozwijana przez community tango, oraz z ostatnich warsztatów Team0xf (o nich później) dowiedziałem się, że istnieje coś takiego jak libd.

Tutaj będzie poruszona jedynie kombinacja DMD+tango i tylko pod linuxem. DMD dlatego, że zazwczaj jest o krok dalej niż gdc, to digitalmars definiuje kierunek rozwoju D, jednak szeroko pojęte 'D community' ma wpływ na rozwój języka (warto jednak zerknąć na gdc, gdyż poprzez użycie gcc, daje on czasem lepszą optymalizację). Warto może w tym miejscu wspomnieć, że dmd pod linuxem z gcc ale jedynie w celu linkowania. Pod windowsem korzysta z kompilatora C digitalmars - dmc.
Tango, jeśli się nie mylę wyrosło z dwóch projektów ares oraz mango. Dlaczego tango? Głównie dlatego, że mi bardziej przypadła do gustu niż phobos ;)
Jeżeli ktoś jest zainteresowany spróbowaniem phobosa, to pod koniec artykułu w następnym wpisie będzie małe wyjaśnienie gdzie znaleźć ładny opis instalacji i użycia

Instalacja potrzebnego softu

Będziemy potrzebować dmd i tango, które można ściągnąć w jednej paczce. Dodatkowo do budowania będzie nam potrzebny Rebuild który jest częścią projektu DSSS. (Rebuild jest nam potrzebny, ze względu na pewne problemy z linkerem. Ponadto ułatwia on kompilację dużych projektów. Na dokładkę DSSS zmierza ku temu, by zostać ujednoliconym systemem pozyskiwania, budowania, instalowania i konfiguracji projektów stworzonych w D). Ja wrzucam dmd+tango do /opt/dmd a dsss'a do /opt/dsss rób jak chcesz.

  • wget http://downloads.dsource.org/projects/tango/0.99.2/tango-0.99.2-bin-linux-dmd.1.021.tar.gz
  • wget http://svn.dsource.org/projects/dsss/downloads/0.73/dsss-0.73-dmd-gnuWlinux-x86.tar.gz
  • mkdir -p /opt/dmd /opt/dsss
  • tar -xvzf tango-0.99.2-bin-linux-dmd.1.021.tar.gz -C /opt/dmd --strip 1
  • tar -xvzf dsss-0.73-dmd-gnuWlinux-x86.tar.gz -C /opt/dsss --strip 1

Okej zrobione. Pozostaje dodać /opt/dmd/lib do /etc/ld.so.conf i wydać polecenie ldconfig oraz dodać do PATH /opt/dmd/bin oraz /opt/dsss/bin. Jeśli to czytasz, ufam że sobie poradzisz ;)

And there was no Software yet. But God created programs; small and big... And told them - Go and multiply yourselves and fill all the Memory.

Oczywiście zaczniemy od hello world. Normalnie rebuild dość sporo plików obiektowych, więc będziemy podawać do niego opcję -oqlib, żeby wszystkie pliki obiektowe wrzucał do katalogu lib w katalogu w którym kompilujemy program.
Program w D zaczyna się od funkcji main, która ma 4 określone deklaracje, obowiązują proste zasady:

  • funkcja main musi być typu void lub int, zwracana wartość jest przekazywana do systemu operacyjnego,
  • jeżeli typem zwracanym przez main jest void, wartością zwracaną do systemu jest 0,
  • main może przyjmować jeden argument typu char[][], lub nie przyjmuje wcale,

Powyższe zasady owocują w czterech możliwych deklaracjach funkcji main. My użyjemy najprostszej.

  1.  import tango.io.Console;
  2.  
  3.  void main()
  4.  {
  5.       Cout ("Zażółć gęślą jaźń").newline.append("druga linia").newline;
  6.  }
  • # Kompilujemy nasz super program:
  • rebuild -oqobj hello.d

Tak jak wspominałem, pliki obiektowe wrzucamy do katalogu obj. Program wynikowy nazywa się hello po odpaleniu możemy podziwiać efekty naszej żmudnej pracy ;).
W pierwszej linijce importujemy moduł (o modułach za chwilę) Console, jego dokumentację można znaleźć tutaj. Console jest klasą niskopoziomową i akceptuje input tylko w postaci tekstu w UTFie. (Możemy jednak zmusić ją, do wypisania tekstu w iso, konwertując go na hexy: "Za\xbf\xf3\xb3\xe6 g\xea\xb6l\xb1 ja\xbc\xf1" :>)
Dla ciekawych:
Jeśli zajrzymy do dokumentacji zrozumiemy co dzieje się dalej (a jeśli nie zrozumiemy to się domyślimy ;)). Cout jest statyczną klasą (o tym też może później) typu Output. Wywołanie Cout("tekst") powoduje tak na prawdę wywołanie Cout.append("tekst"); (o tym też później).
Ponieważ metoda append, zwraca obiekt typu Output możemy całość (Cout.append(...)) potraktować jako klasę i wywołać jedną z jej metod: newline (w D metody które nie mają parametrów nie muszą mieć nawiasów przy wywoływaniu). Ponieważ metoda newline również zwraca obiekt typu Output, znów możemy wywołać na nim metodę owej klasy. Jeżeli więc komuś ułatwia to czytanie (chyba może jedynie zaciemnić), można to zapisać tak:
(((Cout ("Zażółć gęślą jaźń")).newline()).append("druga linia")).newline(); // fuj! :>

Tu miał być jeszcze jeden przykład, ale postanowiłem, że zostanie wydzielony do osobnej części ;)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [język D] [pierwszy program] [programowanie]
2 komentarze
09
listopad-2007
001829

Większość z joggerowiczów słyszała chociaż o pythonie czy rubym. Niektórzy nawet piszą bardzo ciekawe artykuły na temat jednego bądź drugiego. Serią kilku artykułów chciałbym natomiast przybliżyć joggerowiczom mniej popularny język -- D. Mam nadzieję, że uda mi się skłonić chociaż kilka (no choćby jedną) osobę do zapoznania się z tym językiem.
Na wstępie zaznaczam, że nie jestem guru tego języka ;). Artykuł będzie ciut przydługi, prawdziwa przygoda zacznie się dopiero od następnego razu.

D jest językiem mającym poniekąd związek z C i C++. Mającym bo oprócz pewnych podobieństw w składni różni się od nich znacznie. D jest tak zwanym językiem wieloparadygmatowym umożliwiającym: programowanie impreatywne, programowanie obiektowe oraz metaprogramowanie (odsyłam do angielskiej wiki, bo na polskiej ten artykuł praktycznie nie istnieje ;)).

Przede wszystkim: D jest językiem kompilowanym do kodu natywnego (chociaż może być również interpretowany), przy czym szybkość kompilacji bije na głowę szybkość kompilatorów C czy C++. Jeżeli przyjmiemy, że kod w C++ wykonuje się szybciej niż kod w Javie (proszę o nie prowadzenie flame'a na ten temat w komentarzach :>), tak kod w D dorównuje szybkością C++ a nawet przewyższa.

D ma statyczne sprawdzanie typów. W D typy zmiennych podstawowych mają określone rozmiary w przeciwieństwie do C czy C++. D ma wbudowane typy zmiennych, które np w C++ są dostarczane przez biblioteki. Są to m.in: Tablice dynamiczne, stringi (ciągi znaków niespecjalnie pasuje, a każdy programista wie co to string), słowniki, liczby urojone. (Podobnie jak w pythonie, prawda?). D posiada dwie trzy (odmienne) biblioteki standardowe (więcej na ten temat w przyszłym odcinku). Istnieją dwa kompilatory D: oficjalny dmd, oraz nakładka na gcc - gdc.

Nieco więcej o cechach D (część może w chwili obecnej być niezrozumiała, ale może wyjaśni się w przyszłości) (acha, * oznacza, że może kiedyś więcej na dany temat ;)):
  • Różne:
    • Wbudowany garbage collector, ale nie trzeba z niego korzystać,
    • wersjonowanie, debugowanie i unittesty wbudowane w język,
    • Aliasowanie typów (odpowiednikiem alias (dla typów) w D jest typedef z C/C++, aliasowanie typów ma na celu jedynie skrócenie pisania, nic więcej),
    • Silne typowanie z użyciem typedef'a (szczegóły *),
    • foreach :)
    • stringi w switchu() (tego mi często brakuje w C ;/),
    • Wbudowany assembler (tak, nie tak jak w C, gdzie składnia asemblera jest zależna od kompilatora ;/), składnia jest określona, zestaw instrukcji jest poszerzany, o ile się nie mylę, w planach są kolejne architektury (na razie jest x86 to chyba oczywiste :>),
    • Dostęp do bibliotek C (nie oznacza to jednak, że można korzystać bezpośrednio z plików .h),
    • Możliwość kontroli wyrównania w pamięci elementów struktur,
    • SRC może być w unicodzie, IO w unikodzie,
    • Tworzenie dokumentacji z komentarzy (ddoc)
  • Funkcje:
    • Delegaty funkcji (w .necie też są),
    • przeciążanie funkcji,
    • typy składowania parametrówargumentów fukcji,
    • zagnieżdżone funkcje (sic!),
    • literały funkcji i delegat (w polskim zaczyna się przyjmować słowo literał, choć ja bym chyba wolał funkcje explicite, strinig explicite itd, ale to taka tam moja fanaberia :>),
    • bezpieczne typowanie argumentów funkcji ze zmienną ilością afgumentów (uff koszmarnie to po polsku wygląda, chodzi o znane z C funkcje: blabla(char *s, ...), które w C nie mają możliwości sprawdzania typów),
    • 'leniwy' typ składowania dla argumentów umożliwiający 'Leniwe' wartościowanie argumentów funkcji,
    • wykonywanie funkcji w czasie kompilacji (sic!) (z pewnymi ograniczeniami, ale jednak) (Oh yeah! można zrzucić np precomputing na kompilator, a niektórzy evil haxorzy piszą tak całe programy :>),
  • Tablice: łatwa zmiana rozmiaru (zazwyczaj chodzi nam o rozszerzanie :]), znany z pythona (strzelam, że z ruby'ego też Array slicing, bounds checking (sprawdzanie zakresu, jakby było niejasne :]), literały tablic, tablice asocjacyjne (indeksem AA w D może być cokolwiek)
  • OOP: moduły, interfejsy, zagnieżdżone klasy, klasy wewnętrzne (taka wariacja klas zagnieżdżonych), przeciążanie operatorów, kowariancja zwracanych typów (przez przeciążoną metodę w klasie dziedzicącej), proste 'właściwości' (w pythonie jest do tego property() w javie i (chyba) .necie settery i gettery, w D nie trzeba nic robić :])
  • OOP: D nie wspiera dziedziczenia wielobazowego (zwanego też dziedziczeniem wielokrotnym, choć ta nazwa sugeruje więcej niż nazwa 'wielobazowe').
  • Generic Programming (a jakże mogłoby zabraknąć!) (na polskiej wiki, użyte jest programowanie uogólnione, które przepraszam za wyrażenie wydaje mi się maksymalnie syfne :>)).
    • Szablony klas, szablony funkcji, uszczegóławianie typów parametrów szablonowych (niekoniecznie do konkretnych typów) (*), liczbowe parametry szblonów (*), aliasowanie parametrów szablonów (umożliwia to parametryzowanie szablonów dowolnym innym symbolem z D: nazwami, nazwami modułów, nazwami szablonów, instancji szablonów), szablony ze zmienną ilością parametrów (a przez to również argumentów).
    • mixiny szablonów i mixiny - podobne nazwy, ale to dwie zupełnie różne rzeczy, mixiny pozwalają w pewien sposób generować kod w czasie kompilacji,
    • static if - to chyba konstrukcja specyficzna dla D, w pewien sposób przypomina ifdef z C, ale tylko przypomina :]. static if (zamykający else if oraz else również są statyczne) pozwala na warunkową kompilację, ale jest to normalny element języka, więc musi być poprawny składniowo, po drugie może być używany w szablonach, więcej szczegółów (*),
    • assert i static assert - assert wiadomo do czego służy, static assert natomiast sprawdzany jest w czasie kompilacji (*),
    • typeof - ma inne zastosowanie niż w innych językach, do sprawdzania typów jest linijkę niżej, (*),
    • wyrażenia is - pozwalają na różne sprawdzanie typów i nie tylko w czasie kompilacji, nie będe teraz wnikał, (*) :],
  • Niezawodność:
    • Contract programming - w łatwy sposób można stawiać wymagania dla wejścia i wymagania dla wyjścia, które się odrzuca budując wersję do wypuszczenia,
    • statyczne konstruktory i destruktory (zarówno dla klas jak i modułów) - wywoływane odpowiednio prze wejściem do main i po opuszczeniu main,
    • try/catch/finally, do tego dochodzi jeszcze scope ale (*)
    • synchronized - dla wątków

To oczywiście nie wszystko, starałem się dużą przedstawić dużą część możliwości, stąd ten chaos :> Co dalej? Gdzie udać się z tego miejsca? Oto garść linków:

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [D programowanie] [język D] [krótko o D]
9 komentarzy
02
listopad-2007
232129

Dostałem zaproszenie z Powerset do ich właśnie co otwartego dla szerszej rzeszy Powerlabs. O samej firmie i ich pomyśle na 'nową technologię wyszukiwania' było głośno jakiś czas temu.

Opis

Daje linki do szotów w tekście , bo flickr brzydko zmienił rozmiary :]. Strona jest zrobiona super-hiper-web2.0 wygląda niemalże jak last.fm :> (Autorzy starają się stworzyć wokół tego community, punkty za komentarze/wkład). Dostępnych jest pięć 'dem'. 4 bazujące na wikipedii Cytaty, Biznes, Sztuka i przygotowany specjalnie Halloween. Pozwalają one wyszukiwać frazy w stylu: "Co ... powiedział ... ?" (cytaty), "Kogo zabił ... ?" (halloween). Dokładnie widać na skrinszotach, nie chce mi się przepisywać, leniwy jestem :>. No więc wpisałem 'Co powiedział Linus Torvalds o BSD' a drugie 'Who killed electric sheep?', muszę powiedzieć, że jestem średnio zadowolony z uzyskanych rezultatów.
Najważniejszym i najbardziej reklamowanym demem jest PowerMouse czyli owa rozreklamowana przeglądarka. Wyszukuje ona na zasadzie połączeń między obiektami. Na skrinszocie widać 3 okienka do wpisania (something connection something), na innym część wyników po wpisaniu boy, oraz po wybraniu konkretnego wyniku.
Jeszcze zanim zapomnę, Powerlabs, jako źródła danych używają wikipedii. (wyniki niektóre są dziwne :>

Krytyka

No więc byłbym zachwycony tym genialnym wynalazkiem. Byłbym. Na pierwszy rzut oka widać, że jeśli jest robiona jakaś analiza tekstów, to jest ona robiona słabo, a szczerze, to wygląda to tak jakby całość głównie się opierała o łapanie kontekstu. Z NLP ma to niewiele wspólnego.
Druga rzecz, tak się nieszczęśliwie składa, że pisałem tekst na temat projektu Microsoftu automatycznego tworzenia bazy semantycznej. Zainteresowanych odsyłam tutaj a wszystkim polecam zebrane tam Przykłady.
Czym się różni projekt Microsoftu od powerset? Otóż Microsoft zatrudnił naukowców, którzy samym tematem zajmują się od kilkudziesięciu lat (chcąc nie chcąc kilka prac musiałem przeczytać), a nad Mindnetem pracują ponad 10 lat. Baza zarówno demonstracyjna jak i ta na której rzeczywiście pracują w MS oparta jest o kilka (czy może nawet kilkanaście) słowników. Mindnet czy też mnex nie jest nastawiony na szybkie wskocznie na rynek z superową web2.0 stroną ;) a tym bardziej na tworzenie wokół tego community.
Dalszy komentarz chyba zbędny ;)

catz: [kom.puterowe] [Techblog]
tagz: [powerlabs] [powermouse] [powerset] [superhiperweb2.0power]
Dodaj swoją opinię
27
październik-2007
132922

Instalacja vmware server i kompilacja modułów poszła bez problemu, ale vmware nie chciało ruszyć. Zapisuję, żeby nie zapomnieć, najpierw symlink:

  • ln -s /usr/lib/libhal.so.1 /usr/lib/libhal.so.0

a potem albo startować z ustawionym LD_PRELOAD:

  • LD_PRELOAD=/usr/lib/libdbus-1.so.3 vmware

albo z racji, że jestem leniwy, a mam nadzieję, że błędów to nie spowoduje, to zrobiłem:

  • mv /usr/lib/libdbus-1.so.2{,-blablabla}

Przez ostatnie dwa miesiące blog był prawie martwy, mam nadzieję, że jednak uda mi się go utrzymać przy życiu. Mam plany, myślę, że ciekawe, na co najmniej kilka wpisów, ale jakoś ciężko mi znaleźć czas (zła organizacja?).

catz: [kom.puterowe]
tagz: [problemy] [ubuntu] [ubuntu gutsy] [vmware] [vmware server]
4 komentarze
20
sierpień-2007
124808

Wszyscy znają Snorta, prawda? A nawet jeśli nie znają, to zapewne słyszeli o czymś takim. W zeszły piątek nastąpiło, to o czym niektórzy wiedzieli już wcześniej, Sourcefire wziął pod opiekę ClamAVa. Co to oznacza dla użytkowników końcowych? ClamAV będzie dalej dostępny na GPLu. Komercyjny support prawdopodobnie spowoduje, że powiększy się ekipa sigmakerów jak i developerów, nie było to możliwe przy funkcjonującym systemie donacji. Zainteresowanych odsyłam do ofert pracy. Szczegółowe informacje na temat przejęcia znajdziecie w linkach:

P.S. Wszystkich fanów ;) i czytelników przepraszam, że ostatnio nie daję znaku życia, ale nie dysponuję zbyt dużą ilością wolnego czasu.

catz: [kom.puterowe] [Techblog]
tagz: [clamav] [linux] [snort] [sourcefire]
2 komentarze
16
lipiec-2007
231451
GMail hacking logo

Dwie rzeczy drażniły mnie od dłuższego czasu w gmailu, mianowicie brak czcionki o stałej szerokości przy czytaniu i pisaniu wiadomości. Jakiś czas temu postatnowiłem to zmienić, a teraz podzielę się z wami JTZ w Operze.

Pokaż więcej...

catz: [bro.wsers] [go.ogle] [kom.puterowe] [Techblog]
tagz: [czcionka stałej szerokości] [gmail] [gmail hacking] [google] [monospaced] [opera]
4 komentarze
14
lipiec-2007
212317
Simple DOM Viewer header

Jest jedna rzecz, której strasznie brakuje mi w Operze, mianowicie DOMInspectora, takiego jak ma Firefox. Co prawda jest Opera Developer Console, jednak z pewnych względów, nie wystarcza mi. Zapewne łatwiej byłoby zmodyfikować tamten kod, jednak jest on dość obszerny i nie chciało mi się nad nim siedzieć/czytać, więc napisałem pierwszą wersję mojego małego DOMInspectora dla Opery.

Pokaż więcej...

catz: [bro.wsers] [kom.puterowe] [pro.gramowanie] [Techblog]
tagz: [dom viewer] [dominspector] [opera] [webdevelopment]
2 komentarze
27
czerwiec-2007
191058

zsh in uxterm Przez dłuższy czas używałem, zsh, później z powodu problemów z UTFem wróciłem do basha, jednakże ostatnio wróciłem do zsh, jednakże nie z powodów o kŧórych będzie mowa poniżej.
Jakiś czas temu porównywałem różne shelle i postanowiłem się podzielić wynikami.

Pokaż więcej...

catz: [kom.puterowe] [pro.gramowanie] [Techblog]
tagz: [bash] [ksh] [optymalizacja skryptów] [porównanie shelli] [zsh]
27 komentarzy
21
czerwiec-2007
225609

Niedawno pojawiły się badania megapanelu za kwiecień 2007. Czołówka nie zmieniła się. Co powinno zrobić Google?

Pokaż więcej...

catz: [go.ogle] [kom.puterowe] [Techblog]
tagz: [dominacja] [google polska] [rozwój]
7 komentarzy
12
czerwiec-2007
104212

W środę pojawił się exploit na Yahoo Messegnger'a 8, w czwartek Yahoo wypuściło patcha na znalezioną lukę (Więcej jest na SecurityFocus.
Bardzo dobrze, że Yahoo zareagowało tak, szybko, gdzyż w trzy dni później (w sobotę), pojawił się malware, wykorzystujący tę lukę.
Shellcode oryginalnego exploita, został podmieniony na złośliwy, który ściąga niewykrywany (w sobotę) malware z rodziny dropperów (czyli taki, który ściąga trojana, backdora lub inny malware). Szczegóły na Sans Security.
Dla nas nie ma to żadnych skutków, gdyż ja osobiście nie mam znajomych uzywających YM, jednakże niepokojące jest tempo, w jakim twórcy wszelkiego rodzaju malware'u wykorzystują nowo odkryte luki.

catz: [kom.puterowe] [Techblog]
tagz: [malware] [sans security] [yahoo messanger 8]
Dodaj swoją opinię
10
czerwiec-2007
171343

Prawda, że chwytliwy temat? ;)
Otóż obejrzałem ostatnio 3 Tech Talki, którymi chciałbym się podzielić, a chwilowo (nadal) mam problemy z dostępem do szortów.

Pokaż więcej...

catz: [go.ogle] [kom.puterowe] [pro.gramowanie] [Techblog]
tagz: [ani vulnerability] [google tech talks] [python] [vim]
3 komentarze
03
czerwiec-2007
171651

Updejtowałem ostatnio e17 i spotkała mnie miła niespodzianka.

  • konfigi się nie rozwaliły :D zazwyczaj uzywałem, następującego (zmodyfikowanego przeze mnie skryptu znalezionego na gentoo wiki (nie nie używam gentoo)) skryptu do backupu bindingów.
  • na pulpicie pojawiły się ikonki z ~/Desktop, właściwie nie ma to dla mnie znaczenia. Można je dowolnie poukładać, jeszcze nie doszedłem do tego jak je 'uszeregować' :)
  • nie wiem czy to teraz, może po prostu wcześniej nie zauważyłem, ale w głównym menu, pojawiło się Files, gdzie kryje się pseudo File Manager. (Kiedyś było coś takiego jak EFM - E17 File Manager, ale nie wiem czy to nadal jest rozwijane, było to oparte o evfs i u mnie coś kijowo działało). Dlaczego pseudo? ano dlatego, że do jakiejś sensownej funkcjonalności to mu daleko. Jedna ciekawa rzecz, że pliki są sortowane 'po skosie' a nie rzędami jak w większości FMów :) Ciekaw jestem czy to się przyjmie (btw, przechodzenie po katalogach, w prawo/w lewo, też przechodzi 'po skosie' :))
  • udało mi się jakoś sprawić żeby mpd zadziałał :> głupio się przyznać, ale wcześniej miałem z tym problemy ;) a skoro się udało, to skompilowałem emphasis, czyli frontend dla mpd dla E17, na skrinie po lewej widać zakładkę medialib, a po prawej zakładkę search. Zakładka playlist nie wiem do czego jest (bo ja używam medialib), w każdym razie, nie działa, a zakładka stats jeszcze nie jest zaimplementowana.
catz: [kom.puterowe] [Techblog] [Xo.rg]
tagz: [e17] [e17-backup-bindings] [emphasis]
8 komentarzy
08
maj-2007
100840

Wpis ten jest odpowiedzią między innymi na komentarze dunDera i Cthulu, do poprzedniego wpisu. Pomyślałem, że zainteresuje to więcej osób, a prędzej ktoś przeczyta wpis niż komentarz.

Piraci, którzy działają na skalę globalną, mają dość kasy żeby wykupić program do dekodowania tego syfu od samych twórców zabezpieczenia cichaczem ;)

Otóż nie jest to takie proste, jak napisałem, system nie został i prawdopodobnie jeszcze 'jakiś czas' nie zostanie złamany.

Narzędzia

Jest sobie program napisany przez arnezamiego, do odczytywania: klucza przetwarzania, generwoania z niego klucza nośnika, odczytywania identyfikatora woluminu, generowania unikatowego klucza tytułu i odszyfrowania kluczy utworu (gdyż jest ich kilka).
Jest BackupHDDVD, ale nie jest to narzędzie dla piratów, pozwala on zdeszyfrować film i zapisać na dysku, ALE, trzeba mu podać zestaw kluczy utworu albo o ilę się nie mylę klucz nośnika (stąd strony takie jak zdjęta już hddvdkeys.com).
Pewnie można by połączyć oba programy, ale... moim zdaniem: firmy odwołają certyfikat dla windvd, wprowadzą jakieś poprawki, które uniemożliwią działanie programowi arnemzaniego (i znowu spowoduje to kłopoty dla zwykłych uzytkowników).
Jak pisałem wcześniej, system nie został złamany i bez posiadania odpowiednich kluczy, nie będzie możliwe dekodowanie, bo pewnych kluczy otrzymać się nie da.

Inne możliwości

Najprostszym rozwiazaniem, byłoby zakupienie napędu i próby modyfikacji jego firmware'u, to jednak najprawdopodobniej spowodowałoby odwołanie napędu (nie jego certyfikatu, lecz odwołanie go w MKB, co spowodowałoby, że nie mógłby on otrzymać klucza przeodtwarzania, a tym samym, byłby właściwie bezużyteczny).
Ważne, żeby zdać sobie sprawę, że tak na prawdę wytwórniom filmowym, nie zależy na tym, by film nie został spiracony. Ważniejsze jest by:

  1. maksymalnie opóźnić proces wydania wersji pirackich,
  2. jeżeli już wyszły wersje pirackie, odwołać odpowiednie urządzenia, żeby w przyszłości nie mogły słuzyć do wydawania pirackich wersji

Co do wykupienia, 'programu do dekodowania' od twórców systemu, trzeba pamiętać, że AACS jest zależny od hardware'u, więc nawet gdyby jakiś magiczny program istniał (np wykorzystujący jakąś nieopublikowaną furtkę), bez odpowiedniego sprzętu sam w sobie pewnie nic nie zrobi.

Universal hack

Zdecydowanie najlepszym wyjściem, byłoby uzyskać klucz, który można by określić głównym kluczem urządzeń. To z tego klucza, zostały poprzez funkcję jednokierunkową używającą AESa w specjalnym procesie, wygenerowane klucze wszystkich urządzeń na rynku. Ponieważ jest to funkcja jednokierunkowa oparta o AESa posiadając klucze urządzenia, nie jesteśmy w stanie otrzymać tego głównego klucza (no chyba, że ktoś wie jak złamać AESa :)).
Klucz ten znają zapewne 'wybrane osoby', więc najprościej byłoby go od owych osób 'wyciągnąć'.
Spowodowałoby to, że AACSLA, musiałby zmienić klucze wszystkich urządzeń, co jest w praktyce niemożliwe.

Należy zdać sobie sprawę, że łamanie zabezpieczeń to wieczna walka, między twórcami zabezpieczeń, a między tymi, którzy chcieliby je obejść (to tak niekoniecznie odnośnie zabezpieczeń HD-DVD). Tak, ta wojna najpewniej najbardziej odbije się na tych, którzy chcieliby 'po prostu obejrzeć film'.

catz: [kom.puterowe] [Techblog]
tagz: [aacs] [aacs keys] [backuphddvd] [drm] [master device key]
8 komentarzy