本文共 8029 字,大约阅读时间需要 26 分钟。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <getopt.h> 4 #include <syslog.h> 5 #include <sys/types.h> 6 #include <sys/stat.h> 7 #include <unistd.h> 8 #include <paths.h> 9 #include <fcntl.h> 10 #include <sys/resource.h> 11 #include <sys/inotify.h> 12 #include < string .h> 13 14 /* default fwupload directory to upload file */ 15 /* #define FW_MONITOR_DEFAULT_DIR "/tmp/fwupload" */ 16 #define FW_MONITOR_DEFAULT_DIR "/home/mysterywho/SiangWei/fwupgrade/daemon/upload" 17 18 19 #define FW_MONITOR "fw_monitor" 20 #define BUFFER_SIZE 1024 21 #define PATH_MAX 128 22 23 24 /* ------------------------------------------------------------------------------ */ 25 26 typedef struct MSImHeader_s * MSImHeader_p; 27 typedef struct MSImHeader_s { 28 u_int32_t upgradeCnt; 29 char fwId[ 64 ]; 30 u_int32_t hdrChksum; 31 u_int32_t imgChksum; 32 u_int32_t imgType; 33 u_int8_t ModelID[ 4 ]; 34 u_int32_t imgLen; 35 } MSImHeader_t; 36 37 /* ------------------------------------------------------------------------------ */ 38 39 static void usage ( const char *); 40 static void init_daemon ( void ); 41 static void fw_monitor ( const int , const int ); 42 static void event_handler ( const int , const int ); 43 static void event_check ( struct inotify_event *); 44 45 /* ------------------------------------------------------------------------------- */ 46 47 static char *mondir = NULL; 48 49 /* use FIRMWARE_ID to do simple check */ 50 const char *FIRMWARE_ID = " MitraStar " ; 51 /* ------------------------------------------------------------------------------- */ 52 53 54 int main ( int argc, char *argv[]) 55 { 56 int opt = 0 , bendian = 0 ; 57 58 /* parse options */ 59 while ((opt = getopt(argc, argv, " hbd: " )) != EOF) { 60 61 switch (opt) { 62 case ' h ' : 63 usage(argv[ 0 ]); 64 break ; 65 case ' b ' : 66 bendian = 1 ; 67 break ; 68 case ' d ' : 69 mondir = optarg; 70 break ; 71 default : 72 usage(argv[ 0 ]); 73 break ; 74 } 75 } 76 77 openlog(FW_MONITOR, LOG_PID, LOG_USER); 78 79 /* monitor directory */ 80 if (!mondir) { 81 syslog(LOG_NOTICE, " monitor default fwupload directory (%s)\n " , FW_MONITOR_DEFAULT_DIR); 82 mondir = FW_MONITOR_DEFAULT_DIR; 83 } 84 85 umask( 000 ); 86 87 /* create the monitor directory "$mondir */ 88 if (mkdir(mondir, S_IRWXU | S_IRWXG | S_IRWXO) < 0 ) { 89 syslog(LOG_ERR, " cannot creat the directory (%s)\n " , mondir); 90 return - 1 ; 91 } 92 93 94 /* daemon init */ 95 init_daemon(); /* to do */ 96 97 return 0 ; 98 } 99 /* main */ 100 101 102 /* --------------------------------------------------------------------------------- */ 103 104 105 static void usage ( const char *pgname) 106 { 107 fprintf(stderr, " Options:\n " ); 108 fprintf(stderr, " -h display this help message and exit\n " ); 109 fprintf(stderr, " -b specify big endian for fwcheck (default: little endian)\n " ); 110 fprintf(stderr, " -d DIR indicate the firmware uploading directory (default: %s)\n\n " , FW_MONITOR_DEFAULT_DIR); 111 exit( 1 ); 112 } 113 /* usage */ 114 115 116 /* ---------------------------------------------------------------------------------- */ 117 118 119 static void init_daemon() 120 { 121 int fd, wd, currentfd = 0 ; 122 123 switch (fork()) { 124 case - 1 : 125 /* error */ 126 syslog(LOG_ERR, " fork: %m\n " ); 127 exit( 1 ); 128 case 0 : 129 /* child */ 130 break ; 131 default : 132 /* parent */ 133 exit( 0 ); 134 } 135 136 if (setsid() < 0 ) { 137 syslog(LOG_ERR, " setsid: %m\n " ); 138 exit( 1 ); 139 } 140 141 chdir( " / " ); 142 143 umask( 0 ); 144 145 146 /* to find the max number of fd that was have opend */ 147 // currentfd = open(_PATH_DEVNULL,O_RDWR);
148 149 /* close open fd */ 150 // for (fd = 0; fd < currentfd + 1; ++fd) {
151 // close(fd);
152 // }
153 154 /* close standard I/O: stdin, stdout, and stderr */ 155 // fd = open(_PATH_DEVNULL, O_RDWR); /* stdin */
156 // dup(fd); /* stdout */
157 // dup(fd); /* stderr */
158 159 160 161 /* inotify init */ 162 if ((fd = inotify_init()) < 0 ) { 163 syslog(LOG_ERR, " inotify_init: %m\n " ); 164 exit( 1 ); 165 } 166 167 /* inotify watch */ 168 if ((wd = inotify_add_watch(fd, mondir, IN_MOVED_TO | IN_CREATE)) < 0 ) { 169 syslog(LOG_ERR, " inotify_add_watch: %m\n " ); 170 exit( 1 ); 171 } 172 173 174 /* daemon loop - monitor dir */ 175 fw_monitor(fd, wd); 176 177 } 178 /* init_daemon */ 179 180 /* ---------------------------------------------------------------------------------- */ 181 182 183 static void fw_monitor ( const int fd, const int wd) 184 { 185 fd_set fdset; 186 struct timeval timeout; 187 188 while ( 1 ) { 189 timeout.tv_sec = 5 ; 190 timeout.tv_usec = 0 ; 191 192 /* clears a set */ 193 FD_ZERO(&fdset); 194 195 /* add fd to fdset */ 196 FD_SET(fd, &fdset); 197 198 199 if ( select (fd + 1 , &fdset, NULL, NULL, &timeout) > 0 && FD_ISSET(fd, &fdset)) 200 event_handler(fd, wd); 201 202 203 } 204 } 205 /* fw_watcher */ 206 207 208 /* ---------------------------------------------------------------------------------- */ 209 210 211 static void event_handler ( const int fd, const int wd) 212 { 213 int length, i; 214 char buffer[BUFFER_SIZE] = { 0 }; 215 char path[PATH_MAX]; 216 struct inotify_event * event = NULL; 217 218 219 length = read(fd, buffer, BUFFER_SIZE); 220 if (length < 0 ) { 221 syslog(LOG_WARNING, " read: %m\n " ); 222 return ; 223 } 224 225 for (i = 0 ; i < length; i += ( sizeof ( struct inotify_event) + event ->len)) { 226 227 event = ( struct inotify_event *)&buffer[i]; 228 229 if ( event ->wd == wd && event ->len) { 230 231 switch ( event ->mask) { 232 233 case IN_CREATE: 234 syslog(LOG_DEBUG, " do NOT allow a directory, delete it (%s/)\n " , event ->name); 235 sprintf(path, " %s/%s " , mondir, event ->name); 236 remove(path); 237 break ; 238 239 case IN_MOVED_TO: 240 /* file uploaded */ 241 syslog(LOG_INFO, " find a file(%s), must to be check \n " , event ->name); 242 event_check( event ); 243 break ; 244 245 default : 246 /* unexpected events */ 247 syslog(LOG_INFO, " unkown event in \"%s\" (%d)\n " , mondir, event ->mask); 248 } 249 } /* if */ 250 } /* for */ 251 252 } 253 /* event_handler */ 254 255 /* -------------------------------------------------------------------------------------- */ 256 257 258 static void event_check ( struct inotify_event * event ) 259 { 260 char cmd[PATH_MAX], upfile[PATH_MAX]; 261 FILE * fpin = NULL; 262 int Readcount; 263 MSImHeader_t header; 264 265 266 sprintf(upfile, " %s/%s " , mondir, event ->name); 267 268 /* firmware simple check - to check fwId */ 269 if ((fpin = fopen(upfile, " r " )) == NULL){ 270 syslog(LOG_ERR, " fopen: %m\n " ); 271 return ; 272 } 273 274 /* magic_num : move point to MSImHeader start address */ 275 fseek(fpin, 0 , SEEK_SET); 276 Readcount = fread(&header, sizeof (MSImHeader_t), 1 , fpin); 277 278 if (Readcount != 1 ){ 279 syslog(LOG_ERR, " fread: %m\n " ); 280 remove(upfile); 281 return ; 282 } 283 284 285 printf( " kernel information\n " ); 286 printf( " header.upgradeCnt = %d\n " ,header.upgradeCnt); 287 printf( " header.fwId = %s\n " ,header.fwId); 288 printf( " header.hdrChksum = %x\n " ,header.hdrChksum); 289 printf( " header.imgChksum = %x\n " ,header.imgChksum); 290 printf( " header.imgType = %x\n " ,header.imgType); 291 printf( " header.ModelID = %d%d%d%d\n " ,header.ModelID[ 0 ],header.ModelID[ 1 ],header.ModelID[ 2 ],header.ModelID[ 3 ]); 292 printf( " header.imgLen = %d\n " ,header.imgLen); 293 294 295 if (memcmp(FIRMWARE_ID, header.fwId, 9 ) == 0 ){ 296 /* to do upgrade firmware */ 297 syslog(LOG_INFO, " upgrade firmware(%s)\n " , upfile); 298 printf( " correct fwID\n " ); 299 } 300 else { 301 syslog(LOG_INFO, " error firmware (%s)\n " , upfile); 302 remove(upfile); 303 } 304 305 /* to do firmware check */ 306 307 // syslog(LOG_DEBUG, "validate firmware/configuration failed, delete it (%s)\n", upfile);
308 // remove(upfile);
309 310 /* to do firmware check */ 311 312 313 314 // sprintf(cmd, " %s %s ",FIRMWARE_UPGRADE, upfile);
315 // syslog(LOG_DEBUG, "upgrade firmware (%s)\n", cmd);
316 // system(cmd);
317 318 } 319 /* event_check */ 转载地址:http://hxsgi.baihongyu.com/