aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-07-24 02:50:11 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-07-24 02:50:11 +0000
commitf45e439c3a12eeda28c2401207b97267ea10f74f (patch)
treea9655c841ea02c069c727476609c646392c5d307
parentab644035af51b173570ed2fbd12bfd7604c8321c (diff)
Work on copy of firmware so that it doesn't get corrupted on a "make install" (bug #2106)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@3500 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xchannels/chan_iax2.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 58945b711..fd1ae70c6 100755
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -924,11 +924,28 @@ static int try_firmware(char *s)
{
struct stat stbuf;
struct iax_firmware *cur;
+ int ifd;
int fd;
int res;
+
struct ast_iax2_firmware_header *fwh, fwh2;
struct MD5Context md5;
unsigned char sum[16];
+ unsigned char buf[1024];
+ int len, chunk;
+ char *s2;
+ char *last;
+ s2 = alloca(strlen(s) + 100);
+ if (!s2) {
+ ast_log(LOG_WARNING, "Alloca failed!\n");
+ return -1;
+ }
+ last = strrchr(s, '/');
+ if (last)
+ last++;
+ else
+ last = s;
+ snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)rand());
res = stat(s, &stbuf);
if (res < 0) {
ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
@@ -937,11 +954,45 @@ static int try_firmware(char *s)
/* Make sure it's not a directory */
if (S_ISDIR(stbuf.st_mode))
return -1;
- fd = open(s, O_RDONLY);
- if (fd < 0) {
+ ifd = open(s, O_RDONLY);
+ if (ifd < 0) {
ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
return -1;
}
+ fd = open(s2, O_RDWR | O_CREAT | O_EXCL);
+ if (fd < 0) {
+ ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
+ close(ifd);
+ return -1;
+ }
+ /* Unlink our newly created file */
+ unlink(s2);
+
+ /* Now copy the firmware into it */
+ len = stbuf.st_size;
+ while(len) {
+ chunk = len;
+ if (chunk > sizeof(buf))
+ chunk = sizeof(buf);
+ res = read(ifd, buf, chunk);
+ if (res != chunk) {
+ ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
+ close(ifd);
+ close(fd);
+ return -1;
+ }
+ res = write(fd, buf, chunk);
+ if (res != chunk) {
+ ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
+ close(ifd);
+ close(fd);
+ return -1;
+ }
+ len -= chunk;
+ }
+ close(ifd);
+ /* Return to the beginning */
+ lseek(fd, 0, SEEK_SET);
if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
close(fd);