1 /*---------------------------------------------------------------------------- 2 -- 3 -- Module: xtmMsgBase 4 -- 5 -- Project: Xdiary 6 -- System: xtm - X Desktop Calendar 7 -- Subsystem: <> 8 -- Function block: <> 9 -- 10 -- Description: 11 -- Basic XDiary message routines. 12 -- 13 -- Filename: xtmMsgBase.c 14 -- 15 -- Authors: Roger Larsson, Ulrika Bornetun 16 -- Creation date: 1991-04-01 17 -- 18 -- 19 -- (C) Copyright Ulrika Bornetun, Roger Larsson (1995) 20 -- All rights reserved 21 -- 22 -- Permission to use, copy, modify, and distribute this software and its 23 -- documentation for any purpose and without fee is hereby granted, 24 -- provided that the above copyright notice appear in all copies. Ulrika 25 -- Bornetun and Roger Larsson make no representations about the usability 26 -- of this software for any purpose. It is provided "as is" without express 27 -- or implied warranty. 28 ----------------------------------------------------------------------------*/ 29 30 /* SCCS module identifier. */ 31 static char SCCSID[] = "@(#) Module: xtmMsgBase.c, Version: 1.1, Date: 95/02/18 15:52:32"; 32 33 34 /*---------------------------------------------------------------------------- 35 -- Include files 36 ----------------------------------------------------------------------------*/ 37 38 #include <pwd.h> 39 #include <string.h> 40 #include <stdlib.h> 41 #include <stdio.h> 42 #include <ctype.h> 43 #include <unistd.h> 44 45 #include <X11/Intrinsic.h> 46 47 #include <Xm/Xm.h> 48 49 #include "System.h" 50 #include "DirList.h" 51 #include "Message.h" 52 #include "TimDate.h" 53 54 #include "msgXdiary.h" 55 #include "xtmGlobal.h" 56 #include "xtmCalDb.h" 57 #include "xtmCustBase.h" 58 #include "xtmDbTools.h" 59 #include "xtmFormat.h" 60 #include "xtmGroupDb.h" 61 #include "xitError.h" 62 #include "xitTools.h" 63 #include "xtmMsgBase.h" 64 #include "xtmLocate.h" 65 66 /*---------------------------------------------------------------------------- 67 -- Macro definitions 68 ----------------------------------------------------------------------------*/ 69 70 #define max( a, b ) (a < b ? b : a ) 71 72 /* Alloc memory size in bytes. */ 73 #define SEGMENT_SIZE 1000 74 75 76 /*---------------------------------------------------------------------------- 77 -- Type declarations 78 ----------------------------------------------------------------------------*/ 79 80 81 /*---------------------------------------------------------------------------- 82 -- Global definitions 83 ----------------------------------------------------------------------------*/ 84 85 /* Name of module. */ 86 static char *module_name = "xtmMsgBase"; 87 88 89 /*---------------------------------------------------------------------------- 90 -- Function prototypes 91 ----------------------------------------------------------------------------*/ 92 93 static Boolean 94 sendInternalMessage( XTM_GL_BASE_DATA_REF appl_data_ref, 95 Widget mainW, 96 char *user_ref, 97 char *directory, 98 TIM_TIME_REF entry_date, 99 TIM_TIME_REF entry_time, 100 int duration, 101 char *message, 102 char *text ); 103 104 static Boolean 105 sendMailMessage( XTM_GL_BASE_DATA_REF appl_data_ref, 106 Widget mainW, 107 char *mail_address, 108 TIM_TIME_REF entry_date, 109 TIM_TIME_REF entry_time, 110 int duration, 111 char *message, 112 char *text ); 113 114 115 116 /*---------------------------------------------------------------------------- 117 -- Functions 118 ----------------------------------------------------------------------------*/ 119 120 Boolean xtmMbSendMessage(XTM_GL_BASE_DATA_REF appl_data_ref,Widget mainW,int msg_to_count,XmStringTable msg_to,Boolean only_mail,Boolean mail_fail,TIM_TIME_REF entry_date,TIM_TIME_REF entry_time,int duration,char * message,char * text)121 xtmMbSendMessage( XTM_GL_BASE_DATA_REF appl_data_ref, 122 Widget mainW, 123 int msg_to_count, 124 XmStringTable msg_to, 125 Boolean only_mail, 126 Boolean mail_fail, 127 TIM_TIME_REF entry_date, 128 TIM_TIME_REF entry_time, 129 int duration, 130 char *message, 131 char *text ) 132 { 133 134 /* Type definitions. */ 135 typedef enum { MESSAGE, MAIL } MESSAGE_TYPE; 136 typedef enum { NONE, CALENDAR, GROUP } RECIPIENT_TYPE; 137 138 /* Variables. */ 139 Boolean ok; 140 int alloc_size; 141 int index; 142 char recipient_buffer[ 250 ]; 143 char *char_ref; 144 char *recipients; 145 char *recipient_ref; 146 MESSAGE_TYPE message_type; 147 RECIPIENT_TYPE recipient_type; 148 TIM_TIME_REF default_date; 149 TIM_TIME_REF default_time; 150 XTM_GD_ENTRY group_info; 151 152 153 /* Code. */ 154 155 default_time = TimMakeTime( 1970, 1, 1, 12, 0, 0 ); 156 default_date = TimLocalTime( TimMakeTimeNow() ); 157 default_date = TimMakeTime( TimIndexOfYear( default_date ), 158 TimIndexOfMonth( default_date ), 159 TimIndexOfDay( default_date ), 160 0, 0, 0 ); 161 162 if( entry_date <= 0 ) 163 entry_date = default_date; 164 165 if( entry_time <= 0 ) 166 entry_time = default_time; 167 168 169 /* Buffer for recipients. */ 170 recipients = (char *) SysMalloc( SEGMENT_SIZE ); 171 alloc_size = SEGMENT_SIZE; 172 *recipients = '\0'; 173 174 175 /* Expand databases, groups and mail addresses. */ 176 index = 0; 177 178 while( index < msg_to_count ) { 179 180 char_ref = xitStringGetString( *(msg_to + index), CS ); 181 182 sscanf( char_ref, "%s", recipient_buffer ); 183 SysFree( char_ref ); 184 185 recipient_ref = recipient_buffer; 186 187 188 /* Find the type of recipient. */ 189 recipient_type = CALENDAR; 190 191 /* A group? */ 192 ok = xtmGdFetchNamedGroup( appl_data_ref -> custom_data -> group_db_handle, 193 recipient_ref, &group_info ); 194 195 if( ok ) { 196 recipient_type = GROUP; 197 198 if( group_info.members != NULL ) 199 recipient_ref = group_info.members; 200 else 201 recipient_type = NONE; 202 } 203 204 205 /* Save the recipient(s). */ 206 if( recipient_type != NONE ) { 207 208 int append_size; 209 int extend_size; 210 211 append_size = strlen( recipient_ref ) + 5; 212 213 /* Any space left? */ 214 if( strlen( recipients ) + append_size >= alloc_size ) { 215 extend_size = max( append_size, SEGMENT_SIZE ); 216 217 alloc_size = alloc_size + extend_size + 5; 218 recipients = (char *) SysRealloc( recipients, alloc_size ); 219 } 220 221 strcat( recipients, recipient_ref ); 222 strcat( recipients, " " ); 223 224 if( recipient_type == GROUP ) 225 SysFree( recipient_ref ); 226 227 } /* if */ 228 229 index++; 230 231 } /* while */ 232 233 234 /* Start to send messages/mails. */ 235 recipient_ref = recipients; 236 237 do { 238 239 int char_read; 240 char location[ XTM_GL_MAX_DIR + 1 ]; 241 char *directory_ref; 242 char *mail_address; 243 XTM_CD_CAL_INFO db_info; 244 245 while( isspace( *recipient_ref ) ) 246 recipient_ref++; 247 248 if( *recipient_ref == '\0' ) 249 break; 250 251 char_read = strlen( recipient_ref ); 252 sscanf( recipient_ref, "%s%n", recipient_buffer, &char_read ); 253 recipient_ref = recipient_ref + char_read; 254 255 256 /* Where do we send the message? */ 257 mail_address = recipient_buffer; 258 directory_ref = NULL; 259 260 /* Fetch user diary DB directory. */ 261 ok = xtmCdFetchNamedDb( appl_data_ref -> custom_data -> cal_db_handle, 262 recipient_buffer, 263 &db_info, NULL ); 264 265 /* A 'real' calendar. */ 266 if( ok ) { 267 directory_ref = db_info.directory; 268 269 if( strlen( db_info.mail_address ) > 0 ) 270 mail_address = db_info.mail_address; 271 272 /* Try to locate the calendar. */ 273 } else { 274 ok = xtmLcLocateCalendar( 275 mainW, recipient_buffer, 276 appl_data_ref -> custom_data -> find_location_script, 277 location, sizeof( location ) ); 278 279 if( ok ) 280 directory_ref = location; 281 282 } /* if */ 283 284 285 /* What kind of message do we send? */ 286 if( only_mail ) 287 message_type = MAIL; 288 else 289 message_type = MESSAGE; 290 291 292 /* Try internal message. */ 293 if( message_type == MESSAGE ) { 294 295 ok = sendInternalMessage( appl_data_ref, mainW, 296 recipient_buffer, directory_ref, 297 entry_date, entry_time, duration, 298 message, text ); 299 300 /* If we failed, try normal mail message? */ 301 if( ! ok && mail_fail ) 302 message_type = MAIL; 303 304 } /* if */ 305 306 307 /* Try mail message. */ 308 if( message_type == MAIL ) 309 ok = sendMailMessage( appl_data_ref, mainW, 310 mail_address, 311 entry_date, entry_time, duration, 312 message, text ); 313 314 } while( True ); 315 316 317 /* Free occupied memory. */ 318 SysFree( recipients ); 319 320 321 return( True ); 322 323 } /* xtmMbSendMessage */ 324 325 326 /*----------------------------------------------------------------------*/ 327 328 static Boolean sendInternalMessage(XTM_GL_BASE_DATA_REF appl_data_ref,Widget mainW,char * user_ref,char * directory,TIM_TIME_REF entry_date,TIM_TIME_REF entry_time,int duration,char * message,char * text)329 sendInternalMessage( XTM_GL_BASE_DATA_REF appl_data_ref, 330 Widget mainW, 331 char *user_ref, 332 char *directory, 333 TIM_TIME_REF entry_date, 334 TIM_TIME_REF entry_time, 335 int duration, 336 char *message, 337 char *text ) 338 { 339 340 /* Variables. */ 341 UINT32 operations; 342 XTM_DB_MESSAGE_DEF msg; 343 XTM_DB_STATUS db_status; 344 struct passwd *password_ref; 345 346 347 /* Code. */ 348 349 if( directory == NULL || strlen( directory ) == 0 ) 350 return( False ); 351 352 /* Fetch the database permissions. */ 353 xtmDbCheckDbOperations( directory, True, &operations ); 354 if( ! flagIsSet( operations, XTM_DB_FLAG_MODE_MSG ) ) 355 return( False ); 356 357 358 /* Construct the message record. */ 359 msg.version = XTM_DB_MESSAGE_VERSION; 360 msg.flags = 0; 361 msg.date = (UINT32) entry_date; 362 msg.time = (UINT32) entry_time; 363 msg.duration = (UINT16) duration; 364 msg.message_length = (UINT16) strlen( message ); 365 msg.text_length = (UINT16) strlen( text ); 366 367 368 /* Name of sender. */ 369 password_ref = getpwuid( getuid() ); 370 if( password_ref != NULL ) 371 strncpy( msg.from, password_ref -> pw_name, 20 ); 372 else 373 strcpy( msg.from, "---" ); 374 msg.from[ 20 ] = '\0'; 375 376 377 /* Send the message. */ 378 db_status = xtmDbInsertMessage( directory, &msg, message, text ); 379 if( db_status != XTM_DB_OK ) 380 return( False ); 381 382 383 return( True); 384 385 } /* sendInternalMessage */ 386 387 388 /*----------------------------------------------------------------------*/ 389 390 static Boolean sendMailMessage(XTM_GL_BASE_DATA_REF appl_data_ref,Widget mainW,char * mail_address,TIM_TIME_REF entry_date,TIM_TIME_REF entry_time,int duration,char * message,char * text)391 sendMailMessage( XTM_GL_BASE_DATA_REF appl_data_ref, 392 Widget mainW, 393 char *mail_address, 394 TIM_TIME_REF entry_date, 395 TIM_TIME_REF entry_time, 396 int duration, 397 char *message, 398 char *text ) 399 { 400 401 /* Variables. */ 402 char buffer1[ 41 ]; 403 char buffer2[ 41 ]; 404 char command[ 100 ]; 405 char duration_buffer[ 20 ]; 406 char time_buffer[ 40 ]; 407 char *char_ref; 408 FILE *file_ref; 409 410 411 /* Code. */ 412 413 /* The subject is the first 40 characters in the first line. */ 414 strncpy( buffer1, message, 40 ); 415 buffer1[ 40 ] = '\0'; 416 417 char_ref = strchr( buffer1, '\n' ); 418 if( char_ref != NULL ) 419 *char_ref = '\0'; 420 421 if( strlen( buffer1 ) == 0 ) 422 strcpy( buffer1, "---" ); 423 424 /* Construct command. */ 425 sprintf( command, "mail -s '%s' %s", buffer1, mail_address ); 426 427 428 /* Make the entry time field. */ 429 xtmFoFormatDate( entry_date, buffer1, sizeof( buffer1 ) ); 430 xtmFoFormatTime( entry_time, buffer2, sizeof( buffer2 ) ); 431 432 sprintf( time_buffer, "%s %s", buffer1, buffer2 ); 433 434 435 /* Make the duration field. */ 436 sprintf( duration_buffer, "%2d:%02d", duration / 60, duration % 60 ); 437 438 439 /* Open pipe to send mail. */ 440 file_ref = (FILE *) popen( command, "w" ); 441 if( file_ref == NULL ) 442 return( False ); 443 444 445 /* Send the mail. */ 446 if( entry_date == 0 ) 447 fprintf( file_ref, "%s\n\n%s", message, text ); 448 else 449 fprintf( file_ref, msgGetText( MXDI_ENTRY_MAIL_MESSAGE ), 450 message, time_buffer, duration_buffer, text ); 451 452 453 /* That's it. */ 454 #ifdef XD_HAS_NO_WAITPID 455 fclose( file_ref ); 456 #else 457 pclose( file_ref ); 458 #endif 459 460 return( True ); 461 462 } /* sendMailMessage */ 463 464 465 466 467