Kód:
/*
 * Meno: Ondrej Zary
 * Kruzok: info7
 * Datum: 10.5.2003
 * Zadanie: zadanie04c
 * Kompilacia: cc pripravne_04c.c -o pripravne_04c
 *
 * Text zadania:
 * Napiste program, ktory v zadanom adresari, uvedenom ako argument, a jeho
 * podadresaroch, najde vsetky symbolicke linky.
 * Ak bude program spusteny s prepinacom -e, vyhlada len linky s existujucim
 * cielovym suborom; s prepinacom -n len linky s neexistujucim cielovym suborom.
 * Program NESMIE pouzivat na prehladavanie adresara externy program (musi
 * prehladavat adresar rekurzivne).
 *
 * Syntax:
 * zadanie2 [-h] [-e] [-n] adresar
 *
 * Format vystupu (na standardny vystup):
 * Output: 'najdena linka'
 *
 * Bonusove body mozete ziskat ak vas program bude vediet prehladavat lubovolny
 * pocet zadanych adresarov (ak nebude adresar uvedeny, prehladava sa aktualny
 * pracovny adresar).
 *
 * Rieste aj cast zadania oznacenu ako bonusovu.
 *
 * Program musi osetrovat pocet a spravnost argumentov. Program musi mat help,
 * ktory sa vypise pri zadani argumentu -h a ma tvar:
 * Meno programu (C) meno autora
 *
 * Usage&#58; <meno_programu> <arg1> <arg2> ...
 *    <arg1>&#58; xxxxxx
 *    <arg2>&#58; yyyyy
 *
 * Korektny vystup programu musi ist na standardny vystup &#40;stdout&#41;.
 * Chybovy vystup programu musi ist na chybovy vystup &#40;stderr&#41;.
 * Chybovy vystup musi mat tvar&#58;
 * Error&#58; 'adresar, subor, program,... pri ktorom nastala chyba'&#58; popis chyby ...
 * Ak program pouziva nejake pomocne vypisy, musia ist na chybovy vystup a
 * musia mat tvar&#58;
 * Debug&#58; vypis ...
 *
 * Program sa musi dat skompilovat !!!
 * Prikaz pre kompilaciu je uvedeny vyssie, v pripade potreby ho modifikujte !!!
 *
 * Poznamky&#58; &#40;sem vlozte pripadne poznamky k vypracovanemu zadaniu&#41;
 *
 * Riesenie&#58;
 */

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <string.h>
#include <fcntl.h>

void Help&#40;&#41; &#123;
        printf&#40;"zadanie04 &#40;c&#41; Rainbow\n"&#41;;
        printf&#40;"usage&#58; zadanie04 &#91;-h&#93; &#91;-e&#93; &#91;-n&#93; &#91;adresar&#93; &#91;...&#93;\n"&#41;;
        printf&#40;"      -h&#58; tento help\n"&#41;;
        printf&#40;"      -e&#58; hlada len linky s existujucim cielovym suborom\n"&#41;;
        printf&#40;"      -n&#58; hlada len linky s neexistujucim cielovym suborom\n"&#41;;
        printf&#40;" adresar&#58; adresar&#40;e&#41;, kde sa budu linky hladat\n"&#41;;
&#125;

void SearchDir&#40;char *dirname, int type&#41; &#123;
        DIR *dp;
        struct dirent *dir;
        struct stat filestat;
        char path&#91;PATH_MAX&#93;;
        char buf&#91;PATH_MAX&#93;;
        int i,desc;

        if &#40;&#40;dp=opendir&#40;dirname&#41;&#41; == NULL&#41; &#123;
                fprintf&#40;stderr,"Error&#58; chyba pri citani adresara %s\n",dirname&#41;;
                return;
        &#125;

        while &#40;&#40;dir=readdir&#40;dp&#41;&#41; != NULL&#41; &#123;
                if &#40;&#40;!strcmp&#40;dir->d_name,"."&#41;&#41; || &#40;!strcmp&#40;dir->d_name,".."&#41;&#41;&#41; continue;
                strcpy&#40;path,dirname&#41;;
                if &#40;dirname&#91;strlen&#40;dirname&#41;-1&#93; != '/'&#41; strcat&#40;path,"/"&#41;;
                strcat&#40;path,dir->d_name&#41;;
                if &#40;lstat&#40;path,&filestat&#41; == -1&#41; &#123;
                        fprintf&#40;stderr,"Error&#58; chyba pri lstat\n"&#41;;
                        continue;
                &#125;
                if &#40;S_ISDIR&#40;filestat.st_mode&#41;&#41; SearchDir&#40;path,type&#41;;
                if &#40;S_ISLNK&#40;filestat.st_mode&#41;&#41; &#123;
                        if &#40;type == 0&#41; &#123;
                                printf&#40;"Output&#58; '%s'\n",path&#41;;
                                continue;
                        &#125;
                        if &#40;&#40;i=readlink&#40;path,buf,sizeof&#40;buf&#41;&#41;&#41; == -1&#41; &#123;
                                fprintf&#40;stderr,"Error&#58; chyba pri readlink %s\n",path&#41;;
                                continue;
                        &#125;
                        buf&#91;i&#93;=0;
                        if &#40;&#40;desc=open&#40;buf,O_RDONLY&#41;&#41; == -1&#41; &#123;
                                if &#40;type == 2&#41; printf&#40;"Output&#58; '%s'\n",path&#41;;
                        &#125;
                        else &#123;
                                if &#40;type == 1&#41; printf&#40;"Output&#58; '%s'\n",path&#41;;
                                close&#40;desc&#41;;
                        &#125;
                &#125;
        &#125;
        closedir&#40;dp&#41;;
&#125;

int main&#40;int argc, char *argv&#91;&#93;&#41; &#123;
        int o,type=0;

        opterr = 0;
        while &#40;&#40;o = getopt&#40;argc, argv, "hen"&#41;&#41; != -1&#41;
                switch &#40;o&#41; &#123;
                        case 'h'&#58;
                                Help&#40;&#41;;
                                exit&#40;0&#41;;
                        case 'e'&#58;
                                type=1;
                                break;
                        case 'n'&#58;
                                type=2;
                                break;
                        case '?'&#58;
                        default&#58;
                                fprintf&#40;stderr, "Error&#58; '%c'&#58; nespravny prepinac\n", optopt&#41;;
                                exit&#40;1&#41;;
                &#125;
        argc -= optind;
        argv += optind;

        if &#40;argc == 0&#41; SearchDir&#40;".",type&#41;;
        else for &#40;o=0;o<argc;o++&#41; SearchDir&#40;argv&#91;o&#93;,type&#41;;
&#125;