Home / Community / Blog

I had to check if I can compile my source code on another machine using repository only.

The problem was that ELF files almost always differ (depend on time, path etc). The solutions was objdump and disassemble parameter.

I had the "original" elf file (manipulator-src.elf) and "new" one (manipulator.elf) compiled on other machine using repository only, so I've run:

objdump -d manipulator-src.elf > manipulator-src.dump
objdump -d manipulator.elf > manipulator.dump

and then compare .dump files:

diff -u manipulator-src.dump manipulator.dump
--- manipulator-src.dump    Sat Dec 14 19:33:28 2013
+++ manipulator.dump       Sat Dec 14 19:34:03 2013
@@ -1,5 +1,5 @@

-manipulator-src.elf:     file format elf32-avr32
+manipulator.elf:     file format elf32-avr32


 Disassembly of section .reset:

as you can see only second line was different because of file name.

When I've used ldapsearch, I've noticed that not every attribute I can search is displayed.

For example I can search locked accounts:

ldapsearch -x -H ldap://ldap.mydomain.com -W \
-D "cn=jaqb,dc=mydomain,dc=com" \
-b "ou=Users,dc=mydomain,dc=com" \
"(pwdAccountLockedTime=*)"

but pwdAccountLockedTime attribute is not displayed.

According to ldapsearch manual you have to add + (plus sign) do filter attributes. Now it looks like this:

ldapsearch -x -H ldap://ldap.mydomain.com -W \
-D "cn=jaqb,dc=mydomain,dc=com" \
-b "ou=Users,dc=mydomain,dc=com" \
"(pwdAccountLockedTime=*)" "+"

, but now "normal" attributes aren't shown. To show both regular and operational attributes you have add * (asterisk sign):

ldapsearch -x -H ldap://ldap.mydomain.com -W \
-D "cn=jaqb,dc=mydomain,dc=com" \
-b "ou=Users,dc=mydomain,dc=com" \
"(pwdAccountLockedTime=*)" "+" "*"

There is another search attribute 1.1 - not to show any attributes:

ldapsearch -x -H ldap://ldap.mydomain.com -W \
-D "cn=jaqb,dc=mydomain,dc=com" \
-b "ou=Users,dc=mydomain,dc=com" \
"(pwdAccountLockedTime=*)" 1.1

sometimes useful in scripts.

Instalacja wtyczki Meeting Calendar for Redmine przebiega standardowo. Rozpakowałem do katalogu redmine_meeting_room_calendar. Potem

[root@jaqb redmine]# RAILS_ENV=production rake redmine:plugins:migrate

Po zainstalowaniu pojawia się dodatkowe pole w menu: Meeting rooms. Po kliknięciu pokazuje się.

Plugin not configured correctly!
See Administration -> Plugins -> Configuration

No to trzeba skonfigurować, ale wcześniej...

Do działania wymaga założenia osobnego projektu - ja go nazwałem Spotkania.

Następnie trzeba założyć nowy typ zagadnienia (Trackers » New tracker) który nazwałem Spotkanie i dopisać do niego standardowe pola Przypisany do (Assignee), Data rozpoczęcia (Start date) i Data oddania (Due date). Przepływ (workflow) skopiować z Błąd.

Założyć nowe Pola niestandardowe (Custom fields » Issues):

  • Początek spotkania oraz Koniec spotkania (dwa różne pola, nazwy nie mają znaczenia) jako lista z wartościami
    07:00, 07:30, 08:00, ..., 17:00
    
    (godziny wg. uznania, moim zdaniem spotkania nie powinny się zaczynać przed 09:00 ;-) dla nowo założonego typu zagadnienia (tracker) Spotkanie. Powinny mieć zaznaczone pola Wymagany (Required) i Przeszukiwany (Searchable).
  • Miejsce (nazwa nie jest istotna) jako lista z wartościami, np.:
    Pokój 13
    Duża sala na I piętrze
    Pokój spotkań
    
    Także dopinamy dla nowo założonego typu zagadnienia (tracker) Spotkanie. Powinny być zaznaczone pola Wymagany (Required) i Przeszukiwany (Searchable) oraz Atrybut filtrowania (Used as a filter).

Można sprawdzić (i ew. dopisać) czy dla Typu zagadnienia (tracker) Spotkanie są włączone pola Początek spotkania, Koniec spotkania i Miejsce oraz projekt Spotkania.

Teraz można konfigurować:

  • Project: Spotkania
  • Tracker: Spotkanie
  • Custom field 'Room': Miejsce
  • Custom field 'Start': Początek spotkania
  • Custom field 'End': Koniec spotkania

Teraz już można zająć się czymś ciekawszym niż praca.

I've just spend more than hour to find QuickRoute ... again. So I've decided to put this post just to remember.

