diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-07-24 02:50:11 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-07-24 02:50:11 +0000 |
commit | f45e439c3a12eeda28c2401207b97267ea10f74f (patch) | |
tree | a9655c841ea02c069c727476609c646392c5d307 | |
parent | ab644035af51b173570ed2fbd12bfd7604c8321c (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-x | channels/chan_iax2.c | 55 |
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); |