#include "global.h" #include "upd.h" static inline int ChkImg(const char *csImg, char *psDir) { int res = 0; getcwd(psDir, MAXPATHLEN); if (access(csImg, R_OK) == -1) { printf("Error:: Unable to find new image %s #%d - %s\n", csImg, errno, strerror(errno)); res = -1; } else { strlcat(psDir, "/", MAXPATHLEN); strlcat(psDir, csImg, MAXPATHLEN); } return res; } // ------------------------------- int Activate(const char *csImg) { char szDir[MAXPATHLEN]; if (ChkImg(csImg, szDir) == -1) return -1; VERB(3) printf("Activate procedure for %s\n", szDir); unlink(FIRMWARE_IMG); if (symlink(szDir, FIRMWARE_IMG) == -1) { printf("Error:: Unable to activate new image %s #%d - %s\n", csImg, errno, strerror(errno)); return -2; } syslog(LOG_NOTICE, "Activate new image %s", csImg); VERB(1) printf("Activate new image %s\n", csImg); return 0; } int Install(const char *csImg, const char *psDir) { int src, dst, len; u_char buf[BUFSIZ]; char szDir[MAXPATHLEN], szFile[MAXPATHLEN]; struct stat ss, ds; strlcpy(szFile, psDir, MAXPATHLEN); strlcat(szFile, "/", MAXPATHLEN); strlcat(szFile, csImg, MAXPATHLEN); if (access(szFile, R_OK) == -1) { printf("Error:: Unable to find new image %s #%d - %s\n", csImg, errno, strerror(errno)); return -1; } else { memset(&ss, 0, sizeof ss); if (stat(szFile, &ss) == -1) { printf("Error:: Unable to find new image %s #%d - %s\n", csImg, errno, strerror(errno)); return -1; } } getcwd(szDir, MAXPATHLEN); VERB(3) printf("Install procedure from %s to %s\n", szFile, szDir); strlcat(szDir, "/", MAXPATHLEN); strlcat(szDir, csImg, MAXPATHLEN); memset(&ds, 0, sizeof ds); if (stat(szDir, &ds) == -1 && ENOENT != errno) { printf("Error:: Unable to stat target #%d - %s\n", errno, strerror(errno)); return -1; } if (ss.st_dev == ds.st_dev && ss.st_ino == ds.st_ino) { printf("Error:: Unable to install into self ...\n"); return -1; } dst = open(szDir, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (dst == -1) { printf("Error:: in create image %s #%d - %s\n", szDir, errno, strerror(errno)); return -1; } src = open(szFile, O_RDONLY); if (src == -1) { printf("Error:: in open image %s #%d - %s\n", szFile, errno, strerror(errno)); close(dst); unlink(szDir); return -1; } while ((len = read(src, buf, BUFSIZ)) > 0) if (write(dst, buf, len) == -1) { printf("Error:: in write image #%d - %s\n", errno, strerror(errno)); close(src); close(dst); unlink(szDir); len = -1; break; } close(src); close(dst); if (!len) { syslog(LOG_NOTICE, "Install image %s to %s", csImg, szDir); VERB(1) printf("Install image %s to %s\n", csImg, szDir); } return len; } int Rollback(const char *csImg) { int src, dst, len; u_char buf[BUFSIZ]; char szDir[MAXPATHLEN], szFile[MAXPATHLEN]; struct stat ss, ds; getcwd(szFile, MAXPATHLEN); strlcat(szFile, "/", MAXPATHLEN); strlcat(szFile, FIRMWARE_BAK, MAXPATHLEN); if (access(szFile, R_OK) == -1) { printf("Error:: Unable to find backup image #%d - %s\n", errno, strerror(errno)); return -1; } else { memset(&ss, 0, sizeof ss); if (stat(szFile, &ss) == -1) { printf("Error:: Unable to find backup image #%d - %s\n", errno, strerror(errno)); return -1; } } getcwd(szDir, MAXPATHLEN); strlcat(szDir, "/", MAXPATHLEN); strlcat(szDir, csImg, MAXPATHLEN); VERB(3) printf("Rollback procedure for image %s from backup!\n", csImg); memset(&ds, 0, sizeof ds); if (stat(szDir, &ds) == -1 && ENOENT != errno) { printf("Error:: Unable to stat target #%d - %s\n", errno, strerror(errno)); return -1; } if (ss.st_dev == ds.st_dev && ss.st_ino == ds.st_ino) { printf("Error:: Unable to rollback into self ...\n"); return -1; } src = open(szFile, O_RDONLY); if (src == -1) { printf("Error:: in open backup %s #%d - %s\n", szFile, errno, strerror(errno)); return -1; } dst = open(szDir, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (dst == -1) { printf("Error:: in create image %s #%d - %s\n", szDir, errno, strerror(errno)); close(src); return -1; } while ((len = read(src, buf, BUFSIZ)) > 0) if (write(dst, buf, len) == -1) { printf("Error:: in write image #%d - %s\n", errno, strerror(errno)); close(dst); close(src); unlink(szDir); len = -1; break; } close(dst); close(src); if (!len) { syslog(LOG_NOTICE, "Rollback image %s to %s", csImg, szDir); VERB(1) printf("Rollback image %s to %s\n", csImg, szDir); } return len; return 0; } int tFTP(const char *csImg, const char *psDir) { int src, dst, len; u_char buf[BUFSIZ]; char szDir[MAXPATHLEN], szFile[MAXPATHLEN]; struct stat ss, ds; if (ChkImg(csImg, szDir) == -1) return -1; else { memset(&ss, 0, sizeof ss); if (stat(szDir, &ss) == -1) { printf("Error:: Unable to find image %s #%d - %s\n", szDir, errno, strerror(errno)); return -1; } } VERB(3) printf("tFTP procedure for %s to %s\n", szDir, psDir); strlcpy(szFile, psDir, MAXPATHLEN); strlcat(szFile, "/", MAXPATHLEN); strlcat(szFile, csImg, MAXPATHLEN); memset(&ds, 0, sizeof ds); if (stat(szFile, &ds) == -1 && ENOENT != errno) { printf("Error:: Unable to stat target %s #%d - %s\n", szFile, errno, strerror(errno)); return -1; } if (ss.st_dev == ds.st_dev && ss.st_ino == ds.st_ino) { printf("Error:: Unable to copy into self ...\n"); return -1; } dst = open(szFile, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (dst == -1) { printf("Error:: in create backup %s #%d - %s\n", szFile, errno, strerror(errno)); return -1; } src = open(szDir, O_RDONLY); if (src == -1) { printf("Error:: in open image %s #%d - %s\n", szDir, errno, strerror(errno)); close(dst); unlink(szFile); return -1; } while ((len = read(src, buf, BUFSIZ)) > 0) if (write(dst, buf, len) == -1) { printf("Error:: in write backup #%d - %s\n", errno, strerror(errno)); close(src); close(dst); unlink(szFile); len = -1; break; } close(src); close(dst); if (!len) { syslog(LOG_NOTICE, "Export tFTP image %s to %s", csImg, psDir); VERB(1) printf("Export tFTP image %s to %s\n", csImg, psDir); } return len; } int Backup(const char *csImg) { int src, dst, len; u_char buf[BUFSIZ]; char szDir[MAXPATHLEN], szFile[MAXPATHLEN]; if (ChkImg(csImg, szDir) == -1) return -1; getcwd(szFile, MAXPATHLEN); strlcat(szFile, "/", MAXPATHLEN); strlcat(szFile, FIRMWARE_BAK, MAXPATHLEN); VERB(3) printf("Backup procedure for %s\n", szDir); dst = open(szFile, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (dst == -1) { printf("Error:: in create backup %s #%d - %s\n", szFile, errno, strerror(errno)); return -1; } src = open(szDir, O_RDONLY); if (src == -1) { printf("Error:: in open image %s #%d - %s\n", szDir, errno, strerror(errno)); close(dst); unlink(szFile); return -1; } while ((len = read(src, buf, BUFSIZ)) > 0) if (write(dst, buf, len) == -1) { printf("Error:: in write backup #%d - %s\n", errno, strerror(errno)); close(src); close(dst); unlink(szFile); len = -1; break; } close(src); close(dst); if (!len) { syslog(LOG_NOTICE, "Backup image %s", csImg); VERB(1) printf("Backup image %s\n", csImg); } return len; } int Clean(const char *csImg) { char szDir[MAXPATHLEN], szFile[MAXPATHLEN]; if (ChkImg(csImg, szDir) == -1) return -1; getcwd(szFile, MAXPATHLEN); strlcat(szFile, "/", MAXPATHLEN); strlcat(szFile, FIRMWARE_BAK, MAXPATHLEN); VERB(3) printf("Clean procedure for %s\n", szDir); if (unlink(szFile) == -1) { printf("Error:: in clean backup #%d - %s\n", errno, strerror(errno)); return -1; } syslog(LOG_NOTICE, "Clean backup for image %s", csImg); VERB(1) printf("Clean backup for image %s\n", csImg); return 0; } int Daemonize(struct sockaddr_in sin, const char *csTFTP) { VERB(3) printf("Daemonize procedure for %s:%d to %s\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), csTFTP); return 0; }