If You want to display track on some specific map (i.e. orienteering map with control points) it's a solution. One disadvantage - it depends on .NET so it works only under MS Windows.

It's quite old (December 2011), but works even on Windows 8.

Wcześniej opisałem jak się pozbyć komunikatu

lmtpunix[1000]: IOERROR: fstating sieve script /var/lib/imap/sieve/u/user/defaultbc: No such file or directory

za pomocą RoundCubeMail z odpowiednią wtyczką. Jednak to rozwiązanie jest dla pojedynczych użytkowników. Rozwiązanie globalne jest następujące.

Trzeba przygotować zwykły plik tekstowy z zawartością np.:

/* empty script */

ważne, żeby był poprawnym skryptem Sieve. Niech się nazywa pusty.sieve. Następnie uruchamiamy konsolę, tu z domyślnym użytkownikiem cyrus:

sieveshell -u cyrus -a cyrus localhost

i wydajemy polecenie załadowania skryptu na serwer oraz ustawiamy go aktywnym:

> put pusty.sieve globalny
> activate globalny

dla pewności można to sprawdzić:

> list
globalny  <- active script

teraz można już wyjść z powłoki (poleceniem quit).

Wykonane zmiany widać również w systemie plikowym:

# ls -l /var/lib/imap/sieve/global/
total 8
lrwxrwxrwx 1 cyrus mail 11 Apr 14  2013 defaultbc -> globalny.bc
-rw------- 1 cyrus mail 20 Apr 14  2013 globalny.bc
-rw------- 1 cyrus mail 18 Apr 14  2013 globalny.script

Oczywiście nic nie stoi na przeszkodzie, żeby globalny plik nie był pusty, tylko wykonywał jakąś akcję.

Trzeba także zapewnić wpis w /etc/cyrus.conf w sekcji SERVICES wyglądający jakoś tak:

sieve         cmd="timsieved" listen="sieve" prefork=0

czy działa najłatwiej sprawdzić sprawdzając czy cyrus-master słucha na porcie 4190:

# netstat -ntlp | grep 4190
tcp        0      0 0.0.0.0:4190                0.0.0.0:*                   LISTEN      1443/cyrus-master

jak widać u mnie słucha.

Skoro już mam postawionego LDAP to przydałoby się wykorzystać ich również do logowania się do strony. Robi się to bardzo prosto.

W pliku ezpublish_legacy/settings/override/site.ini.append.php (dla starszych wersji bez ezpublish_legacy) w sekcji UserSettings trzeba dopisać

LoginHandler[]=LDAP

a następnie skonfigurować parametry połączenia. Ja skopiowałem plik settings/ldap.ini do settings/override/ldap.ini.append.php i tam zmieniłem:

LDAPServer=ldap.domain.local
LDAPBaseDn=ou--Users,ou--MyOrganization,dc--domain,dc--local
LDAPBindUser=someuser
LDAPBindPassword=somepassword

(w zasadzie w tym pliku wystarczy zrobić tylko powyższe wpisy w sekcji LDAPSettings) po przeładowaniu plików ini w panelu administracyjnym mogłem się zalogować kontem z LDAP.

Do działania oczywiście potrzebna jest obsługa LDAP w PHP, w CentOS pakiet nazywa się (cóż za niespodzianka!) php-ldap.

Po tym jak dorobiłem przycisk spam do Roundcube'a mogłem się łatwo pozbywać niechcianej poczty, ale ona cały czas zalegała w katalogu Junk. Przydało by się, żeby spam był kasowany po pewnym czasie. Do tego służy polecenie cyr_expire i parametr expire.

Najpierw sprawdziłem stan aktualny. Wydałem więc polecenie:

localhost> info user/jaqb/Junk
{user/jaqb/Junk}:
  condstore: false
  duplicatedeliver: false
  lastpop:
  lastupdate: 14-Oct-2013 21:29:32 +0200
  partition: default
  pop3newuidl: true
  sharedseen: false
  size: 3451803

teraz ustawiam kasowanie na 60 dni

localhost> mboxcfg user/jaqb/Junk expire 60

jak widać poniżej pojawił się nowy parametr

localhost> info user/jaqb/Junk
{user/jaqb/Junk}:
  condstore: false
  duplicatedeliver: false
  expire: 60
  lastpop:
  lastupdate: 14-Oct-2013 21:29:32 +0200
  partition: default
  pop3newuidl: true
  sharedseen: false
  size: 3451803

teraz trzeba sprawdzić, czy w pliku /etc/cyrus.conf jest wpis:

delprune      cmd="cyr_expire -E 3" at=0400

oczywiście można zmienić godzinę z 4:00 na jakąś inną.

Nowy dzień przywitał mnie oczyszczoną skrzynką.

