/** * Creates a file filled with zeroes * * @param fh the file handle * @param size the size of the file * @return GNUNET_OK if created ok, GNUNET_SYSERR otherwise */ static int make_empty_file (const struct GNUNET_DISK_FileHandle *fh, size_t size) { char buffer[BUFFSIZE]; size_t bytesleft = size; int res = 0; if (GNUNET_DISK_handle_invalid (fh)) return GNUNET_SYSERR; memset (buffer, 0, sizeof (buffer)); GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_SET); while (bytesleft > 0) { if (bytesleft > sizeof (buffer)) { res = GNUNET_DISK_file_write (fh, buffer, sizeof (buffer)); if (res >= 0) bytesleft -= res; } else { res = GNUNET_DISK_file_write (fh, buffer, bytesleft); if (res >= 0) bytesleft -= res; } if (GNUNET_SYSERR == res) return GNUNET_SYSERR; } return GNUNET_OK; }
static void write_bw_gnuplot_script (char * fn, struct LoggingPeer *lp, char **fs, int slaves) { struct GNUNET_DISK_FileHandle *f; char * gfn; char *data; int c_s; GNUNET_asprintf (&gfn, "gnuplot_bw_%s",fn); fprintf (stderr, "Writing bandwidth plot for master %u to `%s'\n", lp->peer->no, gfn); f = GNUNET_DISK_file_open (gfn, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_EXEC | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == f) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", gfn); GNUNET_free (gfn); return; } /* Write header */ if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, BW_TEMPLATE, strlen(BW_TEMPLATE))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn); for (c_s = 0; c_s < slaves; c_s++) { GNUNET_asprintf (&data, "%s"\ "'%s' using 2:%u with lines title 'BW out master %u - Slave %u ', \\\n" \ "'%s' using 2:%u with lines title 'BW in master %u - Slave %u '"\ "%s\n", (0 == c_s) ? "plot " :"", fs[c_s], LOG_ITEMS_TIME + LOG_ITEM_ATS_BW_OUT, lp->peer->no, c_s, fs[c_s], LOG_ITEMS_TIME + LOG_ITEM_ATS_BW_IN, lp->peer->no, c_s, (c_s < lp->peer->num_partners -1) ? ", \\" : "\n pause -1"); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn); GNUNET_free (data); } if (GNUNET_SYSERR == GNUNET_DISK_file_close(f)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n", gfn); else GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Data successfully written to plot file `%s'\n", gfn); GNUNET_free (gfn); }
/** * @brief Iterator function for #store_valid_peers. * * Implements #GNUNET_CONTAINER_PeerMapIterator. * Writes single peer to disk. * * @param cls the file handle to write to. * @param peer current peer * @param value unused * * @return #GNUNET_YES if we should continue to * iterate, * #GNUNET_NO if not. */ static int store_peer_presistently_iterator (void *cls, const struct GNUNET_PeerIdentity *peer, void *value) { const struct GNUNET_DISK_FileHandle *fh = cls; char peer_string[128]; int size; ssize_t ret; if (NULL == peer) { return GNUNET_YES; } size = GNUNET_snprintf (peer_string, sizeof (peer_string), "%s\n", GNUNET_i2s_full (peer)); GNUNET_assert (53 == size); ret = GNUNET_DISK_file_write (fh, peer_string, size); GNUNET_assert (size == ret); return GNUNET_YES; }
static void run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { char *fn; const struct GNUNET_DISK_FileHandle *stdout_read_handle; const struct GNUNET_DISK_FileHandle *wh; #if !WINDOWS GNUNET_asprintf (&fn, "cat"); #else GNUNET_asprintf (&fn, "w32cat"); #endif hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL)) { GNUNET_break (0); ok = 1; GNUNET_free (fn); return; } proc = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ERR, hello_pipe_stdin, hello_pipe_stdout, fn, "test_gnunet_echo_hello", "-", NULL); GNUNET_free (fn); /* Close the write end of the read pipe */ GNUNET_DISK_pipe_close_end (hello_pipe_stdout, GNUNET_DISK_PIPE_END_WRITE); /* Close the read end of the write pipe */ GNUNET_DISK_pipe_close_end (hello_pipe_stdin, GNUNET_DISK_PIPE_END_READ); wh = GNUNET_DISK_pipe_handle (hello_pipe_stdin, GNUNET_DISK_PIPE_END_WRITE); /* Write the test_phrase to the cat process */ if (GNUNET_DISK_file_write (wh, test_phrase, strlen (test_phrase) + 1) != strlen (test_phrase) + 1) { GNUNET_break (0); ok = 1; return; } /* Close the write end to end the cycle! */ GNUNET_DISK_pipe_close_end (hello_pipe_stdin, GNUNET_DISK_PIPE_END_WRITE); stdout_read_handle = GNUNET_DISK_pipe_handle (hello_pipe_stdout, GNUNET_DISK_PIPE_END_READ); die_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1), &end_task, NULL); GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, stdout_read_handle, &read_call, (void *) stdout_read_handle); }
/** * Return unique variant of the namespace name. * Use it after GNUNET_PSEUDONYM_get_info() to make sure * that name is unique. * * @param cfg configuration * @param nsid cryptographic ID of the namespace * @param name name to uniquify * @param suffix if not NULL, filled with the suffix value * @return NULL on failure (should never happen), name on success. * Free the name with GNUNET_free(). */ char * GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_HashCode * nsid, const char *name, unsigned int *suffix) { struct GNUNET_HashCode nh; uint64_t len; char *fn; struct GNUNET_DISK_FileHandle *fh; unsigned int i; unsigned int idx; char *ret; struct stat sbuf; GNUNET_CRYPTO_hash (name, strlen (name), &nh); fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); GNUNET_assert (fn != NULL); len = 0; if (0 == STAT (fn, &sbuf)) GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES)); fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); i = 0; idx = -1; while ((len >= sizeof (struct GNUNET_HashCode)) && (sizeof (struct GNUNET_HashCode) == GNUNET_DISK_file_read (fh, &nh, sizeof (struct GNUNET_HashCode)))) { if (0 == memcmp (&nh, nsid, sizeof (struct GNUNET_HashCode))) { idx = i; break; } i++; len -= sizeof (struct GNUNET_HashCode); } if (idx == -1) { idx = i; if (sizeof (struct GNUNET_HashCode) != GNUNET_DISK_file_write (fh, nsid, sizeof (struct GNUNET_HashCode))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn); } GNUNET_DISK_file_close (fh); ret = GNUNET_malloc (strlen (name) + 32); GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx); if (suffix != NULL) *suffix = idx; GNUNET_free (fn); return ret; }
/** * Signal handler called for SIGCHLD. Triggers the * respective handler by writing to the trigger pipe. */ static void sighandler_child_death () { static char c; int old_errno = errno; /* back-up errno */ GNUNET_break (1 == GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_WRITE), &c, sizeof (c))); errno = old_errno; /* restore errno */ }
/** * Clears a bit from bitArray if the respective usage * counter on the disk hits/is zero. * * @param bitArray memory area to set the bit in * @param bitIdx which bit to test * @param fh A file to keep the 4bit address usage counters in */ static void decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_FileHandle *fh) { off_t fileslot; unsigned char value; unsigned int high; unsigned int low; unsigned int targetLoc; if (GNUNET_DISK_handle_invalid (fh)) return; /* cannot decrement! */ /* Each char slot in the counter file holds two 4 bit counters */ fileslot = bitIdx / 2; targetLoc = bitIdx % 2; if (GNUNET_SYSERR == GNUNET_DISK_file_seek (fh, fileslot, GNUNET_DISK_SEEK_SET)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "seek"); return; } if (1 != GNUNET_DISK_file_read (fh, &value, 1)) value = 0; low = value & 0xF; high = (value & 0xF0) >> 4; /* decrement, but once we have reached the max, never go back! */ if (targetLoc == 0) { if ((low > 0) && (low < 0xF)) low--; if (low == 0) { clearBit (bitArray, bitIdx); } } else { if ((high > 0) && (high < 0xF)) high--; if (high == 0) { clearBit (bitArray, bitIdx); } } value = ((high << 4) | low); if (GNUNET_SYSERR == GNUNET_DISK_file_seek (fh, fileslot, GNUNET_DISK_SEEK_SET)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "seek"); return; } GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); }
static int testOpenClose () { struct GNUNET_DISK_FileHandle *fh; uint64_t size; fh = GNUNET_DISK_file_open (".testfile", GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); GNUNET_assert (GNUNET_NO == GNUNET_DISK_handle_invalid (fh)); GNUNET_break (5 == GNUNET_DISK_file_write (fh, "Hello", 5)); GNUNET_DISK_file_close (fh); GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO, GNUNET_YES)); if (size != 5) return 1; GNUNET_break (0 == UNLINK (".testfile")); return 0; }
/** * Sets a bit active in the bitArray and increments * bit-specific usage counter on disk (but only if * the counter was below 4 bit max (==15)). * * @param bitArray memory area to set the bit in * @param bitIdx which bit to test * @param fh A file to keep the 4 bit address usage counters in */ static void incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_FileHandle *fh) { OFF_T fileSlot; unsigned char value; unsigned int high; unsigned int low; unsigned int targetLoc; setBit (bitArray, bitIdx); if (GNUNET_DISK_handle_invalid (fh)) return; /* Update the counter file on disk */ fileSlot = bitIdx / 2; targetLoc = bitIdx % 2; GNUNET_assert (fileSlot == GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET)); if (1 != GNUNET_DISK_file_read (fh, &value, 1)) value = 0; low = value & 0xF; high = (value & (~0xF)) >> 4; if (targetLoc == 0) { if (low < 0xF) low++; } else { if (high < 0xF) high++; } value = ((high << 4) | low); GNUNET_assert (fileSlot == GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET)); GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); }
/** * Store values in hashmap in file and free data * * @param plugin the plugin context */ static int store_and_free_entries (void *cls, const struct GNUNET_HashCode *key, void *value) { struct GNUNET_DISK_FileHandle *fh = cls; struct FlatFileEntry *entry = value; char *line; char *block_b64; struct GNUNET_CRYPTO_HashAsciiEncoded query; size_t block_size; block_size = ntohl (entry->block->purpose.size) + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) + sizeof (struct GNUNET_CRYPTO_EcdsaSignature); GNUNET_STRINGS_base64_encode ((char*)entry->block, block_size, &block_b64); GNUNET_CRYPTO_hash_to_enc (&entry->query, &query); GNUNET_asprintf (&line, "%s,%s\n", (char*)&query, block_b64); GNUNET_free (block_b64); GNUNET_DISK_file_write (fh, line, strlen (line)); GNUNET_free (entry->block); GNUNET_free (entry); return GNUNET_YES; }
void GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l, char *experiment_name, int plots) { struct GNUNET_DISK_FileHandle *f[l->num_slaves]; struct GNUNET_DISK_FileHandle *f_m; char *tmp_exp_name; char *filename_master; char *filename_slaves[l->num_slaves]; char *data; struct PeerLoggingTimestep *cur_lt; struct PartnerLoggingTimestep *plt; struct GNUNET_TIME_Absolute timestamp; int c_m; int c_s; timestamp = GNUNET_TIME_absolute_get(); tmp_exp_name = experiment_name; for (c_m = 0; c_m < l->num_masters; c_m++) { GNUNET_asprintf (&filename_master, "%s_%llu_master%u_%s", experiment_name, timestamp.abs_value_us, c_m, l->name); fprintf (stderr, "Writing data for master %u to file `%s'\n", c_m,filename_master); f_m = GNUNET_DISK_file_open (filename_master, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == f_m) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", filename_master); GNUNET_free (filename_master); return; } GNUNET_asprintf (&data, "# master %u; experiment : %s\n" "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; \n" , c_m, experiment_name); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f_m, data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to log file `%s'\n",filename_master); GNUNET_free (data); for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) { GNUNET_asprintf (&filename_slaves[c_s], "%s_%llu_master%u_slave_%u_%s", tmp_exp_name, timestamp.abs_value_us, c_m, c_s, l->name); fprintf (stderr, "Writing data for master %u slave %u to file `%s'\n", c_m, c_s, filename_slaves[c_s]); f[c_s] = GNUNET_DISK_file_open (filename_slaves[c_s], GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == f[c_s]) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", filename_slaves[c_s]); GNUNET_free (filename_slaves[c_s]); GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close(f_m)); GNUNET_free (filename_master); return; } /* Header */ GNUNET_asprintf (&data, "# master %u; slave %u ; experiment : %s\n" "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; " \ "rtt; bw in; bw out; ats_cost_lan; ats_cost_wlan; ats_delay; ats_distance; ats_network_type; ats_utilization_up ;ats_utilization_down;" \ "pref bandwidth; pref delay\n", c_m, c_s, experiment_name); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f[c_s], data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to log file `%s'\n",filename_slaves[c_s]); GNUNET_free (data); } for (cur_lt = l->lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next) { if (l->verbose) fprintf (stderr, "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n", l->lp[c_m].peer->no, (long long unsigned int) cur_lt->timestamp.abs_value_us, (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start, cur_lt->timestamp).rel_value_us / 1000, cur_lt->total_messages_sent, cur_lt->total_bytes_sent, cur_lt->total_throughput_send, cur_lt->total_messages_received, cur_lt->total_bytes_received, cur_lt->total_throughput_recv); /* Assembling master string */ GNUNET_asprintf (&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;\n", (long long unsigned int) cur_lt->timestamp.abs_value_us, (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start, cur_lt->timestamp).rel_value_us / 1000, cur_lt->total_messages_sent, cur_lt->total_bytes_sent, cur_lt->total_throughput_send, cur_lt->total_messages_received, cur_lt->total_bytes_received, cur_lt->total_throughput_recv); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f_m, data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to master file %u\n", c_m); GNUNET_free (data); for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) { plt = &cur_lt->slaves_log[c_s]; /* Log partners */ /* Assembling slave string */ GNUNET_asprintf(&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%u;%u;%u;%u;%u;%.3f;%.3f\n", (long long unsigned int) cur_lt->timestamp.abs_value_us, (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start, cur_lt->timestamp).rel_value_us / 1000, plt->total_messages_sent, plt->total_bytes_sent, plt->throughput_sent, plt->total_messages_received, plt->total_bytes_received, plt->throughput_recv, (double) plt->app_rtt / 1000, plt->bandwidth_in, plt->bandwidth_out, plt->ats_delay, plt->ats_distance, plt->ats_network_type, plt->ats_utilization_out, plt->ats_utilization_in, plt->pref_bandwidth, plt->pref_delay); if (l->verbose) fprintf (stderr, "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %llu bw_in %u bw_out %u \n", plt->slave->no, plt->total_messages_sent, plt->total_bytes_sent, plt->throughput_sent, plt->total_messages_received, plt->total_bytes_received, plt->throughput_recv, plt->app_rtt, (long long unsigned int) plt->ats_delay.rel_value_us, plt->bandwidth_in, plt->bandwidth_out); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f[c_s], data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to log file `%s'\n", filename_slaves[c_s]); GNUNET_free (data); } } for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) { if (GNUNET_SYSERR == GNUNET_DISK_file_close(f[c_s])) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close log file for master[%u] slave[%u]\n", c_m, c_s); continue; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Data file successfully written to log file for `%s'\n", filename_slaves[c_s]); } if (GNUNET_SYSERR == GNUNET_DISK_file_close(f_m)) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "close", filename_master); GNUNET_free (filename_master); return; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Data file successfully written to log file for master `%s'\n", filename_master); if (GNUNET_YES == plots) { write_throughput_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves); write_rtt_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves); write_bw_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves); } } GNUNET_free (filename_master); }
static void write_throughput_gnuplot_script (char * fn, struct LoggingPeer *lp, char **fs, int slaves) { struct GNUNET_DISK_FileHandle *f; char * gfn; char *data; int c_s; GNUNET_asprintf (&gfn, "gnuplot_throughput_%s",fn); fprintf (stderr, "Writing throughput plot for master %u and %u slaves to `%s'\n", lp->peer->no, slaves, gfn); f = GNUNET_DISK_file_open (gfn, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_EXEC | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == f) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", gfn); GNUNET_free (gfn); return; } /* Write header */ if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, THROUGHPUT_TEMPLATE, strlen(THROUGHPUT_TEMPLATE))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn); /* Write master data */ GNUNET_asprintf (&data, "plot '%s' using 2:%u with lines title 'Master %u send total', \\\n" \ "'%s' using 2:%u with lines title 'Master %u receive total', \\\n", fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no, fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn); GNUNET_free (data); for (c_s = 0; c_s < slaves; c_s++) { GNUNET_asprintf (&data, "'%s' using 2:%u with lines title 'Master %u - Slave %u send', \\\n" \ "'%s' using 2:%u with lines title 'Master %u - Slave %u receive'%s\n", fs[c_s], LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no, lp->peer->partners[c_s].dest->no, fs[c_s], LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no, lp->peer->partners[c_s].dest->no, (c_s < lp->peer->num_partners -1) ? ", \\" : "\n pause -1"); if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn); GNUNET_free (data); } if (GNUNET_SYSERR == GNUNET_DISK_file_close(f)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n", gfn); else GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Data successfully written to plot file `%s'\n", gfn); GNUNET_free (gfn); }
int main (int argc, char *argv[]) { struct GNUNET_DISK_FileHandle *fh; struct GNUNET_HELLO_Message *orig; struct GNUNET_HELLO_Message *result; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk; uint64_t fsize; GNUNET_log_setup ("gnunet-hello", "INFO", NULL); if (argc != 2) { FPRINTF (stderr, "%s", _("Call with name of HELLO file to modify.\n")); return 1; } if (GNUNET_OK != GNUNET_DISK_file_size (argv[1], &fsize, GNUNET_YES, GNUNET_YES)) { FPRINTF (stderr, _("Error accessing file `%s': %s\n"), argv[1], STRERROR (errno)); return 1; } if (fsize > 65536) { FPRINTF (stderr, _("File `%s' is too big to be a HELLO\n"), argv[1]); return 1; } if (fsize < sizeof (struct GNUNET_MessageHeader)) { FPRINTF (stderr, _("File `%s' is too small to be a HELLO\n"), argv[1]); return 1; } fh = GNUNET_DISK_file_open (argv[1], GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_USER_READ); if (NULL == fh) { FPRINTF (stderr, _("Error opening file `%s': %s\n"), argv[1], STRERROR (errno)); return 1; } { char buf[fsize] GNUNET_ALIGN; GNUNET_assert (fsize == GNUNET_DISK_file_read (fh, buf, fsize)); GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); orig = (struct GNUNET_HELLO_Message *) buf; if ( (fsize != GNUNET_HELLO_size (orig)) || (GNUNET_OK != GNUNET_HELLO_get_key (orig, &pk)) ) { FPRINTF (stderr, _("Did not find well-formed HELLO in file `%s'\n"), argv[1]); return 1; } result = GNUNET_HELLO_create (&pk, &add_from_hello, &orig); GNUNET_assert (NULL != result); fh = GNUNET_DISK_file_open (argv[1], GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == fh) { FPRINTF (stderr, _("Error opening file `%s': %s\n"), argv[1], STRERROR (errno)); GNUNET_free (result); return 1; } fsize = GNUNET_HELLO_size (result); if (fsize != GNUNET_DISK_file_write (fh, result, fsize)) { FPRINTF (stderr, _("Error writing HELLO to file `%s': %s\n"), argv[1], STRERROR (errno)); (void) GNUNET_DISK_file_close (fh); return 1; } GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); } return 0; }
/** * Create a new private key by reading it from a file. If the * files does not exist, create a new key and write it to the * file. Caller must free return value. Note that this function * can not guarantee that another process might not be trying * the same operation on the same file at the same time. * If the contents of the file * are invalid the old file is deleted and a fresh key is * created. * * @param filename name of file to use to store the key * @return new private key, NULL on error (for example, * permission denied) */ struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename) { struct GNUNET_CRYPTO_EddsaPrivateKey *priv; struct GNUNET_DISK_FileHandle *fd; unsigned int cnt; int ec; uint64_t fs; if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) return NULL; while (GNUNET_YES != GNUNET_DISK_file_test (filename)) { fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_FAILIFEXISTS, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == fd) { if (EEXIST == errno) { if (GNUNET_YES != GNUNET_DISK_file_test (filename)) { /* must exist but not be accessible, fail for good! */ if (0 != ACCESS (filename, R_OK)) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename); else GNUNET_break (0); /* what is going on!? */ return NULL; } continue; } LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); return NULL; } cnt = 0; while (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey), GNUNET_YES)) { short_wait (); if (0 == ++cnt % 10) { ec = errno; LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not acquire lock on file `%s': %s...\n"), filename, STRERROR (ec)); } } LOG (GNUNET_ERROR_TYPE_INFO, _("Creating a new private key. This may take a while.\n")); priv = GNUNET_CRYPTO_eddsa_key_create (); GNUNET_assert (NULL != priv); GNUNET_assert (sizeof (*priv) == GNUNET_DISK_file_write (fd, priv, sizeof (*priv))); GNUNET_DISK_file_sync (fd); if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); return priv; } /* key file exists already, read it! */ fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); if (NULL == fd) { LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); return NULL; } cnt = 0; while (1) { if (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey), GNUNET_NO)) { if (0 == ++cnt % 60) { ec = errno; LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not acquire lock on file `%s': %s...\n"), filename, STRERROR (ec)); LOG (GNUNET_ERROR_TYPE_ERROR, _ ("This may be ok if someone is currently generating a private key.\n")); } short_wait (); continue; } if (GNUNET_YES != GNUNET_DISK_file_test (filename)) { /* eh, what!? File we opened is now gone!? */ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename); if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); return NULL; } if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) fs = 0; if (fs < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) { /* maybe we got the read lock before the key generating * process had a chance to get the write lock; give it up! */ if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); if (0 == ++cnt % 10) { LOG (GNUNET_ERROR_TYPE_ERROR, _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"), filename, (unsigned int) fs, (unsigned int) sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); LOG (GNUNET_ERROR_TYPE_ERROR, _("This may be ok if someone is currently generating a key.\n")); } short_wait (); /* wait a bit longer! */ continue; } break; } fs = sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey); priv = GNUNET_malloc (fs); GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs)); if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); return priv; }
/** * Write to the helper-process * * @param cls handle to the helper process */ static void helper_write (void *cls) { struct GNUNET_HELPER_Handle *h = cls; struct GNUNET_HELPER_SendHandle *sh; const char *buf; ssize_t t; h->write_task = NULL; if (NULL == (sh = h->sh_head)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Helper write had no work!\n"); return; /* how did this happen? */ } buf = (const char*) sh->msg; t = GNUNET_DISK_file_write (h->fh_to_helper, &buf[sh->wpos], ntohs (sh->msg->size) - sh->wpos); if (-1 == t) { /* On write-error, restart the helper */ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Error writing to `%s': %s\n"), h->binary_name, STRERROR (errno)); if (NULL != h->exp_cb) { h->exp_cb (h->cb_cls); GNUNET_HELPER_stop (h, GNUNET_NO); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping and restarting helper task!\n"); stop_helper (h, GNUNET_NO); /* Restart the helper */ h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, h->retry_back_off), &restart_task, h); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitted %u bytes to %s\n", (unsigned int) t, h->binary_name); sh->wpos += t; if (sh->wpos == ntohs (sh->msg->size)) { GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh); if (NULL != sh->cont) sh->cont (sh->cont_cls, GNUNET_YES); GNUNET_free (sh); } if (NULL != h->sh_head) h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, h->fh_to_helper, &helper_write, h); }