/*
 * PRACTICE OF PROGRAMMING!
 * tty(1) simulation
 *
 * safari.tafreshi@gmail.com
 * safarionline.ir
 */

/*
 * دستور tty(1) نام و آدرسِ فایل مربوط به ترمینال فعلی که
 * در حال استفاده از آن هستیم را برمی‌گرداند. بدیهی است که دستور موجود
 * در سیستم‌های لینوکس قطعا جزئیات بسیار بیشتری دارد. این برنامه صرفا
 * به قصد تمرین و یادگیری نوشته شده است و حالت پیش فرض آن را پیاده می‌کند:
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <dirent.h>
#include <sys/stat.h>
#include <limits.h>
#include <sys/sysmacros.h>

void
search(char *dir, int minor, int major) {
    char path[PATH_MAX];
    DIR *dirp;
    struct dirent *dirent;
    int s;
    struct stat st;

    dirp = opendir(dir);
    if (dirp == NULL)
        err(EXIT_FAILURE, "opendir");

    while ((dirent = readdir(dirp)) != NULL) {
        sprintf(path, "%s/%s", dir, dirent->d_name);
        s = lstat(path, &st);
        if (s == -1)
            err(EXIT_FAILURE, "lstat");
        if (minor(st.st_rdev) == minor &&  major(st.st_rdev) == major) {
            printf("%s\n", path);
            exit(EXIT_SUCCESS);
        }
    }
    closedir(dirp);
}

int
main(int argc, char *argv[])
{
    struct stat st;
    int s, minor, major;
    char *dirs[] = {"/dev", "/dev/pts", NULL};

    s = fstat(STDIN_FILENO, &st);
    if (s == -1)
        err(EXIT_FAILURE, "fstat");

    minor = minor(st.st_rdev);
    major = major(st.st_rdev);

    for (int i = 0; dirs[i] != NULL; i++)
        search(dirs[i], minor, major);

    exit(EXIT_FAILURE);
}
