/** * Rozpoczyna wysyłanie pliku o danej nazwie. * * \param sess Struktura sesji * \param rcpt Numer odbiorcy * \param filename Nazwa pliku w lokalnym systemie plików * \param filename1250 Nazwa pliku w kodowaniu CP-1250 * \param hash Skrót SHA-1 pliku (lub \c NULL jeśli ma być wyznaczony) * * \return Struktura \c gg_dcc7 lub \c NULL w przypadku błędu * * \ingroup dcc7 */ struct gg_dcc7 *gg_dcc7_send_file(struct gg_session *sess, uin_t rcpt, const char *filename, const char *filename1250, const char *hash) { struct gg_dcc7 *dcc = NULL; const char *tmp; char hash_buf[GG_DCC7_HASH_LEN]; struct stat st; int fd = -1; gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_send_file(%p, %d, \"%s\", %p)\n", sess, rcpt, filename, hash); if (!sess || !rcpt || !filename) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file() invalid parameters\n"); errno = EINVAL; goto fail; } if (!filename1250) filename1250 = filename; if (stat(filename, &st) == -1) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file() stat() failed (%s)\n", strerror(errno)); goto fail; } if ((st.st_mode & S_IFDIR)) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file() that's a directory\n"); errno = EINVAL; goto fail; } if ((fd = open(filename, O_RDONLY)) == -1) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_send_file() open() failed (%s)\n", strerror(errno)); goto fail; } if (!hash) { if (gg_file_hash_sha1(fd, (uint8_t*) hash_buf) == -1) goto fail; hash = hash_buf; } if ((tmp = strrchr(filename1250, '/'))) filename1250 = tmp + 1; if (!(dcc = gg_dcc7_send_file_common(sess, rcpt, fd, st.st_size, filename1250, hash, 1))) goto fail; return dcc; fail: if (fd != -1) { int errsv = errno; close(fd); errno = errsv; } free(dcc); return NULL; }
/** * \internal Rozpoczyna wysyłanie pliku o danym deskryptorze. * * \note Wysyłanie pliku nie będzie działać poprawnie, jeśli deskryptor * źródłowy jest w trybie nieblokującym i w pewnym momencie zabraknie danych. * * \param sess Struktura sesji * \param rcpt Numer odbiorcy * \param fd Deskryptor pliku * \param size Rozmiar pliku * \param filename1250 Nazwa pliku w kodowaniu CP-1250 * \param hash Skrót SHA-1 pliku * * \return Struktura \c gg_dcc7 lub \c NULL w przypadku błędu * * \ingroup dcc7 */ struct gg_dcc7 *gg_dcc7_send_file_fd(struct gg_session *sess, uin_t rcpt, int fd, size_t size, const char *filename1250, const char *hash) { gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_dcc7_send_file_fd(%p, %d, %d, %u, \"%s\", %p)\n", sess, rcpt, fd, size, filename1250, hash); return gg_dcc7_send_file_common(sess, rcpt, fd, size, filename1250, hash, 0); }