static void report_text_subtitle(ReportContext * ctx, gchar * text) { gchar *str = ctx->output; int i = strlen(text); str = h_strdup_cprintf("\n%s\n", str, text); for (; i; i--) str = h_strconcat(str, "-", NULL); str = h_strconcat(str, "\n\n", NULL); ctx->output = str; }
static void dbstore_move_file(const char *old_path, const char *new_path, const char *ext) { char *old_file = h_strconcat(old_path, ext, (void *) 0); char *new_file = h_strconcat(new_path, ext, (void *) 0); if (file_exists(old_file)) { if (-1 == rename(old_file, new_file)) { g_warning("could not rename \"%s\" as \"%s\": %m", old_file, new_file); } } HFREE_NULL(old_file); HFREE_NULL(new_file); }
static void dbstore_unlink_file(const char *path, const char *ext) { char *file = h_strconcat(path, ext, NULL_PTR); if (file_exists(file)) { if (-1 == unlink(file)) { s_carp("could not unlink \"%s\": %m", file); } } HFREE_NULL(file); }
/** * Open configuration file for writing. We don't clobber the existing file * yet and open a ".new" instead. Renaming will occur afterwards, when * file_config_close() is called. * * @returns opened FILE if success, NULL on error. */ static FILE * file_config_open(const char *what, const file_path_t *fv) { FILE *out = NULL; char *path; path = h_strconcat(fv->dir, G_DIR_SEPARATOR_S, fv->name, ".", new_ext, (void *) 0); g_return_val_if_fail(NULL != path, NULL); if (is_absolute_path(path)) { out = file_fopen(path, "w"); if (out == NULL) s_warning("unable to persist %s", what); } HFREE_NULL(path); return out; }
/** * Create new pathname from the concatenation of the dirname and the basename * of the file. A directory separator is inserted, unless "dir" already ends * with one or "file" starts with one. * * @param dir the directory path * @param file the filename * * @return a newly allocated string that must be freed with hfree(). */ char * make_pathname(const char *dir, const char *file) { const char *sep; size_t n; g_assert(dir); g_assert(file); n = strlen(dir); if (G_DIR_SEPARATOR == file[0] || '/' == file[0]) sep = ""; else if (n > 0 && G_DIR_SEPARATOR == dir[n - 1]) sep = ""; else if (G_DIR_SEPARATOR != '/' && n > 0 && '/' == dir[n - 1]) sep = ""; else if (G_DIR_SEPARATOR != '/' && strchr(dir, G_DIR_SEPARATOR)) sep = G_DIR_SEPARATOR_S; else sep = "/"; return h_strconcat(dir, sep, file, (void *) 0); }
/** * Writes the browse host data of the context ``ctx'' to the buffer * ``dest''. This must be called multiple times to retrieve the complete * data until zero is returned i.e., the end of file is reached. * * This routine deals with HTML data generation. * * @param ctx an initialized browse host context. * @param dest the destination buffer. * @param size the amount of bytes ``dest'' can hold. * * @return -1 on failure, zero at the end-of-file condition or if size * was zero. On success, the amount of bytes copied to ``dest'' * is returned. */ static ssize_t browse_host_read_html(struct special_upload *ctx, void *const dest, size_t size) { static const char header[] = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\r\n" "<html>\r\n" "<head>\r\n" "<title>Browse Host</title>\r\n" "</head>\r\n" "<body>\r\n"; static const char trailer[] = "</ul>\r\n</body>\r\n</html>\r\n"; struct browse_host_upload *bh = cast_to_browse_host_upload(ctx); char *p = dest; g_assert(NULL != bh); g_assert(NULL != dest); g_assert(size <= INT_MAX); g_assert(UNSIGNED(bh->state) < NUM_BH_STATES); g_assert(bh->b_size <= INT_MAX); g_assert(bh->b_offset <= bh->b_size); do { switch (bh->state) { case BH_STATE_HEADER: if (!bh->b_data) { bh->b_data = header; bh->b_size = CONST_STRLEN(header); } p += browse_host_read_data(bh, p, &size); if (bh->b_size == bh->b_offset) browse_host_next_state(bh, BH_STATE_LIBRARY_INFO); break; case BH_STATE_LIBRARY_INFO: if (!bh->b_data) { bh->w_buf_size = w_concat_strings(&bh->w_buf, "<h1>", product_get_name(), "</h1>\r\n" "<h3>", version_get_string(), " sharing ", uint64_to_string(shared_files_scanned()), " file", shared_files_scanned() == 1 ? "" : "s", " ", short_kb_size(shared_kbytes_scanned(), GNET_PROPERTY(display_metric_units)), " total</h3>\r\n" "<ul>\r\n", (void *) 0); bh->b_data = bh->w_buf; bh->b_size = bh->w_buf_size - 1; /* minus trailing NUL */ bh->b_offset = 0; } p += browse_host_read_data(bh, p, &size); if (bh->b_size == bh->b_offset) browse_host_next_state(bh, BH_STATE_FILES); break; case BH_STATE_TRAILER: if (!bh->b_data) { bh->b_data = trailer; bh->b_size = CONST_STRLEN(trailer); } p += browse_host_read_data(bh, p, &size); if (bh->b_size == bh->b_offset) browse_host_next_state(bh, BH_STATE_EOF); break; case BH_STATE_FILES: if (bh->b_data && bh->b_size == bh->b_offset) { g_assert(bh->w_buf == bh->b_data); wfree(bh->w_buf, bh->w_buf_size); bh->w_buf = NULL; bh->w_buf_size = 0; bh->b_data = NULL; } if (!bh->b_data) { const shared_file_t *sf; bh->file_index++; sf = shared_file_sorted(bh->file_index); if (!sf) { if (bh->file_index > shared_files_scanned()) browse_host_next_state(bh, BH_STATE_TRAILER); /* Skip holes in the file_index table */ } else if (SHARE_REBUILDING == sf) { browse_host_next_state(bh, BH_STATE_REBUILDING); } else { const char * const name_nfc = shared_file_name_nfc(sf); const filesize_t file_size = shared_file_size(sf); size_t html_size; char *html_name; { const char *dir; char *name; dir = shared_file_relative_path(sf); if (dir) { name = h_strconcat(dir, "/", name_nfc, (void *) 0); } else { name = deconstify_char(name_nfc); } html_size = 1 + html_escape(name, NULL, 0); html_name = walloc(html_size); html_escape(name, html_name, html_size); if (name != name_nfc) { HFREE_NULL(name); } } if (sha1_hash_available(sf)) { const struct sha1 *sha1 = shared_file_sha1(sf); bh->w_buf_size = w_concat_strings(&bh->w_buf, "<li><a href=\"/uri-res/N2R?urn:sha1:", sha1_base32(sha1), "\">", html_name, "</a> [", short_html_size(file_size, GNET_PROPERTY(display_metric_units)), "]</li>\r\n", (void *) 0); } else { char *escaped; escaped = url_escape(name_nfc); bh->w_buf_size = w_concat_strings(&bh->w_buf, "<li><a href=\"/get/", uint32_to_string(shared_file_index(sf)), "/", escaped, "\">", html_name, "</a>" " [", short_html_size(file_size, GNET_PROPERTY(display_metric_units)), "]</li>\r\n", (void *) 0); if (escaped != name_nfc) { HFREE_NULL(escaped); } } wfree(html_name, html_size); bh->b_data = bh->w_buf; bh->b_size = bh->w_buf_size - 1; /* minus trailing NUL */ bh->b_offset = 0; } } if (bh->b_data) p += browse_host_read_data(bh, p, &size); break; case BH_STATE_REBUILDING: if (!bh->b_data) { static const char msg[] = "<li>" "<b>" "The library is currently being rebuild. Please, " "try again in a moment." "</b>" "</li>"; bh->b_data = msg; bh->b_size = CONST_STRLEN(msg); } p += browse_host_read_data(bh, p, &size); if (bh->b_size == bh->b_offset) browse_host_next_state(bh, BH_STATE_TRAILER); break; case BH_STATE_EOF: return p - cast_to_char_ptr(dest); case NUM_BH_STATES: g_assert_not_reached(); } } while (size > 0); return p - cast_to_char_ptr(dest); }
void __scan_ide_devices(void) { FILE *proc_ide; gchar *device, iface, *model, *media, *pgeometry = NULL, *lgeometry = NULL; gint n = 0, i = 0, cache, nn = 0; gchar *capab = NULL, *speed = NULL, *driver = NULL, *ide_storage_list; /* remove old devices from global device table */ moreinfo_del_with_prefix("DEV:IDE"); ide_storage_list = g_strdup(_("\n[IDE Disks]\n")); iface = 'a'; for (i = 0; i <= 16; i++) { device = g_strdup_printf("/proc/ide/hd%c/model", iface); if (g_file_test(device, G_FILE_TEST_EXISTS)) { gchar buf[128]; cache = 0; proc_ide = fopen(device, "r"); if (!proc_ide) continue; (void) fgets(buf, 128, proc_ide); fclose(proc_ide); buf[strlen(buf) - 1] = 0; model = g_strdup(buf); g_free(device); device = g_strdup_printf("/proc/ide/hd%c/media", iface); proc_ide = fopen(device, "r"); if (!proc_ide) { free(model); continue; } (void) fgets(buf, 128, proc_ide); fclose(proc_ide); buf[strlen(buf) - 1] = 0; media = g_strdup(buf); if (g_str_equal(media, "cdrom")) { /* obtain cd-rom drive information from cdrecord */ GTimer *timer; gchar *tmp = g_strdup_printf("cdrecord dev=/dev/hd%c -prcap 2>/dev/stdout", iface); FILE *prcap; if ((prcap = popen(tmp, "r"))) { /* we need a timeout so cdrecord does not try to get information on cd drives with inserted media, which is not possible currently. half second should be enough. */ timer = g_timer_new(); g_timer_start(timer); while (fgets(buf, 128, prcap) && g_timer_elapsed(timer, NULL) < 0.5) { if (g_str_has_prefix(buf, " Does")) { if (g_str_has_suffix(buf, "media\n") && !strstr(buf, "speed")) { gchar *media_type = g_strstrip(strstr(buf, "Does ")); gchar **ttmp = g_strsplit(media_type, " ", 0); capab = h_strdup_cprintf("\nCan %s#%d=%s\n", capab, ttmp[1], ++nn, ttmp[2]); g_strfreev(ttmp); } else if (strstr(buf, "Buffer-Underrun-Free")) { capab = h_strdup_cprintf ("\nSupports BurnProof=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes"); } else if (strstr(buf, "multi-session")) { capab = h_strdup_cprintf ("\nCan read multi-session CDs=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes"); } else if (strstr(buf, "audio CDs")) { capab = h_strdup_cprintf ("\nCan play audio CDs=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes"); } else if (strstr(buf, "PREVENT/ALLOW")) { capab = h_strdup_cprintf ("\nCan lock media=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes"); } } else if ((strstr(buf, "read") || strstr(buf, "write")) && strstr(buf, "kB/s")) { speed = g_strconcat(speed ? speed : "", strreplacechr(g_strstrip(buf), ":", '='), "\n", NULL); } else if (strstr(buf, "Device seems to be")) { driver = g_strdup_printf(_("Driver=%s\n"), strchr(buf, ':') + 1); } } pclose(prcap); g_timer_destroy(timer); } g_free(tmp); } g_free(device); device = g_strdup_printf("/proc/ide/hd%c/cache", iface); if (g_file_test(device, G_FILE_TEST_EXISTS)) { proc_ide = fopen(device, "r"); if (proc_ide) { (void) fscanf(proc_ide, "%d", &cache); fclose(proc_ide); } else { cache = 0; } } g_free(device); device = g_strdup_printf("/proc/ide/hd%c/geometry", iface); if (g_file_test(device, G_FILE_TEST_EXISTS)) { gchar *tmp; proc_ide = fopen(device, "r"); if (proc_ide) { (void) fgets(buf, 64, proc_ide); for (tmp = buf; *tmp; tmp++) { if (*tmp >= '0' && *tmp <= '9') break; } pgeometry = g_strdup(g_strstrip(tmp)); (void) fgets(buf, 64, proc_ide); for (tmp = buf; *tmp; tmp++) { if (*tmp >= '0' && *tmp <= '9') break; } lgeometry = g_strdup(g_strstrip(tmp)); fclose(proc_ide); } else { pgeometry = g_strdup("Unknown"); lgeometry = g_strdup("Unknown"); } } g_free(device); n++; gchar *devid = g_strdup_printf("IDE%d", n); ide_storage_list = h_strdup_cprintf("$%s$%s=\n", ide_storage_list, devid, model); storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, model, g_str_equal(media, "cdrom") ? "cdrom" : "hdd"); gchar *strhash = g_strdup_printf(_("[Device Information]\n" "Model=%s\n"), model); const gchar *url = vendor_get_url(model); if (url) { strhash = h_strdup_cprintf(_("Vendor=%s (%s)\n"), strhash, vendor_get_name(model), url); } else { strhash = h_strdup_cprintf(_("Vendor=%s\n"), strhash, vendor_get_name(model)); } strhash = h_strdup_cprintf(_("Device Name=hd%c\n" "Media=%s\n" "Cache=%dkb\n"), strhash, iface, media, cache); if (driver) { strhash = h_strdup_cprintf("%s\n", strhash, driver); g_free(driver); driver = NULL; } if (pgeometry && lgeometry) { strhash = h_strdup_cprintf(_("[Geometry]\n" "Physical=%s\n" "Logical=%s\n"), strhash, pgeometry, lgeometry); g_free(pgeometry); pgeometry = NULL; g_free(lgeometry); lgeometry = NULL; } if (capab) { strhash = h_strdup_cprintf(_("[Capabilities]\n%s"), strhash, capab); g_free(capab); capab = NULL; } if (speed) { strhash = h_strdup_cprintf(_("[Speeds]\n%s"), strhash, speed); g_free(speed); speed = NULL; } moreinfo_add_with_prefix("DEV", devid, strhash); g_free(devid); g_free(model); } else { g_free(device); } iface++; } if (n) { storage_list = h_strconcat(storage_list, ide_storage_list, NULL); g_free(ide_storage_list); } }
gboolean __scan_udisks2_devices(void) { GSList *node, *drives; udiskd *disk; gchar *udisks2_storage_list = NULL, *features = NULL, *moreinfo = NULL; gchar *devid, *label; const gchar *url, *vendor_str, *icon; int n = 0, i; static struct { char *media_prefix; char *icon; } media2icon[] = { { "thumb", "usbfldisk"}, { "flash", "usbfldisk"}, { "floppy", "media-floppy"}, { "optical", "cdrom"}, { NULL, NULL} }; moreinfo_del_with_prefix("DEV:UDISKS"); udisks2_storage_list = g_strdup(_("\n[UDisks2]\n")); drives = get_udisks2_all_drives_info(); for (node = drives; node != NULL; node = node->next) { disk = (udiskd *)node->data; devid = g_strdup_printf("UDISKS%d", n++); if (disk->vendor && strlen(disk->vendor) > 0) { label = g_strdup_printf("%s %s", disk->vendor, disk->model); vendor_str = disk->vendor; } else{ label = g_strdup(disk->model); vendor_str = disk->model; } icon = NULL; if (disk->media_compatibility){ for (i = 0; media2icon[i].media_prefix != NULL; i++) { if (g_str_has_prefix(disk->media_compatibility, media2icon[i].media_prefix)) { icon = media2icon[i].icon; break; } } } if (icon == NULL && disk->ejectable && g_strcmp0(disk->connection_bus, "usb") == 0) { icon = "usbfldisk"; } if (icon == NULL){ icon = "hdd"; } url = vendor_get_url(vendor_str); udisks2_storage_list = h_strdup_cprintf("$%s$%s=\n", udisks2_storage_list, devid, label); storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, label, icon); features = h_strdup_cprintf("%s", features, disk->removable ? _("Removable"): _("Fixed")); if (disk->ejectable) { features = h_strdup_cprintf(", %s", features, _("Ejectable")); } if (disk->smart_enabled) { features = h_strdup_cprintf(", %s", features, _("Smart monitoring")); } moreinfo = g_strdup_printf(_("[Drive Information]\n" "Model=%s\n"), label); if (url) { moreinfo = h_strdup_cprintf(_("Vendor=%s (%s)\n"), moreinfo, vendor_get_name(vendor_str), url); } else { moreinfo = h_strdup_cprintf(_("Vendor=%s\n"), moreinfo, vendor_get_name(vendor_str)); } moreinfo = h_strdup_cprintf(_("Revision=%s\n" "Block Device=%s\n" "Serial=%s\n" "Size=%s\n" "Features=%s\n"), moreinfo, disk->revision, disk->block_dev, disk->serial, size_human_readable((gfloat) disk->size), features); if (disk->rotation_rate > 0) { moreinfo = h_strdup_cprintf(_("Rotation Rate=%d\n"), moreinfo, disk->rotation_rate); } if (disk->media_compatibility || disk->media) { moreinfo = h_strdup_cprintf(_("Media=%s\n" "Media compatibility=%s\n"), moreinfo, disk->media ? disk->media : _("(None)"), disk->media_compatibility ? disk->media_compatibility : _("(Unknown)")); } if (disk->connection_bus && strlen(disk->connection_bus) > 0) { moreinfo = h_strdup_cprintf(_("Connection bus=%s\n"), moreinfo, disk->connection_bus); } if (disk->smart_enabled) { moreinfo = h_strdup_cprintf(_("[Smart monitoring]\n" "Status=%s\n" "Bad Sectors=%ld\n" "Power on time=%d days %d hours\n" "Temperature=%d°C\n"), moreinfo, disk->smart_failing ? _("Failing"): _("OK"), disk->smart_bad_sectors, disk->smart_poweron/(60*60*24), (disk->smart_poweron/60/60) % 24, disk->smart_temperature); } moreinfo_add_with_prefix("DEV", devid, moreinfo); g_free(devid); g_free(features); g_free(label); features = NULL; moreinfo = NULL; devid = NULL; udiskd_free(disk); } g_slist_free(drives); if (n) { storage_list = h_strconcat(storage_list, udisks2_storage_list, NULL); g_free(udisks2_storage_list); return TRUE; } g_free(udisks2_storage_list); return FALSE; }
/* SCSI support by Pascal F.Martin <*****@*****.**> */ void __scan_scsi_devices(void) { FILE *proc_scsi; gchar buffer[256], *buf; gint n = 0; gint scsi_controller = 0; gint scsi_channel = 0; gint scsi_id = 0 ; gint scsi_lun = 0; gchar *vendor = NULL, *revision = NULL, *model = NULL; gchar *scsi_storage_list; /* remove old devices from global device table */ moreinfo_del_with_prefix("DEV:SCSI"); scsi_storage_list = g_strdup(_("\n[SCSI Disks]\n")); int otype = 0; if (proc_scsi = fopen("/proc/scsi/scsi", "r")) { otype = 1; } else if (proc_scsi = popen("lsscsi -c", "r")) { otype = 2; } if (otype) { while (fgets(buffer, 256, proc_scsi)) { buf = g_strstrip(buffer); if (!strncmp(buf, "Host: scsi", 10)) { sscanf(buf, "Host: scsi%d Channel: %d Id: %d Lun: %d", &scsi_controller, &scsi_channel, &scsi_id, &scsi_lun); n++; } else if (!strncmp(buf, "Vendor: ", 8)) { buf[17] = '\0'; buf[41] = '\0'; buf[53] = '\0'; vendor = g_strdup(g_strstrip(buf + 8)); model = g_strdup_printf("%s %s", vendor, g_strstrip(buf + 24)); revision = g_strdup(g_strstrip(buf + 46)); } else if (!strncmp(buf, "Type: ", 8)) { char *p; gchar *type = NULL, *icon = NULL; if (!(p = strstr(buf, "ANSI SCSI revision"))) { p = strstr(buf, "ANSI SCSI revision"); } if (p != NULL) { while (*(--p) == ' '); *(++p) = 0; static struct { char *type; char *label; char *icon; } type2icon[] = { { "Direct-Access", "Disk", "hdd"}, { "Sequential-Access", "Tape", "tape"}, { "Printer", "Printer", "lpr"}, { "WORM", "CD-ROM", "cdrom"}, { "CD-ROM", "CD-ROM", "cdrom"}, { "Scanner", "Scanner", "scanner"}, { "Flash Disk", "USB Flash Disk", "usbfldisk" }, { NULL, "Generic", "scsi"} }; int i; if (model && strstr(model, "Flash Disk")) { type = "Flash Disk"; icon = "usbfldisk"; } else { for (i = 0; type2icon[i].type != NULL; i++) if (g_str_equal(buf + 8, type2icon[i].type)) break; type = type2icon[i].label; icon = type2icon[i].icon; } } gchar *devid = g_strdup_printf("SCSI%d", n); scsi_storage_list = h_strdup_cprintf("$%s$%s=\n", scsi_storage_list, devid, model); storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, model, icon); gchar *strhash = g_strdup_printf(_("[Device Information]\n" "Model=%s\n"), model); const gchar *url = vendor_get_url(model); if (url) { strhash = h_strdup_cprintf(_("Vendor=%s (%s)\n"), strhash, vendor_get_name(model), url); } else { strhash = h_strdup_cprintf(_("Vendor=%s\n"), strhash, vendor_get_name(model)); } strhash = h_strdup_cprintf(_("Type=%s\n" "Revision=%s\n" "[SCSI Controller]\n" "Controller=scsi%d\n" "Channel=%d\n" "ID=%d\n" "LUN=%d\n"), strhash, type, revision, scsi_controller, scsi_channel, scsi_id, scsi_lun); moreinfo_add_with_prefix("DEV", devid, strhash); g_free(devid); g_free(model); g_free(revision); g_free(vendor); scsi_controller = scsi_channel = scsi_id = scsi_lun = 0; } } if (otype == 1) fclose(proc_scsi); else if (otype == 2) pclose(proc_scsi); } if (n) { storage_list = h_strconcat(storage_list, scsi_storage_list, NULL); g_free(scsi_storage_list); } }
static void report_html_footer(ReportContext * ctx) { ctx->output = h_strconcat(ctx->output, "</tbody></table></body></html>", NULL); }
/** * Make filename prettier, by removing leading "_", making sure the filename * does not start with "-" or ".", and stripping consecutive "_" or "_" that * surround a punctuation character. * * Finally, ensure the filename is not completely empty, as this is * awkward to manipulate from a shell. * * @param filename the filename to beautify * * @returns a newly allocated string holding the beautified filename, even if * it is a mere copy of the original. */ char * filename_beautify(const char *filename) { const char *s; char *q; uchar c; size_t len; size_t j = 0; static const char punct[] = "_-+=.,<>{}[]"; /* 1st MUST be '_' */ static const char strip[] = "_-."; static const char empty[] = "{empty}"; g_assert(filename); s = filename; len = strlen(filename); q = halloc(len + 1); /* Trailing NUL */ while ((c = *s++)) { uchar d; /* Beautified filename cannot start with stripped characters */ if (j == 0) { if (NULL == strchr(strip, c)) q[j++] = c; continue; } g_assert(j > 0); d = q[j - 1]; /* Last char we've kept in beautified name */ /* A "_" followed by a punctuation character, strip the "_" */ if (d == '_' && NULL != strchr(punct, c)) { q[j - 1] = c; continue; } /* A punctuation character followed by "_", ignore that "_" */ if (NULL != strchr(&punct[1], d) && c == '_') continue; q[j++] = c; } g_assert(j <= len); q[j] = '\0'; /* Ensure we have no empty name */ if (j == 0) { HFREE_NULL(q); return h_strdup(empty); } /* * If there was an extension following stripped chars (e.g. "_.ext"), * then the filename kept will become "ext" (we assume a valid extension * cannot contain "escaped" chars). In which case we will prepend the * string "{empty}." to it. */ if (NULL == strchr(q, '.') && j < len && '.' == filename[len - j]) { char *r = h_strconcat(empty, ".", q, NULL_PTR); HFREE_NULL(q); return r; } return q; }