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
  
97
  
98
  
99
  
100
  
101
  
102
  
103
  
104
  
105
  
106
  
107
  
/* 
 * $Id: proc.pike,v 1.2 1997/09/03 05:19:29 per Exp $ 
 */ 
 
inherit "wizard"; 
 
constant name= "Status//Extended process status"; 
constant doc = "Shows detailed process status on Solaris 2.5 and 2.6."; 
 
constant more=1; 
 
void create() 
{ 
  if(!file_stat("/usr/proc/bin/")) throw("Only available under Solaris 2.4 and newer\n"); 
} 
 
string proc(string prog, int pid ) 
{ 
  if(!pid) pid=getpid(); 
  object p = ((program)"privs")("Process status"); 
  return popen("/usr/proc/bin/p"+prog+" "+pid); 
} 
 
string process_map(string in) 
{ 
  string q="<table>"; 
  mapping map = ([]); 
  foreach((in/"\n")[1..], string m) 
  { 
    string a,b; 
    while(sscanf(m, "%s: %s", a,b)==2) m=a+":"+b; 
    m=replace(m,"[ heap ]","Heap&nbsp(malloced&nbsp;memory)"); 
    m=replace(m,"[ stack ]","Stack"); 
    array row = (replace(m,"\t"," ")/" "-({""}))[1..]; 
    row=replace(row, "read/exec", "read/exec/shared"); 
    row=replace(row, "read/shared", "read/exec/shared"); 
    row=replace(row, "read/exec/shared", "Shared"); 
    row=replace(row, "read/write/shared", "Shared"); 
    row=replace(row, "read/write/exec/shared", "Shared"); 
    row=replace(row, "read/write", "Private"); 
    row=replace(row, "read/write/exec", "Private"); 
 
    if(sizeof(row)>1) 
      map[row[1]] += (int)row[0]; 
  } 
  foreach(sort(indices(map)), string s) 
    if(map[s]>1024) 
      q += "<tr><td>"+s+"</td><td>"+sprintf("%.1f%s",map[s]/1024.0,"Mb")+"</td>"; 
    else 
      q += "<tr><td>"+s+"</td><td>"+sprintf("%d%s",map[s],"Kb")+"</td>"; 
  return q+"</table>"; 
} 
 
string process_map2(string in) 
{ 
  string kbytes,resident,shared,priv; 
  if(sscanf(((in/"\n")[-2]/" "-({""}))[2..]*" ", 
            "%[^ ] %[^ ] %[^ ] %[^ ]",kbytes,resident,shared,priv)==4) 
    return sprintf("%d Kbytes, %d Kb shared, %d Kb private, %d Kb resident", 
                   (int)kbytes,(int)shared,(int)priv,(int)resident); 
  return "Failed to parse output from pmap."; 
} 
 
string format_proc_line(string in, int ipid) 
{ 
  string pre; 
  int pid; 
  sscanf(in, "%*s%d%*s", pid); 
  sscanf(in,"%[ ]%s",pre,in); 
  pre=replace(pre,"  "," |"); 
  if(strlen(pre))pre=" "+pre[1..]; 
  if(search(in,"/proc/")==-1) 
    return (pre+ 
            "<a href=/Actions/?action=proc.pike&pid="+pid+"&unique="+time()+">"+ 
            (ipid==pid?"<b>":"")+ 
            html_encode_string(in)+ 
            (ipid==pid?"</b>":"")+ 
            "</a>\n"); 
  return ""; 
} 
 
 
mixed page_0(object id, object mc) 
{ 
  string map = proc("map -x",(int)id->variables->pid); 
  if(sscanf(map, "%*sShared%*s") != 2) 
    map = process_map(proc("map",(int)id->variables->pid)); 
  else 
    map = process_map2(map); 
   
  string tree = Array.map(proc("tree -a",(int)id->variables->pid)/"\n",format_proc_line, 
                          (int)id->variables->pid||getpid())*""; 
 
  return ("<font size=+1>Process Tree for "+(id->variables->pid||getpid())+"</font><pre>\n"+ 
          tree+ 
          "</pre><font size=+1>Misc status for "+(id->variables->pid||getpid()) 
          +"</font><pre>Memory Usage: "+map+"\n\nCredentials: "+ 
          ((proc("cred",id->variables->pid)/":")[1..]*":")+ 
          "\nPwd: "+ 
          ((proc("wdx",id->variables->pid)/":")[1..]*":")+ 
//      "Stack: "+(proc("stack",id->variables->pid)/":")[1..]*":"+ 
          "</pre>"); 
} 
 
mixed handle(object id) { return wizard_for(id,0); }