mbus_config.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:24k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * FILE:     mbus_config.c
  3.  * AUTHOR:   Colin Perkins
  4.  * MODIFIED: Orion Hodson
  5.  *           Markus Germeier
  6.  * 
  7.  * Copyright (c) 1999-2001 University College London
  8.  * All rights reserved.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, is permitted provided that the following conditions 
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *      This product includes software developed by the Computer Science
  21.  *      Department at University College London
  22.  * 4. Neither the name of the University nor of the Department may be used
  23.  *    to endorse or promote products derived from this software without
  24.  *    specific prior written permission.
  25.  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "config_unix.h"
  38. #include "config_win32.h"
  39. #include "debug.h"
  40. #include "memory.h"
  41. #include "crypt_random.h"
  42. #include "base64.h"
  43. #include "mbus.h"
  44. #include "mbus_config.h"
  45. #define MBUS_ENCRYPT_BY_DEFAULT
  46. #define MBUS_ENCRKEY_LEN      8
  47. #define MBUS_HASHKEY_LEN     12
  48. #define MBUS_BUF_SIZE    1500
  49. #define MBUS_FILE_NAME   ".mbus"
  50. #define MBUS_FILE_NAME_LEN    5
  51. struct mbus_config {
  52. #ifdef WIN32
  53. HKEY   cfgKey;
  54. #else
  55. fd_t   cfgfd;
  56. #endif
  57. int   cfg_locked;
  58. };
  59. char *mbus_new_encrkey(void)
  60. {
  61. char *key; /* The key we are going to return... */
  62. #ifdef MBUS_ENCRYPT_BY_DEFAULT
  63. /* Create a new key, for use by the hashing routines. Returns */
  64. /* a key of the form (DES,MTIzMTU2MTg5MTEyMQ==)               */
  65. char  random_string[MBUS_ENCRKEY_LEN];
  66. char  encoded_string[(MBUS_ENCRKEY_LEN*4/3)+4];
  67. int  encoded_length;
  68. int  i, j, k;
  69. /* Step 1: generate a random string for the key... */
  70. for (i = 0; i < MBUS_ENCRKEY_LEN; i++) {
  71. random_string[i] = ((int32_t)lbl_random() | 0x000ff000) >> 24;
  72. }
  73. /* Step 2: fill in parity bits to make DES library happy */
  74. for (i = 0; i < MBUS_ENCRKEY_LEN; ++i) {
  75.         k = random_string[i] & 0xfe;
  76. j = k;
  77. j ^= j >> 4;
  78. j ^= j >> 2;
  79. j ^= j >> 1;
  80. j = (j & 1) ^ 1;
  81. random_string[i] = k | j;
  82. }
  83. /* Step 3: base64 encode that string... */
  84. memset(encoded_string, 0, (MBUS_ENCRKEY_LEN*4/3)+4);
  85. encoded_length = base64encode(random_string, MBUS_ENCRKEY_LEN, encoded_string, (MBUS_ENCRKEY_LEN*4/3)+4);
  86. /* Step 4: put it all together to produce the key... */
  87. key = (char *) xmalloc(encoded_length + 18);
  88. sprintf(key, "(DES,%s)", encoded_string);
  89. #else
  90. key = (char *) xmalloc(9);
  91. sprintf(key, "(NOENCR)");
  92. #endif
  93. return key;
  94. }
  95. char *mbus_new_hashkey(void)
  96. {
  97. /* Create a new key, for use by the hashing routines. Returns  */
  98. /* a key of the form (HMAC-MD5-96,MTIzMTU2MTg5MTEyMQ==)           */
  99. char  random_string[MBUS_HASHKEY_LEN];
  100. char  encoded_string[(MBUS_HASHKEY_LEN*4/3)+4];
  101. int  encoded_length;
  102. int  i;
  103. char *key;
  104. /* Step 1: generate a random string for the key... */
  105. for (i = 0; i < MBUS_HASHKEY_LEN; i++) {
  106. random_string[i] = ((int32_t)lbl_random() | 0x000ff000) >> 24;
  107. }
  108. /* Step 2: base64 encode that string... */
  109. memset(encoded_string, 0, (MBUS_HASHKEY_LEN*4/3)+4);
  110. encoded_length = base64encode(random_string, MBUS_HASHKEY_LEN, encoded_string, (MBUS_HASHKEY_LEN*4/3)+4);
  111. /* Step 3: put it all together to produce the key... */
  112. key = (char *) xmalloc(encoded_length + 26);
  113. sprintf(key, "(HMAC-MD5-96,%s)", encoded_string);
  114. return key;
  115. }
  116. static void rewrite_config(struct mbus_config *m)
  117. {
  118. #ifdef WIN32
  119. char *hashkey = mbus_new_hashkey();
  120. char *encrkey = mbus_new_encrkey();
  121. char *scope   = MBUS_DEFAULT_SCOPE_NAME;
  122. const uint32_t  cver    = MBUS_CONFIG_VERSION;
  123. const uint32_t  port    = MBUS_DEFAULT_NET_PORT;
  124. char *addr    = xstrdup(MBUS_DEFAULT_NET_ADDR);
  125. char  buffer[MBUS_BUF_SIZE];
  126. LONG  status;
  127. status = RegSetValueEx(m->cfgKey, "CONFIG_VERSION", 0, REG_DWORD, (const uint8_t *) &cver, sizeof(cver));
  128. if (status != ERROR_SUCCESS) {
  129. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  130. debug_msg("Unable to set version: %sn", buffer);
  131. abort();
  132. }
  133. status = RegSetValueEx(m->cfgKey, "HASHKEY", 0, REG_SZ, hashkey, strlen(hashkey) + 1);
  134. if (status != ERROR_SUCCESS) {
  135. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  136. debug_msg("Unable to set hashkey: %sn", buffer);
  137. abort();
  138. }
  139. status = RegSetValueEx(m->cfgKey, "ENCRYPTIONKEY", 0, REG_SZ, encrkey, strlen(encrkey) + 1);
  140. if (status != ERROR_SUCCESS) {
  141. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  142. debug_msg("Unable to set encrkey: %sn", buffer);
  143. abort();
  144. }
  145. status = RegSetValueEx(m->cfgKey, "SCOPE", 0, REG_SZ, scope, strlen(scope) + 1);
  146. if (status != ERROR_SUCCESS) {
  147. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  148. debug_msg("Unable to set scope: %sn", buffer);
  149. abort();
  150. }
  151. status = RegSetValueEx(m->cfgKey, "ADDRESS", 0, REG_SZ, addr, strlen(addr) + 1);
  152. if (status != ERROR_SUCCESS) {
  153. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  154. debug_msg("Unable to set address: %sn", buffer);
  155. abort();
  156. }
  157. status = RegSetValueEx(m->cfgKey, "PORT", 0, REG_DWORD, (const uint8_t *) &port, sizeof(port));
  158. if (status != ERROR_SUCCESS) {
  159. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  160. debug_msg("Unable to set port: %sn", buffer);
  161. abort();
  162. }
  163. xfree(addr);
  164. #else
  165. char *hashkey = mbus_new_hashkey();
  166. char *encrkey = mbus_new_encrkey();
  167. char  buf[1024];
  168. if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
  169. perror("Can't seek to start of config file");
  170. abort();
  171. }
  172. sprintf(buf, "[MBUS]nCONFIG_VERSION=%dnHASHKEY=%snENCRYPTIONKEY=%snSCOPE=%snADDRESS=%snPORT=%dn", 
  173. MBUS_CONFIG_VERSION, hashkey, encrkey, MBUS_DEFAULT_SCOPE_NAME, MBUS_DEFAULT_NET_ADDR, MBUS_DEFAULT_NET_PORT);
  174. write(m->cfgfd, buf, strlen(buf));
  175. free(hashkey);
  176. xfree(encrkey);
  177. #endif
  178. }
  179. void mbus_lock_config_file(struct mbus_config *m)
  180. {
  181. #ifdef WIN32
  182. /* Open the registry and create the mbus entries if they don't exist   */
  183. /* already. The default contents of the registry are random encryption */
  184. /* and authentication keys, and node local scope.                      */
  185. HKEY key    = HKEY_CURRENT_USER;
  186. LPCTSTR subKey = "Software\Mbone Applications\mbus";
  187. DWORD disp;
  188. char buffer[MBUS_BUF_SIZE];
  189. LONG status;
  190. status = RegCreateKeyEx(key, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &(m->cfgKey), &disp);
  191. if (status != ERROR_SUCCESS) {
  192. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  193. debug_msg("Unable to open registry: %sn", buffer);
  194. abort();
  195. }
  196. if (disp == REG_CREATED_NEW_KEY) {
  197. rewrite_config(m);
  198. debug_msg("Created new registry entry...n");
  199. } else {
  200. debug_msg("Opened existing registry entry...n");
  201. }
  202. #else
  203. /* Obtain a valid lock on the mbus configuration file. This function */
  204. /* creates the file, if one does not exist. The default contents of  */
  205. /* this file are random authentication and encryption keys, and node */
  206. /* local scope.                                                      */
  207. struct flock  l;
  208. struct stat  s;
  209. char *buf;
  210. char *cfg_file;
  211. char            *cfg_loc;
  212. int              cfg_loc_len;
  213. cfg_loc = getenv("MBUS");
  214. if (cfg_loc == NULL) {
  215.                 cfg_loc = getenv("HOME");
  216.                 if (cfg_loc == NULL) {
  217.                         /* The getpwuid() stuff is to determine the users    */
  218.                         /* home directory, into which we write a .mbus       */
  219.                         /* config file. The struct returned by getpwuid() is */
  220.                         /* statically allocated, so it's not necessary to    */
  221.                         /* free it afterwards.                               */
  222.                         struct passwd *p;
  223.                         p = getpwuid(getuid());
  224.                         if (p == NULL) {
  225.                                 perror("Unable to get passwd entry");
  226.                                 abort();       
  227.                         }
  228.                         cfg_loc = p->pw_dir;
  229.                 }
  230. }
  231. /* Check if config_loc is terminated by mbus config file name. If    */
  232.         /* it's not add it.  This is allows environment variable MBUS to     */
  233.         /* point to config file of directory of config file.                 */
  234.         cfg_loc_len = strlen(cfg_loc);
  235. if (cfg_loc_len < MBUS_FILE_NAME_LEN ||
  236.     strcmp(cfg_loc + cfg_loc_len - MBUS_FILE_NAME_LEN, MBUS_FILE_NAME)){
  237.                 /* File location does not include config file name.          */
  238.                 cfg_file = (char*)xmalloc(cfg_loc_len + MBUS_FILE_NAME_LEN + 2);
  239.                 sprintf(cfg_file, "%s/%s", cfg_loc, MBUS_FILE_NAME);
  240. } else {
  241.                 cfg_file = xstrdup(cfg_loc);
  242. }
  243.         
  244. m->cfgfd = open(cfg_file, O_RDWR | O_CREAT, 0600);
  245. if (m->cfgfd == -1) {
  246. perror("Unable to open mbus configuration file");
  247. abort();
  248. }
  249. /* We attempt to get a lock on the config file, blocking until  */
  250. /* the lock can be obtained. The only time this should block is */
  251. /* when another instance of this code has a write lock on the   */
  252. /* file, because the contents are being updated.                */
  253. l.l_type   = F_WRLCK;
  254. l.l_start  = 0;
  255. l.l_whence = SEEK_SET;
  256. l.l_len    = 0;
  257. if (fcntl(m->cfgfd, F_SETLKW, &l) == -1) {
  258. perror("Unable to lock mbus configuration file");
  259. printf("The most likely reason for this error is that %sn", cfg_file);
  260. printf("is on an NFS filestore, and you have not correctly setup file locking. n");
  261. printf("Ask your system administrator to ensure that rpc.lockd and/or rpc.statdn");
  262. printf("are running. n");
  263. abort();
  264. }
  265. xfree(cfg_file);
  266. if (fstat(m->cfgfd, &s) != 0) {
  267. perror("Unable to stat config filen");
  268. abort();
  269. }
  270. if (s.st_size == 0) {
  271. /* Empty file, create with sensible defaults... */
  272. rewrite_config(m);
  273. } else {
  274. /* Read in the contents of the config file... */
  275. buf = (char *) xmalloc(s.st_size+1);
  276. memset(buf, '', s.st_size+1);
  277. if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
  278. perror("Unable to read config filen");
  279. abort();
  280. }
  281. /* Check that the file contains sensible information...   */
  282. /* This is rather a pathetic check, but it'll do for now! */
  283. if (strncmp(buf, "[MBUS]", 6) != 0) {
  284. debug_msg("Mbus config file has incorrect headern");
  285. abort();
  286. }
  287. xfree(buf);
  288. }
  289. #endif
  290. m->cfg_locked = TRUE;
  291. if (mbus_get_version(m) < MBUS_CONFIG_VERSION) {
  292. rewrite_config(m);
  293. debug_msg("Updated Mbus configuration database.n");
  294. }
  295. if (mbus_get_version(m) > MBUS_CONFIG_VERSION) {
  296. debug_msg("Mbus configuration database has later version number than expected.n");
  297. debug_msg("Continuing, in the hope that the extensions are backwards compatible.n");
  298. }
  299. }
  300. void mbus_unlock_config_file(struct mbus_config *m)
  301. {
  302. #ifdef WIN32
  303. LONG status;
  304. char buffer[MBUS_BUF_SIZE];
  305. status = RegCloseKey(m->cfgKey);
  306. if (status != ERROR_SUCCESS) {
  307. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  308. debug_msg("Unable to close registry: %sn", buffer);
  309. abort();
  310. }
  311. debug_msg("Closed registry entry...n");
  312. #else
  313. struct flock l;
  314. l.l_type   = F_UNLCK;
  315. l.l_start  = 0;
  316. l.l_whence = SEEK_SET;
  317. l.l_len    = 0;
  318. if (fcntl(m->cfgfd, F_SETLKW, &l) == -1) {
  319. perror("Unable to unlock mbus configuration file");
  320. abort();
  321. }
  322. close(m->cfgfd);
  323. m->cfgfd = -1;
  324. #endif
  325. m->cfg_locked = FALSE;
  326. }
  327. #ifndef WIN32
  328. static void mbus_get_key(struct mbus_config *m, struct mbus_key *key, const char *id)
  329. {
  330. struct stat  s;
  331. char *buf;
  332. char *line;
  333. char *tmp;
  334. int  pos;
  335.         int              linepos;
  336. ASSERT(m->cfg_locked);
  337. if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
  338. perror("Can't seek to start of config file");
  339. abort();
  340. }
  341. if (fstat(m->cfgfd, &s) != 0) {
  342. perror("Unable to stat config filen");
  343. abort();
  344. }
  345. /* Read in the contents of the config file... */
  346. buf = (char *) xmalloc(s.st_size+1);
  347. memset(buf, '', s.st_size+1);
  348. if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
  349. perror("Unable to read config filen");
  350. abort();
  351. }
  352. line = (char *) xmalloc(s.st_size+1);
  353. sscanf(buf, "%s", line);
  354. if (strcmp(line, "[MBUS]") != 0) {
  355. debug_msg("Invalid .mbus filen");
  356. abort();
  357. }
  358. pos = strlen(line) + 1;
  359. while (pos < s.st_size) {
  360.                 /* get whole line and filter out spaces */
  361.                 /* this is good enough for getting keys */
  362.                 linepos=0;
  363.                 do {
  364.                     while((buf[pos+linepos]==' ')||(buf[pos+linepos]=='n')
  365.                                                  ||(buf[pos+linepos]=='t'))
  366.                         pos++;
  367.                     sscanf(buf+pos+linepos, "%s", line+linepos);                
  368.                     linepos = strlen(line);
  369.                 } while((buf[pos+linepos]!='n') && (s.st_size>(pos+linepos+1)));
  370.                 pos += linepos + 1;
  371. if (strncmp(line, id, strlen(id)) == 0) {
  372. key->algorithm   = (char *) strdup(strtok(line+strlen(id), ",)"));
  373. if (strcmp(key->algorithm, "NOENCR") != 0) {
  374. key->key     = (char *) strtok(NULL  , ")");
  375.                                 ASSERT(key->key!=NULL);
  376. key->key_len = strlen(key->key);
  377. tmp = (char *) xmalloc(key->key_len);
  378. key->key_len = base64decode(key->key, key->key_len, tmp, key->key_len);
  379. key->key = tmp;
  380. } else {
  381. key->key     = NULL;
  382. key->key_len = 0;
  383. }
  384. xfree(buf);
  385. xfree(line);
  386. return;
  387. }
  388. }
  389. debug_msg("Unable to read hashkey from config filen");
  390. xfree(buf);
  391. xfree(line);
  392. }
  393. #endif
  394. void mbus_get_encrkey(struct mbus_config *m, struct mbus_key *key)
  395. {
  396. /* This MUST be called while the config file is locked! */
  397. int  i, j, k;
  398. #ifdef WIN32
  399. long  status;
  400. DWORD  type;
  401. char *buffer;
  402. int    buflen = MBUS_BUF_SIZE;
  403. char *tmp;
  404. ASSERT(m->cfg_locked);
  405. /* Read the key from the registry... */
  406. buffer = (char *) xmalloc(MBUS_BUF_SIZE);
  407. status = RegQueryValueEx(m->cfgKey, "ENCRYPTIONKEY", 0, &type, buffer, &buflen);
  408. if (status != ERROR_SUCCESS) {
  409. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  410. debug_msg("Unable to get encrkey: %sn", buffer);
  411. abort();
  412. }
  413. ASSERT(type == REG_SZ);
  414. ASSERT(buflen > 0);
  415. /* Parse the key... */
  416. key->algorithm   = strdup(strtok(buffer+1, ",)"));
  417. if (strcmp(key->algorithm, "NOENCR") != 0) {
  418. key->key     = (char *) strtok(NULL  , ")");
  419. key->key_len = strlen(key->key);
  420. tmp = (char *) xmalloc(key->key_len);
  421. key->key_len = base64decode(key->key, key->key_len, tmp, key->key_len);
  422. key->key = tmp;
  423. } else {
  424. key->key     = NULL;
  425. key->key_len = 0;
  426. }
  427. xfree(buffer);
  428. #else
  429. mbus_get_key(m, key, "ENCRYPTIONKEY=(");
  430. #endif
  431. if (strcmp(key->algorithm, "DES") == 0) {
  432. ASSERT(key->key != NULL);
  433. ASSERT(key->key_len == 8);
  434. /* check parity bits */
  435. for (i = 0; i < 8; ++i) 
  436. {
  437. k = key->key[i] & 0xfe;
  438. j = k;
  439. j ^= j >> 4;
  440. j ^= j >> 2;
  441. j ^= j >> 1;
  442. j = (j & 1) ^ 1;
  443. ASSERT((key->key[i] & 0x01) == j);
  444. }
  445. }
  446. }
  447. void mbus_get_hashkey(struct mbus_config *m, struct mbus_key *key)
  448. {
  449. /* This MUST be called while the config file is locked! */
  450. #ifdef WIN32
  451. long  status;
  452. DWORD  type;
  453. char *buffer;
  454. int  buflen = MBUS_BUF_SIZE;
  455. char *tmp;
  456. ASSERT(m->cfg_locked);
  457. /* Read the key from the registry... */
  458. buffer = (char *) xmalloc(MBUS_BUF_SIZE);
  459. status = RegQueryValueEx(m->cfgKey, "HASHKEY", 0, &type, buffer, &buflen);
  460. if (status != ERROR_SUCCESS) {
  461. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  462. debug_msg("Unable to get encrkey: %sn", buffer);
  463. abort();
  464. }
  465. ASSERT(type == REG_SZ);
  466. ASSERT(buflen > 0);
  467. /* Parse the key... */
  468. key->algorithm   = strdup(strtok(buffer+1, ","));
  469. key->key         = strtok(NULL  , ")");
  470. key->key_len     = strlen(key->key);
  471. /* Decode the key... */
  472. tmp = (char *) xmalloc(key->key_len);
  473. key->key_len = base64decode(key->key, key->key_len, tmp, key->key_len);
  474. key->key = tmp;
  475. xfree(buffer);
  476. #else
  477. mbus_get_key(m, key, "HASHKEY=(");
  478. #endif
  479. }
  480. void mbus_get_net_addr(struct mbus_config *m, char *net_addr, uint16_t *net_port, int *net_scope)
  481. {
  482. #ifdef WIN32
  483. long  status;
  484. DWORD  type;
  485. char *buffer;
  486. int  buflen = MBUS_BUF_SIZE;
  487. uint32_t port;
  488. ASSERT(m->cfg_locked);
  489. /* Read the key from the registry... */
  490. buffer = (char *) xmalloc(MBUS_BUF_SIZE);
  491.         buflen = MBUS_BUF_SIZE;
  492. status = RegQueryValueEx(m->cfgKey, "ADDRESS", 0, &type, buffer, &buflen);
  493. if (status != ERROR_SUCCESS) {
  494. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  495. debug_msg("Unable to get address: %sn", buffer);
  496. strcpy(net_addr, MBUS_DEFAULT_NET_ADDR);
  497. } else {
  498. ASSERT(type == REG_SZ);
  499. ASSERT(buflen > 0);
  500. strncpy(net_addr, buffer, buflen);
  501. }
  502. buflen = sizeof(port);
  503. status = RegQueryValueEx(m->cfgKey, "PORT", 0, &type, (uint8_t *) &port, &buflen);
  504. if (status != ERROR_SUCCESS) {
  505. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  506. debug_msg("Unable to get port: %sn", buffer);
  507. *net_port  = MBUS_DEFAULT_NET_PORT;
  508. } else {
  509. ASSERT(type == REG_DWORD);
  510. ASSERT(buflen == 4);
  511. *net_port = (uint16_t) port;
  512. }
  513. buflen = MBUS_BUF_SIZE;
  514. status = RegQueryValueEx(m->cfgKey, "SCOPE", 0, &type, buffer, &buflen);
  515. if (status != ERROR_SUCCESS) {
  516. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  517. debug_msg("Unable to get scope: %sn", buffer);
  518. *net_scope = MBUS_DEFAULT_SCOPE;
  519. } else {
  520. ASSERT(type == REG_SZ);
  521. ASSERT(buflen > 0);
  522. if (strncmp(buffer, SCOPE_HOSTLOCAL_NAME, strlen(SCOPE_HOSTLOCAL_NAME)) == 0) {
  523. *net_scope = SCOPE_HOSTLOCAL;
  524. } else if (strncmp(buffer, SCOPE_LINKLOCAL_NAME, strlen(SCOPE_LINKLOCAL_NAME)) == 0) {
  525. *net_scope = SCOPE_LINKLOCAL;
  526. } else {
  527. debug_msg("Unrecognized scope: %sn", buffer);
  528. *net_scope = MBUS_DEFAULT_SCOPE;
  529. }
  530. }
  531.         xfree(buffer);
  532. #else
  533. struct stat  s;
  534. char *buf;
  535. char *line;
  536. int  pos;
  537. int              pos2;
  538.         int              linepos;
  539. int              scope;
  540. char            *addr;
  541. uint16_t        port;
  542. ASSERT(m->cfg_locked);
  543. addr = (char *)xmalloc(20);
  544. memset(addr, 0, 20);
  545. port = 0;
  546. scope = -1;
  547. if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
  548. perror("Can't seek to start of config file");
  549. abort();
  550. }
  551. if (fstat(m->cfgfd, &s) != 0) {
  552. perror("Unable to stat config filen");
  553. abort();
  554. }
  555. /* Read in the contents of the config file... */
  556. buf = (char *) xmalloc(s.st_size+1);
  557. memset(buf, '', s.st_size+1);
  558. if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
  559. perror("Unable to read config filen");
  560. abort();
  561. }
  562. line = (char *) xmalloc(s.st_size+1);
  563. sscanf(buf, "%s", line);
  564. if (strcmp(line, "[MBUS]") != 0) {
  565. debug_msg("Invalid .mbus filen");
  566. abort();
  567. }
  568. pos = strlen(line) + 1;
  569. while (pos < s.st_size) {
  570.                 /* get whole line and filter out spaces */
  571.                 linepos=0;
  572.                 do {
  573.                     while((buf[pos+linepos]==' ')||(buf[pos+linepos]=='n')
  574.                                                  ||(buf[pos+linepos]=='t'))
  575.                         pos++;
  576.                     sscanf(buf+pos+linepos, "%s", line+linepos);                
  577.                     linepos = strlen(line);
  578.   
  579.                 } while((buf[pos+linepos]!='n') && (s.st_size>(pos+linepos+1)));
  580.                 pos += linepos + 1;     
  581. if (strncmp(line, "SCOPE", strlen("SCOPE")) == 0) {
  582.     pos2 = strlen("SCOPE") + 1;
  583.     if (strncmp(line+pos2, SCOPE_HOSTLOCAL_NAME, 
  584. strlen(SCOPE_HOSTLOCAL_NAME)) == 0) {
  585. scope = SCOPE_HOSTLOCAL;
  586.     }
  587.     if (strncmp(line+pos2, SCOPE_LINKLOCAL_NAME, 
  588. strlen(SCOPE_LINKLOCAL_NAME)) == 0) {
  589. scope = SCOPE_LINKLOCAL ;
  590.     }
  591. }
  592. if (strncmp(line, "ADDRESS", strlen("ADDRESS")) == 0) {
  593.     pos2 = strlen("ADDRESS") + 1;
  594.     strncpy(addr, line+pos2, 16);
  595. }
  596. if (strncmp(line, "PORT", strlen("PORT")) == 0) {
  597.     pos2 = strlen("PORT") + 1;
  598.     port = atoi(line+pos2);
  599. }
  600.     
  601. }
  602. /* If we did not find all values, fill in the default ones */
  603. *net_port  = (port>0)?port:MBUS_DEFAULT_NET_PORT;
  604. *net_scope = (scope!=-1)?scope:MBUS_DEFAULT_SCOPE;
  605. if (strlen(addr)>0) {
  606. strncpy(net_addr, addr, 16);
  607. } else {
  608. strcpy(net_addr, MBUS_DEFAULT_NET_ADDR);
  609. }
  610. debug_msg("using Addr:%s Port:%d Scope:%s for MBUSn", 
  611.   net_addr, *net_port, (*net_scope==0)?SCOPE_HOSTLOCAL_NAME:SCOPE_LINKLOCAL_NAME);
  612. xfree(buf);
  613. xfree(line);
  614. xfree(addr);
  615. #endif
  616. }
  617. int mbus_get_version(struct mbus_config *m)
  618. {
  619. #ifdef WIN32
  620. long status;
  621. DWORD type;
  622. uint32_t cver;
  623. int verl;
  624. char buffer[MBUS_BUF_SIZE];
  625. ASSERT(m->cfg_locked);
  626. /* Read the key from the registry... */
  627.         verl = sizeof(&cver);
  628. status = RegQueryValueEx(m->cfgKey, "CONFIG_VERSION", 0, &type, (uint8_t *) &cver, &verl);
  629. if (status != ERROR_SUCCESS) {
  630. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
  631. debug_msg("Unable to get version: %sn", buffer);
  632. return 0;
  633. }
  634. ASSERT(type == REG_DWORD);
  635. ASSERT(verl == 4);
  636. return cver;
  637. #else
  638. struct stat  s;
  639. char *buf;
  640. char *line;
  641. int  pos;
  642. int              pos2;
  643.         int              linepos;
  644. int  version = 0;
  645. ASSERT(m->cfg_locked);
  646. if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
  647. perror("Can't seek to start of config file");
  648. abort();
  649. }
  650. if (fstat(m->cfgfd, &s) != 0) {
  651. perror("Unable to stat config filen");
  652. abort();
  653. }
  654. /* Read in the contents of the config file... */
  655. buf = (char *) xmalloc(s.st_size+1);
  656. memset(buf, '', s.st_size+1);
  657. if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
  658. perror("Unable to read config filen");
  659. abort();
  660. }
  661. line = (char *) xmalloc(s.st_size+1);
  662. sscanf(buf, "%s", line);
  663. if (strcmp(line, "[MBUS]") != 0) {
  664. debug_msg("Invalid .mbus filen");
  665. abort();
  666. }
  667. pos = strlen(line) + 1;
  668. while (pos < s.st_size) {
  669.                 /* get whole line and filter out spaces */
  670.                 linepos=0;
  671.                 do {
  672. while((buf[pos+linepos]==' ')||(buf[pos+linepos]=='n') ||(buf[pos+linepos]=='t')) {
  673. pos++;
  674. }
  675. sscanf(buf+pos+linepos, "%s", line+linepos);                
  676. linepos = strlen(line);
  677.                 } while((buf[pos+linepos]!='n') && (s.st_size>(pos+linepos+1)));
  678.                 pos += linepos + 1;     
  679. if (strncmp(line, "CONFIG_VERSION", strlen("CONFIG_VERSION")) == 0) {
  680.     pos2    = strlen("CONFIG_VERSION") + 1;
  681.     version = atoi(line+pos2);
  682. }
  683.     
  684. }
  685. xfree(buf);
  686. xfree(line);
  687. return version;
  688. #endif
  689. }
  690. struct mbus_config *mbus_create_config(void)
  691. {
  692. return (struct mbus_config *) xmalloc(sizeof(struct mbus_config));
  693. }