Difference between revisions of "Coding Contest 25 novembre 2016"
(Created page with "== Esercizio 1 == scrivere un programma che passato come parametro il path di una directory (cwd se manca il paramtro) stampi il path relativo di tutti i file con nome palind...") |
m (→Esercizio 4) |
||
Line 35: | Line 35: | ||
Trovare i file di contenuto uguale nella directory corrente e convertirli in link dello stesso file. | Trovare i file di contenuto uguale nella directory corrente e convertirli in link dello stesso file. | ||
+ | |||
+ | Esempio di soluzione dell'esercizio [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 09:06, 6 December 2016 (CET). | ||
+ | (in aula sembrava avere un bug ma non era vero. Alcuni file in /tmp non sono stati convertiti in link perché appartenevano ad altro utente). | ||
+ | |||
+ | <syntaxhighlight lang=C> | ||
+ | #include <stdio.h> | ||
+ | #include <fcntl.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <unistd.h> | ||
+ | #include <stdarg.h> | ||
+ | #include <string.h> | ||
+ | #include <libgen.h> | ||
+ | #include <errno.h> | ||
+ | #include <dirent.h> | ||
+ | #include <mhash.h> | ||
+ | #include <sys/types.h> | ||
+ | #include <sys/stat.h> | ||
+ | |||
+ | struct file { | ||
+ | struct file *next; | ||
+ | unsigned char hash[20]; | ||
+ | char *name; | ||
+ | }; | ||
+ | |||
+ | struct file *head; | ||
+ | |||
+ | static int ckcontents(int fd1, int fd2) { | ||
+ | char buf1[BUFSIZ],buf2[BUFSIZ]; | ||
+ | ssize_t n1, n2; | ||
+ | do { | ||
+ | n1 = read(fd1, buf1, BUFSIZ); | ||
+ | n2 = read(fd2, buf2, BUFSIZ); | ||
+ | } while (n1 == n2 && n1 > 0 && memcmp(buf1, buf2, n2 == 0)); | ||
+ | return n1 == n2; | ||
+ | } | ||
+ | |||
+ | static int cksize(int fd1, int fd2) { | ||
+ | struct stat st1, st2; | ||
+ | return | ||
+ | fstat(fd1, &st1) == 0 && | ||
+ | fstat(fd2, &st2) == 0 && | ||
+ | st1.st_size == st2.st_size; | ||
+ | } | ||
+ | |||
+ | int filecmp(char *path1, char *path2) { | ||
+ | int fd1 = open(path1, O_RDONLY); | ||
+ | int fd2 = open(path2, O_RDONLY); | ||
+ | int rval = | ||
+ | fd1 >= 0 && fd2 >=0 && cksize(fd1, fd2) && ckcontents(fd1, fd2); | ||
+ | close(fd1); | ||
+ | close(fd2); | ||
+ | return rval; | ||
+ | } | ||
+ | |||
+ | #if 0 | ||
+ | void printhash(unsigned char * hash) { | ||
+ | int i; | ||
+ | for (i = 0; i < mhash_get_block_size(MHASH_SHA1); i++) | ||
+ | printf("%.2x", hash[i]); | ||
+ | } | ||
+ | #endif | ||
+ | |||
+ | void compute_sha1sum(char *path, char *hash) { | ||
+ | int fd; | ||
+ | MHASH td; | ||
+ | if ((fd = open(path, O_RDONLY)) >= 0) { | ||
+ | if ((td = mhash_init(MHASH_SHA1)) != MHASH_FAILED) { | ||
+ | ssize_t n; | ||
+ | char buf[BUFSIZ]; | ||
+ | while ((n = read(fd, buf, BUFSIZ)) > 0) | ||
+ | mhash(td, buf, n); | ||
+ | mhash_deinit(td, hash); | ||
+ | } | ||
+ | close(fd); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | static void check_n_link(char *name) { | ||
+ | struct file **scan; | ||
+ | unsigned char hash[20]; | ||
+ | compute_sha1sum(name, hash); | ||
+ | for (scan = &head; *scan != NULL; scan = &((*scan) -> next)) { | ||
+ | //printhash((*scan)->hash); printf(" - "); printhash(hash); printf("\n"); | ||
+ | if (memcmp((*scan)->hash, hash, 20) == 0 && | ||
+ | filecmp((*scan)->name, name)) { | ||
+ | unlink(name); | ||
+ | link((*scan)->name, name); | ||
+ | printf("%s and %s have the same contents\n", (*scan)->name, name); | ||
+ | return; | ||
+ | } | ||
+ | } | ||
+ | *scan = malloc(sizeof(struct file)); | ||
+ | if (*scan) { | ||
+ | (*scan)->next = NULL; | ||
+ | memcpy((*scan)->hash, hash, 20); | ||
+ | (*scan)->name = name; | ||
+ | //printf("%s\n",name); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | static void freefilelist() { | ||
+ | while (head) { | ||
+ | struct file *delenda; | ||
+ | delenda = head; | ||
+ | head = head->next; | ||
+ | free(delenda); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void err_exit(char *fmt, ...) { | ||
+ | va_list ap; | ||
+ | |||
+ | va_start(ap, fmt); | ||
+ | vfprintf(stderr, fmt, ap); | ||
+ | va_end(ap); | ||
+ | exit(2); | ||
+ | } | ||
+ | |||
+ | static int regular_only(const struct dirent *d) { | ||
+ | const char *name = d->d_name; | ||
+ | struct stat st; | ||
+ | return stat(name, &st) == 0 && S_ISREG(st.st_mode); | ||
+ | } | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | struct dirent **list; | ||
+ | int n; | ||
+ | int i; | ||
+ | n = scandir(".", &list, regular_only, alphasort); | ||
+ | if (n > 0) { | ||
+ | for (i=0; i<n; i++) { | ||
+ | char *name = list[i]->d_name; | ||
+ | check_n_link(name); | ||
+ | } | ||
+ | freefilelist(); | ||
+ | for (i=0; i<n; i++) | ||
+ | free(list[i]); | ||
+ | free(list); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> |
Revision as of 09:06, 6 December 2016
Esercizio 1
scrivere un programma che passato come parametro il path di una directory (cwd se manca il paramtro) stampi il path relativo di tutti i file con nome palindromo presenti nel sottoalbero.
2720c84e673c75c20a27a07ffcd6826b31c8babc esercizio1.c Leonardo (talk) 17:23, 25 November 2016 (CET)
86aca4384a296bf12c69541fc5418fe4b6656e0d es1.c Fabio.capucci (talk) 17:30, 25 November 2016 (CET)
071fccfe63b8121f951444cb57001ccdd4ec02d0 Es1.c FilippoB (talk) 17:31, 25 November 2016 (CET)
235f2414cfe5b81973b1d388ce9431aa02b5f305 MatteoC (talk) 17:43, 25 November 2016 (CET)
168d3422b92fc78519e19d6a8e156b260a7798a6 testdir.c Tamino (talk) 18:06, 25 November 2016 (CET)
Esercizio 2
lancia tutti gli eseguibili della directory passata come primo paramtro e concatena gli output. (i parametri rimanenti devono essere passati a tutti gli eseguibili)
lanciatutti dir 1 2 3
se nella directory dir sono presenti a, b e c (eseguibili) lancia a 1 2 3', b 1 2 3, c 1 2 3
Esercizio 3
Scrivere un programma che deve ottenere il pid passato come parametro. indicare se e' impossibile
fdf7b609e470c43a32a50801e76e78c32aebfbb1 main.tar.gz Alexp (talk) 17:22, 25 November 2016 (CET)
Esercizio 4
Trovare i file di contenuto uguale nella directory corrente e convertirli in link dello stesso file.
Esempio di soluzione dell'esercizio Renzo (talk) 09:06, 6 December 2016 (CET). (in aula sembrava avere un bug ma non era vero. Alcuni file in /tmp non sono stati convertiti in link perché appartenevano ad altro utente).
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <libgen.h>
#include <errno.h>
#include <dirent.h>
#include <mhash.h>
#include <sys/types.h>
#include <sys/stat.h>
struct file {
struct file *next;
unsigned char hash[20];
char *name;
};
struct file *head;
static int ckcontents(int fd1, int fd2) {
char buf1[BUFSIZ],buf2[BUFSIZ];
ssize_t n1, n2;
do {
n1 = read(fd1, buf1, BUFSIZ);
n2 = read(fd2, buf2, BUFSIZ);
} while (n1 == n2 && n1 > 0 && memcmp(buf1, buf2, n2 == 0));
return n1 == n2;
}
static int cksize(int fd1, int fd2) {
struct stat st1, st2;
return
fstat(fd1, &st1) == 0 &&
fstat(fd2, &st2) == 0 &&
st1.st_size == st2.st_size;
}
int filecmp(char *path1, char *path2) {
int fd1 = open(path1, O_RDONLY);
int fd2 = open(path2, O_RDONLY);
int rval =
fd1 >= 0 && fd2 >=0 && cksize(fd1, fd2) && ckcontents(fd1, fd2);
close(fd1);
close(fd2);
return rval;
}
#if 0
void printhash(unsigned char * hash) {
int i;
for (i = 0; i < mhash_get_block_size(MHASH_SHA1); i++)
printf("%.2x", hash[i]);
}
#endif
void compute_sha1sum(char *path, char *hash) {
int fd;
MHASH td;
if ((fd = open(path, O_RDONLY)) >= 0) {
if ((td = mhash_init(MHASH_SHA1)) != MHASH_FAILED) {
ssize_t n;
char buf[BUFSIZ];
while ((n = read(fd, buf, BUFSIZ)) > 0)
mhash(td, buf, n);
mhash_deinit(td, hash);
}
close(fd);
}
}
static void check_n_link(char *name) {
struct file **scan;
unsigned char hash[20];
compute_sha1sum(name, hash);
for (scan = &head; *scan != NULL; scan = &((*scan) -> next)) {
//printhash((*scan)->hash); printf(" - "); printhash(hash); printf("\n");
if (memcmp((*scan)->hash, hash, 20) == 0 &&
filecmp((*scan)->name, name)) {
unlink(name);
link((*scan)->name, name);
printf("%s and %s have the same contents\n", (*scan)->name, name);
return;
}
}
*scan = malloc(sizeof(struct file));
if (*scan) {
(*scan)->next = NULL;
memcpy((*scan)->hash, hash, 20);
(*scan)->name = name;
//printf("%s\n",name);
}
}
static void freefilelist() {
while (head) {
struct file *delenda;
delenda = head;
head = head->next;
free(delenda);
}
}
void err_exit(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(2);
}
static int regular_only(const struct dirent *d) {
const char *name = d->d_name;
struct stat st;
return stat(name, &st) == 0 && S_ISREG(st.st_mode);
}
int main(int argc, char *argv[]) {
struct dirent **list;
int n;
int i;
n = scandir(".", &list, regular_only, alphasort);
if (n > 0) {
for (i=0; i<n; i++) {
char *name = list[i]->d_name;
check_n_link(name);
}
freefilelist();
for (i=0; i<n; i++)
free(list[i]);
free(list);
}
}