file-info/main.c

154 lines
4.1 KiB
C

#define _POSIX_C_SOURCE 2
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/stat.h>
#include <pwd.h>
#include <linux/limits.h>
#define RC_OK 0
#define RC_ERROR -1
static const char* _err_invalid_arg = "nebyl zadán platný soubor";
static int get_command_output_line(const char* cmd,
char* outbuff, size_t bufsize)
{
FILE* pf = popen(cmd, "r");
if (NULL == pf) {
return RC_ERROR;
}
int retval = RC_OK;
if (!feof(pf)) {
if (NULL == fgets(outbuff, bufsize, pf)) {
*outbuff = 0;
retval = RC_ERROR;
}
}
else
retval = RC_ERROR;
pclose(pf);
char* pnl = strrchr(outbuff, '\n');
if (pnl)
*pnl = 0;
return retval;
}
static int get_mime_type(const char* file_path,
char* outbuff, size_t buffsize)
{
char* cmdbuff = (char*)malloc(strlen(file_path) + 64);
if (NULL == cmdbuff)
abort();
strcpy(cmdbuff, "xdg-mime query filetype \"");
strcat(cmdbuff, file_path);
strcat(cmdbuff, "\"");
if (RC_OK != get_command_output_line(cmdbuff, outbuff, buffsize)) {
free(cmdbuff);
return RC_ERROR;
}
free(cmdbuff);
return RC_OK;
}
static int get_app_name(const char* desktop_file,
char* outbuff, size_t buffsize)
{
char filepath[PATH_MAX];
strcpy(filepath, "/usr/share/applications/");
strncat(filepath, desktop_file, sizeof(filepath) - strlen(filepath) - 1);
FILE* pf = fopen(filepath, "r");
if (NULL == pf)
return RC_ERROR;
char line[512];
*outbuff = 0;
while (fgets(line, sizeof(line), pf)) {
if (sscanf(line, "Name=%s", outbuff) == 1)
break;
}
fclose(pf);
return (0 == *outbuff) ? RC_ERROR : RC_OK;
}
static int get_mime_opener(const char* mimetype,
char* outbuff, size_t buffsize)
{
char cmdbuff[256];
strcpy(cmdbuff, "xdg-mime query default ");
strncat(cmdbuff, mimetype, sizeof(cmdbuff) - strlen(cmdbuff) - 1);
return get_command_output_line(cmdbuff, outbuff, buffsize);
}
static int show_file_info(const char* file_path)
{
struct stat fst;
char buff[256];
struct passwd* pwd;
if (0 != stat(file_path, &fst)) {
return errno;
}
printf("velikost: %lu MiB (%lu bytů)\n",
fst.st_size / 1024 / 1024, fst.st_size);
printf("na disku: %lu MiB (%lu bytů)\n",
(fst.st_blocks * 512) / 1024 / 1024, fst.st_blocks * 512);
printf("pevných odkazů: %lu\n", fst.st_nlink);
strftime(buff, sizeof(buff), "poslední přístup: %d.%m.%Y %H:%M:%S",
localtime((const time_t*)&fst.st_atime));
puts(buff);
strftime(buff, sizeof(buff), " poslední úprava: %d.%m.%Y %H:%M:%S",
localtime((const time_t*)&fst.st_mtime));
puts(buff);
strftime(buff, sizeof(buff), " změna stavu: %d.%m.%Y %H:%M:%S",
localtime((const time_t*)&fst.st_ctime));
puts(buff);
char permission[4];
unsigned int uperm;
uperm = 100 * (0x7 & (fst.st_mode >> 6)) +
10 * (0x7 & (fst.st_mode >> 3)) +
(0x7 & fst.st_mode);
permission[3] = 0;
permission[0] = (S_IRUSR & fst.st_mode) ? 'r' : '-';
permission[1] = (S_IWUSR & fst.st_mode) ? 'w' : '-';
permission[2] = (S_IXUSR & fst.st_mode) ? 'x' : '-';
if ((pwd = getpwuid(fst.st_uid)) != NULL) {
printf("vlastník: %s (%d)\n", pwd->pw_name, pwd->pw_uid);
}
else {
printf("User ID: %u\n", fst.st_uid);
}
printf("oprávnění: %u\n", uperm);
printf("uživatel: %s", permission);
permission[0] = (S_IRGRP & fst.st_mode) ? 'r' : '-';
permission[1] = (S_IWGRP & fst.st_mode) ? 'w' : '-';
permission[2] = (S_IXGRP & fst.st_mode) ? 'x' : '-';
printf(" skupina: %s", permission);
permission[0] = (S_IROTH & fst.st_mode) ? 'r' : '-';
permission[1] = (S_IWOTH & fst.st_mode) ? 'w' : '-';
permission[2] = (S_IXOTH & fst.st_mode) ? 'x' : '-';
printf(" ostatní: %s\n", permission);
if (RC_OK == get_mime_type(file_path, buff, sizeof(buff))) {
printf("mime typ: %s\n", buff);
if (RC_OK == get_mime_opener(buff, buff, sizeof(buff))) {
printf("výchozí aplikace: %s", buff);
if (RC_OK == get_app_name(buff, buff, sizeof(buff))) {
printf(" (%s)", buff);
}
printf("\n");
}
}
printf("\nstiskni enter pro ukončení...");
getchar();
return EXIT_SUCCESS;
}
int main(int argc, char** argv)
{
if (argc < 2) {
puts(_err_invalid_arg);
return EXIT_FAILURE;
}
return show_file_info(argv[1]);
}