Zakup nowego komputera spowodował to, że moim domu znajdują się dwa działające komputery, niestety łącze od anteny było jedno, więc tylko jeden komputer mógł być podłączony do Internetu. Oczywiście mógłbym ustanowić jeden komputer serwerem, ale mijałoby się to z celem, bo musiałby być włączony, gdy chciałbym skorzystać z Internetu z drugiego komputera. Rozwiązaniem był zakup routera z funkcją WISP (możliwość dzielenia łącza opartego na antenie). Zakupiłem Techniclana WAR-54GS. Miałem trochę z nim problemów, jednak one były z winy routera.
Słabsza karta radiowa w routerze
Okazało się, że router ma słabszą kartę radiową i tak moja radiówka pokazywała zasięg 25%, a router 10%, problemem było jednak to, że przy 10% router nie chciał się połączyć przez PPPoE. Trzeba było zmienić pozycję anteny (ponad 1 metr wyżej się znalazła) i teraz radiówka z komputera pokazywała zasięg 40%, a router 25%, co było wystarczające.
Zepsute firmware
Chciałem sobie zaktualizować firmware na najnowsze. Problem w tym, że zamiast ściągnąć dla Techniclana WAR-54GS ściągnąłem dla Techniclana WAR-54G i zainstalowałem, to go doprowadziło do stanu, w którym nie był użyteczny. Dobrze, że komuś chciało się stworzyć oprogramowanie do przywracania oryginalnego firmware, na stronie http://approsoftware.com/pl/podstrona-recovery.html jest napisane, jak przywrócić oprogramowanie. Zastosuję się do ich wskazówek, nie będę pisał jak przywrócić oryginalnego oprogramowanie, jedynie dodam, że przy Techniclanie WAR-54GS przy transmisji TFTP podpinamy do LAN3.
MTU
Maximum Transmission Unit (MTU) – rozmiar największego datagramu (w bajtach), który można przekazać przez warstwę protokołu komunikacyjnego. MTU zmniejsza się w celu uniknięcia fragmentacji. W moim routerze MTU było ustawione na 1496, a na moim Linuksie na 1500 i to powodowało, że żadne strony https, jabber - prawie wszystko z szyfrowaniem SSL nie chciało mi działać oraz ftp nie za bardzo działało. Metodą prób i błędów można dojść do optymalnego MTU. Początkowo ustawmy w routerze i komputerze MTU 1400 i sprawdźmy działanie stron https. Jeśli strony https działają to MTU zwiększamy o 20, jeśli nie to zmniejszamy o 20 i dalej sprawdzamy działanie stron https. U mnie optymalne MTU to 1480.
Człowiek robi męczące rzeczy z dwóch powodów. Pierwszy powód to czysta ciekawość, a drugi powód to konieczność. Otóż mój kolega posiada Windowsa i chce testować mój program do nauki słówek Konkord, też lubi tak jak uczyć się języków obcych. Niestety nigdy nic nie kompilowałem na Windowsie, musiałem opierać się na skromnych informacjach z Internetu, a najlepsze jest to, że nie było nic po polsku.
MinGW kontra Cygwin
Przechodząc do sedna sprawy, na moim Debianie kompiluję swój program gcc, gdy kiedyś na Windowsie pracowałem, programy kompilowałem MinGW dołączonym do środowiska developerskiego DevC++ (lecz wtedy nie wiedziałem, że używam jakiegoś MinGW). Lecz teraz wiedziałem, że chcą budować aplikację linuksową na Windowsa, mam dwie możliwości, albo zainstalować Cygwina - implementację standardu POSIX dla systemów z rodziny Windows, albo użyć kompilatora MinGW - gcc przeportowanego na systemy z rodziny Windows.
Cygwin zapewniał by mi to, że nie musiałbym zmieniać kodu programu, ani przekompilowywać zewnętrznych bibliotek, których w nim używam, lecz zmusiłbym również tym użytkowników do instalacji Cygwina, a oni raczej nie chcieli by instalować takiego kombajna dla jednego kilkudziesięcokilobajtowego (bez wkompilowanych bibliotek) programu.
MinGW tworzy mi program z rozszerzeniem .exe, który będzie działał na każdym Windowsie i będzie samowystarczalny. Jednak w tym wypadku będę musiał przekompilować biblioteki i je dołączyć do program i czasem zmienić kod programu.
Zdecydowałem się na drugie rozwiązanie, dużo czasu poświęciłem na wstępne przygotowywania, czyli na to, żeby zainstalować i skompilować to, co będzie mi potrzebne do skompilowania programu. Nie żebym aż tak długo się zastanawiał, lecz te pakiety trochę ważą.
Znalazłem na Hard Core Security Lab artykuł o tworzenie superbezpiecznych haseł i to tylko przy użyciu żółtej karteczki. Niestety ciężko jest stworzyć sensowną żółtą karteczkę, dlatego napisałem program, który pomógłby mi w tym. Jednak przed wgłębianiem się dalej w mój wpis proponuję przeczytać HCSL - Superbezpieczne hasła zapisane na żółtej karteczce.
Pewnie artykuł się spodobał, ale mam kilka uwag, część jest w komentarzach innych użytkowników portalu. Po pierwsze lepiej stosować karteczkę, np. 10x10. Wtedy można stosować już jakąś lepszą metodą, kwadrat, prostokąt, lub kształt jakiejś literki, ruchy z szachów itd. Po drugie wygenerowane hasło pierwsze przepisywałbym z karteczki, a później nauczyłbym się na pamięć i karteczkę wywalił.
A jeśli komuś już się nie chce tak strasznie wymyślać znaków, jakie mógłby wpisać na tą karteczkę, to proponuję skompilować to:
SaaS, czyli oprogramowanie jako usługa - internetowe serwisy takie jak desktopowe programy, np. Google Docs. Oznacza to, że nie mam dostępu do kodu programu, a nawet jakbym miał, to nie mógłbym go edytować, bo wpłynęłoby to na innych użytkowników. Nie widziałbym czy oprogramowanie mnie inwigiluje czy nie, wyobraźmy sobie, że wkracza ABW i każe zamieścić funkcję w edytorze tekstu (zmiana natychmiastowo objęła by wszystkich użytkowników), która będzie ich informowała czy ktoś wpisał np. "cenzura". Ze 100% pewnością mogę stwierdzić, że byłoby notowane, kto i kiedy używał programu.
Kolejną przeszkodą jest to, że byłaby pojemność dysku by się marnowała, a sieć byłaby strasznie obciążona, a dużych korzyści jak na razie z tego nie widać. Jedyną korzyścią może być to, że np. mając zainstalowany system pracujący jak przeglądarka i dane na serwerze nie byłoby dużej różnicy czy korzystalibyśmy z laptopa czy komputera stacjonarnego. Ale to zniknie, gdy upowszechni się IPv6.
Wyobraźmy sobie, że mamy jakieś elektroniczne urządzenie, takie coś w rodzaju routera, które mogłoby uruchamiać inne urządzenia w całym mieszkaniu i byłoby z nimi połączone przez sieć. Jesteśmy w pociągu i chcemy uzyskać przez laptopa dostęp do danych na dysku naszego komputera. No to wpisujemy adres tego naszego routera w przeglądarce, wpisujemy hasło i nazwę użytkownika, włączamy nasz komputer, łączymy się za pomocą zdalnego pulpitu z naszym komputerem (gdy już się włączy), kopiujemy te dane, wyłączamy komputer. I po co nam w tym wypadku dane na jakimś zewnętrznym serwerze.
Gdy ktoś się zastanawia jak postawić stronę lub udostępniać usługi anonimowo w sieci Tor, tzw. „pedofilskiej cebulowej sieci”, to odpowiedź znajdzie poniżej. Sam z tego nie korzystam, bo nie jest mi to w tej chwili do niczego potrzebne, jednak instrukcja stworzona przy pocie mózgu, dzięki której można dostosować Apache do Tora, powinna się komuś przydać.
Czy zastanawiałeś się kiedyś jak za pomocą prostych narzędzi zrobić skrypt, który będzie automatycznie robił codziennie kopię zapasową wybranych przez Ciebie folderów na dysku? Taki automat można zrobić z prostych narzędzi dostępnych w każdej dystrybucji linuksowej: Tara i Anacrona. Trochę poszukałem i znalazłem posta na debian.linux.pl, trochę dodałem od siebie i wyszedł mi dość prosty i użyteczny skrypt.
Wiem, że nie każdemu przyda się informacja jak zdobyć własny adres IPv6, bo to co daje własny adres IPv6 oferuje już zewnętrzny adres IPv4 albo po prostu komuś wystarcza zwykły wewnętrzny adres IPv4. Jednak ja nie do tych osób kieruje ten post – kieruje go to osób, które nie wiedzą, co to jest IPv6 i do tych, którym nie udało się zdobyć zewnętrznego adres IP. Jednak zanim przejdziesz do odpowiedzi na tytułowe pytania, wypadałoby żebyś poznał trochę teorii.
Czy zastanawiałeś się kiedyś, jak wpisać z klawiatury znaki: „, ”, —, ≠, π, §? Ja musiałem — dzięki Biblionetce, więc stworzyłem prawidziwy polski układ klawiatury. Dostałem tam recenzje do zwrotu, bo nie zawierała polskiego cudzysłowu, tylko angielski. Oczywiście można wstawiać znaki specjalne z menu w OpenOffice Writer lub Microsoft Office Word, jednak zawsze to będzie dłuższe niż wpisanie odpowiedniego znaku z klawiatury. Dodatkowe znaki uzyskałem, usuwając zduplikowane lub niepotrzebne znaki na klawiaturze, bo na co komu potrzebne są znaki run lub znak dolara pod dwoma skrótami.
Szukając informacji o tym, jak się modyfikuje układ klawiatury, trafiłem na wpis „Uwaga joggerowi linuksiarze” na blogu „mrUwka okiem” oraz na wpis „Przypisywanie własnych znaków specjalnych (Unicode) do skrótów klawiaturowych” na stronie http://nerdblog.pl. Niestety nie spodobała mi się modyfikacja mrUwka, ale korzystając z jego patcha, wiki i komentarzy użytkowników na obu tych blogach udało mi się stworzyć układ, który będzie mi odpowiadał.
Opis modyfikacji układu:
ZNAK
NOWA POZYCJA
STARA POZYCJA
ZASTĄPIONE
POWODY
leftsinglequotemark ‘
AltGr-Shift-Tilde
brak
notsign ¬
notsign jest dostępny pod AltGr-Tilde
cent ¢
AltGr-Shift-4
brak
dollar $
dollar jest dostępny pod Shift-4
EuroSign €
AltGr-5
brak
onehalf ½
onehalf przeniesiono na AltGr-7
onehalf ½
AltGr-7
AltGr-5
braceleft {
braceleft jest dostępny pod Shift-AD11
U00A7 §
AltGr-8
brak
bracketleft [
bracketleft jest dostępny pod AD11
guillemotleft «
AltGr-9
brak
bracketright ]
bracketright jest dostępny pod AD12
guillemotright »
AltGr-0
brak
braceright }
braceright jest dostępny pod Shift-AD12
endash –
AltGr-Minus
brak
backlash
backlash jest dostępny pod swoim klawiszem
emdash —
AltGr-Equal
brak
dead_cedilla ņŗ
dead_cedilla przeniesiona pod AltGr-J
notequal ≠
Shift-AltGr-Equal
brak
dead_ogonek ąǫę
dead_ogonek jest dostępny pod swoim klawiszem
doublelowquotemark „
AltGr-Q
brak
at @
at jest dostępny pod Shift-2
singlelowquotemark ‚
Shift-AltGr-Q
brak
Greek_OMEGA Ω
Zamiast Greek_OMEGA Greek_omega zostało dodane pod Shift-AltGr-D
leftsinglequotemark został przeniesiony pod AltGr-Shift-Tilde
oe œ
AltGr-B
brak
rightdoublequotemark ”
rightdoublequotemark został przeniesiony pod AltGr-W
infinity ∞
Shift-AltGr-B
brak
rightsinglequotemark ’
rightsinglequotemark został przeniesiony pod Shift-AltGr-W
ellipsis …
AltGr-,
brak
nic
nobreakspace mama i tata
AltGr-space
brak
nic
Aby zmodyfikować układ klawiatury, ściągamy patch, a następnie wydajemy w katalogu, gdzie jest patch, jako root polecenie: patch /usr/share/X11/xkb/symbols/pl polski.patch, a później: setxkbmap.
Jeszcze myślę nad dodaniem greckich alfa i beta oraz kilku innych. Musiałbym usunąć kilka innych znaków i mam już kandydatów. Później zajmę się porządkowaniem układu.
Miałem ostatnio malutki problem, dotyczył on brzydkich ostrzeżeń występujących przy starcie systemu. Nie usuwałem go, bo nie za bardzo miałem kiedy. Dzisiaj się za niego wziąłem. Ostrzeżenia wyglądały tak:
SYSFS{}= will be removed in a future udev version, please use ATTR{}= to match the event device, or ATTRS{}= to match a parent device, in /etc/udev/rules.d/56-hpmud_support.rules:10
BUS= will be removed in a future udev version, please use SUBSYSTEM= to match the event device, or SUBSYSTEMS= to match a parent device, in /etc/udev/rules.d/025_logitechmouse.rules:1
Trochę kombinowałem i jakoś to usunąłem, ale okazuje się, że niepotrzebnie, bo wystarczy wydać jako root polecenie: dpkg-reconfigure udev.
Podczas wprowadzenia zmian i testowania programu do nauki słówek wykryłem błąd, który nie był zwykłą literówką, lecz błędem w strukturze programu, pojawiającym się raz na ileś. Taki błąd jest najgorszy, bo trudno odgadnąć, dlaczego to program się wyspuje, jest trudny do uchwycenia. Z tym błędem wiązało się też, że rozwiązując go, musiałem stanąć przed dylematem, które rozwiązanie wybrać.
Zaprezentuję przykład, gdzie będzie ten sam błąd
#include
#include
using namespace std;
int main() {
vector elements;
int **wsk_to_elements = new int*[10000];
for(int i = 0; i < 10000; i++) {
elements.push_back(i);
wsk_to_elements[i] = &elements[i];
}
for(int i = 0; i < 10000; i++) {
elements.push_back(i);
}
vector elements2;
for(int i = 0; i < 100; i++) {
elements2.push_back(i+10000);
}
for(int i = 0; i < 10000; i++) {
cout << *wsk_to_elements[i] << endl;
}
return 0;
}
Niby wszystko w porządku, ale… po skompilowaniu i uruchomienu raczej zobaczymy, że 100 pierwszych wskaźników z tablicy wsk_to_elements wskazuje nam na jakieś elementy, których wartość jest większa od 10000, czyli chyba elementy vectora elements2. Dlaczego? Vector to taki obiekt, który przechowuje nam elementy, pozwala nam dodawać i usuwać elementy w każdej chwili, ale też stara się zachować ciągłość w pamięci, dlatego gdy przy dodaniu 1000 elementu vector widzi, że na nie ma już miejsca na prawo, to przenosi wszystkie elementy do takiego miejsca w pamięci, gdzie będzie mógł dodać ten 1000 element. Krótko mówiąc, nie gwarantuje nam, że elementy będą cały czas w tym samym miejscu w pamięci. Można się przed tym zabezpieczyć rezerwując miejsce na x elementów, dając mu x w konstuktorze, ale przecież nie zawsze wiemy, jaki rozmiar nam będzie potrzebny. Dlatego użycie wskaźników na elementy vectora jest samobójstwem.
I właśnie taki błąd miałem w programie i miałem do wyboru kilka możliwości rozwiązania problemu:
I. Posłużyć się iteratorami, ale w praktyce wyglądałoby to tak:
class SingleWord {
//…
vector::iterator something;
//…
}
class Kurs {
//…
vector singleWords;
//…
Trochę głupio uzależniać klasę SingleWord, która ma być niezależna od klas ją wykorzystujących. W porównaniu do drugiego rozwiązania zachowałbym taki sam czas dostępu do elementów.
I rozwiązanie nie jest rozwiązaniem, bo ma te same wady, co rozwiązanie oparte na wskaźnikach. Rozwiązaniem podobnym do tego opartego na iteratorach byłoby:
class SingleWord {
//…
unsigned int something; //numer słowa w vectorze
//…
}
class Kurs {
//…
vector singleWords;
//…
To rozwiązanie ma jedną zasadniczę wadę: klasa SingleWord jest zależna od klasy ją wykorzystującej Kurs.
II. W samym vectorze posłużyć się wskaźnikami, wyglądałoby to tak:
class SingleWord {
//…
SingleWord *something;
//…
}
class Kurs {
//…
vector singleWords;
}
W tym rozwiązaniu klasa SingleWord zachowuje swoją niezależność, ale jest trochę wolniejszy dostęp do elementów z klasy Kurs, bo odbywa się przez wskaźniki. To, że w vectorze są wskaźniki, ma jeszcze inną zaletę, gdy vector będzie zmieniał swoje miejsce w pamięci, nie będzie kopiował ponad 100 bitowego elementu klasy SingleWord, lecz 64 bitowe wskaźniki. Oczywiście nie należy zapomnieć, że tym przypadku musimy samodzielnie zwalniać pamięć, vector.erase() usunie tylko wskaźniki, elementy, na które wskazywały zostaną.
Wybrałem II rozwiązanie, lecz zaskutkowało to tym, że musiałem zmieniać działanie wielu funkcji. Przy okazji tych zmian, stwierdziłem, że gdy chcę odmówić prawa do zmieniania elementu, lepiej zwrócić "wskaźnik na stały element" niż "element", program będzie szybciej działał, ponieważ wskaźnik jest tylko 64 bitowy. Zmieniłem… lecz mocno się zdziwiłem, bo funkcja wygląda tak: