static int mail_AttachFiles( KMail mail, KMsg msg, const char * boundary ) { struct _MFile file = { NULL, NULL }; Pair afile = lfirst( msg->afiles ); file.headers = snew(); while( afile ) { if( !msg_CreateFile( msg, &file, mail->error, boundary, F_NAME(afile), F_CTYPE(afile), "attachment", NULL ) ) { return delMFile( &file ); } if( !smtp_write( mail->smtp, sstr( file.headers ) ) || !smtp_write( mail->smtp, sstr( file.body ) ) || !smtp_write( mail->smtp, "\r\n" ) ) { mail_FormatError( mail, "mail_AttachFiles(\"%s\"), internal error", F_NAME(afile) ); return delMFile( &file ); } afile = lnext( msg->afiles ); } delMFile( &file ); return 1; }
/** * port_add_internal * * < private > * Unsafe, need lock fen_lock. */ static gboolean port_add_internal (file_obj_t* fobj, off_t* len, gpointer f, gboolean need_stat) { int ret; struct stat buf; _f* fo = NULL; g_assert (f && fobj); FK_W ("%s [0x%p] %s\n", __func__, f, fobj->fo_name); if ((fo = g_hash_table_lookup (_obj_fen_hash, f)) == NULL) { fo = g_new0 (_f, 1); fo->fobj = fobj; fo->user_data = f; g_assert (fo); FK_W ("[ NEW_FO ] [0x%p] %s\n", fo, F_NAME(fo)); g_hash_table_insert (_obj_fen_hash, f, fo); } if (fo->is_active) { return TRUE; } if (fo->port == NULL) { fo->port = pnode_new (); } if (need_stat) { if (FN_STAT (F_NAME(fo), &buf) != 0) { FK_W ("LSTAT [%-20s] %s\n", F_NAME(fo), g_strerror (errno)); goto L_exit; } g_assert (len); fo->fobj->fo_atime = buf.st_atim; fo->fobj->fo_mtime = buf.st_mtim; fo->fobj->fo_ctime = buf.st_ctim; *len = buf.st_size; } if (port_associate (F_PORT(fo), PORT_SOURCE_FILE, (uintptr_t)fo->fobj, FEN_ALL_EVENTS, (void *)fo) == 0) { fo->is_active = TRUE; FK_W ("%s %s\n", "PORT_ASSOCIATE", F_NAME(fo)); return TRUE; } else { FK_W ("PORT_ASSOCIATE [%-20s] %s\n", F_NAME(fo), g_strerror (errno)); L_exit: FK_W ("[ FREE_FO ] [0x%p]\n", fo); g_hash_table_remove (_obj_fen_hash, f); pnode_delete (fo->port); g_free (fo); } return FALSE; }
/** * port_remove * * < private > * Unsafe, need lock fen_lock. */ void port_remove (gpointer f) { _f* fo = NULL; FK_W ("%s\n", __func__); if ((fo = g_hash_table_lookup (_obj_fen_hash, f)) != NULL) { /* Marked */ fo->user_data = NULL; g_hash_table_remove (_obj_fen_hash, f); if (port_dissociate (F_PORT(fo), PORT_SOURCE_FILE, (uintptr_t)fo->fobj) == 0) { /* * Note, we can run foode_delete if dissociating is failed, * because there may be some pending events (mostly like * FILE_DELETE) in the port_get. If we delete the foode * the fnode may be deleted, then port_get will run on an invalid * address. */ FK_W ("[ FREE_FO ] [0x%p]\n", fo); pnode_delete (fo->port); g_free (fo); } else { FK_W ("PORT_DISSOCIATE [%-20s] %s\n", F_NAME(fo), g_strerror (errno)); } } }
static gboolean port_fetch_event_cb (void *arg) { pnode_t *pn = (pnode_t *)arg; _f* fo; uint_t nget = 0; port_event_t pe[PE_ALLOC]; timespec_t timeout; gpointer f; gboolean ret = TRUE; /* FK_W ("IN <======== %s\n", __func__); */ G_LOCK (fen_lock); memset (&timeout, 0, sizeof (timespec_t)); do { nget = 1; if (port_getn (pn->port, pe, PE_ALLOC, &nget, &timeout) == 0) { int i; for (i = 0; i < nget; i++) { fo = (_f*)pe[i].portev_user; /* handle event */ switch (pe[i].portev_source) { case PORT_SOURCE_FILE: /* If got FILE_EXCEPTION or add to port failed, delete the pnode */ fo->is_active = FALSE; if (fo->user_data) { FK_W("%s\n", printevent(F_NAME(fo), pe[i].portev_events, "RAW")); port_add_kevent (pe[i].portev_events, fo->user_data); } else { /* fnode is deleted */ goto L_delete; } if (pe[i].portev_events & FILE_EXCEPTION) { g_hash_table_remove (_obj_fen_hash, fo->user_data); L_delete: FK_W ("[ FREE_FO ] [0x%p]\n", fo); pnode_delete (fo->port); g_free (fo); } break; default: /* case PORT_SOURCE_TIMER: */ FK_W ("[kernel] unknown portev_source %d\n", pe[i].portev_source); } } } else { FK_W ("[kernel] port_getn %s\n", g_strerror (errno)); nget = 0; } } while (nget == PE_ALLOC); /* Processing g_eventq */ port_process_kevents (); if (pn->ref == 0) { pn->port_source_id = 0; ret = FALSE; } G_UNLOCK (fen_lock); /* FK_W ("OUT ========> %s\n", __func__); */ return ret; }