api updates
[tridge/hacksm.git] / common.c
1 /*
2   a test implementation of a HSM daemon
3
4   Andrew Tridgell August 2008
5
6  */
7
8 #include "hacksm.h"
9
10 static const struct {
11         dm_eventtype_t ev;
12         const char *name;
13 } dmapi_event_strings[] = {
14 #define EVENT_STRING(x) { x, #x }
15         EVENT_STRING(DM_EVENT_INVALID),
16         EVENT_STRING(DM_EVENT_CLOSE),
17         EVENT_STRING(DM_EVENT_MOUNT),
18         EVENT_STRING(DM_EVENT_PREUNMOUNT),
19         EVENT_STRING(DM_EVENT_UNMOUNT),
20         EVENT_STRING(DM_EVENT_NOSPACE),
21         EVENT_STRING(DM_EVENT_DEBUT),
22         EVENT_STRING(DM_EVENT_CREATE),
23         EVENT_STRING(DM_EVENT_POSTCREATE),
24         EVENT_STRING(DM_EVENT_REMOVE),
25         EVENT_STRING(DM_EVENT_POSTREMOVE),
26         EVENT_STRING(DM_EVENT_RENAME),
27         EVENT_STRING(DM_EVENT_POSTRENAME),
28         EVENT_STRING(DM_EVENT_SYMLINK),
29         EVENT_STRING(DM_EVENT_POSTSYMLINK),
30         EVENT_STRING(DM_EVENT_LINK),
31         EVENT_STRING(DM_EVENT_POSTLINK),
32         EVENT_STRING(DM_EVENT_READ),
33         EVENT_STRING(DM_EVENT_WRITE),
34         EVENT_STRING(DM_EVENT_TRUNCATE),
35         EVENT_STRING(DM_EVENT_ATTRIBUTE),
36         EVENT_STRING(DM_EVENT_CANCEL),
37         EVENT_STRING(DM_EVENT_DESTROY),
38         EVENT_STRING(DM_EVENT_USER),
39         EVENT_STRING(DM_EVENT_PREPERMCHANGE),
40         EVENT_STRING(DM_EVENT_POSTPERMCHANGE),
41         EVENT_STRING(DM_EVENT_MAX),
42 };
43
44 const char *dmapi_event_string(dm_eventtype_t ev)
45 {
46         int i;
47         for (i=0;i<sizeof(dmapi_event_strings)/sizeof(dmapi_event_strings[0]);i++) {
48                 if (dmapi_event_strings[i].ev == ev) {
49                         return dmapi_event_strings[i].name;
50                 }
51         }
52         return "UNKNOWN";
53 }
54
55 void hsm_recover_session(const char *name, dm_sessid_t *sid)
56 {
57         int ret, i;
58         u_int n = 0;
59         dm_sessid_t *sess = NULL;
60         dm_sessid_t oldsid = DM_NO_SESSION;
61
62         ret = dm_getall_sessions(0, NULL, &n);
63         if (ret == 0) {
64                 goto new_session;
65         }
66         if (errno != E2BIG) {
67                 printf("Bad error code %s from dm_getall_sessions\n", strerror(errno));
68                 exit(1);
69         }
70
71         sess = (dm_sessid_t *)calloc(sizeof(dm_sessid_t), n);
72         if (sess == NULL) {
73                 printf("No memory for %u sessions\n", n);
74                 exit(1);
75         }
76
77         ret = dm_getall_sessions(n, sess, &n);
78         if (ret != 0) {
79                 printf("dm_getall_sessions failed\n");
80                 exit(1);
81         }
82
83         for (i=0;i<n;i++) {
84                 char buf[DM_SESSION_INFO_LEN+1] = "";
85                 size_t len = 0;
86
87                 ret = dm_query_session(sess[i], DM_SESSION_INFO_LEN, buf, &len);
88                 if (ret != 0) {
89                         continue;
90                 }
91                 buf[len] = 0;
92                 if (strcmp(buf, name) == 0) {
93                         printf("Recovered existing session\n");
94                         oldsid = sess[i];
95                         break;
96                 }
97         }
98         free(sess);
99
100 new_session:
101         ret = dm_create_session(oldsid, discard_const(name), sid);
102         if (ret != 0) {
103                 printf("Failed to create session\n");
104                 exit(1);
105         }
106 }
107
108
109 void msleep(int t)
110 {
111         struct timeval tval;  
112
113         tval.tv_sec = 0;
114         tval.tv_usec = t;
115  
116         select(0,NULL,NULL, NULL, &tval);
117 }
118
119 void hsm_cleanup_tokens(dm_sessid_t sid, dm_response_t response, int retcode)
120 {
121         dm_token_t *tok = NULL;
122         u_int n = 0;
123         int ret, i, total=0;
124
125         while (1) {
126                 u_int n2;
127                 ret = dm_getall_tokens(sid, n, tok, &n2);
128                 if (ret == -1 && errno == E2BIG) {
129                         n = n2;
130                         tok = realloc(tok, sizeof(dm_token_t)*n);
131                         continue;
132                 }
133                 if (ret == -1) {
134                         printf("dm_getall_tokens - %s\n", strerror(errno));
135                         return;
136                 }
137                 if (ret == 0 && n2 == 0) {
138                         break;
139                 }
140                 printf("Cleaning up %u tokens\n", n2);
141                 for (i=0;i<n2;i++) {
142                         dm_respond_event(sid, tok[i], 
143                                          response, retcode, 0, NULL);
144                         total++;
145                 }
146         }
147         if (tok) free(tok);
148 }
149
150 const char *timestring(void)
151 {
152         time_t t = time(NULL);
153         struct tm *tm = localtime(&t);
154         static char TimeBuf[100];
155
156         strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
157         return TimeBuf;
158 }