SQUAT jest to system indeksowania poczty by wyszukiwanie wiadomości trwało szybciej - w sumie fajna sprawa, ale...

Serwer poczty oparty na Cyrus IMAP po zainstalowaniu krzyczał w logu, że:

SQUAT failed to open index file
SQUAT failed

naprawienie tego jest dość proste w pliku /etc/cyrus.conf w sekcji EVENTS dopisujemy dwie linijki:

squat cmd="squatter -r *" period=60
squat cmd="squatter -r *@*" period=60

które mówią, żeby serwer co 60 min poleceniem squatter przebudował indeksy.

Przy większych systemach trzeba by pewnie pomyśleć o wydajności i użyć przełączników -s lub/i -i.

Tak jak obiecałem w opisie ustawiania ograniczeń teraz pokażę jak zdjąć limit ze skrzynki.

Kasowanie wygląda podobnie jak zmiana wielkości tyle, że ustawiamy rozmiar kwoty na wartość none:

cyradm -user cyrus localhost
localhost> listquota user/jaqb
 STORAGE 37094/40960 (90.5615234375%)
localhost> setquota user/jaqb none
remove quota
localhost> listquota user/jaqb
  /
localhost> quit

Jak widać ograniczenie zniknęło.

Miałem ciekawy przypadek błędu w repozytorium. Od razu powiem, że bez kopi zapasowej nie udało by mi się go rozwiązać.

Kopia robocza na jednym komputerze - wszystko działa (latami). Po jakimś czasie zachciało mi się (akurat - po prostu musiałem) w nim grzebnąć, ale już na nowym sprzęcie i ... klops. Okazało się, że repozytorium jest uszkodzone, co gorsza, jak się później okazało, już na wersji 2 (błąd dysku ???).

Komunikaty błędu miałem różne. Komenda svn pokazywała:

svn: REPORT of '/svnprv/reponame/!svn/vcc/default': Could not read \
 chunk size: connection was closed by server (http://localhost)

w error_log apache'a było:

[error] [client 127.0.0.1] Provider encountered an error while \
 streaming a REPORT response.  [500, #0]
[error] [client 127.0.0.1] A failure occurred while driving \
 the update report editor  [500, #160004]

a polecenie svnadmin verify reponame zwracało:

svnadmin: Checksum mismatch while reading representation:
   expected:  10b6f87d95a8283b4dc96607a662c4de
     actual:  1865015a5837bc21ea73397ee68e1c44

Po przejrzeniu backup'ów (makaronizm, ale "kopia zapasowa" jest taka długa...) znalazłem taki który miał poprawnie zapisaną wersję drugą - z przed 2 lat! W ten sposób posunąłem się o 400% (z wersji 1 do 4 ;-) do pełni szczęścia trochę brakuje...

Niby coś-tam działało, bo WebSVN ładnie pokazywał historie i doszedłem do tego, że mogę ściągać diff'y między różnymi wersjami, np.:

svn di http://localhost/svn/reponame@7 \
       http://localhost/svn/reponame@15

W ten sposób dowiedziałem się, że tylko wersja 2 jest uszkodzona. Niestety próby odzyskania reszty danych z bieżącego repozytorium nie dawały pozytywnych rezultatów (testowałem na różnych wersjach):

svnadmin dump -r3 reponame
svnadmin: Checksum mismatch while reading representation:
   expected:  959148e046aafa5f51db215c9ee0796d
     actual:  98824bfc23034f920d603d42a0810843

Oczywiście działało dla wersji 0 i 1. Kluczem okazał się przełącznik --incremental !

svnadmin dump -r3 --incremental reponame
* Dumped revision 3.

Teraz już poszło gładko. Trzeba założyć nowe repozytorium i załadować do niego dane z kopii (była spakowana bzip2):

svnadmin create reponame-new
bzcat reponame-2011-09-25.dump.bz2 | svnadmin load reponame-new
...
------- Committed revision 4 >>>

ustalić numer ostatniej wersji, powiedzmy 45 (żeby nie było równo) i wtedy (jak widać wersję 4 już miałem):

for x in `seq 5 45` ; do
    svnadmin dump --incremental -r $x reponame \
   | svnadmin load reponame-new;
done

... no trochę to trwało, ale za to pełen sukces.

Teraz wystarczy skasować stare i zmienić nazwę "nowego":

rm -rf reponam
mv reponame-new reponame

Ładowane dane były do pustego repozytorium, więc UUID się nie zmienił.

Teraz trzeba poprawić skrypt, żeby po pierwsze wychwytywał błędy przy robieniu zrzutu (dump) i może dodatkowo wykonywał jeszcze zrzut ostatnich np. 10 wersji...

Just my blog...

Mon Di Mi Do Fr Sa So
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30