diff -Nur -X/mnt/data/freeciv-dev/freeciv/diff_ignore freeciv/ai/aiunit.c activities/ai/aiunit.c
--- freeciv/ai/aiunit.c	Thu Feb 15 22:18:12 2001
+++ activities/ai/aiunit.c	Mon Feb 19 19:12:07 2001
@@ -1122,13 +1122,13 @@
   } /* end if we have a home */
 
   /* keep barbarians aggresive and primitive */
-  if( is_barbarian(pplayer) ) {
-     if( get_tile_infrastructure_set(map_get_tile(punit->x,punit->y)) &&
-         is_land_barbarian(pplayer) )
-       punit->ai.ai_role = AIUNIT_PILLAGE;  /* land barbarians pillage */
-     else
-       punit->ai.ai_role = AIUNIT_ATTACK;
-     return;
+  if (is_barbarian(pplayer)) {
+    if (can_unit_do_activity(punit, ACTIVITY_PILLAGE)
+	&& is_land_barbarian(pplayer))
+      punit->ai.ai_role = AIUNIT_PILLAGE;  /* land barbarians pillage */
+    else
+      punit->ai.ai_role = AIUNIT_ATTACK;
+    return;
   }
 
   if (punit->ai.charge) { /* I am a bodyguard */
diff -Nur -X/mnt/data/freeciv-dev/freeciv/diff_ignore freeciv/common/unit.c activities/common/unit.c
--- freeciv/common/unit.c	Mon Feb 19 18:58:02 2001
+++ activities/common/unit.c	Mon Feb 19 19:16:31 2001
@@ -597,6 +597,30 @@
 }
 
 /**************************************************************************
+Check if the unit's current activity is actually legal.
+**************************************************************************/
+int can_unit_continue_current_activity(struct unit *punit)
+{
+  enum unit_activity current = punit->activity;
+  int target = punit->activity_target;
+  int current2 = current == ACTIVITY_FORTIFIED ? ACTIVITY_FORTIFYING : current;
+  int result;
+
+  if (punit->connecting)
+    return can_unit_do_connect(punit, current);
+
+  punit->activity = ACTIVITY_IDLE;
+  punit->activity_target = 0;
+
+  result = can_unit_do_activity_targeted(punit, current2, target);
+
+  punit->activity = current;
+  punit->activity_target = target;
+
+  return result;
+}
+
+/**************************************************************************
 ...
 **************************************************************************/
 int can_unit_do_activity(struct unit *punit, enum unit_activity activity)
@@ -728,8 +752,14 @@
       pspresent = get_tile_infrastructure_set(ptile);
       if (pspresent && is_ground_unit(punit)) {
 	psworking = get_unit_tile_pillage_set(punit->x, punit->y);
-	if (target == S_NO_SPECIAL)
-	  return ((pspresent & (~psworking)) != 0);
+	if (ptile->city && (target & (S_ROAD | S_RAILROAD)))
+	    return 0;
+	if (target == S_NO_SPECIAL) {
+	  if (ptile->city)
+	    return ((pspresent & (~(psworking | S_ROAD |S_RAILROAD))) != 0);
+	  else
+	    return ((pspresent & (~psworking)) != 0);
+	}
 	else if ((!game.rgame.pillage_select) &&
 		 (target != get_preferred_pillage(pspresent)))
 	  return 0;
diff -Nur -X/mnt/data/freeciv-dev/freeciv/diff_ignore freeciv/common/unit.h activities/common/unit.h
--- freeciv/common/unit.h	Mon Feb 19 18:58:07 2001
+++ activities/common/unit.h	Mon Feb 19 19:00:15 2001
@@ -140,6 +140,7 @@
 int can_unit_change_homecity(struct unit *punit);
 int can_unit_do_connect(struct unit *punit, enum unit_activity activity);
 char* get_activity_text (int activity);
+int can_unit_continue_current_activity(struct unit *punit);
 int can_unit_do_activity(struct unit *punit, enum unit_activity activity);
 int can_unit_do_activity_targeted(struct unit *punit,
 				  enum unit_activity activity, int target);
diff -Nur -X/mnt/data/freeciv-dev/freeciv/diff_ignore freeciv/server/citytools.c activities/server/citytools.c
--- freeciv/server/citytools.c	Mon Feb 19 18:58:11 2001
+++ activities/server/citytools.c	Mon Feb 19 19:24:59 2001
@@ -1087,8 +1087,7 @@
 
   /* Catch fortress building, transforming into ocean, etc. */
   unit_list_iterate(map_get_tile(x, y)->units, punit) {
-    if (punit->activity != ACTIVITY_FORTIFIED
-	&& !can_unit_do_activity(punit, punit->activity))
+    if (!can_unit_continue_current_activity(punit))
       handle_unit_activity_request(punit, ACTIVITY_IDLE);
   } unit_list_iterate_end;
 }
diff -Nur -X/mnt/data/freeciv-dev/freeciv/diff_ignore freeciv/server/maphand.c activities/server/maphand.c
--- freeciv/server/maphand.c	Mon Feb 19 18:58:15 2001
+++ activities/server/maphand.c	Mon Feb 19 19:00:24 2001
@@ -114,19 +114,8 @@
 	}
       }
       unit_list_iterate(map_get_tile(x, y)->units, punit) {
-	/* Because of the way can_unit_do_activity() works we do
-	   fortified as a special case. (since you can never go
-	   straight to ACTIVITY_FORTIFY can_unit_do_activity()
-	   returns 0.) */
-	if (punit->activity == ACTIVITY_FORTIFIED) {
-	  punit->activity = ACTIVITY_IDLE;
-	  if (can_unit_do_activity(punit, ACTIVITY_FORTIFYING)) {
-	    punit->activity = ACTIVITY_FORTIFIED;
-	  } /* else let it remain on idle. */
-	} else if (!can_unit_do_activity(punit, punit->activity)
-		   && !punit->connecting) {
+	if (!can_unit_continue_current_activity(punit))
 	  handle_unit_activity_request(punit, ACTIVITY_IDLE);
-	}
       } unit_list_iterate_end;
     }
   }
@@ -172,8 +161,7 @@
 	break;
       }
       unit_list_iterate(map_get_tile(x, y)->units, punit) {
-	if (!can_unit_do_activity(punit, punit->activity)
-	    && !punit->connecting)
+	if (!can_unit_continue_current_activity(punit))
 	  handle_unit_activity_request(punit, ACTIVITY_IDLE);
       } unit_list_iterate_end;
     }
diff -Nur -X/mnt/data/freeciv-dev/freeciv/diff_ignore freeciv/server/unittools.c activities/server/unittools.c
--- freeciv/server/unittools.c	Thu Feb 15 22:18:12 2001
+++ activities/server/unittools.c	Mon Feb 19 19:24:31 2001
@@ -1383,6 +1383,11 @@
 
   send_unit_info(0, punit);
 
+  unit_list_iterate(ptile->units, punit2) {
+    if (!can_unit_continue_current_activity(punit2))
+      handle_unit_activity_request(punit2, ACTIVITY_IDLE);
+  } unit_list_iterate_end;
+
   /* Any units that landed in water or boats that landed on land as a
      result of settlers changing terrain must be moved back into their
      right environment.