2012-10-27 6 views
9

Do pracy domowej muszę napisać program w języku C i jedną z rzeczy, które musi zrobić, to sprawdzenie, czy plik istnieje i czy jest on wykonywany przez właściciela.Używanie stat do sprawdzania, czy plik jest wykonywany w C

Używanie (stat(path[j], &sb) >= 0 Jestem w stanie sprawdzić, czy plik wskazany przez ścieżkę [j] istnieje.

Przeglądam strony man, wiele pytań i odpowiedzi na stackoverflow i kilka stron internetowych, ale nie jestem w stanie objąć głowy dokładnie, jak sprawdzić, czy plik jest wykonywalny za pomocą statystyk. Myślałem, że to będzie tak proste jak ((stat(path[j], &sb) >= 0) && (sb.st_mode > 0) && (S_IEXEC), ale o ile mogę powiedzieć, testując go, wydaje się zignorować fakt, że te pliki nie są wykonywalne.

Myślę, że być może stat nie działa tak, jak myślę. Zakładając, że używam statystyk, jak mogę to naprawić?

+2

'&& (S_IEXEC)' w ogóle nie zależy od 'sb', co to ma zrobić w twoim teście? – Mat

+2

Wyszukaj operator bitowy AND. Musisz go użyć i S_IXUSR przeciwko sb.st_mode – goji

+1

Zabawne, że gdyby to było pytanie w Pythonie, wszyscy natychmiast [krzyczeli o tym, jak strasznie niebezpiecznie to jest] (http://stackoverflow.com/questions/82831/how-do -i-check-if-a-file-exists-using-python) ze względu na możliwy stan wyścigu, jeśli planujesz później polegać na tym wyniku. Jeśli to robisz (i ciesz się bezpiecznym utrzymaniem), możesz chcieć uzyskać blokadę pliku przed wywołaniem 'stat'. – Kos

Odpowiedz

9

Można wprawdzie skorzystać stat to zrobić. Po prostu musisz użyć S_IXUSR (S_IEXEC jest starym synonimem S_IXUSR), aby sprawdzić, czy masz uprawnienia do wykonywania. Bitwise AND operator (&) sprawdza, czy bity z S_IXUSR są ustawione, czy nie.

if (stat(file, &sb) == 0 && sb.st_mode & S_IXUSR) 
    /* executable */ 
else 
    /* non-executable */ 

przykład:

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 

int main(int argc, char **argv) 
{ 
    if (argc > 1) { 
     struct stat sb; 
     printf("%s is%s executable.\n", argv[1], stat(argv[1], &sb) == 0 && 
               sb.st_mode & S_IXUSR ? 
               "" : " not"); 
    } 
    return 0; 
} 
+0

(sb.st_mode & S_IXUSR) po prostu upewniając się, że go mam. Więc S_IXUSR przechowuje tę cyfrę sb.st_mode, która wskazuje, że jest ona wykonywalna, otoczona cyframi 0 i bitowymi, a da tylko 1, jeśli ten konkretny bit jest ustawiony na 1? –

+0

Co masz na myśli? – md5

+0

Przypadkowo uderzyłem enter przed zakończeniem, naprawiłem go. –

4

Spróbuj:

((stat(path[j], &sb) >= 0) && (sb.st_mode > 0) && (S_IEXEC & sb.st_mode)

0

Możemy wykorzystać bibliotekę libmagic.so która pochodzi wraz z plikiem (1) użytkowego. To może wykryć wszystkie pliki wykonywalne skrypty jak ELF, bash/python/perl itp

Oto mój kod:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "magic.h" 

int 
main(int argc, char **argv) 
{ 
    struct magic_set *ms; 
    const char *result; 
    char *desired; 
    size_t desired_len; 
    int i; 
    FILE *fp; 

    ms = magic_open(MAGIC_RAW); 
    if (ms == NULL) { 
     (void)fprintf(stderr, "ERROR opening MAGIC_NONE: out of memory\n"); 
     return -1; 
    } 
    if (magic_load(ms, NULL) == -1) { 
     (void)fprintf(stderr, "ERROR loading with NULL file: %s\n", magic_error(ms)); 
     return 11; 
    } 

    if (argc > 1) { 
     if (argc != 2) { 
     (void)fprintf(stderr, "Usage: ./a.out </path/to/file>\n"); 
     } else { 
     if ((result = magic_file(ms, argv[1])) == NULL) { 
      (void)fprintf(stderr, "ERROR loading file %s: %s\n", argv[1], magic_error(ms)); 
      return -1; 
     } else { 
      if (strstr(result, (const char *)"executable")) { 
       printf("%s: is executable\n", argv[1], result); 
      } 
     } 
     } 
    } 
    magic_close(ms); 
    return 0; 
} 

$ gcc test.c -I/ścieżka/do/magic.h/usr/lib /libmagic.so.1

./a.out/bin/ls

./a.out a.out

./a.out test.c

Powiązane problemy