1 // RosterBroadcastTestApp1.cpp 2 3 #include <stdio.h> 4 #include <string.h> 5 6 #include <Application.h> 7 #include <Entry.h> 8 #include <File.h> 9 #include <Message.h> 10 #include <Messenger.h> 11 #include <OS.h> 12 #include <Resources.h> 13 #include <Roster.h> 14 #include <String.h> 15 16 #include "RosterTestAppDefs.h" 17 18 BMessenger unitTesterMessenger; 19 20 static const char *kUnitTesterSignature 21 = "application/x-vnd.obos-roster-broadcast-test"; 22 23 // init_unit_tester_messenger 24 static 25 status_t 26 init_unit_tester_messenger() 27 { 28 // Unfortunately BeOS R5 doesn't update the roster-side information about 29 // the app looper's port ID once a BApplication has been created, and 30 // thus we can't construct a BMessenger targeting a BApplication created 31 // after the first one using the signature/team ID constructor. 32 // We need to do some hacking. 33 struct fake_messenger { 34 port_id fPort; 35 int32 fHandlerToken; 36 team_id fTeam; 37 int32 extra0; 38 int32 extra1; 39 bool fPreferredTarget; 40 bool extra2; 41 bool extra3; 42 bool extra4; 43 } &fake = *(fake_messenger*)&unitTesterMessenger; 44 // get team 45 status_t error = B_OK; 46 fake.fTeam = BRoster().TeamFor(kUnitTesterSignature); 47 if (fake.fTeam < 0) 48 error = fake.fTeam; 49 // find app looper port 50 bool found = false; 51 int32 cookie = 0; 52 port_info info; 53 while (error == B_OK && !found) { 54 error = get_next_port_info(fake.fTeam, &cookie, &info); 55 found = (error == B_OK && !strcmp("AppLooperPort", info.name)); 56 } 57 // init messenger 58 if (error == B_OK) { 59 fake.fPort = info.port; 60 fake.fHandlerToken = 0; 61 fake.fPreferredTarget = true; 62 } 63 return error; 64 } 65 66 // get_app_path 67 status_t 68 get_app_path(char *buffer) 69 { 70 status_t error = (buffer ? B_OK : B_BAD_VALUE); 71 image_info info; 72 int32 cookie = 0; 73 bool found = false; 74 if (error == B_OK) { 75 while (!found && get_next_image_info(0, &cookie, &info) == B_OK) { 76 if (info.type == B_APP_IMAGE) { 77 strncpy(buffer, info.name, B_PATH_NAME_LENGTH); 78 buffer[B_PATH_NAME_LENGTH] = 0; 79 found = true; 80 } 81 } 82 } 83 if (error == B_OK && !found) 84 error = B_ENTRY_NOT_FOUND; 85 return error; 86 } 87 88 // TestApp 89 class TestApp : public BApplication { 90 public: 91 TestApp(const char *signature) : BApplication(signature) 92 { 93 } 94 95 virtual void ArgvReceived(int32 argc, char **argv) 96 { 97 BMessage message(MSG_ARGV_RECEIVED); 98 message.AddInt32("argc", argc); 99 for (int32 i = 0; i < argc; i++) 100 message.AddString("argv", argv[i]); 101 unitTesterMessenger.SendMessage(&message); 102 } 103 104 virtual void RefsReceived(BMessage *_message) 105 { 106 BMessage message(*_message); 107 message.what = MSG_REFS_RECEIVED; 108 unitTesterMessenger.SendMessage(&message); 109 } 110 111 virtual void MessageReceived(BMessage *_message) 112 { 113 BMessage message(MSG_MESSAGE_RECEIVED); 114 message.AddMessage("message", _message); 115 message.AddInt32("sender", _message->ReturnAddress().Team()); 116 if (_message->what == MSG_1) 117 message.AddBool("don't ignore", true); 118 unitTesterMessenger.SendMessage(&message); 119 if (_message->what == MSG_1) { 120 // _message->SendReply(MSG_2); 121 BMessage reply(MSG_2); 122 _message->SendReply(&reply, be_app_messenger); 123 } 124 } 125 126 virtual bool QuitRequested() 127 { 128 unitTesterMessenger.SendMessage(MSG_QUIT_REQUESTED); 129 return true; 130 } 131 132 virtual void ReadyToRun() 133 { 134 unitTesterMessenger.SendMessage(MSG_READY_TO_RUN); 135 } 136 }; 137 138 // main 139 int 140 main(int argc, char **argv) 141 { 142 // find app file and get signature from resources 143 char path[B_PATH_NAME_LENGTH]; 144 status_t error = get_app_path(path); 145 char signature[B_MIME_TYPE_LENGTH]; 146 if (error == B_OK) { 147 // init app file 148 BFile file; 149 error = file.SetTo(path, B_READ_ONLY); 150 // get signature 151 BString signatureString; 152 if (error == B_OK) { 153 if (file.ReadAttrString("signature", &signatureString) == B_OK 154 && signatureString.Length() > 0) { 155 strcpy(signature, signatureString.String()); 156 } else 157 strcpy(signature, kDefaultTestAppSignature); 158 } else 159 printf("ERROR: Couldn't init app file: %s\n", strerror(error)); 160 } else 161 printf("ERROR: Couldn't get app ref: %s\n", strerror(error)); 162 // create the app 163 TestApp *app = NULL; 164 if (error == B_OK) { 165 app = new TestApp(signature); 166 // unitTesterMessenger = BMessenger(kUnitTesterSignature); 167 error = init_unit_tester_messenger(); 168 if (error != B_OK) 169 printf("ERROR: Couldn't init messenger: %s\n", strerror(error)); 170 // send started message 171 BMessage message(MSG_STARTED); 172 message.AddString("path", path); 173 unitTesterMessenger.SendMessage(&message); 174 // send main() args message 175 BMessage argsMessage(MSG_MAIN_ARGS); 176 argsMessage.AddInt32("argc", argc); 177 for (int i = 0; i < argc; i++) 178 argsMessage.AddString("argv", argv[i]); 179 unitTesterMessenger.SendMessage(&argsMessage); 180 // run the app 181 app->Run(); 182 delete app; 183 // send terminated message 184 unitTesterMessenger.SendMessage(MSG_TERMINATED); 185 } 186 return 0; 187 } 188 189