📄 gnunet-auto-share.c
字号:
record_fn,
&size,
GNUNET_YES)) ||
(-1 == (fd = GNUNET_disk_file_open (ectx, record_fn, O_RDONLY))))
{
GNUNET_free (record_fn);
return NULL;
}
buf = MMAP (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED)
{
GNUNET_GE_LOG_STRERROR_FILE (ectx,
GNUNET_GE_ADMIN | GNUNET_GE_USER |
GNUNET_GE_ERROR | GNUNET_GE_BULK,
"mmap", record_fn);
GNUNET_free (record_fn);
CLOSE (fd);
return NULL;
}
ret = NULL;
off = 0;
while (off < size)
{
d = read_file_record (&buf[off], size - off, &ret);
if (d == 0)
{
GNUNET_GE_BREAK (NULL, 0);
break;
}
off += d;
}
MUNMAP (buf, size);
CLOSE (fd);
return ret;
}
static void
write_all_records (struct DirectoryRecord *dr)
{
const char dummy;
long off;
unsigned int d;
unsigned long long size;
char *record_fn;
int fd;
char *buf;
struct FileRecord *pos;
size = 0;
pos = dr->records;
while (pos != NULL)
{
size += write_file_record (NULL, 0, pos);
pos = pos->next;
}
record_fn = get_record_file_name (dr->dirname);
if ((-1 == (fd = GNUNET_disk_file_open (ectx,
record_fn,
O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR))))
{
GNUNET_free (record_fn);
return;
}
LSEEK (fd, size - 1, SEEK_SET);
WRITE (fd, &dummy, 1);
buf = MMAP (NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED)
{
GNUNET_GE_LOG_STRERROR_FILE (ectx,
GNUNET_GE_ADMIN | GNUNET_GE_USER |
GNUNET_GE_ERROR | GNUNET_GE_BULK,
"mmap", record_fn);
CLOSE (fd);
UNLINK (record_fn);
GNUNET_free (record_fn);
return;
}
off = 0;
pos = dr->records;
while (pos != NULL)
{
d = write_file_record (&buf[off], size - off, pos);
if (d == 0)
{
GNUNET_GE_BREAK (NULL, 0);
break;
}
pos = pos->next;
off += d;
}
MUNMAP (buf, size);
CLOSE (fd);
}
static struct FileRecord *
find_entry (struct DirectoryRecord *dr, const char *filename)
{
struct FileRecord *pos = dr->records;
while ((pos != NULL) && (0 != strcmp (filename, pos->filename)))
pos = pos->next;
return pos;
}
static int
test_run (const char *filename, const char *dirName, void *cls)
{
struct DirectoryRecord *dr = cls;
GNUNET_HashCode hc;
struct FileRecord *rec;
struct stat buf;
char *fn;
if (filename[0] == '.')
return GNUNET_OK;
if (ul != NULL)
return GNUNET_SYSERR;
fn = GNUNET_malloc (strlen (filename) + strlen (dirName) + 2);
strcpy (fn, dirName);
strcat (fn, DIR_SEPARATOR_STR);
strcat (fn, filename);
if (0 != stat (fn, &buf))
{
fprintf (myout, _("Could not access `%s': %s\n"), fn, strerror (errno));
fflush (myout);
GNUNET_free (fn);
return GNUNET_OK;
}
rec = find_entry (dr, fn);
if (rec == NULL)
{
rec = GNUNET_malloc (sizeof (struct FileRecord));
rec->next = dr->records;
rec->filename = GNUNET_strdup (fn);
rec->mtime = buf.st_mtime;
rec->size = buf.st_size;
rec->last_seen = time (NULL);
GNUNET_hash_file (NULL, fn, &rec->hc);
rec->next = dr->records;
dr->records = rec;
dr->records_changed = GNUNET_YES;
if (GNUNET_NO == GNUNET_FS_test_indexed (sock, &rec->hc))
{
dr->run = 1;
GNUNET_free (fn);
/* keep iterating to mark all other files in this tree! */
return GNUNET_OK;
}
}
else
{
rec->last_seen = time (NULL);
}
if ((rec->mtime != buf.st_mtime) || (rec->size != buf.st_size))
{
GNUNET_hash_file (NULL, fn, &hc);
if (0 != memcmp (&hc, &rec->hc, sizeof (GNUNET_HashCode)))
dr->run = 1;
rec->mtime = buf.st_mtime;
rec->size = buf.st_size;
rec->hc = hc;
}
if (S_ISDIR (buf.st_mode))
GNUNET_disk_directory_scan (ectx, fn, &test_run, dr);
GNUNET_free (fn);
return GNUNET_OK;
}
struct AddMetadataClosure
{
const char *filename;
struct GNUNET_MetaData *meta;
};
static int
add_meta_data (void *cls,
struct GNUNET_GC_Configuration *cfg,
struct GNUNET_GE_Context *ectx,
const char *section, const char *option)
{
struct AddMetadataClosure *amc = cls;
EXTRACTOR_KeywordType type;
EXTRACTOR_KeywordType max;
char *value;
if ((0 != strcmp (amc->filename, section)) &&
((0 != strncmp (amc->filename,
section,
strlen (amc->filename))) ||
(strlen (section) != strlen (amc->filename) + 1) ||
((section[strlen (section) - 1] != '/') &&
(section[strlen (section) - 1] != '\\'))))
return 0;
max = EXTRACTOR_getHighestKeywordTypeNumber ();
for (type = 0; type < max; type++)
{
if (0 == strcasecmp (option, EXTRACTOR_getKeywordTypeAsString (type)))
break;
}
if (type == max)
{
GNUNET_GE_LOG (ectx,
GNUNET_GE_USER | GNUNET_GE_WARNING | GNUNET_GE_BULK,
_
("Unknown keyword type `%s' in metadata configuration\n"),
option);
return 0;
}
value = NULL;
GNUNET_GC_get_configuration_value_string (cfg,
section, option, NULL, &value);
if (value != NULL)
{
GNUNET_meta_data_insert (amc->meta, type, value);
GNUNET_free (value);
}
return 0;
}
static int
probe_directory (const char *filename, const char *dirName, void *cls)
{
struct DirectoryRecord *dr = cls;
struct stat buf;
struct AddMetadataClosure amc;
struct GNUNET_ECRS_URI *kuri;
char *fn;
char *keys;
if (GNUNET_shutdown_test ())
return GNUNET_SYSERR; /* aborted */
if (filename[0] == '.')
return GNUNET_OK;
if (ul != NULL)
return GNUNET_SYSERR;
fn = GNUNET_malloc (strlen (filename) + strlen (dirName) + 2);
strcpy (fn, dirName);
strcat (fn, DIR_SEPARATOR_STR);
strcat (fn, filename);
if (0 != stat (fn, &buf))
{
fprintf (myout, "Could not stat `%s': %s\n", fn, STRERROR (errno));
fflush (myout);
GNUNET_free (fn);
return GNUNET_OK;
}
dr->run = 0;
test_run (filename, dirName, dr);
if (0 == dr->run)
{
GNUNET_free (fn);
return GNUNET_OK;
}
amc.meta = GNUNET_meta_data_create ();
amc.filename = filename;
/* attaching a listener will prompt iteration
over all config values! */
GNUNET_GC_attach_change_listener (meta_cfg, &add_meta_data, &amc);
GNUNET_GC_detach_change_listener (meta_cfg, &add_meta_data, &amc);
keys = GNUNET_meta_data_get_by_type (amc.meta, EXTRACTOR_KEYWORDS);
if (keys != NULL)
kuri = GNUNET_ECRS_keyword_string_to_uri (NULL, keys);
else
kuri = NULL;
GNUNET_meta_data_delete (amc.meta, EXTRACTOR_KEYWORDS, keys);
GNUNET_free_non_null (keys);
ul = GNUNET_FSUI_upload_start (ctx,
fn,
(GNUNET_FSUI_DirectoryScanCallback) &
GNUNET_disk_directory_scan, ectx, anonymity,
priority, GNUNET_YES, GNUNET_YES,
!do_no_direct_references,
GNUNET_get_time () + 2 * GNUNET_CRON_YEARS,
amc.meta, gloKeywords, kuri);
if (kuri != NULL)
GNUNET_ECRS_uri_destroy (kuri);
GNUNET_meta_data_destroy (amc.meta);
GNUNET_free (fn);
return GNUNET_SYSERR;
}
/**
* Actual main function.
*
* @return return 0 for ok, -1 on error
*/
int
auto_share_main ()
{
int errorCode;
int work_done;
unsigned long long verbose;
GNUNET_CronTime delay;
char *metafn;
char *dirs;
char *dirs_idx1;
char *dirs_idx2;
struct FileRecord *rpos;
int filedes[2]; /* pipe between client and parent */
struct DirectoryRecord *head;
struct DirectoryRecord *pos;
if (GNUNET_SYSERR == GNUNET_pid_file_kill_owner (ectx, cfg, PIDFILE_DATA))
{
fprintf (myout, _("Failed to stop running gnunet-auto-share.\n"));
fflush (myout);
errorCode = -1;
if (GNUNET_NO == debug_flag)
GNUNET_terminal_detach_complete (ectx, filedes, GNUNET_NO);
return GNUNET_SYSERR;
}
errorCode = 0;
if ((GNUNET_NO == debug_flag)
&& (GNUNET_OK != GNUNET_terminal_detach (ectx, cfg, filedes,
PIDFILE_DATA)))
return GNUNET_SYSERR;
if (GNUNET_NO != debug_flag)
GNUNET_pid_file_write (ectx, cfg, getpid (), PIDFILE_DATA);
head = NULL;
sock = GNUNET_client_connection_create (ectx, cfg);
if (sock == NULL)
{
fprintf (myout, _("Failed to connect to gnunetd.\n"));
fflush (myout);
errorCode = -1;
if (GNUNET_NO == debug_flag)
GNUNET_terminal_detach_complete (ectx, filedes, GNUNET_NO);
goto quit;
}
GNUNET_GC_get_configuration_value_number (cfg,
"GNUNET",
"VERBOSE", 0, 9999, 0, &verbose);
metafn = NULL;
GNUNET_GC_get_configuration_value_filename (cfg,
"GNUNET-AUTO-SHARE",
"METADATA",
GNUNET_DEFAULT_HOME_DIRECTORY
"/metadata.conf", &metafn);
GNUNET_GC_get_configuration_value_string (cfg,
"GNUNET-AUTO-SHARE",
"DIRS", "", &dirs);
meta_cfg = GNUNET_GC_create ();
if (GNUNET_YES == GNUNET_disk_file_test (NULL, metafn))
GNUNET_GC_parse_configuration (meta_cfg, metafn);
if (GNUNET_NO == debug_flag)
GNUNET_terminal_detach_complete (ectx, filedes, GNUNET_YES);
GNUNET_free (metafn);
/* fundamental init */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -