• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/procd/sysupgrade.c

  1 /*
  2  * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
  3  * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
  4  * Copyright (C) 2017 Matthias Schiffer <mschiffer@universe-factory.net>
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU Lesser General Public License version 2.1
  8  * as published by the Free Software Foundation
  9  *
 10  * This program is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  * GNU General Public License for more details.
 14  */
 15 
 16 
 17 #define _GNU_SOURCE
 18 #include "watchdog.h"
 19 #include "sysupgrade.h"
 20 
 21 #include <ctype.h>
 22 #include <stdio.h>
 23 #include <stdlib.h>
 24 #include <unistd.h>
 25 
 26 #include <libubox/blobmsg.h>
 27 
 28 void sysupgrade_exec_upgraded(const char *prefix, char *path,
 29                               const char *backup, char *command,
 30                               struct blob_attr *options)
 31 {
 32         char *wdt_fd = watchdog_fd();
 33         char *argv[] = { "/sbin/upgraded", NULL, NULL, NULL};
 34         struct blob_attr *option;
 35         int rem;
 36         int ret;
 37 
 38         ret = chroot(prefix);
 39         if (ret < 0) {
 40                 fprintf(stderr, "Failed to chroot for upgraded exec.\n");
 41                 return;
 42         }
 43 
 44         argv[1] = path;
 45         argv[2] = command;
 46 
 47         if (wdt_fd) {
 48                 watchdog_set_cloexec(false);
 49                 setenv("WDTFD", wdt_fd, 1);
 50         }
 51 
 52         if (backup)
 53                 setenv("UPGRADE_BACKUP", backup, 1);
 54 
 55         blobmsg_for_each_attr(option, options, rem) {
 56                 const char *prefix = "UPGRADE_OPT_";
 57                 char value[11];
 58                 char *name;
 59                 char *c;
 60                 int tmp;
 61 
 62                 if (asprintf(&name, "%s%s", prefix, blobmsg_name(option)) <= 0)
 63                         continue;
 64                 for (c = name + strlen(prefix); *c; c++) {
 65                         if (isalnum(*c) || *c == '_') {
 66                                 *c = toupper(*c);
 67                         } else {
 68                                 c = NULL;
 69                                 break;
 70                         }
 71                 }
 72 
 73                 if (!c) {
 74                         fprintf(stderr, "Option \"%s\" contains invalid characters\n",
 75                                 blobmsg_name(option));
 76                         free(name);
 77                         continue;
 78                 }
 79 
 80                 switch (blobmsg_type(option)) {
 81                 case BLOBMSG_TYPE_INT32:
 82                         tmp = blobmsg_get_u32(option);
 83                         break;
 84                 case BLOBMSG_TYPE_INT16:
 85                         tmp = blobmsg_get_u16(option);
 86                         break;
 87                 case BLOBMSG_TYPE_INT8:
 88                         tmp = blobmsg_get_u8(option);
 89                         break;
 90                 default:
 91                         fprintf(stderr, "Option \"%s\" has unsupported type: %d\n",
 92                                 blobmsg_name(option), blobmsg_type(option));
 93                         free(name);
 94                         continue;
 95                 }
 96                 snprintf(value, sizeof(value), "%u", tmp);
 97 
 98                 setenv(name, value, 1);
 99 
100                 free(name);
101         }
102 
103         execvp(argv[0], argv);
104 
105         /* Cleanup on failure */
106         fprintf(stderr, "Failed to exec upgraded.\n");
107         unsetenv("WDTFD");
108         watchdog_set_cloexec(true);
109         ret = chroot(".");
110         if (ret < 0) {
111                 fprintf(stderr, "Failed to reset chroot, exiting.\n");
112                 exit(EXIT_FAILURE);
113         }
114 }
115 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt