Kolokwium poprawkowe odbędzie się w czwartek, 27 marca 2008 r. o godzinie 16:00 w sali 136.


Zadania:

  1. Napisać program wyświetlający w czytelnej postaci swoją nazwę i wszystkie argumenty wiersza poleceń, np.:

      $ python program.py -a 'Cos tam'
      nazwa programu: './program.py'
      argument nr 1: '-a'
      argument nr 2: 'Cos tam'
    			
  2. Napisać program, który dla każdej z zadanych w parametrach wiersza poleceń zmiennych środowiskowych wyświetli w osobnym wierszu napis postaci NAZWA=WARTOŚĆ, np.

      $ env ABC=abc ./program.py HOME ABC
      HOME=/home/mklisow
      ABC=abc
    			

    Jeżeli któraś z wymienionych zmiennych nie jest zdefiniowana, to program ma tylko wyświetlić informację o tym na standardowym wyjściu błędów i zakończyć działanie z kodem błędu będącym niewielką liczbą całkowitą większą od zera.

  3. Napisać program wyświetlający na standardowym wyjściu plik zadany w wierszu poleceń.

  4. Napisać program kopiujący plik zadany pierwszym parametrem wiersza poleceń na plik zadany drugim parametrem wiersza poleceń.

  5. Pliki mp3 oprócz muzyki mogą zawierać dodatkowe informacje o utworze w postaci etykiet (tagów) typu ID3v1 lub ID3v2. Etykieta ID3v1 zajmuje ostatnie 128 bajtów w pliku i zawiera następujące informacje (w tej kolejności):

    Pola są uzupełniane znakami pustymi (ASCII 0) do wymaganej długości.

    Napisać program, który dostaje w  parametrze nazwę pliku. Jeżeli plik zawiera etykietę ID3v1 to program wyświetla informacje o utworze.

  6. Napisać program dostający w parametrze wiersza poleceń nazwę katalogu i wyświetlający na standardowym wyjściu wszystkie podkatalogi znajdujące się bezpośrednio w nim - każdy w osobnym wierszu. W przypadku jakiegoś błędu odpowiedni komunikat powinien zostać wyświetlony na standardowym wyjściu błędów i program powinien zakończyć się z kodem błędu różnym od zera.

  7. Zmodyfikować program z zadania nr tak, aby w przypadku otrzymania opcji -r program wyświetlał także (najlepiej z odpowiednim wcięciem) podkatalogi wszystkich wyświetlanych katalogów. Np.

      $ ./my_ls.py kat
      kat1
      kat2
        podkat21
        podkat22
      kat3
        podkat31
          podpodkat311
        podkat32
          podpodkat321
          podpodkat322
      kat4
      
    
  8. Napisać program wyświetlający na standardowym wyjściu informację o rozmiarze pliku zadanego w parametrze wiersza poleceń, np.

      $ ./rozm.py plik.txt
      plik.txt   2345678
    
    Program obsługuje następujące opcje:

  9. Napisać program tworzący w bieżącym katalogu plik FIFO o nazwie zadanej w parametrze wiersza poleceń (o ile taki plik jeszcze nie istnieje - w takim wypadku program ma wyświetlić odpowiedni komunikat na standardowym wyjściu błędów i zakończyć się z kodem wyjścia większym od zera), czeka aż jakiś program otworzy ten plik do zapisu, a następnie wypisuje na standardowym wyjściu wszystko co zostanie zapisane do tego pliku aż do czasu, gdy plik nie będzie już otwarty do zapisu przez żaden program. Po zakończeniu odczytu program usuwa plik FIFO.

  10. Napisać dwa programy (klient i serwer) komunikujące się za pomocą dwóch plików FIFO. Oba programy dostają w pierwszych dwóch parametrach wiersza poleceń nazwy obu plików. Pierwszy z nich służy do przesyłania danych od klienta do serwera, a drugi w odwrotną stronę. Serwer dostaje ponadto w trzecim parametrze wiersza poleceń nazwę pliku - słownika (słownik ma postać pliku tekstowego - w każdym wierszu jest osobny wyraz). Klient wysyła serwerowi kolejne wczytane ze standardowego wejścia słowa (każde w osobnym wierszu), a następnie odbiera odpowiedź zawierającą informację o tym, czy zadane słowo jest w słowniku. Jeżeli nie, to wyświetla na standardowym wyjściu odpowiedni komunikat.

  11. Napisać program dostający w parametrach wiersza poleceń dwa pliki FIFO. Program otwiera oba do odczytu, a następnie wyświetla na standardowym wyjściu to co odczyta z tych plików. Dane z plików mają być odczytane i wyświetlone od razu, gdy jest to możliwe (a nie np. najpierw całe dane z jednego pliku, a później całe dane z drugiego) - w rozwiązaniu skorzystać z funkcji select lub z wątków. Program kończy działanie, gdy żaden z plików nie będzie już otwarty do zapisu.

  12. Napisać program służący do rozmowy za pomocą plików FIFO. Jeżeli program ma dwa parametry wiersza poleceń to oznaczają one nazwę plików FIFO i program:

    Jeżeli program ma jeden parametr to oznacza on nazwę pliku FIFO i program:

    Żeby nazwiązać rozmowę trzeba uruchomić dwa programy - jeden z jednym, drugi z dwoma parametrami. Pierwszy parametr obu programów musi wskazywać na ten sam plik FIFO. Następnie każdy z tych programów równocześnie:

    Program kończy działanie po odczytaniu końca pliku ze standardowego wejścia lub zakończeniu działania (i zamknięciu plików) przez drugi program.

    Napisać dwie wersje programu: jedną korzystającą z wątków, a drugą z funkcji select.

  13. Napisać program pobierający od użytkownika nazwy domenowe komputerów i wyświetlający ich adresy IP lub informację o błędzie. Program kończy działanie po wczytaniu pustego wiersza. Np (wiersze pogrubione są wierszami wpisanymi przez użytkownika).

    $ ./dns2ip.py
    hektor.umcs.lublin.pl
    212.182.57.178
    localhost
    127.0.0.1
    google.con
    Nie znaleziono hosta.
    google.com
    72.14.207.99
    
    
  14. Napisać program łączący się z zadanym serwerem (pierwszy argument wiersza poleceń - adres IP lub domenowy) na zadanym porcie (drugi argument wiersza poleceń) i wyświetla na standardowym wyjściu wszystkie dane otrzymane od serwera (sam nic nie wysyła). Program kończy działanie po zakończeniu połączenia przez serwer. Przykład użycia:

    $ ./klient.py matrix.umcs.lublin.pl 13
    Thu Nov  2 00:00:36 2006
    
  15. Zmodyfikować program z zadania tak, aby przed odczytaniem danych z serwera program wysłał mu dane wczytane ze standardowego wejścia (aż do wczytania końca pliku). Przykłady użycia (wiersze pogrubione są wierszami wpisanymi przez użytkownika):

    $ ./klient.py 212.182.57.178 79
    root
    Login: root                             Name: root
    Directory: /root                        Shell: /bin/bash
    Last login Thu Dec 21 15:18 (CET) on tty1
    New mail received Fri Mar  9 10:33 2007 (CET)
         Unread since Fri Mar  9 07:40 2007 (CET)
    
    $ ./klient.py liza.umcs.lublin.pl 80
    GET / HTTP/1.1
    Host: liza.umcs.lublin.pl
    
    HTTP/1.1 200 OK
    Date: Fri, 09 Mar 2007 09:39:35 GMT
    Server: Apache/1.3.37 (Unix) PHP/5.2.0 with Suhosin-Patch mod_ssl/2.8.28
    OpenSSL/0.9.7e-p1
    Last-Modified: Thu, 11 Aug 2005 10:03:26 GMT
    ETag: "108b41-69-42fb226e"
    Accept-Ranges: bytes
    Content-Length: 105
    Content-Type: text/html
    
    <HTML>
    <HEAD>
    <META HTTP-EQUIV="refresh" content="0;url=liza/index.html">
    </HEAD>
    <BODY>
    </BODY>
    </HTML>
    
  16. Zmodyfikować program z zadania tak, aby zamiast numeru portu można było podać nazwę usługi (np. „http”). Przykład użycia (wiersze pogrubione są wierszami wpisanymi przez użytkownika):

    $ ./klient.py hektor.umcs.lublin.pl finger
    root
    Login: root                             Name: root
    Directory: /root                        Shell: /bin/bash
    Last login Thu Dec 21 15:18 (CET) on tty1
    New mail received Fri Mar  9 10:33 2007 (CET)
         Unread since Fri Mar  9 07:40 2007 (CET)
    
  17. Napisać program dostający w parametrze wiersza poleceń numer portu, na którym ma on oczekiwać na połączenia od klientów. Po zaakceptowaniu połączenia program wyświetla na standardowym wyjściu adres IP i nazwę domenową klienta (o ile taka jest), który się połączył, zamyka to połączenie i oczekuje na kolejne.

  18. Zmodyfikować zadanie tak, aby na standardowym wyjściu wywietlała się też informacja, który raz połączono się z tego adresu.

  19. Napisać program umożliwiający rozmowę przez sieć pomiędzy dwoma uzytkownikami. Program może być uruchomiony z jednym lub dwoma argumentami wiersza poleceń. Jeżeli uruchomiony jest z jednym parametrem (serwer), to oznacza on port, na którym program nasłuchuje na połączenie. Jeżeli z dwoma (klient) to oznaczają one adres komputera (IP lub domenowy) i numer portu, z którym program ma się połączyć. Po nawiązaniu (lub zaakceptowaniu) połączenia programy na zmianę wysyłają wiadomości wczytane ze standardowego wejścia (po jednym wierszu) i wyświetlają na standardowym wyjściu odpowiedź. Pierwsza wiadomość wysyłana jest przez klienta. Program kończy działanie, gdy ze standardowego wejścia wczytany zostanie koniec pliku lub rozmówca zamknie połączenie.

  20. Praca domowa nr 1 (termin oddania: 30.11.2007)

    Program z zadania przerobić tak, aby wiadomości nie musiały być wysyłane na zmianę, tzn. program musi cały czas być gotowy zarówno do odebrania danych od rozmówcy i wyświetlenia ich na standardowym wyjściu, jak i do pobrania danych od użytkownika ze standardowego wejścia i wysłania ich do rozmówcy (można użyć funkcji select() lub wątków).

    Program ma obsługiwać opcję „-f”. Użycie tej opcji powoduje zapisywanie całej rozmowy do pliku będącego argumentem tej opcji. Każdy wiersz pliku z zapisem rozmowy rozpoczyna się od ciągu znaków „1: ” (wiersz wczytany od użytkownika) lub „2: ” (wiersz odebrany od rozmówcy).

    Wszystkie komunikaty o błędach programu powinny być wyświetlone na standardowym wyjściu błędów (a nie standardowym wyjściu). W przypadku błędu powodującego zakończenie programu kod błędu zwrócony przez program powinien być niewielką liczbą całkowitą większą od zera. Wszystkie wyjątki powinny być przechwycone i w miarę możliwości sensownie obsłużone.

  21. Napisać zestaw dwóch programów (klient i serwer) umożliwiający użytkownikowi pobranie plików ze zdalnego komputera.

    Żądanie przesyłane od klienta do serwera składa się z pojedynczego wiersza zawierającego nazwę pliku. Odpowiedź pozytywna składa się z wiersza zawierającego napis 'ok' oraz z ciągu bajtów (przesyłany plik). Po przesłaniu całego pliku serwer zamyka połączenie. Odpowiedź negatywna składa się z jednego wiersza zawierającego napis 'nf'. Wielkość liter w pierwszym wierszu odpowiedzi nie ma znaczenia. Wiersze żądań lub odpowiedzi zakończone są znakiem o kodzie 10 ('\n').

  22. Zmodyfikować protokół z zadania nr w następujący sposób:

    Zmodyfikowany ma być tylko protokół. Funkcjonalność programów pozostaje bez zmian. Jeżeli liczba plików w odpowiedzi jest mniejsza niż w żądaniu, klient powinien wysłać kolejne żądanie dotyczące pozostałych plików.

    Przykładowe żądanie może wyglądać tak:
    program.py
    niedostepny_plik
    pliczek.txt
    bardzo_duzy_plik.exe
    info.txt
    
    
    a  przykładowa odpowiedź na nie może wyglądać tak:

    3
    ok 146
    #!/usr/bin/python
    
    import sys
    
    try:
    	print sys.argv[1]
    except IndexError:
    	print >> sys.stderr, "'%s': brak argumentu" % sys.argv[0]
    	sys.exit(1)
    nf
    ok 52
    To jest plik tekstowy,
    którego rozmiar to 52 bajty.
    

  23. Napisać serwer współbieżny serwer echa (odsyłający z powrotem klientom otrzymane od nich dane).

  24. Zmodyfikować program z zadania nr tak, żeby serwer wysyłał dane otrzymane od dowolnego klienta każdemu podłączonemu do niego klientowi.

  25. Zmodyfikować program z zadania nr tak, żeby serwer wyświetlał na standardowym wyjściu diagnostycznym informacje o podłączeniu lub odłączeniu się klienta (adres IP i numer portu klienta). Ponadto serwer wyświetla na standardowym wyjściu wszystkie dane otrzymane od klientów oraz wysyła wszystkim połączonym klientom dane wczytane ze standardowego wejścia.

  26. Napisać program używający protokołu HTTP/1.1 dostający w parametrze wiersza poleceń url postaci

    http://adres_komputera[:nr_portu][zasób]
    (np. http://www.google.com, http://matrix.umcs.lublin.pl:8888/index.html), wysyła serwerowi żądanie HEAD dotyczące tego zasobu i wyświetla na standardowym wyjściu kod i komunikat z pierwszego wiersza odpowiedzi serwera (np. „200 OK”, „404 Not Found”). Jeżeli w url-u nie został podany port, to przyjmowany jest port 80, a jeżeli nie ma podanego zasobu, to przyjmowany jest „/

    Protokół HTTP:
  27. Zmodyfikować program z zadania nr tak, żeby wyświetlał również (o ile informacje te znajdują się w odpowedzi serwera) informacje o czasie ostatniej modyfikacji zasobu i o rodzaju oprogramowania serwera.

  28. Napisać klienta protokołu HTTP/1.1 służącego do pobrania jednego pliku (URL zadany w wierszu poleceń).

  29. Zmodyfikować program z zadania nr tak, aby nie pobierał pliku jeżeli w jego katalogu roboczym istnieje plik o nazwie zadanej w URL-u nowszy niż na serwerze (użyć w nagłówku żądania pola „If-Modified-Since”).

  30. Napisać prosty iteracyjny serwer http udostępniający pliki ze swojego katalogu roboczego. Serwer wysyła pliki o rozszerzeniach „txt”, „htm”, „html”, „pdf”, „ps”, „gif”, „jpeg” z odpowiednim typem MIME wysłanym w polu nagłówkowym „Content-Type” (typ MIME dobrać tylko na podstawie rozszerzenia, a nie sprawdzania zawartości pliku). Wszystkie pozostałe wysyłane są jako typ „application/octet-stream”. Po wysłaniu pliku serwer zamyka połączenie (zaznacza to też odpowiednim polem w nagłówku).

  31. Zmodyfikować program z zadania nr tak, aby w przypadku uzycia przez klienta protokołu HTTP/1.1 serwer oczekiwał na dalsze żądania za pomocą tego samego połączenia. W takim przypadku serwer wysyła w nagłówku także rozmiar pliku.

  32. Napisać prostego klienta protokołu HTTP służącego do pobrania z serwera jednego pliku. Plik do pobrania jest zadany jako pierwszy argument wiersza poleceń, który ma format URL-a w następującej postaci

        http://host[:port][abs_path]
    

    gdzie port (port, na którym nasłuchuje serwer) domyślnie ma wartość 80, a host jest nazwą domenową lub adresem IP serwera. Obsłuzyć odpowiednio odpowiedzi serwera 301 i 302 (tzn. pobrać pliki ze wskazanej lokalizacji). Plik powinien być zapisany pod nazwą będącą ostatnim elementem ścieżki (abs_path). W przypadku pominięcia ścieżki przyjmowana jest ścieżka „/” a plik zapisywany jest pod nazwą „index.html” (jeżeli typ pliku jest inny niż „text/html” program pyta użytkownika pod jaką nazwą zapisać plik). W przypadku użycia opcji „-s” plik zapisywany jest pod nazwą będącą argumentem tej opcji. W przypadku odpowiedzi innej niż 2xx3xx wyświetlić odpowiedni komunikat o błędzie. W przypadku użycia opcji -v program wypisuje na standardowym wyjściu informacje o wszystkich przekierowaniach.

    Wszystkie komunikaty o błędach programu powinny być wyświetlone na standardowym wyjściu błędów (a nie standardowym wyjściu). W przypadku błędu powodującego zakończenie programu kod błędu zwrócony przez program powinien być niewielką liczbą całkowitą większą od zera. Wszystkie wyjątki powinny być przechwycone i w miarę możliwości sensownie obsłużone.

  33. Napisać klienta protokołu POP3 pobierającego od użytkownika login oraz hasło i wyświetlającego liczbę listów oraz nadawców i tematy wszystkich wiadomości znajdujących się w skrzynce. Adres serwera (domenowy lub IP) zadany jest pierwszym parametrem wiersza poleceń. Opcjonalny drugi parametr oznacza numer portu (domyślnie używany jest port 110). Do pobrania hasła można użyć funkcji getpassmodułu getpass.

  34. Zmodyfikować program z zadania tak, żeby użytkownik po obejrzeniu tematów i nadawców wiadomości miał możliwość wyświetlenia treści wybranej wiadomości.

  35. Napisać program umożliwiający użytkownikowi wysłanie maila za pomocą protokołu SMTP. Program dostaje jeden parametr - adres serwera SMTP, którego należy użyć i ewentualnie po dwukropku numer portu (domyślnie 25). Program pobiera od użytkownika następujące informacje: nadawcę, odbiorcę, temat i treść wiadomości. Jeżeli wysłanie się nie powiodło na standardowym wyjściu wyświetlana jest informacja o ostatnim żądaniu SMTP wysłanym do serwera i odpowiedź na nie. W przypadku użycia opcji -v program wyświetla informacje o wszystkich wysłanych żądaniach i odpowiedziach serwera.

  36. Zmodyfikować program z zadania nr tak, aby próbował przed wysłaniem maila zalogować się na serwerze metodą PLAIN lub LOGIN za pomocą loginu i hasła pobranych od użytkownika.

  37. Zmodyfikować program z zadania nr tak, aby umożliwiał przesyłanie załączników.

  38. Praca domowa nr 2 (termin oddania: 15.01.2008)

    Napisać prostego klienta protokołów POP3 i SMTP umożliwiającego odbieranie i odczytywanie, oraz redagowanie i wysyłanie wiadomości e-mail.

    Dodatkowe uwagi:

  39. Praca domowa nr 3 (termin oddania: 06.02.2008)
    Termin oddania przesunięty na 08.02.2008, termin rezerwowy bez zmian: 13.02.208

    Napisać serwer umożliwiający klientom zdalne edytowanie plików tekstowych. Komunikacja klientów z serwerem odbywać się ma za pomocą protokołu opisanego poniżej.

    Opis protokołu:

    Po nazwiązaniu połączenia klient z serwerem wymieniają kolejno żądania i odpowiedzi aż do zamknięcia połączenia przez klienta. Każde żądanie składa się z trzyliterowego słowa kluczowego i ewentualnych argumentów. Każda odpowiedź składa się z dwuliterowego słowa kluczowego i ewentualnych argumentów. Słowa kluczowe i argumenty oddzielone są od siebie pojedynczymi spacjami. Słowa kluczowe pisane są wielkimi literami. Wszystkie przesyłane żądania i odpowiedzi kończą się sekwencją dwóch znaków o kodach 13 i 10 (w Pythonie '\r' i '\n').

    Klient może wysłać następujące żądania: Następujące żądania mogą być wysłane przez klienta tylko jeżeli edytuje on jakiś plik:

    Odpowiedź serwera w przypadku błędu, to

    ER kod

    gdzie kod jest kodem błędu.

    Kody błędu:

    Wiersze numerowane są od liczby 1.

    W protokole nie ma instrukcji kończenia sesji - klient po prostu zamyka połączenie.

    Opis programu serwera

    Serwer jest serwerem współbieżnym (mogącym obsługiwać na raz wielu klientów) działającym domyślnie na porcie nr 9876.

    Serwer dostaje w parametrze wiersza poleceń nazwę katalogu z udostępnianymi plikami. Serwer udostępnia tylko pliki, do których ma prawo do odczytu, znajdujące się bezpośrednio w wybranym katalogu. Żadne pliki spoza tego katalogu ani z jego podkatalogów nie mogą być w żaden sposób udostępnione klientowi.

    Ewentualny drugi parametr wiersza poleceń oznacza numer portu, na którym ma działać serwer (jeżeli nie chcemy korzystać z domyślnego).

    Dany plik może być na raz otwarty tylko przez jednego klienta. Serwer umożliwia otwarcie go przez innego klienta dopiero po zamknięciu pliku lub zamknięciu połączenia przez pierwszego klienta.

    Po zapisaniu pliku przez serwer każdy wiersz w pliku ma kończyć się pojedynczym znakiem o kodzie 10, bez względu na to jak było w oryginalnym pliku. Jeżeli np. w oryginale wszystkie wiersze kończyły się sekwencją dwóch znaków o kodach 13 i 10, lub ostatni wiersz nie zawierał żadnego znaku końca wiersza, to plik zostanie zmodyfikowany nawet jeżeli został tylko otwarty i zamknięty.

    Uwagi: