Changeset ce1836e in mainline
- Timestamp:
- 2012-05-15T19:51:06Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2bd578a
- Parents:
- 6df2202 (diff), bf9e6fc (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 3 edited
- 34 moved
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile.common
r6df2202 rce1836e 72 72 $(USPACE_PATH)/srv/loader/loader \ 73 73 $(USPACE_PATH)/app/init/init \ 74 $(USPACE_PATH)/srv/loc /loc\74 $(USPACE_PATH)/srv/locsrv/locsrv \ 75 75 $(USPACE_PATH)/srv/bd/rd/rd \ 76 76 $(USPACE_PATH)/srv/vfs/vfs … … 107 107 $(USPACE_PATH)/srv/hid/remcons/remcons \ 108 108 $(USPACE_PATH)/srv/net/ethip/ethip \ 109 $(USPACE_PATH)/srv/net/inet /inet\109 $(USPACE_PATH)/srv/net/inetsrv/inetsrv \ 110 110 $(USPACE_PATH)/srv/net/loopip/loopip \ 111 111 $(USPACE_PATH)/srv/net/tcp/tcp \ 112 112 $(USPACE_PATH)/srv/net/udp/udp \ 113 113 $(USPACE_PATH)/srv/taskmon/taskmon \ 114 $(USPACE_PATH)/srv/devman/devman 114 $(USPACE_PATH)/srv/devman/devman \ 115 $(USPACE_PATH)/srv/websrv/websrv 115 116 116 117 RD_DRVS = \ … … 157 158 $(USPACE_PATH)/app/edit/edit \ 158 159 $(USPACE_PATH)/app/ext2info/ext2info \ 159 $(USPACE_PATH)/app/inet cfg/inetcfg\160 $(USPACE_PATH)/app/inet/inet \ 160 161 $(USPACE_PATH)/app/kill/kill \ 161 162 $(USPACE_PATH)/app/killall/killall \ 162 $(USPACE_PATH)/app/loc info/locinfo\163 $(USPACE_PATH)/app/loc/loc \ 163 164 $(USPACE_PATH)/app/mkfat/mkfat \ 164 165 $(USPACE_PATH)/app/mkexfat/mkexfat \ … … 184 185 $(USPACE_PATH)/app/usbinfo/usbinfo \ 185 186 $(USPACE_PATH)/app/vuhid/vuh \ 186 $(USPACE_PATH)/app/mkbd/mkbd \ 187 $(USPACE_PATH)/app/websrv/websrv 187 $(USPACE_PATH)/app/mkbd/mkbd 188 188 189 189 ifeq ($(CONFIG_PCC),y) -
uspace/Makefile
r6df2202 rce1836e 42 42 app/getterm \ 43 43 app/init \ 44 app/inet cfg\44 app/inet \ 45 45 app/kill \ 46 46 app/killall \ 47 47 app/klog \ 48 app/loc info\48 app/loc \ 49 49 app/lsusb \ 50 50 app/mkfat \ … … 69 69 app/nettest3 \ 70 70 app/ping \ 71 app/websrv \72 71 app/sysinfo \ 73 72 app/mkbd \ 74 73 srv/clipboard \ 75 srv/loc \74 srv/locsrv \ 76 75 srv/devman \ 77 76 srv/loader \ 78 77 srv/net/ethip \ 79 srv/net/inet \78 srv/net/inetsrv \ 80 79 srv/net/loopip \ 81 80 srv/net/tcp \ … … 103 102 srv/hid/remcons \ 104 103 srv/hw/char/s3c24xx_uart \ 104 srv/websrv \ 105 105 drv/infrastructure/root \ 106 106 drv/infrastructure/rootvirt \ -
uspace/app/inet/Makefile
r6df2202 rce1836e 28 28 29 29 USPACE_PREFIX = ../.. 30 BINARY = inet cfg30 BINARY = inet 31 31 32 32 SOURCES = \ 33 inet cfg.c33 inet.c 34 34 35 35 include $(USPACE_PREFIX)/Makefile.common -
uspace/app/inet/inet.c
r6df2202 rce1836e 27 27 */ 28 28 29 /** @addtogroup inet cfg29 /** @addtogroup inet 30 30 * @{ 31 31 */ … … 43 43 #include <sys/types.h> 44 44 45 #define NAME "inet cfg"45 #define NAME "inet" 46 46 47 47 static void print_syntax(void) … … 187 187 rc = inetcfg_addr_create_static(aobj_name, &naddr, link_id, &addr_id); 188 188 if (rc != EOK) { 189 printf(NAME ": Failed creating static address '%s' (% d)\n",190 aobj_name, rc);189 printf(NAME ": Failed creating static address '%s' (%s)\n", 190 aobj_name, str_error(rc)); 191 191 return EIO; 192 192 } … … 345 345 346 346 printf("Configured addresses:\n"); 347 347 if (count > 0) 348 printf(" [Addr/Width] [Link-Name] [Addr-Name] [Def-MTU]\n"); 348 349 ainfo.name = linfo.name = astr = NULL; 349 350 … … 415 416 416 417 printf("Static routes:\n"); 418 if (count > 0) 419 printf(" [Dest/Width] [Router-Addr] [Route-Name]\n"); 417 420 418 421 srinfo.name = dest_str = router_str = NULL; -
uspace/app/init/init.c
r6df2202 rce1836e 307 307 spawn("/srv/loopip"); 308 308 spawn("/srv/ethip"); 309 spawn("/srv/inet ");309 spawn("/srv/inetsrv"); 310 310 spawn("/srv/tcp"); 311 311 spawn("/srv/udp"); -
uspace/app/loc/Makefile
r6df2202 rce1836e 28 28 29 29 USPACE_PREFIX = ../.. 30 EXTRA_CFLAGS = -Iinclude 31 BINARY = locinfo 30 BINARY = loc 32 31 33 32 SOURCES = \ 34 loc info.c33 loc.c 35 34 36 35 include $(USPACE_PREFIX)/Makefile.common -
uspace/app/loc/loc.c
r6df2202 rce1836e 27 27 */ 28 28 29 /** @addtogroup loc info29 /** @addtogroup loc 30 30 * @{ 31 31 */ 32 /** @file loc info.c Print information from location service.32 /** @file loc.c Print information from location service. 33 33 */ 34 34 … … 41 41 #include <sys/typefmt.h> 42 42 43 #define NAME "loc info"43 #define NAME "loc" 44 44 45 int main(int argc, char *argv[]) 45 static int show_cat(const char *cat_name, category_id_t cat_id) 46 { 47 service_id_t *svc_ids; 48 size_t svc_cnt; 49 char *svc_name; 50 int rc; 51 size_t j; 52 53 printf("%s (%" PRIun "):\n", cat_name, cat_id); 54 55 rc = loc_category_get_svcs(cat_id, &svc_ids, &svc_cnt); 56 if (rc != EOK) { 57 printf(NAME ": Failed getting list of services in " 58 "category %s, skipping.\n", cat_name); 59 return rc; 60 } 61 62 for (j = 0; j < svc_cnt; j++) { 63 rc = loc_service_get_name(svc_ids[j], &svc_name); 64 if (rc != EOK) { 65 printf(NAME ": Unknown service name (SID %" 66 PRIun ").\n", svc_ids[j]); 67 continue; 68 } 69 printf("\t%s (%" PRIun ")\n", svc_name, svc_ids[j]); 70 free(svc_name); 71 } 72 73 free(svc_ids); 74 return EOK; 75 } 76 77 static int list_svcs_by_cat(void) 46 78 { 47 79 category_id_t *cat_ids; 48 80 size_t cat_cnt; 49 service_id_t *svc_ids;50 size_t svc_cnt;51 81 52 size_t i , j;82 size_t i; 53 83 char *cat_name; 54 char *svc_name;55 84 int rc; 56 85 … … 58 87 if (rc != EOK) { 59 88 printf(NAME ": Error getting list of categories.\n"); 60 return 1;89 return rc; 61 90 } 62 91 … … 68 97 if (cat_name == NULL) { 69 98 printf(NAME ": Error allocating memory.\n"); 70 return 1; 99 free(cat_ids); 100 return rc; 71 101 } 72 102 73 printf("%s (%" PRIun "):\n", cat_name, cat_ids[i]); 103 rc = show_cat(cat_name, cat_ids[i]); 104 (void) rc; 74 105 75 rc = loc_category_get_svcs(cat_ids[i], &svc_ids, &svc_cnt);76 if (rc != EOK) {77 printf(NAME ": Failed getting list of services in "78 "category %s, skipping.\n", cat_name);79 free(cat_name);80 continue;81 }82 83 for (j = 0; j < svc_cnt; j++) {84 rc = loc_service_get_name(svc_ids[j], &svc_name);85 if (rc != EOK) {86 printf(NAME ": Unknown service name (SID %"87 PRIun ").\n", svc_ids[j]);88 continue;89 }90 printf("\t%s (%" PRIun ")\n", svc_name, svc_ids[j]);91 free(svc_name);92 }93 94 free(svc_ids);95 106 free(cat_name); 96 107 } 97 108 98 109 free(cat_ids); 110 return EOK; 111 } 112 113 static void print_syntax(void) 114 { 115 printf("syntax:\n" 116 "\t" NAME " List categories and services " 117 "they contain\n" 118 "\t" NAME " show-cat <category> List services in category\n"); 119 } 120 121 int main(int argc, char *argv[]) 122 { 123 int rc; 124 char *cmd; 125 char *cat_name; 126 category_id_t cat_id; 127 128 if (argc <= 1) { 129 rc = list_svcs_by_cat(); 130 if (rc != EOK) 131 return 1; 132 return 0; 133 } 134 135 cmd = argv[1]; 136 if (str_cmp(cmd, "show-cat") == 0) { 137 if (argc < 3) { 138 printf("Argument missing.\n"); 139 print_syntax(); 140 return 1; 141 } 142 143 cat_name = argv[2]; 144 rc = loc_category_get_id(cat_name, &cat_id, 0); 145 if (rc != EOK) { 146 printf("Error looking up category '%s'.\n", cat_name); 147 return 1; 148 } 149 150 rc = show_cat(cat_name, cat_id); 151 if (rc != EOK) 152 return 1; 153 } else { 154 printf("Invalid command '%s'\n", cmd); 155 print_syntax(); 156 return 1; 157 } 158 99 159 return 0; 100 160 } -
uspace/srv/locsrv/Makefile
r6df2202 rce1836e 29 29 30 30 USPACE_PREFIX = ../.. 31 BINARY = loc 31 BINARY = locsrv 32 32 STATIC_NEEDED = y 33 33 34 34 SOURCES = \ 35 35 category.c \ 36 loc .c36 locsrv.c 37 37 38 38 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/locsrv/category.c
r6df2202 rce1836e 40 40 41 41 #include "category.h" 42 #include "loc .h"42 #include "locsrv.h" 43 43 44 44 /** Initialize category directory. */ -
uspace/srv/locsrv/category.h
r6df2202 rce1836e 37 37 38 38 #include <adt/list.h> 39 #include "loc .h"39 #include "locsrv.h" 40 40 41 41 typedef sysarg_t catid_t; -
uspace/srv/locsrv/locsrv.c
r6df2202 rce1836e 51 51 52 52 #include "category.h" 53 #include "loc .h"53 #include "locsrv.h" 54 54 55 55 #define NAME "loc" -
uspace/srv/locsrv/locsrv.h
r6df2202 rce1836e 33 33 */ 34 34 35 #ifndef LOC _H_36 #define LOC _H_35 #ifndef LOCSRV_H_ 36 #define LOCSRV_H_ 37 37 38 38 #include <ipc/loc.h> -
uspace/srv/net/inetsrv/Makefile
r6df2202 rce1836e 28 28 29 29 USPACE_PREFIX = ../../.. 30 BINARY = inet 30 BINARY = inetsrv 31 31 32 32 SOURCES = \ 33 33 addrobj.c \ 34 34 icmp.c \ 35 inet .c \35 inetsrv.c \ 36 36 inet_link.c \ 37 37 inet_util.c \ -
uspace/srv/net/inetsrv/addrobj.c
r6df2202 rce1836e 44 44 45 45 #include "addrobj.h" 46 #include "inet .h"46 #include "inetsrv.h" 47 47 #include "inet_link.h" 48 48 #include "inet_util.h" 49 50 static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *, inet_link_t *); 49 51 50 52 static FIBRIL_MUTEX_INITIALIZE(addr_list_lock); … … 77 79 } 78 80 79 void inet_addrobj_add(inet_addrobj_t *addr) 80 { 81 fibril_mutex_lock(&addr_list_lock); 81 int inet_addrobj_add(inet_addrobj_t *addr) 82 { 83 inet_addrobj_t *aobj; 84 85 fibril_mutex_lock(&addr_list_lock); 86 aobj = inet_addrobj_find_by_name_locked(addr->name, addr->ilink); 87 if (aobj != NULL) { 88 /* Duplicate address name */ 89 fibril_mutex_unlock(&addr_list_lock); 90 return EEXISTS; 91 } 92 82 93 list_append(&addr->addr_list, &addr_list); 83 94 fibril_mutex_unlock(&addr_list_lock); 95 96 return EOK; 84 97 } 85 98 … … 130 143 * @return Address object 131 144 */ 132 inet_addrobj_t *inet_addrobj_find_by_name(const char *name, inet_link_t *ilink) 133 { 134 log_msg(LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')", 145 static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *name, inet_link_t *ilink) 146 { 147 assert(fibril_mutex_is_locked(&addr_list_lock)); 148 149 log_msg(LVL_DEBUG, "inet_addrobj_find_by_name_locked('%s', '%s')", 135 150 name, ilink->svc_name); 136 151 137 fibril_mutex_lock(&addr_list_lock);138 139 152 list_foreach(addr_list, link) { 140 153 inet_addrobj_t *naddr = list_get_instance(link, … … 142 155 143 156 if (naddr->ilink == ilink && str_cmp(naddr->name, name) == 0) { 144 fibril_mutex_unlock(&addr_list_lock); 145 log_msg(LVL_DEBUG, "inet_addrobj_find_by_name: found %p", 157 log_msg(LVL_DEBUG, "inet_addrobj_find_by_name_locked: found %p", 146 158 naddr); 147 159 return naddr; … … 149 161 } 150 162 151 log_msg(LVL_DEBUG, "inet_addrobj_find_by_name: Not found"); 152 fibril_mutex_unlock(&addr_list_lock); 163 log_msg(LVL_DEBUG, "inet_addrobj_find_by_name_locked: Not found"); 153 164 154 165 return NULL; 166 } 167 168 169 /** Find address object on a link, with a specific name. 170 * 171 * @param name Address object name 172 * @param ilink Inet link 173 * @return Address object 174 */ 175 inet_addrobj_t *inet_addrobj_find_by_name(const char *name, inet_link_t *ilink) 176 { 177 inet_addrobj_t *aobj; 178 179 log_msg(LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')", 180 name, ilink->svc_name); 181 182 fibril_mutex_lock(&addr_list_lock); 183 aobj = inet_addrobj_find_by_name_locked(name, ilink); 184 fibril_mutex_unlock(&addr_list_lock); 185 186 return aobj; 155 187 } 156 188 -
uspace/srv/net/inetsrv/addrobj.h
r6df2202 rce1836e 39 39 40 40 #include <sys/types.h> 41 #include "inet .h"41 #include "inetsrv.h" 42 42 43 43 typedef enum { … … 50 50 extern inet_addrobj_t *inet_addrobj_new(void); 51 51 extern void inet_addrobj_delete(inet_addrobj_t *); 52 extern voidinet_addrobj_add(inet_addrobj_t *);52 extern int inet_addrobj_add(inet_addrobj_t *); 53 53 extern void inet_addrobj_remove(inet_addrobj_t *); 54 54 extern inet_addrobj_t *inet_addrobj_find(inet_addr_t *, inet_addrobj_find_t); -
uspace/srv/net/inetsrv/icmp.c
r6df2202 rce1836e 43 43 #include "icmp.h" 44 44 #include "icmp_std.h" 45 #include "inet .h"45 #include "inetsrv.h" 46 46 #include "inetping.h" 47 47 #include "pdu.h" -
uspace/srv/net/inetsrv/icmp.h
r6df2202 rce1836e 38 38 #define ICMP_H_ 39 39 40 #include "inet .h"40 #include "inetsrv.h" 41 41 42 42 extern int icmp_recv(inet_dgram_t *); -
uspace/srv/net/inetsrv/inet_link.c
r6df2202 rce1836e 45 45 46 46 #include "addrobj.h" 47 #include "inet .h"47 #include "inetsrv.h" 48 48 #include "inet_link.h" 49 49 #include "pdu.h" … … 207 207 addr->ilink = ilink; 208 208 addr->name = str_dup("v4a"); 209 inet_addrobj_add(addr); 209 rc = inet_addrobj_add(addr); 210 if (rc != EOK) { 211 log_msg(LVL_ERROR, "Failed setting IP address on internet link."); 212 inet_addrobj_delete(addr); 213 /* XXX Roll back */ 214 return rc; 215 } 210 216 211 217 iaddr.ipv4 = addr->naddr.ipv4; … … 213 219 if (rc != EOK) { 214 220 log_msg(LVL_ERROR, "Failed setting IP address on internet link."); 221 inet_addrobj_remove(addr); 222 inet_addrobj_delete(addr); 215 223 /* XXX Roll back */ 216 224 return rc; -
uspace/srv/net/inetsrv/inet_link.h
r6df2202 rce1836e 39 39 40 40 #include <sys/types.h> 41 #include "inet .h"41 #include "inetsrv.h" 42 42 43 43 extern int inet_link_discovery_start(void); -
uspace/srv/net/inetsrv/inetcfg.c
r6df2202 rce1836e 46 46 47 47 #include "addrobj.h" 48 #include "inet .h"48 #include "inetsrv.h" 49 49 #include "inet_link.h" 50 50 #include "inetcfg.h" … … 75 75 addr->ilink = ilink; 76 76 addr->name = str_dup(name); 77 inet_addrobj_add(addr); 77 rc = inet_addrobj_add(addr); 78 if (rc != EOK) { 79 log_msg(LVL_DEBUG, "Duplicate address name '%s'.", addr->name); 80 inet_addrobj_delete(addr); 81 return rc; 82 } 78 83 79 84 iaddr.ipv4 = addr->naddr.ipv4; -
uspace/srv/net/inetsrv/inetping.c
r6df2202 rce1836e 46 46 #include "icmp.h" 47 47 #include "icmp_std.h" 48 #include "inet .h"48 #include "inetsrv.h" 49 49 #include "inetping.h" 50 50 -
uspace/srv/net/inetsrv/inetsrv.c
r6df2202 rce1836e 50 50 #include "icmp.h" 51 51 #include "icmp_std.h" 52 #include "inet .h"52 #include "inetsrv.h" 53 53 #include "inetcfg.h" 54 54 #include "inetping.h" … … 57 57 #include "sroute.h" 58 58 59 #define NAME "inet "59 #define NAME "inetsrv" 60 60 61 61 static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg); -
uspace/srv/net/inetsrv/inetsrv.h
r6df2202 rce1836e 27 27 */ 28 28 29 /** @addtogroup inet 29 /** @addtogroup inetsrv 30 30 * @{ 31 31 */ … … 35 35 */ 36 36 37 #ifndef INET _H_38 #define INET _H_37 #ifndef INETSRV_H_ 38 #define INETSRV_H_ 39 39 40 40 #include <adt/list.h> -
uspace/srv/net/inetsrv/pdu.c
r6df2202 rce1836e 45 45 #include <stdlib.h> 46 46 47 #include "inet .h"47 #include "inetsrv.h" 48 48 #include "inet_std.h" 49 49 #include "pdu.h" -
uspace/srv/net/inetsrv/pdu.h
r6df2202 rce1836e 39 39 40 40 #include <sys/types.h> 41 #include "inet .h"41 #include "inetsrv.h" 42 42 43 43 #define INET_CHECKSUM_INIT 0xffff -
uspace/srv/net/inetsrv/reass.c
r6df2202 rce1836e 42 42 #include <stdlib.h> 43 43 44 #include "inet .h"44 #include "inetsrv.h" 45 45 #include "inet_std.h" 46 46 #include "reass.h" -
uspace/srv/net/inetsrv/reass.h
r6df2202 rce1836e 39 39 40 40 #include <sys/types.h> 41 #include "inet .h"41 #include "inetsrv.h" 42 42 43 43 extern int inet_reass_queue_packet(inet_packet_t *); -
uspace/srv/net/inetsrv/sroute.c
r6df2202 rce1836e 44 44 45 45 #include "sroute.h" 46 #include "inet .h"46 #include "inetsrv.h" 47 47 #include "inet_link.h" 48 48 #include "inet_util.h" -
uspace/srv/net/inetsrv/sroute.h
r6df2202 rce1836e 39 39 40 40 #include <sys/types.h> 41 #include "inet .h"41 #include "inetsrv.h" 42 42 43 43 extern inet_sroute_t *inet_sroute_new(void); -
uspace/srv/websrv/websrv.c
r6df2202 rce1836e 1 1 /* 2 * Copyright (c) 201 1Jiri Svoboda2 * Copyright (c) 2012 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 41 41 #include <stdlib.h> 42 42 #include <fcntl.h> 43 #include <task.h> 43 44 44 45 #include <net/in.h> … … 71 72 72 73 static char fbuf[BUFFER_SIZE]; 74 75 static bool verbose = false; 73 76 74 77 /** Responses to send to client. */ … … 187 190 size_t response_size = str_size(msg); 188 191 189 fprintf(stderr, "Sending response\n"); 192 if (verbose) 193 fprintf(stderr, "Sending response\n"); 194 190 195 ssize_t rc = send(conn_sd, (void *) msg, response_size, 0); 191 196 if (rc < 0) { … … 251 256 } 252 257 253 fprintf(stderr, "Request: %s", lbuf); 258 if (verbose) 259 fprintf(stderr, "Request: %s", lbuf); 254 260 255 261 if (str_lcmp(lbuf, "GET ", 4) != 0) { … … 266 272 267 273 *end_uri = '\0'; 268 fprintf(stderr, "Requested URI: %s\n", uri); 274 if (verbose) 275 fprintf(stderr, "Requested URI: %s\n", uri); 269 276 270 277 if (!uri_is_valid(uri)) { … … 287 294 "\n" 288 295 "-h | --help\n" 289 "\tShow this application help.\n"); 296 "\tShow this application help.\n" 297 "-v | --verbose\n" 298 "\tVerbose mode\n"); 290 299 } 291 300 … … 306 315 307 316 port = (uint16_t) value; 317 break; 318 case 'v': 319 verbose = true; 308 320 break; 309 321 /* Long options with double dash */ … … 318 330 319 331 port = (uint16_t) value; 332 } else if (str_cmp(argv[*index] +2, "verbose") == 0) { 333 verbose = true; 320 334 } else { 321 335 usage(); … … 358 372 } 359 373 360 fprintf(stderr, "Creating socket\n"); 374 printf("%s: HelenOS web server\n", NAME); 375 376 if (verbose) 377 fprintf(stderr, "Creating socket\n"); 361 378 362 379 int listen_sd = socket(PF_INET, SOCK_STREAM, 0); … … 380 397 } 381 398 382 fprintf(stderr, "Listening for connections at port %" PRIu16 "\n", 383 port); 399 fprintf(stderr, "%s: Listening for connections at port %" PRIu16 "\n", 400 NAME, port); 401 402 task_retval(0); 403 384 404 while (true) { 385 405 struct sockaddr_in raddr; … … 393 413 } 394 414 395 fprintf(stderr, "Connection accepted (sd=%d), " 396 "waiting for request\n", conn_sd); 415 if (verbose) { 416 fprintf(stderr, "Connection accepted (sd=%d), " 417 "waiting for request\n", conn_sd); 418 } 397 419 398 420 rbuf_out = 0; … … 412 434 } 413 435 414 fprintf(stderr, "Connection closed\n"); 436 if (verbose) 437 fprintf(stderr, "Connection closed\n"); 415 438 } 416 439
Note:
See TracChangeset
for help on using the changeset viewer.