aboutsummaryrefslogtreecommitdiff
path: root/update.c
blob: a7dcc249ffbdac41b7eedf21b5a9502430181dff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <unistd.h>
#include <fcntl.h>
#include <alloca.h>
#include "ninitfeatures.h"

static int infd=-1, outfd=-1;
static uint32t env_free=0;
#include "contrib/put_env.h"

static void die_xx(char *s) {
  char *aa[3]; 
  INIT_ARGS3(aa, "/sbin/ninit","",0);
  write(2,"\nupdate: ",9);
  write(2,s,str_len(s));
  write(2,"\n",1);
  while (1) {
    execve(*aa,aa,environ);	/* really panic !!! */
    nano_sleep(0,800000000);
  }
}
static void safe_read(void *buf, int len) {
  if (read(infd,buf,len) != len) die_xx("error reading");
}
static void safe_write() {
  if (write(outfd,"1",1) != 1) die_xx("error writing");
}

int main(int Argc, char **Argv) {
  uint32t len,i,k;
  char **argv, **env, *s;

  s = Argv[0];
  s[str_rchr(s, '/')] = 0;
  chdir(s);

  infd=open("../in",O_RDWR);
  outfd=open("../out",O_RDWR|O_NONBLOCK);
  fcntl(infd,F_SETFD,FD_CLOEXEC);
  fcntl(outfd,F_SETFD,FD_CLOEXEC);

  if (infd<0 || outfd<0) {
    write(outfd,"0",1);
    die_xx("pipes error");
  }
  write(outfd,"7",1);
  
  safe_read(&len,sizeof(len)); 
  argv = alloca((len+5) * sizeof(char *));
  if (argv==0) die_xx("out of memory");
  safe_write();

  for (i=0; i<len; i++) {	/* argv */
    safe_read(&k, sizeof(k));
    if (k) {
      if ((s=alloca(k+1))==0) die_xx("out of memory");
      safe_read(s,k);
      s[k] = 0;
    } else s = "";
    argv[i] = s;
    safe_write();	
  }
  argv[i] = 0;

  /* ----- environ ----- */
  safe_read(&len,sizeof(len)); 
  if (len==0) { safe_write(); goto ready; }

  env_free=len+1;
  if (environ==0) environ = Argv+Argc;
  for (k=0; environ[k]; ) k++;
  env = alloca((len+k+5) * sizeof(char *));
  if (env==0) die_xx("out of memory");

  byte_copy(env, (k+1)*sizeof(char *), environ);
  environ=env;
  safe_write();

  for (i=0; i<len; i++) {	/* environ */
    safe_read(&k, sizeof(k));
    if (k==0) environ[0] = 0;
    else {
      if ((s=alloca(k+1))==0) die_xx("out of memory");
      safe_read(s,k);
      s[k] = 0;
      put_env(s);
    }
    safe_write();	
  }
  
 ready:
  safe_read(&k,sizeof(k));	/* k = "doit" */
  chdir("/");
  execve(*argv, argv, environ);
  die_xx("PANIC");
  return 1;
}